Return to post
settings
{
main
{
Description: "Path node builder v0.7 CODE: QRD5A Use this tool to create path nodes for your PvE modes. Build project into EXPORT VARS, copy it and paste in your mode. Read more instructions in WORKSHOP SETTINGS"
}
lobby
{
Max Team 1 Players: 1
Max Team 2 Players: 1
Return To Lobby: Never
}
modes
{
Assault
{
enabled maps
{
}
}
Control
{
enabled maps
{
}
}
Escort
{
enabled maps
{
Havana
}
}
Hybrid
{
enabled maps
{
}
}
Team Deathmatch
{
enabled maps
{
}
}
General
{
Enemy Health Bars: Off
Game Mode Start: Manual
Hero Limit: Off
Kill Cam: Off
Kill Feed: Off
Respawn Time Scalar: 0%
Skins: Off
Spawn Health Packs: Disabled
}
}
workshop
{
PLAYER MOVEMENT SPEED: 180
SPAWN ROOM: [2]
}
extensions
{
Play More Effects
}
}
variables
{
global:
0: WorkshopSettingInstructions
1: PropertySpawnRoomIndex
2: PropertyPlayerMovementSpeed
3: PropertyBotMovementSpeed
4: PropertyFreeCamera
5: BuilderHudColorCurrent
6: BuilderHudColorBuildMode
7: BuilderHudColorEditMode
8: BuilderHudColorPathFindingMode
9: BuilderMode
10: LoopIterator1
11: LoopIterator2
12: LoopIterator3
13: StringConcatNodeId
14: StringConcatResult
15: StringConcatCountOfElements
16: BuilderRayCastHitPosition
17: BuilderNodePositions
18: BuilderNodeConnections
19: BuilderNodeEffectIdArray
20: BuilderNodeConnectionEffectsId
21: BuilderNodeWorldTextIdArray
22: BuilderSelectedNodeEffectPos
23: BuilderTrySelectNodeInLOS
24: BuilderSelectedNodeId
25: BuilderInnerArray
26: BuilderIsNodeHaveConnection
27: IsBuildingProject
28: BuilderProgressBarValue
29: BuilderProgressBarValueStep
30: BuildProjectEmptySpace
31: BuildProjectNewElementIndex
32: BuildProjectOldElementIndex
33: BuildProjectQueueArray
34: BuildProjectVisitedNodes
35: BuildProjectCurrentNodeId
36: BuildProjectStartNodeId
37: BuildProjectNeighborNodeId
38: PathFindingStartNodeEffectPos
39: PathFindingTargetNodeEffectPos
40: BeamEffects
41: PathFindingStartNodeId
42: PathFindingTargetNodeId
43: PathFindingResultPath
44: PathFindingShortestDistance
45: PathFindingCurrentDistance
46: PathFindingCurrentNodeId
47: PathFindingBotId
48: NodeTriggerRadius
49: PathFindingStartPosition
50: PathFindingTargetPosition
125: NodePositions
126: NodeConnections
127: DistanceMatrix
player:
0: BuilderModeInfoHudId
119: BotLoopIterator1
120: BotTempArray
121: BotTargetPlayer
122: BotTargetPosition
123: BotTargetNodeId
124: BotCurrentNodeId
125: BotCurrentDistance
126: BotShortestDistance
116: BotLoopIterator1
117: BotTempArray
118: BotTargetPlayer
119: BotTargetPosition
120: BotClosestNodeIdToTarget
121: BotClosestNodeIdToBot
122: BotPrevNodeId
123: BotNextNodeId
124: BotNextNodePosition
125: BotCurrentDistanceToTarget
126: BotShortestDistanceToTarget
127: BotIsPathFinding
}
subroutines
{
0: BuilderSwitchMode
1: BuilderEditModeSelectNode
2: BuilderEditModeDeleteNode
3: BuilderConcatStringConnections
4: BuilderDeleteConnectionsOfNode
5: BuilderConnectDisconnectSelector
6: BuilderConnectNodeBackendLogic
7: BuilderConnectNodeBeamEffect
8: BuilderDisconnectNode
9: BuilderBuildModeCreateNewNode
10: BuilderDeleteAllEffects
11: BuilderBuildProject
12: BuilderOptimizeData
13: BuilderUpdateConnectionIndexes
14: BuilderInitModEffects
15: BuilderBuildPreparedPathNodes
16: BuilderComputeDistanceMatrix
17: BuilderGetClossestNodeIdToCursor
18: PathFindingModeSelectNode
19: PathFindingModeReset
20: DeleteNodeBeams
21: CreateNodeBeams
22: PathFindingGetShortestPath
23: PathFindingCreateBot
24: PathFindingResetBot
124: BotGetCurrentNodeId
125: BotGetTargetNodeId
126: BotGetNextNodeId
24: PathFindingTestBotReset
124: BotStartPathFinding
125: BotGetClosestNodeIdToTarget
126: BotGetNextNodeIdAndPosition
127: BotResetPathFinding
}
rule("=== PATH NODE BUILDER BY HUKUTA94#2589 ===")
{
event
{
Ongoing - Global;
}
actions
{
disabled Disable Inspector Recording;
Create HUD Text(All Players(All Teams), Null, Null, Custom String("PATH NODES BUILDER V{0} BY HUKUTA94#2589", 0.630), Right, -1000,
Create HUD Text(All Players(All Teams), Null, Null, Custom String("PATH NODES BUILDER V{0} BY HUKUTA94#2589", 0.700), Right, -1000,
Color(White), Color(White), Color(White), Visible To, Default Visibility);
}
}
disabled rule("=== EXPORT BLOCK START - COPY THESE RULES AND SUBROUTINES INTO YOUR MODE ===")
{
event
{
Ongoing - Global;
}
}
rule("MAP: WORKSHOP CHAMBER")
{
event
{
Ongoing - Global;
}
conditions
{
Current Map == Map(Workshop Chamber);
}
actions
{
Global.NodePositions = Array(Vector(-0.252, 0.425, -0.037), Vector(15.690, 0.425, 16.016), Vector(-15.527, 0.425, 15.911), Vector(
15.794, 0.425, -15.756), Vector(-15.781, 0.425, -15.775), Vector(-15.802, 0.425, -0.052), Vector(-0.262, 0.425, -15.790),
Vector(15.637, 0.425, -0.001), Vector(0.197, 0.425, 15.665), Vector(-8.102, 0.425, -7.910), Vector(8.013, 0.425, -7.859),
Vector(7.978, 0.425, 8.089), Vector(-8.046, 0.425, 8.175));
Global.NodeConnections = Array(Array(6, 5, 7, 11, 8, 12, 9, 10), Array(7, 11, 8), Array(8, 12, 5), Array(10, 6, 7), Array(9, 6, 5),
Array(2, 12, 9, 4), Array(9, 4, 10, 3), Array(10, 3, 11, 1), Array(1, 11, 12, 2, 0), Array(6, 4, 5, 0), Array(6, 3, 7, 0),
Array(8, 7, 1, 0), Array(2, 5, 8, 0));
Global.DistanceMatrix = Array(Array(9999, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1), Array(2, 9999, 2, 2, 4, 3, 3, 1, 1, 3, 2, 1, 2),
Array(2, 2, 9999, 4, 2, 1, 3, 3, 1, 2, 3, 2, 1), Array(2, 2, 4, 9999, 2, 3, 1, 1, 3, 2, 1, 2, 3), Array(2, 4, 2, 2, 9999, 1, 1,
3, 3, 1, 2, 3, 2), Array(2, 3, 1, 3, 1, 9999, 2, 3, 2, 1, 3, 3, 1), Array(2, 3, 3, 1, 1, 2, 9999, 2, 3, 1, 1, 3, 3), Array(2,
1, 3, 1, 3, 3, 2, 9999, 2, 3, 1, 1, 3), Array(1, 1, 1, 3, 3, 2, 2, 2, 9999, 2, 2, 1, 1), Array(1, 3, 2, 2, 1, 1, 1, 2, 2, 9999,
2, 2, 2), Array(1, 2, 3, 1, 2, 2, 1, 1, 2, 2, 9999, 2, 2), Array(1, 1, 2, 2, 3, 2, 2, 1, 1, 2, 2, 9999, 2), Array(1, 2, 1, 3,
2, 1, 2, 2, 1, 2, 2, 2, 9999));
}
}
rule("MAP: WORKSHOP ISLAND")
{
event
{
Ongoing - Global;
}
conditions
{
Current Map == Map(Workshop Island);
}
actions
{
Global.NodePositions = Array(Vector(-16.004, 0.350, -15.965), Vector(-15.994, 0.350, -0.043), Vector(-15.981, 0.350, 15.908),
Vector(15.941, 0.350, 16.021), Vector(15.980, 0.350, -15.878), Vector(-1.423, 0.350, -16.035), Vector(-1.225, 0.350, 4.747),
Vector(7.259, 0.350, -0.358));
Global.NodeConnections = Array(Array(5, 1, 6), Array(0, 2), Array(3, 1), Array(2, 6, 4), Array(5, 3, 7), Array(4, 0, 7), Array(0,
3, 7), Array(6, 5, 4));
Global.DistanceMatrix = Array(Array(9999, 1, 2, 2, 2, 1, 1, 2), Array(1, 9999, 1, 2, 3, 2, 2, 3), Array(2, 1, 9999, 1, 2, 3, 2, 3),
Array(2, 2, 1, 9999, 1, 2, 1, 2), Array(2, 3, 2, 1, 9999, 1, 2, 1), Array(1, 2, 3, 2, 1, 9999, 2, 1), Array(1, 2, 2, 1, 2, 2,
9999, 1), Array(2, 3, 3, 2, 1, 1, 1, 9999));
}
}
rule("MAP: HAVANA")
{
event
{
Ongoing - Global;
}
conditions
{
Current Map == Map(Havana);
}
actions
{
Global.NodePositions = Array(Vector(126.542, 12.733, -63.277), Vector(113.402, 7.319, -57.302), Vector(147.588, 6.425, -46.749),
Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504,
-46.633), Vector(146.311, 9.444, -61.382), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, -32.974), Vector(126.498,
6.425, -39.920), Vector(148.529, 9.425, -28.549), Vector(134.970, 10.396, -27.167), Vector(124.572, 10.434, -34.300), Vector(
138.605, 5.359, -18.647), Vector(119.009, 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505),
Vector(102.762, 3.157, -33.609), Vector(76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238,
-42.379), Vector(86.252, 12.416, -47.261), Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(99.937,
2.983, -67.099), Vector(113.039, 7.424, -37.337), Vector(106.552, 0.149, -53.045), Vector(120.953, 13.171, -58.443), Vector(
106.179, 7.450, -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229),
Vector(90.675, 7.231, -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(95.569, 3.646, -79.682),
Vector(102.425, 2.387, -72.817), Vector(81.443, 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419,
-96.344), Vector(78.682, 5.418, -96.160), Vector(153.887, 18.628, -22.387));
Global.NodeConnections = Array(Array(7, 3, 6, 28), Array(5, 8, 27), Array(3, 9, 6, 10), Array(4, 7, 2, 6, 9, 10), Array(3, 5),
Array(4, 6, 1), Array(5, 3, 8, 10, 9, 2), Array(3, 0), Array(1, 6, 10, 26, 29), Array(10, 11, 2, 6, 3, 14, 17), Array(6, 8, 9,
2, 3, 17), Array(9, 12), Array(11, 9, 13), Array(12, 10), Array(9, 16), Array(16, 18), Array(14, 15, 18), Array(9, 15), Array(
15, 21, 27), Array(23, 31, 39), Array(22, 32), Array(18, 24, 30, 29, 33), Array(20, 30, 21, 33, 29), Array(19), Array(25, 21,
29, 30, 34, 35, 38), Array(24, 27, 33, 34, 35, 37), Array(8, 18, 15), Array(18, 25), Array(0, 3, 6, 1), Array(24, 21, 8, 18,
25, 30), Array(21, 24, 29, 32, 33), Array(19, 33, 34, 25, 35, 36), Array(30, 20, 31), Array(31, 30, 24, 25, 21, 34, 35), Array(
33, 24, 25, 35), Array(25, 24, 34, 33, 36, 38), Array(37, 35, 38), Array(36, 25), Array(36, 35, 34, 24, 39, 41), Array(38, 19,
40), Array(39, 38), Array(38), Array());
Global.DistanceMatrix = Array(Array(9999, 2, 2, 1, 2, 2, 1, 1, 2, 2, 2, 3, 4, 5, 3, 4, 4, 3, 4, 7, 6, 4, 7, 8, 4, 4, 3, 3, 1, 3, 4,
6, 5, 5, 5, 5, 6, 5, 5, 6, 7, 6), Array(5, 9999, 3, 3, 2, 1, 2, 4, 1, 3, 2, 4, 5, 6, 4, 3, 4, 3, 2, 5, 5, 3, 6, 6, 3, 2, 2, 1,
6, 2, 3, 4, 4, 3, 3, 3, 4, 3, 4, 5, 6, 5), Array(3, 3, 9999, 1, 2, 2, 1, 2, 2, 1, 1, 2, 3, 4, 2, 3, 3, 2, 4, 7, 6, 4, 7, 8, 4,
4, 3, 4, 4, 3, 4, 6, 5, 5, 5, 5, 6, 5, 5, 6, 7, 6), Array(2, 3, 1, 9999, 1, 2, 1, 1, 2, 1, 1, 2, 3, 4, 2, 3, 3, 2, 4, 7, 6, 4,
7, 8, 4, 4, 3, 4, 3, 3, 4, 6, 5, 5, 5, 5, 6, 5, 5, 6, 7, 6), Array(3, 2, 2, 1, 9999, 1, 2, 2, 3, 2, 2, 3, 4, 5, 3, 4, 4, 3, 4,
7, 7, 5, 8, 8, 5, 4, 4, 3, 4, 4, 5, 6, 6, 5, 5, 5, 6, 5, 6, 7, 8, 7), Array(4, 1, 2, 2, 1, 9999, 1, 3, 2, 2, 2, 3, 4, 5, 3, 4,
4, 3, 3, 6, 6, 4, 7, 7, 4, 3, 3, 2, 5, 3, 4, 5, 5, 4, 4, 4, 5, 4, 5, 6, 7, 6), Array(3, 2, 1, 1, 2, 1, 9999, 2, 1, 1, 1, 2, 3,
4, 2, 3, 3, 2, 3, 6, 5, 3, 6, 7, 3, 3, 2, 3, 4, 2, 3, 5, 4, 4, 4, 4, 5, 4, 4, 5, 6, 5), Array(1, 3, 2, 1, 2, 3, 2, 9999, 3, 2,
2, 3, 4, 5, 3, 4, 4, 3, 5, 8, 7, 5, 8, 9, 5, 5, 4, 4, 2, 4, 5, 7, 6, 6, 6, 6, 7, 6, 6, 7, 8, 7), Array(4, 1, 2, 2, 3, 2, 1, 3,
9999, 2, 1, 3, 4, 5, 3, 2, 3, 2, 2, 5, 4, 2, 5, 6, 2, 2, 1, 2, 5, 1, 2, 4, 3, 3, 3, 3, 4, 3, 3, 4, 5, 4), Array(3, 3, 1, 1, 2,
2, 1, 2, 2, 9999, 1, 1, 2, 3, 1, 2, 2, 1, 3, 7, 6, 4, 7, 8, 4, 4, 3, 4, 4, 3, 4, 6, 5, 5, 5, 5, 6, 5, 5, 6, 7, 6), Array(3, 2,
1, 1, 2, 2, 1, 2, 1, 1, 9999, 2, 3, 4, 2, 2, 3, 1, 3, 6, 5, 3, 6, 7, 3, 3, 2, 3, 4, 2, 3, 5, 4, 4, 4, 4, 5, 4, 4, 5, 6, 5),
Array(4, 4, 2, 2, 3, 3, 2, 3, 3, 1, 2, 9999, 1, 2, 2, 3, 3, 2, 4, 8, 7, 5, 8, 9, 5, 5, 4, 5, 5, 4, 5, 7, 6, 6, 6, 6, 7, 6, 6,
7, 8, 7), Array(4, 4, 2, 2, 3, 3, 2, 3, 3, 1, 2, 1, 9999, 1, 2, 3, 3, 2, 4, 8, 7, 5, 8, 9, 5, 5, 4, 5, 5, 4, 5, 7, 6, 6, 6, 6,
7, 6, 6, 7, 8, 7), Array(4, 3, 2, 2, 3, 3, 2, 3, 2, 2, 1, 2, 1, 9999, 3, 3, 4, 2, 4, 7, 6, 4, 7, 8, 4, 4, 3, 4, 5, 3, 4, 6, 5,
5, 5, 5, 6, 5, 5, 6, 7, 6), Array(4, 4, 2, 2, 3, 3, 2, 3, 3, 1, 2, 2, 3, 4, 9999, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 3, 5, 4,
4, 5, 5, 4, 5, 5, 6, 5, 5, 6, 7, 6), Array(6, 5, 4, 4, 5, 5, 4, 5, 4, 3, 4, 4, 5, 6, 2, 9999, 1, 4, 1, 5, 5, 2, 6, 6, 3, 3, 5,
2, 7, 3, 3, 4, 4, 3, 4, 4, 5, 4, 4, 5, 6, 5), Array(5, 5, 3, 3, 4, 4, 3, 4, 4, 2, 3, 3, 4, 5, 1, 1, 9999, 3, 1, 5, 5, 2, 6, 6,
3, 3, 5, 2, 6, 3, 3, 4, 4, 3, 4, 4, 5, 4, 4, 5, 6, 5), Array(4, 4, 2, 2, 3, 3, 2, 3, 3, 1, 2, 2, 3, 4, 2, 1, 2, 9999, 2, 6, 6,
3, 7, 7, 4, 4, 4, 3, 5, 4, 4, 5, 5, 4, 5, 5, 6, 5, 5, 6, 7, 6), Array(7, 4, 5, 5, 6, 5, 4, 6, 3, 4, 4, 5, 6, 7, 3, 1, 2, 5,
9999, 4, 4, 1, 5, 5, 2, 2, 4, 1, 8, 2, 2, 3, 3, 2, 3, 3, 4, 3, 3, 4, 5, 4), Array(9, 6, 7, 7, 8, 7, 6, 8, 5, 7, 6, 8, 9, 10, 7,
5, 6, 7, 4, 9999, 5, 3, 6, 1, 3, 2, 6, 3, 10, 4, 3, 1, 4, 2, 2, 2, 2, 3, 2, 1, 2, 3), Array(7, 4, 5, 5, 6, 5, 4, 6, 3, 5, 4, 6,
7, 8, 6, 4, 5, 5, 3, 3, 9999, 2, 1, 4, 3, 3, 4, 4, 8, 2, 2, 2, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5), Array(6, 3, 4, 4, 5, 4, 3, 5, 2,
4, 3, 5, 6, 7, 4, 2, 3, 4, 1, 3, 3, 9999, 4, 4, 1, 2, 3, 2, 7, 1, 1, 2, 2, 1, 2, 2, 3, 3, 2, 3, 4, 3), Array(6, 3, 4, 4, 5, 4,
3, 5, 2, 4, 3, 5, 6, 7, 5, 3, 4, 4, 2, 3, 1, 1, 9999, 4, 2, 2, 3, 3, 7, 1, 1, 2, 2, 1, 2, 2, 3, 3, 3, 4, 5, 4), Array(10, 7, 8,
8, 9, 8, 7, 9, 6, 8, 7, 9, 10, 11, 8, 6, 7, 8, 5, 1, 6, 4, 7, 9999, 4, 3, 7, 4, 11, 5, 4, 2, 5, 3, 3, 3, 3, 4, 3, 2, 3, 4),
Array(6, 3, 4, 4, 5, 4, 3, 5, 2, 4, 3, 5, 6, 7, 5, 3, 4, 4, 2, 3, 3, 1, 4, 4, 9999, 1, 3, 2, 7, 1, 1, 3, 2, 2, 1, 1, 2, 2, 1,
2, 3, 2), Array(7, 4, 5, 5, 6, 5, 4, 6, 3, 5, 4, 6, 7, 8, 5, 3, 4, 5, 2, 3, 4, 2, 5, 4, 1, 9999, 4, 1, 8, 2, 2, 2, 3, 1, 1, 1,
2, 1, 2, 3, 4, 3), Array(5, 2, 3, 3, 4, 3, 2, 4, 1, 3, 2, 4, 5, 6, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 3, 3, 9999, 2, 6, 2, 3, 4, 4,
3, 4, 4, 5, 4, 4, 5, 6, 5), Array(8, 5, 6, 6, 7, 6, 5, 7, 4, 5, 5, 6, 7, 8, 4, 2, 3, 6, 1, 4, 5, 2, 6, 5, 2, 1, 5, 9999, 9, 3,
3, 3, 4, 2, 2, 2, 3, 2, 3, 4, 5, 4), Array(1, 1, 2, 1, 2, 2, 1, 2, 2, 2, 2, 3, 4, 5, 3, 4, 4, 3, 3, 6, 6, 4, 7, 7, 4, 3, 3, 2,
9999, 3, 4, 5, 5, 4, 4, 4, 5, 4, 5, 6, 7, 6), Array(5, 2, 3, 3, 4, 3, 2, 4, 1, 3, 2, 4, 5, 6, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1,
1, 2, 2, 6, 9999, 1, 3, 2, 2, 2, 2, 3, 2, 2, 3, 4, 3), Array(6, 3, 4, 4, 5, 4, 3, 5, 2, 4, 3, 5, 6, 7, 5, 3, 4, 4, 2, 3, 2, 1,
3, 4, 1, 2, 3, 3, 7, 1, 9999, 2, 1, 1, 2, 2, 3, 3, 2, 3, 4, 3), Array(8, 5, 6, 6, 7, 6, 5, 7, 4, 6, 5, 7, 8, 9, 6, 4, 5, 6, 3,
1, 4, 2, 5, 2, 2, 1, 5, 2, 9, 3, 2, 9999, 3, 1, 1, 1, 1, 2, 2, 2, 3, 3), Array(7, 4, 5, 5, 6, 5, 4, 6, 3, 5, 4, 6, 7, 8, 6, 4,
5, 5, 3, 2, 1, 2, 2, 3, 2, 2, 4, 3, 8, 2, 1, 1, 9999, 2, 2, 2, 2, 3, 3, 3, 4, 4), Array(7, 4, 5, 5, 6, 5, 4, 6, 3, 5, 4, 6, 7,
8, 5, 3, 4, 5, 2, 2, 3, 1, 4, 3, 1, 1, 4, 2, 8, 2, 1, 1, 2, 9999, 1, 1, 2, 2, 2, 3, 4, 3), Array(7, 4, 5, 5, 6, 5, 4, 6, 3, 5,
4, 6, 7, 8, 6, 4, 5, 5, 3, 3, 4, 2, 5, 4, 1, 1, 4, 2, 8, 2, 2, 2, 3, 1, 9999, 1, 2, 2, 2, 3, 4, 3), Array(7, 4, 5, 5, 6, 5, 4,
6, 3, 5, 4, 6, 7, 8, 6, 4, 5, 5, 3, 3, 4, 2, 5, 4, 1, 1, 4, 2, 8, 2, 2, 2, 3, 1, 1, 9999, 1, 2, 1, 2, 3, 2), Array(8, 5, 6, 6,
7, 6, 5, 7, 4, 6, 5, 7, 8, 9, 7, 5, 6, 6, 4, 3, 5, 3, 6, 4, 2, 2, 5, 3, 9, 3, 3, 3, 4, 2, 2, 1, 9999, 1, 1, 2, 3, 2), Array(8,
5, 6, 6, 7, 6, 5, 7, 4, 6, 5, 7, 8, 9, 6, 4, 5, 6, 3, 4, 5, 3, 6, 5, 2, 1, 5, 2, 9, 3, 3, 3, 4, 2, 2, 2, 1, 9999, 2, 3, 4, 3),
Array(7, 4, 5, 5, 6, 5, 4, 6, 3, 5, 4, 6, 7, 8, 6, 4, 5, 5, 3, 2, 4, 2, 5, 3, 1, 2, 4, 3, 8, 2, 2, 3, 3, 2, 1, 1, 1, 2, 9999,
1, 2, 1), Array(8, 5, 6, 6, 7, 6, 5, 7, 4, 6, 5, 7, 8, 9, 7, 5, 6, 6, 4, 1, 5, 3, 6, 2, 2, 3, 5, 4, 9, 3, 3, 2, 4, 3, 2, 2, 2,
3, 1, 9999, 1, 2), Array(8, 5, 6, 6, 7, 6, 5, 7, 4, 6, 5, 7, 8, 9, 7, 5, 6, 6, 4, 2, 5, 3, 6, 3, 2, 3, 5, 4, 9, 3, 3, 3, 4, 3,
2, 2, 2, 3, 1, 1, 9999, 2), Array(8, 5, 6, 6, 7, 6, 5, 7, 4, 6, 5, 7, 8, 9, 7, 5, 6, 6, 4, 3, 5, 3, 6, 4, 2, 3, 5, 4, 9, 3, 3,
4, 4, 3, 2, 2, 2, 3, 1, 2, 3, 9999), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9999));
Global.NodePositions = Array(Vector(113.402, 7.319, -57.302), Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159),
Vector(130.189, 6.425, -63.781), Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(146.311, 9.444,
-61.382), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, -32.974), Vector(126.498, 6.425, -39.920), Vector(148.529,
9.425, -28.549), Vector(134.970, 10.396, -27.167), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(
119.009, 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609),
Vector(76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416,
-47.261), Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179,
7.450, -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675,
7.231, -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(95.569, 3.646, -79.682), Vector(
102.425, 2.387, -72.817), Vector(81.443, 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344),
Vector(78.682, 5.418, -96.160), Vector(153.887, 18.628, -22.387), Vector(127.586, 12.643, -63.344), Vector(118.911, 13.468,
-58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), Vector(81.695,
7.418, -52.140), Vector(125.118, 12.445, -57.134));
Global.NodeConnections = Array(Array(4, 7, 41), Array(2, 8, 5, 9), Array(3, 6, 1, 5, 8, 9), Array(2, 4), Array(3, 5, 1), Array(4,
2, 7, 9, 8, 1), Array(2, 39), Array(5, 9, 24, 25, 23), Array(9, 10, 1, 5, 2, 13, 16), Array(5, 7, 8, 1, 2, 16), Array(8, 11),
Array(10, 8, 12), Array(11, 9), Array(8, 15), Array(15, 17), Array(13, 14, 17), Array(8, 14), Array(14, 20, 43), Array(22, 27,
35), Array(21, 28), Array(17, 23, 26, 25, 29, 7), Array(19, 26, 20, 29, 25), Array(18), Array(20, 25, 26, 30, 31, 42, 29, 7),
Array(7, 17, 14), Array(23, 20, 7, 17, 26, 41), Array(20, 23, 25, 28, 29), Array(18, 29, 30), Array(26, 19, 44), Array(27, 26,
23, 20, 30, 31, 42, 44), Array(29, 23, 31, 42, 34), Array(23, 30, 29, 32, 34, 42), Array(33, 31, 34), Array(32, 42, 41), Array(
32, 31, 30, 35, 37), Array(34, 18, 36), Array(35, 34), Array(34), Array(), Array(6, 40, 45), Array(39, 41, 45), Array(42, 43,
33), Array(33, 23, 29, 31, 30, 41), Array(17, 41), Array(29, 27, 28), Array(39, 40, 5, 2, 1, 8));
Global.DistanceMatrix = Array(Array(9999, 2, 3, 2, 1, 2, 4, 1, 3, 2, 4, 5, 6, 4, 3, 4, 3, 3, 5, 5, 3, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3,
3, 3, 2, 4, 5, 6, 5, 0, 5, 6, 1, 2, 2, 4, 6), Array(0, 9999, 1, 2, 2, 1, 2, 2, 1, 1, 2, 3, 4, 2, 3, 3, 2, 4, 6, 6, 4, 7, 7, 3,
3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 5, 6, 7, 6, 0, 3, 4, 4, 4, 5, 5, 4), Array(0, 1, 9999, 1, 2, 1, 1, 2, 1, 1, 2, 3, 4, 2, 3, 3, 2,
4, 6, 6, 4, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 5, 6, 7, 6, 0, 2, 3, 4, 4, 5, 5, 3), Array(0, 2, 1, 9999, 1, 2, 2, 3, 2, 2,
3, 4, 5, 3, 4, 4, 3, 5, 7, 7, 5, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 6, 7, 8, 7, 0, 3, 4, 5, 5, 6, 6, 4), Array(0, 1, 2, 1,
9999, 1, 3, 2, 2, 2, 3, 4, 5, 3, 4, 4, 3, 4, 6, 6, 4, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 5, 6, 7, 6, 0, 4, 5, 4, 4, 5, 5,
5), Array(0, 1, 1, 2, 1, 9999, 2, 1, 1, 1, 2, 3, 4, 2, 3, 3, 2, 3, 5, 5, 3, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 4, 5, 6, 5,
0, 3, 4, 3, 3, 4, 4, 4), Array(0, 2, 1, 2, 3, 2, 9999, 3, 2, 2, 3, 4, 5, 3, 4, 4, 3, 5, 7, 7, 5, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5,
5, 5, 4, 6, 7, 8, 7, 0, 1, 2, 3, 4, 4, 6, 2), Array(0, 2, 2, 3, 2, 1, 3, 9999, 2, 1, 3, 4, 5, 3, 2, 3, 2, 2, 4, 4, 2, 5, 5, 1,
1, 1, 2, 3, 3, 2, 2, 2, 3, 3, 3, 4, 5, 4, 0, 4, 5, 2, 2, 3, 3, 5), Array(0, 1, 1, 2, 2, 1, 2, 2, 9999, 1, 1, 2, 3, 1, 2, 2, 1,
3, 6, 6, 4, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 5, 6, 7, 6, 0, 3, 4, 4, 4, 4, 5, 4), Array(0, 1, 1, 2, 2, 1, 2, 1, 1, 9999,
2, 3, 4, 2, 2, 3, 1, 3, 5, 5, 3, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 4, 5, 6, 5, 0, 3, 4, 3, 3, 4, 4, 4), Array(0, 2, 2, 3,
3, 2, 3, 3, 1, 2, 9999, 1, 2, 2, 3, 3, 2, 4, 7, 7, 5, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 6, 7, 8, 7, 0, 4, 5, 5, 5, 5, 6,
5), Array(0, 2, 2, 3, 3, 2, 3, 3, 1, 2, 1, 9999, 1, 2, 3, 3, 2, 4, 7, 7, 5, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 6, 7, 8, 7,
0, 4, 5, 5, 5, 5, 6, 5), Array(0, 2, 2, 3, 3, 2, 3, 2, 2, 1, 2, 1, 9999, 3, 3, 4, 2, 4, 6, 6, 4, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4,
4, 5, 5, 5, 6, 7, 6, 0, 4, 5, 4, 4, 5, 5, 5), Array(0, 2, 2, 3, 3, 2, 3, 3, 1, 2, 2, 3, 4, 9999, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4,
4, 4, 4, 5, 5, 4, 5, 5, 6, 5, 6, 7, 8, 7, 0, 4, 5, 4, 5, 3, 5, 5), Array(0, 4, 4, 5, 5, 4, 5, 3, 3, 4, 4, 5, 6, 2, 9999, 1, 4,
1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 5, 4, 5, 6, 7, 6, 0, 6, 7, 3, 4, 2, 4, 7), Array(0, 3, 3, 4, 4, 3, 4, 3, 2, 3, 3,
4, 5, 1, 1, 9999, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 5, 4, 5, 6, 7, 6, 0, 5, 6, 3, 4, 2, 4, 6), Array(0, 2, 2, 3,
3, 2, 3, 3, 1, 2, 2, 3, 4, 2, 1, 2, 9999, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, 5, 5, 6, 5, 6, 7, 8, 7, 0, 4, 5, 4, 5, 3, 5,
5), Array(0, 4, 4, 5, 4, 3, 5, 2, 4, 3, 5, 6, 7, 3, 1, 2, 4, 9999, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, 4, 3, 4, 5, 6, 5,
0, 6, 7, 2, 3, 1, 3, 7), Array(0, 6, 6, 7, 6, 5, 7, 4, 6, 5, 7, 8, 9, 7, 5, 6, 6, 4, 9999, 5, 3, 6, 1, 3, 5, 4, 3, 1, 4, 2, 2,
3, 3, 4, 2, 1, 2, 3, 0, 8, 9, 4, 3, 5, 3, 9), Array(0, 5, 5, 6, 5, 4, 6, 3, 5, 4, 6, 7, 8, 6, 4, 5, 5, 3, 4, 9999, 2, 1, 5, 3,
4, 2, 2, 3, 1, 2, 3, 3, 4, 4, 4, 5, 6, 5, 0, 7, 8, 3, 3, 4, 2, 8), Array(0, 3, 3, 4, 3, 2, 4, 1, 3, 2, 4, 5, 6, 4, 2, 3, 3, 1,
3, 3, 9999, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 3, 4, 5, 4, 0, 5, 6, 2, 2, 2, 2, 6), Array(0, 4, 4, 5, 4, 3, 5, 2, 4, 3, 5,
6, 7, 5, 3, 4, 4, 2, 3, 1, 1, 9999, 4, 2, 3, 1, 1, 2, 2, 1, 2, 2, 3, 3, 3, 4, 5, 4, 0, 6, 7, 2, 2, 3, 2, 7), Array(0, 7, 7, 8,
7, 6, 8, 5, 7, 6, 8, 9, 10, 8, 6, 7, 7, 5, 1, 6, 4, 7, 9999, 4, 6, 5, 4, 2, 5, 3, 3, 4, 4, 5, 3, 2, 3, 4, 0, 9, 10, 5, 4, 6, 4,
10), Array(0, 3, 3, 4, 3, 2, 4, 1, 3, 2, 4, 5, 6, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 9999, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 3, 4, 3,
0, 5, 6, 2, 1, 3, 2, 6), Array(0, 3, 3, 4, 3, 2, 4, 1, 3, 2, 4, 5, 6, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 9999, 2, 3, 4, 4, 3, 3,
3, 4, 4, 4, 5, 6, 5, 0, 5, 6, 3, 3, 2, 4, 6), Array(0, 3, 3, 4, 3, 2, 4, 1, 3, 2, 4, 5, 6, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2,
9999, 1, 3, 2, 2, 2, 2, 3, 2, 3, 4, 5, 4, 0, 5, 6, 1, 2, 2, 3, 6), Array(0, 4, 4, 5, 4, 3, 5, 2, 4, 3, 5, 6, 7, 5, 3, 4, 4, 2,
3, 2, 1, 3, 4, 1, 3, 1, 9999, 2, 1, 1, 2, 2, 3, 3, 3, 4, 5, 4, 0, 6, 7, 2, 2, 3, 2, 7), Array(0, 5, 5, 6, 5, 4, 6, 3, 5, 4, 6,
7, 8, 6, 4, 5, 5, 3, 1, 4, 2, 5, 2, 2, 4, 3, 2, 9999, 3, 1, 1, 2, 3, 3, 2, 2, 3, 3, 0, 7, 8, 3, 2, 4, 2, 8), Array(0, 5, 5, 6,
5, 4, 6, 3, 5, 4, 6, 7, 8, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 9999, 2, 3, 3, 4, 4, 4, 4, 5, 5, 0, 7, 8, 3, 3, 4, 1,
8), Array(0, 4, 4, 5, 4, 3, 5, 2, 4, 3, 5, 6, 7, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 9999, 1, 1, 2, 2, 2, 3, 4, 3,
0, 6, 7, 2, 1, 3, 1, 7), Array(0, 4, 4, 5, 4, 3, 5, 2, 4, 3, 5, 6, 7, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 9999,
1, 2, 2, 1, 2, 3, 2, 0, 6, 7, 2, 1, 3, 2, 7), Array(0, 4, 4, 5, 4, 3, 5, 2, 4, 3, 5, 6, 7, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3,
2, 2, 2, 3, 1, 1, 9999, 1, 2, 1, 2, 3, 2, 0, 6, 7, 2, 1, 3, 2, 7), Array(0, 5, 5, 6, 5, 4, 6, 3, 5, 4, 6, 7, 8, 6, 5, 6, 5, 4,
3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 9999, 1, 1, 2, 3, 2, 0, 7, 8, 2, 2, 3, 3, 8), Array(0, 5, 5, 6, 5, 4, 6, 3, 5, 4, 6,
7, 8, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 1, 9999, 2, 3, 4, 3, 0, 7, 8, 1, 1, 2, 3, 8), Array(0, 5, 5, 6,
5, 4, 6, 3, 5, 4, 6, 7, 8, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 1, 2, 9999, 1, 2, 1, 0, 7, 8, 3, 2, 4, 3,
8), Array(0, 6, 6, 7, 6, 5, 7, 4, 6, 5, 7, 8, 9, 7, 6, 7, 6, 5, 1, 6, 4, 7, 2, 3, 5, 4, 4, 2, 5, 3, 2, 2, 2, 3, 1, 9999, 1, 2,
0, 8, 9, 4, 3, 5, 4, 9), Array(0, 6, 6, 7, 6, 5, 7, 4, 6, 5, 7, 8, 9, 7, 6, 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2,
2, 3, 1, 1, 9999, 2, 0, 8, 9, 4, 3, 5, 4, 9), Array(0, 6, 6, 7, 6, 5, 7, 4, 6, 5, 7, 8, 9, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5,
4, 4, 4, 5, 3, 2, 2, 2, 3, 1, 2, 3, 9999, 0, 8, 9, 4, 3, 5, 4, 9), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9999), Array(0, 2, 2, 3, 3, 2, 1, 3, 2, 3, 3, 4, 5, 3, 4, 4, 3, 4,
6, 7, 5, 8, 7, 4, 4, 4, 5, 5, 6, 4, 4, 4, 4, 3, 5, 6, 7, 6, 0, 9999, 1, 2, 3, 3, 5, 1), Array(0, 2, 2, 3, 3, 2, 2, 3, 2, 3, 3,
4, 5, 3, 4, 4, 3, 3, 5, 6, 4, 7, 6, 3, 4, 4, 4, 4, 5, 3, 3, 3, 3, 2, 4, 5, 6, 5, 0, 1, 9999, 1, 2, 2, 4, 1), Array(0, 5, 5, 6,
5, 4, 6, 3, 5, 4, 6, 7, 8, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 2, 1, 3, 4, 5, 4, 0, 7, 8, 9999, 1, 1, 3,
8), Array(0, 4, 4, 5, 4, 3, 5, 2, 4, 3, 5, 6, 7, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 2, 1, 2, 3, 4, 3, 0,
6, 7, 1, 9999, 2, 2, 7), Array(0, 5, 5, 6, 5, 4, 6, 3, 5, 4, 6, 7, 8, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3,
3, 2, 4, 5, 6, 5, 0, 7, 8, 1, 2, 9999, 4, 8), Array(0, 5, 5, 6, 5, 4, 6, 3, 5, 4, 6, 7, 8, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4,
3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 0, 7, 8, 3, 2, 4, 9999, 8), Array(0, 1, 1, 2, 2, 1, 2, 2, 1, 2, 2, 3, 4, 2, 3, 3, 2, 4,
6, 6, 4, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 3, 5, 6, 7, 6, 0, 1, 1, 2, 3, 3, 5, 9999));
}
}
rule("SUBROUTINE: BOT - RESET PATH FINDING")
{
event
{
Subroutine;
BotResetPathFinding;
}
actions
{
Event Player.BotTargetPlayer = -1;
Event Player.BotTargetNodeId = -1;
Event Player.BotTargetPosition = -1;
Event Player.BotPrevNodeId = -1;
Event Player.BotClosestNodeIdToTarget = -1;
Event Player.BotNextNodeId = -1;
Event Player.BotNextNodePosition = -1;
Event Player.BotIsPathFinding = False;
Stop Facing(Event Player);
Stop Throttle In Direction(Event Player);
disabled Stop Facing(Event Player);
}
}
rule("SUBROUTINE: BOT - GET NEXT NODE ID")
rule("SUBROUTINE: BOT - START PATH FINDING")
{
event
{
Subroutine;
BotGetNextNodeId;
BotStartPathFinding;
}
actions
{
Event Player.BotShortestDistance = 999;
Event Player.BotCurrentDistance = Event Player.BotShortestDistance;
Event Player.BotTempArray = Global.NodeConnections[Event Player.BotCurrentNodeId];
For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotTempArray), 1);
If(Event Player.BotTempArray[Event Player.BotLoopIterator1] == Event Player.BotTargetNodeId);
Event Player.BotCurrentNodeId = Event Player.BotTargetNodeId;
Break;
End;
Event Player.BotCurrentDistance = Global.DistanceMatrix[Event Player.BotTempArray[Event Player.BotLoopIterator1]][Event Player.BotTargetNodeId];
If(Event Player.BotCurrentDistance < Event Player.BotShortestDistance);
Event Player.BotShortestDistance = Event Player.BotCurrentDistance;
Event Player.BotCurrentNodeId = Event Player.BotTempArray[Event Player.BotLoopIterator1];
End;
End;
Abort If(Event Player.BotIsPathFinding == True);
disabled Call Subroutine(BotGetClosestNodeIdToTarget);
Call Subroutine(BotGetNextNodeIdAndPosition);
Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World,
Direction and Turn Rate);
Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1,
To World, Replace existing throttle, Direction and Magnitude);
Event Player.BotIsPathFinding = True;
}
}
rule("SUBROUTINE: BOT - GET CURRENT NODE ID")
rule("SUBROUTINE: BOT - GET CLOSEST NODE ID TO TARGET")
{
event
{
Subroutine;
BotGetCurrentNodeId;
BotGetClosestNodeIdToTarget;
}
actions
{
Event Player.BotCurrentNodeId = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions,
Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True),
Distance Between(Position Of(Event Player), Current Array Element))[0]);
Event Player.BotTargetPosition = Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer)
: Event Player.BotTargetPosition;
Event Player.BotClosestNodeIdToTarget = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(
Global.NodePositions, Is In Line of Sight(Event Player.BotTargetPosition + Vector(0, 2, 0), Current Array Element,
Barriers Do Not Block LOS) == True), Distance Between(Event Player.BotTargetPosition, Current Array Element))[0]);
}
}
rule("SUBROUTINE: BOT - GET TARGET NODE ID")
rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION")
{
event
{
Subroutine;
BotGetTargetNodeId;
BotGetNextNodeIdAndPosition;
}
actions
{
Event Player.BotTargetPosition = Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer)
: Event Player.BotTargetPosition;
Event Player.BotTargetNodeId = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions,
Is In Line of Sight(Event Player.BotTargetPosition + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS)
== True), Distance Between(Event Player.BotTargetPosition, Current Array Element))[0]);
"BOT JUST START FOLLOW PATH OR LOST NEXT NODE"
If(Event Player.BotPrevNodeId == -1);
Log To Inspector(Custom String("PATH FINDING ({0}): BEGIN PATH FINDING", Event Player));
Event Player.BotClosestNodeIdToBot = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions,
Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True),
Distance Between(Position Of(Event Player), Current Array Element))[0]);
Call Subroutine(BotGetClosestNodeIdToTarget);
End;
"I. FIND NEXT NODE IN PATH"
Log To Inspector(Custom String("PATH FINDING ({0}): BEGIN FIND NEXT NODE FROM NODE #{1}", Event Player,
Event Player.BotClosestNodeIdToBot));
"ALWAYS UPDATE CLOSEST NODE TO TARGET IF TARGET IS PLAYER (TARGET POSITION CAN CHANGE)"
If(Event Player.BotTargetPlayer != -1);
Event Player.BotTargetPosition = Position Of(Event Player.BotTargetPlayer);
Call Subroutine(BotGetClosestNodeIdToTarget);
Log To Inspector(Custom String("PATH FINDING ({0}): TARGET IS PLAYER {2}, SET TARGET NODE #{1}", Event Player,
Event Player.BotClosestNodeIdToTarget, Event Player.BotTargetPlayer));
End;
"NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)"
If(Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1);
Log To Inspector(Custom String("PATH FINDING ({0}): NEXT NODE #{1} IS TARGET ", Event Player,
Event Player.BotClosestNodeIdToTarget));
Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToTarget;
"CHECK CONNECTIONS OF REACHED NODE"
Else;
Log To Inspector(Custom String("PATH FINDING ({0}): (BEGIN LOOP) CHECK CONNECTIONS FROM NODE #{1} TO TARGET NODE #{2}",
Event Player, Event Player.BotClosestNodeIdToBot, Event Player.BotClosestNodeIdToTarget));
Event Player.BotShortestDistanceToTarget = 999;
Event Player.BotCurrentDistanceToTarget = Event Player.BotShortestDistanceToTarget;
Event Player.BotTempArray = Global.NodeConnections[Event Player.BotClosestNodeIdToBot];
For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotTempArray), 1);
Event Player.BotCurrentDistanceToTarget = Global.DistanceMatrix[Event Player.BotTempArray[Event Player.BotLoopIterator1]][Event Player.BotClosestNodeIdToTarget];
Log To Inspector(Custom String("PATH FINDING ({0}): NODE #{1}; DISTANCE TO TARGET = {2}", Event Player,
Event Player.BotTempArray[Event Player.BotLoopIterator1], Event Player.BotCurrentDistanceToTarget));
If(Event Player.BotCurrentDistanceToTarget < Event Player.BotShortestDistanceToTarget);
Event Player.BotShortestDistanceToTarget = Event Player.BotCurrentDistanceToTarget;
Event Player.BotNextNodeId = Event Player.BotTempArray[Event Player.BotLoopIterator1];
Log To Inspector(Custom String("PATH FINDING ({0}): SET NEXT NODE #{1}", Event Player, Event Player.BotNextNodeId));
End;
End;
Log To Inspector(Custom String("PATH FINDING ({0}): (END LOOP) NEXT NODE #{1}, DISTANCE TO TARGET NODE = {2}", Event Player,
Event Player.BotNextNodeId, Event Player.BotShortestDistanceToTarget));
End;
"II. AVAILABILITY CHECKING OF NEXT NODE"
Log To Inspector(Custom String("PATH FINDING ({0}): BEGIN AVAILABILITY CHECKING OF NEXT NODE #{1}", Event Player,
Event Player.BotNextNodeId));
"Y-ORD DIFF BETWEEN BOT POS AND NEXT NODE POS"
Log To Inspector(Custom String("PATH FINDING ({0}): Y-ORD DIFF BETWEEN BOT POS AND NEXT NODE POS = {1}", Event Player,
Y Component Of(Position Of(Event Player)) - Y Component Of(Global.NodePositions[Event Player.BotNextNodeId])));
"NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE"
If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.NodePositions[Event Player.BotNextNodeId])
< -3 && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot);
Log To Inspector(Custom String("PATH FINDING ({0}): NEXT NODE {1} IS HIGHER THAN BOT, SET CLOSEST NODE #{2} TO BOT AS NEXT",
Event Player, Event Player.BotNextNodeId, Event Player.BotClosestNodeIdToBot));
Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot;
Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot;
"BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET"
Else If(
Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1 && Is In Line of Sight(
Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS));
Log To Inspector(Custom String(
"PATH FINDING ({0}): CAN SEE TARGET POSITION {1} AND DISTANCE TO TARGET NODE = 1, MOVE TO TARGET POSITION", Event Player,
Event Player.BotTargetPosition));
Event Player.BotNextNodePosition = Event Player.BotTargetPosition;
Abort;
"BOT CAN'T SEE NEXT NODE OR NODE IS LOWER THAN BOT"
disabled Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0),
Global.NodePositions[Event Player.BotNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) == False);
"BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE"
Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0),
Global.NodePositions[Event Player.BotNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS)
== False && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot);
Log To Inspector(Custom String("PATH FINDING ({0}): CAN'T SEE NODE #{1}, SET CLOSEST NODE #{2} AS NEXT", Event Player,
Event Player.BotNextNodeId, Event Player.BotClosestNodeIdToBot));
Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot;
Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot;
End;
Event Player.BotNextNodePosition = Global.NodePositions[Event Player.BotNextNodeId];
Log To Inspector(Custom String("PATH FINDING ({0}): MOVE TO NEXT NODE #{1}", Event Player, Event Player.BotNextNodeId));
Log To Inspector(Custom String("PATH FINDING ({0}): END FIND NEXT NODE", Event Player, Event Player.BotNextNodeId));
}
}
rule("BOT: PATH FINDING - START")
{
event
{
Ongoing - Each Player;
All;
All;
}
conditions
{
Is Dummy Bot(Event Player) == True;
Has Spawned(Event Player) == True;
(Event Player.BotTargetPosition != -1 || Event Player.BotTargetPlayer != -1) == True;
}
actions
{
"GET CLOSSEST NODE ID NEAR BOT TO START PATH FINDING"
Call Subroutine(BotGetCurrentNodeId);
"GET CLOSSEST NODE ID NEAR TARGET POSITION"
Call Subroutine(BotGetTargetNodeId);
"SET MOVEMENT DIRECTION"
Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player),
Global.NodePositions[Event Player.BotCurrentNodeId]), 1, To World, Replace existing throttle, Direction and Magnitude);
Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.NodePositions[Event Player.BotCurrentNodeId]), 500,
To World, Direction and Turn Rate);
Event Player.BotIsPathFinding = True;
Start Rule(BotStartPathFinding, Restart Rule);
}
}
rule("BOT: PATH FINDING - LOST THE CURRENT NODE")
rule("BOT: PATH FINDING - REACHED THE NODE")
{
event
{
Ongoing - Each Player;
All;
All;
}
conditions
{
Is Dummy Bot(Event Player) == True;
Has Spawned(Event Player) == True;
Event Player.BotIsPathFinding == True;
(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Global.NodePositions[Event Player.BotCurrentNodeId] + Vector(
0, 2.500, 0), Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2)
== True;
(Event Player.BotClosestNodeIdToTarget >= 0 && Distance Between(Position Of(Event Player), Event Player.BotNextNodePosition)
< 0.850) == True;
}
actions
{
Wait(0.650, Abort When False);
Call Subroutine(BotGetCurrentNodeId);
Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player),
Global.NodePositions[Event Player.BotCurrentNodeId]), 1, To World, Replace existing throttle, Direction and Magnitude);
Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.NodePositions[Event Player.BotCurrentNodeId]), 500,
To World, Direction and Turn Rate);
Event Player.BotPrevNodeId = Event Player.BotNextNodeId;
Event Player.BotClosestNodeIdToBot = Event Player.BotNextNodeId;
Event Player.BotCurrentDistanceToTarget = Distance Between(Position Of(Event Player), Event Player.BotTargetPosition);
Log To Inspector(Custom String("PATH FINDING ({0}): REACHED NODE #{1}", Event Player, Event Player.BotNextNodeId));
"BOT REACHED THE TARGET NODE OR TARGET POSITION"
If(Event Player.BotNextNodeId == Event Player.BotClosestNodeIdToTarget || Event Player.BotCurrentDistanceToTarget <= 0.850);
"BOT DIDN'T REACH TARGET POSITION"
If(Event Player.BotCurrentDistanceToTarget > 0.850);
Event Player.BotNextNodePosition = Event Player.BotTargetPosition;
Skip(5);
End;
"BOT REACHED TARGET POSITION"
Call Subroutine(BotResetPathFinding);
Abort;
End;
"CONTINUE FOLLOW PATH"
Call Subroutine(BotGetNextNodeIdAndPosition);
Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World,
Direction and Turn Rate);
Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1,
To World, Replace existing throttle, Direction and Magnitude);
}
}
rule("BOT: PATH FINDING - REACHED THE NODE")
rule("BOT: PATH FINDING - LOST THE NODE")
{
event
{
Ongoing - Each Player;
All;
All;
}
conditions
{
Is Dummy Bot(Event Player) == True;
Has Spawned(Event Player) == True;
Event Player.BotIsPathFinding == True;
(Event Player.BotTargetNodeId >= 0 && Distance Between(Position Of(Event Player),
Global.NodePositions[Event Player.BotCurrentNodeId]) < 0.850) == True;
(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotNextNodePosition + Vector(0, 2.500, 0),
Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True;
}
actions
{
Call Subroutine(BotGetTargetNodeId);
"BOT REACHED THE TARGET NODE"
If(Event Player.BotCurrentNodeId == Event Player.BotTargetNodeId);
Call Subroutine(BotResetPathFinding);
Abort;
End;
Call Subroutine(BotGetNextNodeId);
Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player),
Global.NodePositions[Event Player.BotCurrentNodeId]), 1, To World, Replace existing throttle, Direction and Magnitude);
Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.NodePositions[Event Player.BotCurrentNodeId]), 500,
To World, Direction and Turn Rate);
Wait(0.500, Abort When False);
Log To Inspector(Custom String("PATH FINDING ({0}): LOST NEXT NODE FROM SIGHT, BEGIN FIND CLOSEST NODE TO BOT AND NEW NEXT NODE",
Event Player));
"RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE"
Event Player.BotPrevNodeId = -1;
"TRY FIND NEW NEXT NODE"
Call Subroutine(BotGetNextNodeIdAndPosition);
Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodeId), 360, To World,
Direction and Turn Rate);
Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1,
To World, Replace existing throttle, Direction and Magnitude);
}
}
disabled rule("=== EXPORT BLOCK END ===")
{
event
{
Ongoing - Global;
}
}
rule("GLOBAL: INIT MOD")
{
event
{
Ongoing - Global;
}
actions
{
Global.IsBuildingProject = False;
Global.BuilderNodePositions = Empty Array;
Global.BuilderNodeConnections = Empty Array;
Global.BuilderNodeEffectIdArray = Empty Array;
Global.BuilderNodeWorldTextIdArray = Empty Array;
Global.BuilderNodeConnectionEffectsId = Empty Array;
Global.BeamEffects = Empty Array;
Global.NodeTriggerRadius = Workshop Setting Real(Custom String("PATH FINDING"), Custom String("NODE TRIGGER RADIUS"), 0.850, 0.500,
1.500, 0);
Global.PropertySpawnRoomIndex = Workshop Setting Combo(Custom String("MOD PROPERTIES"), Custom String("SPAWN ROOM"), 0, Array(
Custom String("1"), Custom String("2"), Custom String("3")), 0);
Global.PropertyFreeCamera = Workshop Setting Toggle(Custom String("MOD PROPERTIES"), Custom String("FREE FLY CAMERA"), True, 1);
Global.PropertyPlayerMovementSpeed = Workshop Setting Integer(Custom String("MOD PROPERTIES"), Custom String(
"PLAYER MOVEMENT SPEED"), 150, 50, 200, 2);
Global.PropertyBotMovementSpeed = Workshop Setting Integer(Custom String("MOD PROPERTIES"), Custom String(
"TEST BOT MOVEMENT SPEED"), 100, 50, 200, 3);
Start Forcing Spawn Room(All Teams, Global.PropertySpawnRoomIndex);
Create HUD Text(All Players(All Teams), Custom String(""), Null, Null, Left, 0, Color(White), Color(White), Color(White),
Visible To and String, Default Visibility);
"VALUES: \"EDIT\" - EDIT EXISTING NODES; \"BUILD\"- CREATE NEW NODES; \"PATH FINDING\" - TEST COMPUTING PATHS"
Global.BuilderMode = Custom String("PATH FINDING");
Global.BuilderHudColorEditMode = Color(Yellow);
Global.BuilderHudColorBuildMode = Color(Red);
Global.BuilderHudColorPathFindingMode = Color(Purple);
Global.PathFindingStartNodeId = -1;
Global.PathFindingTargetNodeId = -1;
"SELECTED NODE EFFECT"
Call Subroutine(BuilderInitModEffects);
If(Global.NodePositions != Null);
Call Subroutine(BuilderBuildPreparedPathNodes);
End;
}
}
rule("GLOBAL: WORKSHOP SETTINGS INSTRUCTION")
{
event
{
Ongoing - Global;
}
actions
{
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
"1. PLACE NODES AND CONNECT THEM HOW YOU NEED BY USING BUILDER MODES BELOW"), False, -99);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
" 1.1. BUILD MODE - CREATES AND PLACES NEW NODE IN CROSSHAIR'S POSITION"), False, -98);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
" 1.2. EDIT MODE - SELECTS EXISTING NODE AND ALLOWS CONNECT IT TO OTHER NODES"), False, -97);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
" 1.3. PATH FINDING MODE - SETS START AND TARGET NODES TO TEST ROUTE"), False, -96);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
"2. BUILD YOUR PROJECT TO GET EXPORT VARS"), False, -95);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
" 2.1. SWITCH TO BUILD MODE"), False, -94);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
" 2.2. HOLD 'INTERACT' BUTTON A FEW SECONDS TO RUN BUILD PROCESS"), False, -93);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
" 2.3. WAIT WHEN THE PROCESS WILL BE FINISHED"), False, -92);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
" 2.3. OPEN WORKSHOP INSPECTOR AT LAST POSITION AND SELECT 'VARIABLE TARGET' = GLOBAL"), False, -91);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
" 2.4. CLICK (X) BUTTON TO COPY VALUES OF VARS TO CLIPBOARD AND PASTE IT IN ANY TEXT EDITOR"), False, -90);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
" 2.5 DELETE ALL VARS AND ACTIONS EXCEPT NEXT"), False, -89);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
" Global.NodePositions, Global.NodeConnections, Global.DistanceMatrix"), False, -88);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
" 2.6 COPY ALL LINES FROM TEXT EDITOR INTO CLIPBOARD"), False, -87);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
"3. CREATE NEW MAP RULE INSIDE OF 'EXPORT BLOCK' AND PASTE COPIED VALUES FROM CLIPBOARD"), False, -86);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
"4. COPY ALL RULES INSIDE OF 'EXPORT BLOCK' AND PUT THEM IN YOUR GAME MODE"), False, -85);
Global.WorkshopSettingInstructions = Workshop Setting Toggle(Custom String("INSTRUCTIONS - HOW DOES IT WORKS"), Custom String(
"5. PROFIT!"), False, -84);
}
}
rule("SUBROUTINE: INIT MOD EFFECTS")
{
event
{
Subroutine;
BuilderInitModEffects;
}
actions
{
"SELECTED NODE EFFECT"
Global.BuilderSelectedNodeEffectPos = Vector(0, -999, 0);
Create Effect(All Players(All Teams), Sphere, Global.BuilderHudColorEditMode, Global.BuilderSelectedNodeEffectPos,
Global.NodeTriggerRadius, Visible To Position and Radius);
"PATH FINDING EFFECTS"
Global.PathFindingStartNodeEffectPos = Vector(0, -999, 0);
Global.PathFindingTargetNodeEffectPos = Vector(0, -999, 0);
Create Effect(All Players(All Teams), Light Shaft, Global.BuilderHudColorPathFindingMode, Global.PathFindingStartNodeEffectPos,
Global.NodeTriggerRadius, Visible To Position and Radius);
Create Effect(All Players(All Teams), Light Shaft, Global.BuilderHudColorPathFindingMode, Global.PathFindingTargetNodeEffectPos,
Global.NodeTriggerRadius, Visible To Position and Radius);
}
}
disabled rule("=== PLAYER ===")
{
event
{
Ongoing - Global;
}
}
rule("PLAYER: INIT")
{
event
{
Ongoing - Each Player;
All;
All;
}
conditions
{
Is Dummy Bot(Event Player) == False;
Host Player == True;
Has Spawned(Event Player) == True;
}
actions
{
Start Forcing Player To Be Hero(Event Player, Hero(Zenyatta));
Disable Movement Collision With Environment(Event Player, False);
Call Subroutine(BuilderSwitchMode);
disabled Disable Text Chat(Event Player);
disabled Disable Hero HUD(Event Player);
Disable Game Mode HUD(Event Player);
Set Ability 1 Enabled(Event Player, False);
Set Ability 2 Enabled(Event Player, False);
Set Primary Fire Enabled(Event Player, False);
Set Secondary Fire Enabled(Event Player, False);
Set Ultimate Ability Enabled(Event Player, False);
Set Move Speed(Event Player, Global.PropertyPlayerMovementSpeed);
Set Status(Event Player, Null, Phased Out, 9999);
If(Global.PropertyFreeCamera == True);
Set Gravity(Event Player, 0);
Start Accelerating(Event Player, Velocity Of(Event Player) * -1, Speed Of(Event Player) * 2, 10, To World,
Direction Rate and Max Speed);
Set Move Speed(Event Player, Global.PropertyPlayerMovementSpeed * 1.300);
End;
}
}
rule("PLAYER AND BOT: NAVIGATION DEBUG INFO")
{
event
{
Ongoing - Each Player;
All;
All;
}
conditions
{
Has Spawned(Event Player) == True;
}
actions
{
Create HUD Text(Event Player, Custom String("CLOSSEST NODE: {0}\r\nCLOSSEST NODE IN LOS: {1}\r\n{2}", Index Of Array Value(
Global.NodePositions, Sorted Array(Global.NodePositions, Distance Between(Position Of(Event Player), Current Array Element))
[0]), Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions, Is In Line of Sight(
Eye Position(Event Player), Current Array Element, Barriers Do Not Block LOS) == True), Distance Between(Position Of(
Event Player), Current Array Element))[0]), Custom String("CURRENT NODE {1}", Null, Event Player.BotCurrentNodeId)), Null,
Null, Right, -1, Color(White), Color(White), Color(White), Visible To and String, Default Visibility);
}
}
rule("PLAYER: FREE CAMERA")
{
event
{
Ongoing - Each Player;
All;
All;
}
conditions
{
Global.PropertyFreeCamera == True;
Host Player == True;
Has Spawned(Event Player) == True;
(Is Button Held(Event Player, Button(Jump)) || Is Button Held(Event Player, Button(Crouch))) == True;
}
actions
{
If(Is Button Held(Event Player, Button(Jump)));
Apply Impulse(Event Player, Up, 0.640, To World, Incorporate Contrary Motion);
Wait(False, Ignore Condition);
Loop If Condition Is True;
Else If(Is Button Held(Event Player, Button(Crouch)));
Apply Impulse(Event Player, Down, 0.640, To World, Incorporate Contrary Motion);
Wait(False, Ignore Condition);
Loop If Condition Is True;
End;
}
}
rule("PLAYER: SWITCH BUILDER MODE")
{
event
{
Ongoing - Each Player;
All;
All;
}
conditions
{
Is Dummy Bot(Event Player) == False;
Host Player == True;
Has Spawned(Event Player) == True;
Global.IsBuildingProject == False;
Is Button Held(Event Player, Button(Reload)) == True;
}
actions
{
Call Subroutine(BuilderSwitchMode);
}
}
rule("SUBROUTINE: SWITCH MODE")
{
event
{
Subroutine;
BuilderSwitchMode;
}
actions
{
Destroy HUD Text(Event Player.BuilderModeInfoHudId);
If(Global.BuilderMode == Custom String("PATH FINDING"));
Global.BuilderMode = Custom String("BUILD");
Call Subroutine(PathFindingResetBot);
Call Subroutine(PathFindingModeReset);
Global.BuilderHudColorCurrent = Global.BuilderHudColorBuildMode;
Create HUD Text(All Players(All Teams), Custom String("[{0}] - MODE: {1}\r\n{2}", Input Binding String(Button(Reload)),
Global.BuilderMode, Custom String("HOLD {1} - BUILD PROJECT\r\n{0} - CREATE NODE", Input Binding String(Button(Primary Fire)),
Input Binding String(Button(Interact)))), Null, Null, Left, -999, Global.BuilderHudColorCurrent, Color(White), Color(White),
Visible To and String, Default Visibility);
Else If(Global.BuilderMode == Custom String("BUILD"));
Global.BuilderMode = Custom String("EDIT");
Global.BuilderHudColorCurrent = Global.BuilderHudColorEditMode;
Create HUD Text(All Players(All Teams), Custom String("[{0}] - MODE: {1}\r\n{2}", Input Binding String(Button(Reload)),
Global.BuilderMode, Custom String("SELECTED NODE - {0}\r\n{1} - SELECT\r\n{2}",
Global.BuilderSelectedNodeId < 0 ? Custom String("NONE") : Global.BuilderSelectedNodeId, Input Binding String(Button(
Primary Fire)), Custom String("{0} - CONNECT/DISCONNECT\r\n{1} - DELETE", Input Binding String(Button(Secondary Fire)),
Input Binding String(Button(Interact))))), Null, Null, Left, -999, Global.BuilderHudColorCurrent, Color(White), Color(White),
Visible To and String, Default Visibility);
Else If(Global.BuilderMode == Custom String("EDIT"));
Global.BuilderMode = Custom String("PATH FINDING");
Call Subroutine(DeleteNodeBeams);
Global.BuilderHudColorCurrent = Global.BuilderHudColorPathFindingMode;
Create HUD Text(All Players(All Teams), Custom String("[{0}] - MODE: {1}\r\n{2}", Input Binding String(Button(Reload)),
Global.BuilderMode, Custom String("{0} - SET START NODE {1}\r\n{2}", Input Binding String(Button(Primary Fire)),
Global.PathFindingStartNodeId, Custom String("{0} - SET END NODE {1}\r\n{2}", Input Binding String(Button(Secondary Fire)),
Global.PathFindingTargetNodeId, Custom String("{0} - TEST WITH BOT\r\n{1} - BOOP BOT", Input Binding String(Button(Ultimate)),
Input Binding String(Button(Interact)))))), Null, Null, Left, -999, Global.BuilderHudColorCurrent, Color(White), Color(White),
Visible To and String, Default Visibility);
Global.BuilderMode, Custom String("{0} - SET START POS (CLOSEST NODE {1})\r\n{2}", Input Binding String(Button(Primary Fire)),
Global.PathFindingStartNodeId, Custom String("{0} - SET TARGET POS (CLOSEST NODE {1})\r\n{2}", Input Binding String(Button(
Secondary Fire)), Global.PathFindingTargetNodeId, Custom String("{0} - TEST WITH BOT\r\n{1} - BOOP BOT", Input Binding String(
Button(Ultimate)), Input Binding String(Button(Interact)))))), Null, Null, Left, -999, Global.BuilderHudColorCurrent, Color(
White), Color(White), Visible To and String, Default Visibility);
End;
Event Player.BuilderModeInfoHudId = Last Text ID;
Global.BuilderSelectedNodeEffectPos = Vector(0, -999, 0);
Global.BuilderSelectedNodeId = -1;
}
}
rule("SUBROUTINE: GET CLOSSEST NODE ID TO CURSOR")
{
event
{
Subroutine;
BuilderGetClossestNodeIdToCursor;
}
actions
{
"ANY NODE IN LINE OF SIGHT"
Global.BuilderTrySelectNodeInLOS = Filtered Array(Global.BuilderNodePositions, Current Array Element != False && Dot Product(
Facing Direction Of(Event Player), Direction Towards(Eye Position(Event Player), Current Array Element))
>= 0.990 && Is In Line of Sight(Eye Position(Event Player), Current Array Element, Barriers Do Not Block LOS));
If(Global.BuilderTrySelectNodeInLOS != Empty Array);
Global.BuilderTrySelectNodeInLOS = Index Of Array Value(Global.BuilderNodePositions, Global.BuilderTrySelectNodeInLOS[0]);
Else;
Global.BuilderTrySelectNodeInLOS = -1;
End;
}
}
disabled rule("=== EDIT MODE ===")
{
event
{
Ongoing - Global;
}
}
rule("PLAYER: EDIT MODE")
{
event
{
Ongoing - Each Player;
All;
All;
}
conditions
{
Is Dummy Bot(Event Player) == False;
Host Player == True;
Has Spawned(Event Player) == True;
(Is Button Held(Event Player, Button(Primary Fire)) || Is Button Held(Event Player, Button(Secondary Fire)) || Is Button Held(
Event Player, Button(Interact))) == True;
Global.BuilderMode == Custom String("EDIT");
}
actions
{
"ANY NODE IN LINE OF SIGHT"
Call Subroutine(BuilderGetClossestNodeIdToCursor);
"SELECT NODE"
If(Is Button Held(Event Player, Button(Primary Fire)));
Call Subroutine(BuilderEditModeSelectNode);
"CONNECT/DISCONNECT NODE"
Else If(Is Button Held(Event Player, Button(Secondary Fire)) && Global.BuilderSelectedNodeId != -1);
Call Subroutine(BuilderConnectDisconnectSelector);
"DELETE NODE"
Else If(Is Button Held(Event Player, Button(Interact)) && Global.BuilderSelectedNodeId != -1);
Call Subroutine(BuilderEditModeDeleteNode);
End;
}
}
rule("SUBROUTINE: SELECT NODE")
{
event
{
Subroutine;
BuilderEditModeSelectNode;
}
actions
{
If(Global.BuilderTrySelectNodeInLOS != -1);
Global.BuilderSelectedNodeEffectPos = Global.BuilderNodePositions[Global.BuilderTrySelectNodeInLOS];
Else;
Global.BuilderSelectedNodeEffectPos = Vector(0, -999, 0);
Call Subroutine(DeleteNodeBeams);
End;
Global.BuilderSelectedNodeId = Global.BuilderTrySelectNodeInLOS;
Call Subroutine(DeleteNodeBeams);
"DRAW CONNECTED BEAMS"
If(Count Of(Global.BuilderNodeConnections[Global.BuilderSelectedNodeId]) > 0);
Call Subroutine(CreateNodeBeams);
End;
}
}
rule("SUBROUTINE: DELETE NODE")
{
event
{
Subroutine;
BuilderEditModeDeleteNode;
}
actions
{
If(Global.BuilderTrySelectNodeInLOS == -1 || Global.BuilderTrySelectNodeInLOS != Global.BuilderSelectedNodeId);
Small Message(All Players(All Teams), Custom String("LOOK AT NODE {0} TO DELETE IT", Global.BuilderSelectedNodeId));
Abort;
End;
Small Message(All Players(All Teams), Custom String("NODE DELETED"));
Call Subroutine(DeleteNodeBeams);
Play Effect(Event Player, Debuff Impact Sound, Color(White), Event Player, 60);
Destroy Effect(Global.BuilderNodeEffectIdArray[Global.BuilderSelectedNodeId]);
Destroy In-World Text(Global.BuilderNodeWorldTextIdArray[Global.BuilderSelectedNodeId]);
Global.BuilderNodePositions[Global.BuilderTrySelectNodeInLOS] = False;
Global.BuilderSelectedNodeEffectPos = Vector(0, -999, 0);
Call Subroutine(BuilderDeleteConnectionsOfNode);
Global.BuilderSelectedNodeId = -1;
}
}
rule("SUBROUTINE: DELETE ALL CONNECTIONS OF DELETED NODE")
{
event
{
Subroutine;
BuilderDeleteConnectionsOfNode;
}
actions
{
"DELETE ALL CONNECTIONS OF THE DELETED NODE"
For Global Variable(LoopIterator1, 0, Count Of(Global.BuilderNodeConnections[Global.BuilderSelectedNodeId]), 1);
Destroy Effect(
Global.BuilderNodeConnectionEffectsId[Global.BuilderSelectedNodeId][Global.BuilderNodeConnections[Global.BuilderSelectedNodeId][Global.LoopIterator1]]);
End;
"CHECK OTHER NODES FOR CONNECTION WITH DELETED NODE"
For Global Variable(LoopIterator1, 0, Count Of(Global.BuilderNodePositions), 1);
disabled Global.BuilderTrySelectNodeInLOS = Global.BuilderNodeConnections[Global.LoopIterator1][Global.LoopIterator2];
If(Array Contains(Global.BuilderNodeConnections[Global.LoopIterator1], Global.BuilderSelectedNodeId));
"DELETE BEAM EFFECT"
Destroy Effect(Global.BuilderNodeConnectionEffectsId[Global.LoopIterator1][Global.BuilderSelectedNodeId]);
Global.BuilderInnerArray = Global.BuilderNodeConnectionEffectsId[Global.LoopIterator1];
Global.BuilderInnerArray[Global.BuilderSelectedNodeId] = False;
Global.BuilderNodeConnectionEffectsId[Global.LoopIterator1] = Global.BuilderInnerArray;
"REMOVE DELETED NODE FROM CONNECTION ARRAY"
Global.BuilderInnerArray = Global.BuilderNodeConnections[Global.LoopIterator1];
Modify Global Variable(BuilderInnerArray, Remove From Array By Value, Global.BuilderSelectedNodeId);
Global.BuilderNodeConnections[Global.LoopIterator1] = Global.BuilderInnerArray;
"UPDATE IN-WORLD TEXT OF NODE"
Global.StringConcatNodeId = Global.LoopIterator1;
Call Subroutine(BuilderConcatStringConnections);
End;
End;
Global.BuilderNodeConnections[Global.BuilderSelectedNodeId] = False;
Global.BuilderNodeConnectionEffectsId[Global.BuilderSelectedNodeId] = False;
}
}
rule("SUBROUTINE: CONNECT DISCONNECT SELECTOR")
{
event
{
Subroutine;
BuilderConnectDisconnectSelector;
}
actions
{
If(
Global.BuilderSelectedNodeId == -1 || Global.BuilderTrySelectNodeInLOS == -1 || Global.BuilderSelectedNodeId == Global.BuilderTrySelectNodeInLOS);
Small Message(All Players(All Teams), Custom String("LOOK AT OTHER NODE TO CONNECT/DISCONNECT IT"));
Abort;
End;
Global.BuilderIsNodeHaveConnection = Array Contains(Global.BuilderNodeConnections[Global.BuilderSelectedNodeId],
Global.BuilderTrySelectNodeInLOS);
If(!Global.BuilderIsNodeHaveConnection);
Small Message(All Players(All Teams), Custom String("NODE CONNECTED"));
Call Subroutine(BuilderConnectNodeBackendLogic);
Call Subroutine(DeleteNodeBeams);
Call Subroutine(CreateNodeBeams);
Else;
Small Message(All Players(All Teams), Custom String("NODE DISCONNECTED"));
Call Subroutine(BuilderDisconnectNode);
Call Subroutine(DeleteNodeBeams);
Call Subroutine(CreateNodeBeams);
End;
"UPDATE IN-WORLD TEXT OF CONNECTED NODE"
Global.StringConcatNodeId = Global.BuilderSelectedNodeId;
Call Subroutine(BuilderConcatStringConnections);
}
}
rule("SUBROUTINE: CONNECT NODE (BACK-END LOGIC)")
{
event
{
Subroutine;
BuilderConnectNodeBackendLogic;
}
actions
{
"GET CONNECTION ARRAY FOR SELECTED NODE AND ADD NEW CONNECTION"
If(Count Of(Global.BuilderNodeConnections[Global.BuilderSelectedNodeId]) > 0);
Global.BuilderInnerArray = Global.BuilderNodeConnections[Global.BuilderSelectedNodeId];
Modify Global Variable(BuilderInnerArray, Append To Array, Global.BuilderTrySelectNodeInLOS);
"OR CREATE NEW CONNECTION ARRAY FOR SELECTED NODE"
Else;
Global.BuilderInnerArray = Empty Array;
Global.BuilderInnerArray[0] = Global.BuilderTrySelectNodeInLOS;
End;
"ADD CONNECTION ARRAY OF SELECTED NODE IN MATRIX 2X2 OF ALL CONNECTIONS"
Global.BuilderNodeConnections[Global.BuilderSelectedNodeId] = Global.BuilderInnerArray;
Play Effect(All Players(All Teams), Buff Impact Sound, Color(White), Event Player, 60);
Call Subroutine(BuilderConnectNodeBeamEffect);
}
}
rule("SUBROUTINE: CONNECT NODE (BEAM EFFECT)")
{
event
{
Subroutine;
BuilderConnectNodeBeamEffect;
}
actions
{
"'BEAM' EFFECT IS EXIST BETWEEN THESE NODES"
Abort If(Entity Exists(Global.BuilderNodeConnectionEffectsId[Global.BuilderTrySelectNodeInLOS][Global.BuilderSelectedNodeId]));
Abort If(Entity Exists(Global.BuilderNodeConnectionEffectsId[Global.BuilderSelectedNodeId][Global.BuilderTrySelectNodeInLOS]));
"VISUAL EFFECT OF CONNECTION"
Create Beam Effect(All Players(All Teams), Grapple Beam, Global.BuilderNodePositions[Global.BuilderSelectedNodeId],
Global.BuilderNodePositions[Global.BuilderTrySelectNodeInLOS], Color(White), Visible To);
"ARRAY LIKE HASH MAP (KEY : VALUE) - KEY - INDEX OF NODE, VALUE - EFFECT ID"
If(Count Of(Global.BuilderNodeConnectionEffectsId[Global.BuilderSelectedNodeId]) > 0);
Global.BuilderInnerArray = Global.BuilderNodeConnectionEffectsId[Global.BuilderSelectedNodeId];
Else;
Global.BuilderInnerArray = Empty Array;
End;
Global.BuilderInnerArray[Global.BuilderTrySelectNodeInLOS] = Last Created Entity;
"ADD BEAM EFFECT ARRAY IN MATRIX 2X2 OF ALL CONNECTION EFFECTS"
Global.BuilderNodeConnectionEffectsId[Global.BuilderSelectedNodeId] = Global.BuilderInnerArray;
}
}
rule("SUBROUTINE: DISCONNECT NODE")
{
event
{
Subroutine;
BuilderDisconnectNode;
}
actions
{
Play Effect(Event Player, Debuff Impact Sound, Color(White), Event Player, 60);
"GET CONNECTION ARRAY FOR SELECTED NODE"
Global.BuilderInnerArray = Global.BuilderNodeConnections[Global.BuilderSelectedNodeId];
Modify Global Variable(BuilderInnerArray, Remove From Array By Value, Global.BuilderTrySelectNodeInLOS);
"REMOVE CONNECTION ARRAY OF SELECTED NODE IN MATRIX 2X2 OF ALL CONNECTIONS"
Global.BuilderNodeConnections[Global.BuilderSelectedNodeId] = Global.BuilderInnerArray;
"DESTROY BEAM EFFECT"
Abort If(Array Contains(Global.BuilderNodeConnections[Global.BuilderTrySelectNodeInLOS], Global.BuilderSelectedNodeId));
Destroy Effect(Global.BuilderNodeConnectionEffectsId[Global.BuilderSelectedNodeId][Global.BuilderTrySelectNodeInLOS]);
Destroy Effect(Global.BuilderNodeConnectionEffectsId[Global.BuilderTrySelectNodeInLOS][Global.BuilderSelectedNodeId]);
Global.BuilderInnerArray = Global.BuilderNodeConnectionEffectsId[Global.BuilderSelectedNodeId];
Global.BuilderInnerArray[Global.BuilderTrySelectNodeInLOS] = Null;
Global.BuilderNodeConnectionEffectsId[Global.BuilderSelectedNodeId] = Global.BuilderInnerArray;
Global.BuilderInnerArray = Global.BuilderNodeConnectionEffectsId[Global.BuilderTrySelectNodeInLOS];
Global.BuilderInnerArray[Global.BuilderSelectedNodeId] = Null;
Global.BuilderNodeConnectionEffectsId[Global.BuilderTrySelectNodeInLOS] = Global.BuilderInnerArray;
}
}
rule("SUBROUTINE: CONCAT STRING CONNECTIONS")
{
event
{
Subroutine;
BuilderConcatStringConnections;
}
actions
{
Destroy In-World Text(Global.BuilderNodeWorldTextIdArray[Global.StringConcatNodeId]);
Global.StringConcatCountOfElements = Count Of(Global.BuilderNodeConnections[Global.StringConcatNodeId]);
If(Global.StringConcatCountOfElements > 0);
For Global Variable(LoopIterator3, 0, Global.StringConcatCountOfElements, 1);
"FIRST ELEMENT"
If(Global.LoopIterator3 == 0);
Global.StringConcatResult = Custom String("{1}", Null,
Global.BuilderNodeConnections[Global.StringConcatNodeId][Global.LoopIterator3]);
"ADD \",\" SYMBOL BETWEEN ELEMENTS"
Else;
Global.StringConcatResult = Custom String("{0}{2}{1}", Global.StringConcatResult,
Global.BuilderNodeConnections[Global.StringConcatNodeId][Global.LoopIterator3],
Global.LoopIterator3 != Global.StringConcatCountOfElements ? Custom String(", ") : Custom String(" "));
End;
End;
Create In-World Text(All Players(All Teams), Custom String("NODE {0}\r\n[ {1} ]", Global.StringConcatNodeId,
Global.StringConcatResult), Global.BuilderNodePositions[Global.StringConcatNodeId], 1.200, Do Not Clip, Visible To, Color(
White), Default Visibility);
Else;
Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Global.StringConcatNodeId),
Global.BuilderNodePositions[Global.StringConcatNodeId], 1.300, Do Not Clip, Visible To, Color(White), Default Visibility);
End;
Global.BuilderNodeWorldTextIdArray[Global.StringConcatNodeId] = Last Text ID;
}
}
disabled rule("=== BUILD MODE ===")
{
event
{
Ongoing - Global;
}
}
rule("PLAYER: BUILD MODE")
{
event
{
Ongoing - Each Player;
All;
All;
}
conditions
{
Is Dummy Bot(Event Player) == False;
Host Player == True;
Has Spawned(Event Player) == True;
(Is Button Held(Event Player, Button(Primary Fire)) || Is Button Held(Event Player, Button(Interact))) == True;
Global.BuilderMode == Custom String("BUILD");
}
actions
{
"CREATE NEW NODE"
If(Is Button Held(Event Player, Button(Primary Fire)));
Call Subroutine(BuilderBuildModeCreateNewNode);
"OPTIMIZE DATA"
Else If(Is Button Held(Event Player, Button(Interact)));
Create Progress Bar HUD Text(Event Player, Global.BuilderProgressBarValue, Custom String("PREPARING TO BUILD PROJECT"), Top, 1,
Global.BuilderHudColorBuildMode, Global.BuilderHudColorBuildMode, Visible To and Values, Default Visibility);
Global.BuilderProgressBarValue = 0;
Chase Global Variable Over Time(BuilderProgressBarValue, 100, 2, Destination and Duration);
"HOLD BUTTON N SEC TO BEGIN PROCESS"
While(Global.BuilderProgressBarValue != 100);
Wait(0.100, Ignore Condition);
If(Is Button Held(Event Player, Button(Interact)) == False);
Destroy All Progress Bar HUD Text;
Abort;
End;
End;
"RUN BUILD PROJECT"
Destroy All Progress Bar HUD Text;
Call Subroutine(BuilderBuildProject);
End;
}
}
rule("SUBROUTINE: CREATE NEW NODE")
{
event
{
Subroutine;
BuilderBuildModeCreateNewNode;
}
actions
{
Global.BuilderRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player)
+ Facing Direction Of(Event Player) * 1000, Null, Event Player, False);
"NODE'S OFFSET"
Global.BuilderRayCastHitPosition += Ray Cast Hit Normal(Eye Position(Event Player), Eye Position(Event Player)
+ Facing Direction Of(Event Player) * 999, Null, Event Player, False) * (Global.NodeTriggerRadius / 2);
"OTHER NODE IS VERY CLOSE"
If(Is True For Any(Filtered Array(Global.BuilderNodePositions, Current Array Element != False), Distance Between(
Current Array Element, Global.BuilderRayCastHitPosition) < Global.NodeTriggerRadius * 3));
Small Message(Event Player, Custom String("OTHER NODE VERY CLOSE!"));
Abort;
End;
"CREATE NEW NODE"
Modify Global Variable(BuilderNodePositions, Append To Array, Global.BuilderRayCastHitPosition);
Global.BuilderInnerArray = Empty Array;
Global.BuilderNodeConnections[Index Of Array Value(Global.BuilderNodePositions, Global.BuilderRayCastHitPosition)
] = Global.BuilderInnerArray;
Create Effect(All Players(All Teams), Sphere, Color(Red), Global.BuilderRayCastHitPosition, Global.NodeTriggerRadius, Visible To);
Modify Global Variable(BuilderNodeEffectIdArray, Append To Array, Last Created Entity);
Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Index Of Array Value(Global.BuilderNodePositions,
Global.BuilderRayCastHitPosition)), Global.BuilderRayCastHitPosition, 1.300, Do Not Clip, Visible To, Color(White),
Default Visibility);
Modify Global Variable(BuilderNodeWorldTextIdArray, Append To Array, Last Text ID);
Play Effect(Event Player, Buff Impact Sound, Color(White), Event Player, 60);
}
}
disabled rule("=== BUILD PROJECT ===")
{
event
{
Ongoing - Global;
}
}
rule("SUBROUTINE: BUILD PROJECT")
{
event
{
Subroutine;
BuilderBuildProject;
}
actions
{
Global.IsBuildingProject = True;
Call Subroutine(BuilderDeleteAllEffects);
Call Subroutine(BuilderOptimizeData);
Wait(0.050, Ignore Condition);
"SELECTED NODE EFFECT"
Call Subroutine(BuilderInitModEffects);
Wait(0.050, Ignore Condition);
Call Subroutine(BuilderBuildPreparedPathNodes);
Call Subroutine(BuilderComputeDistanceMatrix);
Global.IsBuildingProject = False;
}
}
rule("SUBROUTINE: DELETE ALL EFFECTS")
{
event
{
Subroutine;
BuilderDeleteAllEffects;
}
actions
{
Destroy All Effects;
Destroy All In-World Text;
}
}
rule("SUBROUTINE: OPTIMIZE DATA")
{
event
{
Subroutine;
BuilderOptimizeData;
}
actions
{
Destroy All Progress Bar HUD Text;
Global.BuilderProgressBarValue = 0;
Create Progress Bar HUD Text(Event Player, Global.BuilderProgressBarValue, Custom String("OPTIMIZING DATA"), Top, 1, Color(Green),
Color(Green), Visible To and Values, Default Visibility);
Global.BuilderProgressBarValueStep = 100 / Count Of(Global.BuilderNodePositions);
Global.NodePositions = Empty Array;
Global.DistanceMatrix = Empty Array;
Global.NodeConnections = Empty Array;
Global.BuildProjectEmptySpace = 0;
Global.BuildProjectOldElementIndex = 0;
Global.BuildProjectNewElementIndex = 0;
For Global Variable(LoopIterator1, 0, Count Of(Global.BuilderNodePositions), 1);
Global.BuilderProgressBarValue += Global.BuilderProgressBarValueStep;
"SKIP DELETED NODE (ACCUMULATE SPACE BETWEEN INDEXES)"
If(Global.BuilderNodePositions[Global.LoopIterator1] == False);
Global.BuildProjectEmptySpace += 1;
Continue;
End;
Global.BuildProjectOldElementIndex = Global.LoopIterator1;
Global.BuildProjectNewElementIndex = Global.BuildProjectEmptySpace == 0 ? Global.LoopIterator1 : Global.LoopIterator1 - Global.BuildProjectEmptySpace;
"CONNECTIONS OF CURRENT NODE"
Global.BuilderInnerArray = Global.BuilderNodeConnections[Global.BuildProjectOldElementIndex];
Global.NodeConnections[Global.BuildProjectNewElementIndex] = Global.BuilderInnerArray;
Modify Global Variable(NodePositions, Append To Array, Global.BuilderNodePositions[Global.BuildProjectOldElementIndex]);
"UPDATE INDEXES IN CONNECTION ARRAY"
If(Global.BuildProjectEmptySpace > 0 && Count Of(Global.NodeConnections) > 1);
Call Subroutine(BuilderUpdateConnectionIndexes);
End;
"ANTI-CRASH DELAY"
Wait(0.020, Ignore Condition);
End;
Destroy All Progress Bar HUD Text;
}
}
rule("SUBROUTINE: UPDATE CONNECTION INDEXES")
{
event
{
Subroutine;
BuilderUpdateConnectionIndexes;
}
actions
{
"UPDATE CONNECTION INDEXES IN FINAL (OPTIMIZED) ARRAY"
For Global Variable(LoopIterator2, 0, Count Of(Global.NodeConnections), 1);
Global.BuilderInnerArray = Global.NodeConnections[Global.LoopIterator2];
For Global Variable(LoopIterator3, 0, Count Of(Global.BuilderInnerArray), 1);
If(Global.BuilderInnerArray[Global.LoopIterator3] == Global.BuildProjectOldElementIndex);
Global.BuilderInnerArray[Global.LoopIterator3] = Global.BuildProjectNewElementIndex;
End;
End;
Global.NodeConnections[Global.LoopIterator2] = Global.BuilderInnerArray;
End;
"UPDATE NEXT CONNECTION INDEXES IN INPUT ARRAY"
For Global Variable(LoopIterator2, Global.LoopIterator1 + 1, Count Of(Global.BuilderNodeConnections), 1);
Global.BuilderInnerArray = Global.BuilderNodeConnections[Global.LoopIterator2];
For Global Variable(LoopIterator3, 0, Count Of(Global.BuilderInnerArray), 1);
If(Global.BuilderInnerArray[Global.LoopIterator3] == Global.BuildProjectOldElementIndex);
Global.BuilderInnerArray[Global.LoopIterator3] = Global.BuildProjectNewElementIndex;
End;
End;
Global.BuilderNodeConnections[Global.LoopIterator2] = Global.BuilderInnerArray;
End;
}
}
rule("SUBROUTINE: BUILD PREPARED PATH NODES")
{
event
{
Subroutine;
BuilderBuildPreparedPathNodes;
}
actions
{
Abort If(Count Of(Global.NodePositions) == 0);
Global.BuilderNodeEffectIdArray = Empty Array;
Global.BuilderNodeWorldTextIdArray = Empty Array;
Global.BuilderNodeConnectionEffectsId = Empty Array;
Global.BuilderNodePositions = Global.NodePositions;
Global.BuilderNodeConnections = Empty Array;
"CREATE NODE EFFECTS"
For Global Variable(LoopIterator1, 0, Count Of(Global.NodePositions), 1);
Create Effect(All Players(All Teams), Sphere, Color(Red), Global.NodePositions[Global.LoopIterator1], Global.NodeTriggerRadius,
Visible To);
Modify Global Variable(BuilderNodeEffectIdArray, Append To Array, Last Created Entity);
End;
Wait(0.050, Ignore Condition);
"COPY FROM NodeConnections TO BuilderNodeConnections"
For Global Variable(LoopIterator1, 0, Count Of(Global.NodeConnections), 1);
Global.BuilderInnerArray = Global.NodeConnections[Global.LoopIterator1];
Global.BuilderNodeConnections[Global.LoopIterator1] = Global.BuilderInnerArray;
End;
"ANTI-CRASH DELAY"
Wait(0.030, Ignore Condition);
"CREATE BEAM EFFECTS (CONNECTIONS)"
For Global Variable(LoopIterator1, 0, Count Of(Global.BuilderNodeConnections), 1);
Global.BuilderSelectedNodeId = Global.LoopIterator1;
For Global Variable(LoopIterator2, 0, Count Of(Global.BuilderNodeConnections[Global.LoopIterator1]), 1);
Global.BuilderTrySelectNodeInLOS = Global.BuilderNodeConnections[Global.LoopIterator1][Global.LoopIterator2];
Call Subroutine(BuilderConnectNodeBeamEffect);
End;
End;
"ANTI-CRASH DELAY"
Wait(0.030, Ignore Condition);
"CREATE NODE WORLD TEXTS"
For Global Variable(LoopIterator1, 0, Count Of(Global.NodeConnections), 1);
"UPDATE IN-WORLD TEXT OF CONNECTED NODE"
Global.StringConcatNodeId = Global.LoopIterator1;
Call Subroutine(BuilderConcatStringConnections);
End;
"ANTI-CRASH DELAY"
Wait(0.030, Ignore Condition);
}
}
rule("SUBROUTINE: COMPUTE DISTANCE MATRIX")
{
event
{
Subroutine;
BuilderComputeDistanceMatrix;
}
actions
{
"INIT PROGRESS BAR"
Destroy All Progress Bar HUD Text;
Create Progress Bar HUD Text(All Players(All Teams), Global.BuilderProgressBarValue, Custom String("COMPUTING DISTANCE MATRIX..."),
Top, 1, Color(Purple), Color(Purple), Visible To and Values, Default Visibility);
Global.BuilderProgressBarValue = 0;
Global.BuilderProgressBarValueStep = 100 / Count Of(Global.NodeConnections);
"INIT DISTANCE MATRIX"
Global.DistanceMatrix[Count Of(Global.NodeConnections) - 1] = 0;
"CALCULATE ALL DISTANCES FOR EACH NODE"
For Global Variable(BuildProjectStartNodeId, 0, Count Of(Global.NodeConnections), 1);
"ALL DISTANCES FROM START NODE TO OTHERS"
Global.BuilderInnerArray = Empty Array;
Global.BuilderInnerArray[0] = 0;
"CLEAR QUEUE AND VISITED ARRAYES FOR EACH NODE"
Global.BuildProjectQueueArray = Empty Array;
Global.BuildProjectVisitedNodes = Empty Array;
"PUT THE START NODE IN QUEUE AND MAKE IT VISITED"
Modify Global Variable(BuildProjectQueueArray, Append To Array, Global.BuildProjectStartNodeId);
Modify Global Variable(BuildProjectVisitedNodes, Append To Array, Global.BuildProjectStartNodeId);
"VISIT ALL NODES"
While(Count Of(Global.BuildProjectQueueArray) > 0);
"POP FIRST NODE FROM QUEUE"
Global.BuildProjectCurrentNodeId = Global.BuildProjectQueueArray[0];
Modify Global Variable(BuildProjectQueueArray, Remove From Array By Index, 0);
"VISIT NEIGHBOR NODES"
For Global Variable(LoopIterator1, 0, Count Of(Global.NodeConnections[Global.BuildProjectCurrentNodeId]), 1);
Global.BuildProjectNeighborNodeId = Global.NodeConnections[Global.BuildProjectCurrentNodeId][Global.LoopIterator1];
If(!Array Contains(Global.BuildProjectVisitedNodes, Global.BuildProjectNeighborNodeId));
"ADD NEIGHBOR IN QUEUE AND MARK IT AS VISITED"
Modify Global Variable(BuildProjectQueueArray, Append To Array, Global.BuildProjectNeighborNodeId);
Modify Global Variable(BuildProjectVisitedNodes, Append To Array, Global.BuildProjectNeighborNodeId);
"ACCUMULATE DISTANCE TO NEIGHBOR"
Global.BuilderInnerArray[Global.BuildProjectNeighborNodeId] = Global.BuilderInnerArray[Global.BuildProjectCurrentNodeId] + 1;
End;
End;
"ANTI-CRASH DELAY"
Wait(0.016, Ignore Condition);
End;
"REPLACE ZERO TO INF (9999)"
Global.BuilderInnerArray[Global.BuildProjectStartNodeId] = 9999;
"ADD RESULT IN DISTANCE MATRIX"
Global.DistanceMatrix[Global.BuildProjectStartNodeId] = Global.BuilderInnerArray;
Global.BuilderProgressBarValue += Global.BuilderProgressBarValueStep;
End;
Destroy All Progress Bar HUD Text;
}
}
disabled rule("=== PATH FINDING MODE ===")
{
event
{
Ongoing - Global;
}
}
rule("PLAYER: PATH FINDING MODE")
{
event
{
Ongoing - Each Player;
All;
All;
}
conditions
{
Is Dummy Bot(Event Player) == False;
Host Player == True;
Has Spawned(Event Player) == True;
disabled (Is Button Held(Event Player, Button(Primary Fire)) || Is Button Held(Event Player, Button(Secondary Fire)) || Is Button Held(
Event Player, Button(Ultimate))) == True;
(Is Button Held(Event Player, Button(Primary Fire)) || Is Button Held(Event Player, Button(Secondary Fire)) || Is Button Held(
Event Player, Button(Ultimate)) || Is Button Held(Event Player, Button(Interact))) == True;
Global.BuilderMode == Custom String("PATH FINDING");
}
actions
{
"SET START OR TARGET NODE"
If(Is Button Held(Event Player, Button(Primary Fire)) || Is Button Held(Event Player, Button(Secondary Fire)));
"ANY NODE IN LINE OF SIGHT"
Call Subroutine(BuilderGetClossestNodeIdToCursor);
Call Subroutine(PathFindingModeSelectNode);
"CREATE TEST BOT"
Else If(Is Button Held(Event Player, Button(Ultimate)));
If(Global.PathFindingStartNodeId != -1 && Global.PathFindingTargetNodeId != -1);
Call Subroutine(PathFindingCreateBot);
End;
"BOOP TEST BOT"
Else If(Is Button Held(Event Player, Button(Interact)));
Apply Impulse(Global.PathFindingBotId, Vector(X Component Of(Facing Direction Of(Event Player)), 0.400, Z Component Of(
Apply Impulse(Global.PathFindingBotId, Vector(X Component Of(Facing Direction Of(Event Player)), 0.200, Z Component Of(
Facing Direction Of(Event Player))), 20, To World, Cancel Contrary Motion);
End;
}
}
rule("SUBROUTINE: PATH FINDING SELECT NODE")
{
event
{
Subroutine;
PathFindingModeSelectNode;
}
actions
{
Abort If(Global.BuilderTrySelectNodeInLOS == -1);
disabled Abort If(Global.BuilderTrySelectNodeInLOS == -1);
Global.BuilderRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player)
+ Facing Direction Of(Event Player) * 999, Null, Event Player, False);
"SET START NODE"
If(Is Button Held(Event Player, Button(Primary Fire)));
Global.PathFindingStartNodeId = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions,
Is In Line of Sight(Global.BuilderRayCastHitPosition + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS)
== True), Distance Between(Global.BuilderRayCastHitPosition, Current Array Element))[0]);
Global.PathFindingStartPosition = Global.BuilderRayCastHitPosition;
Global.PathFindingStartNodeEffectPos = Global.PathFindingStartPosition;
"SET TARGET NODE"
Else If(Is Button Held(Event Player, Button(Secondary Fire)));
Global.PathFindingTargetNodeId = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions,
Is In Line of Sight(Global.BuilderRayCastHitPosition + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS)
== True), Distance Between(Global.BuilderRayCastHitPosition, Current Array Element))[0]);
Global.PathFindingTargetPosition = Global.BuilderRayCastHitPosition;
Global.PathFindingTargetNodeEffectPos = Global.PathFindingTargetPosition;
End;
"DRAW PATH"
If(Global.PathFindingStartNodeId != -1 && Global.PathFindingTargetNodeId != -1);
Call Subroutine(PathFindingGetShortestPath);
Call Subroutine(DeleteNodeBeams);
Call Subroutine(CreateNodeBeams);
"CLEAR PATH"
Else If(Global.PathFindingStartNodeId == -1 || Global.PathFindingTargetNodeId == -1);
Call Subroutine(DeleteNodeBeams);
End;
}
}
disabled rule("SUBROUTINE: PATH FINDING SELECT NODE !!!OLD")
{
event
{
Subroutine;
PathFindingModeSelectNode;
}
actions
{
disabled Abort If(Global.BuilderTrySelectNodeInLOS == -1);
"SET START NODE"
If(Is Button Held(Event Player, Button(Primary Fire)));
Global.PathFindingStartPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player)
+ Facing Direction Of(Event Player) * 999, Null, Event Player, False);
Global.PathFindingStartNodeId = Global.BuilderTrySelectNodeInLOS;
Global.PathFindingStartNodeEffectPos = Global.NodePositions[Global.BuilderTrySelectNodeInLOS];
"BIND EFFECT TO NODE"
disabled Global.PathFindingStartNodeEffectPos = Global.NodePositions[Global.BuilderTrySelectNodeInLOS];
"BIND EFFECT TO RAY CAST POS"
Global.PathFindingStartNodeEffectPos = Global.PathFindingStartPosition;
If(Global.PathFindingStartNodeId == Global.PathFindingTargetNodeId);
Global.PathFindingTargetNodeId = -1;
Global.PathFindingTargetNodeEffectPos = Vector(0, -999, 0);
End;
"SET TARGET NODE"
Else If(Is Button Held(Event Player, Button(Secondary Fire)));
Global.PathFindingTargetPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player)
+ Facing Direction Of(Event Player) * 999, Null, Event Player, False);
Global.PathFindingTargetNodeId = Global.BuilderTrySelectNodeInLOS;
Global.PathFindingTargetNodeEffectPos = Global.NodePositions[Global.BuilderTrySelectNodeInLOS];
"BIND EFFECT TO NODE"
disabled Global.PathFindingTargetNodeEffectPos = Global.NodePositions[Global.BuilderTrySelectNodeInLOS];
"BIND EFFECT TO RAY CAST POS"
Global.PathFindingTargetNodeEffectPos = Global.PathFindingTargetPosition;
If(Global.PathFindingTargetNodeId == Global.PathFindingStartNodeId);
Global.PathFindingStartNodeId = -1;
Global.PathFindingStartNodeEffectPos = Vector(0, -999, 0);
End;
End;
"DRAW PATH"
If(Global.PathFindingStartNodeId != -1 && Global.PathFindingTargetNodeId != -1);
Call Subroutine(PathFindingGetShortestPath);
Call Subroutine(DeleteNodeBeams);
Call Subroutine(CreateNodeBeams);
"CLEAR PATH"
Else If(Global.PathFindingStartNodeId == -1 || Global.PathFindingTargetNodeId == -1);
Call Subroutine(DeleteNodeBeams);
End;
}
}
rule("SUBROUTINE: PATH FINDING MODE RESET")
{
event
{
Subroutine;
PathFindingModeReset;
}
actions
{
Global.PathFindingStartNodeId = -1;
Global.PathFindingTargetNodeId = -1;
Global.PathFindingStartNodeEffectPos = Vector(0, -999, 0);
Global.PathFindingTargetNodeEffectPos = Vector(0, -999, 0);
Call Subroutine(DeleteNodeBeams);
}
}
rule("SUBROUTINE: DELETE NODE BEAM EFFECTS")
{
event
{
Subroutine;
DeleteNodeBeams;
}
actions
{
If(Count Of(Global.BeamEffects) > 0);
For Global Variable(LoopIterator1, 0, Count Of(Global.BeamEffects), 1);
Destroy Effect(Global.BeamEffects[Global.LoopIterator1]);
End;
Global.BeamEffects = Empty Array;
End;
}
}
rule("SUBROUTINE: CREATE NODE BEAM EFFECTS")
{
event
{
Subroutine;
CreateNodeBeams;
}
actions
{
If(Global.BuilderMode == Custom String("PATH FINDING"));
For Global Variable(LoopIterator1, 0, Count Of(Global.PathFindingResultPath) - 1, 1);
Create Beam Effect(All Players(All Teams), Bad Beam, Global.NodePositions[Global.PathFindingResultPath[Global.LoopIterator1]],
Global.NodePositions[Global.PathFindingResultPath[Global.LoopIterator1 + 1]], Global.BuilderHudColorCurrent, Visible To);
Modify Global Variable(BeamEffects, Append To Array, Last Created Entity);
End;
Else If(Global.BuilderMode == Custom String("EDIT"));
For Global Variable(LoopIterator1, 0, Count Of(Global.BuilderNodeConnections[Global.BuilderSelectedNodeId]), 1);
Create Beam Effect(All Players(All Teams), Good Beam, Global.BuilderNodePositions[Global.BuilderSelectedNodeId],
Global.BuilderNodePositions[Global.BuilderNodeConnections[Global.BuilderSelectedNodeId][Global.LoopIterator1]],
Global.BuilderHudColorEditMode, Visible To);
Modify Global Variable(BeamEffects, Append To Array, Last Created Entity);
End;
End;
}
}
rule("SUBROUTINE: PATH FINDING GET SHORTEST PATH")
{
event
{
Subroutine;
PathFindingGetShortestPath;
}
actions
{
Global.PathFindingResultPath = Empty Array;
Global.BuildProjectVisitedNodes = Empty Array;
Global.PathFindingCurrentNodeId = Global.PathFindingStartNodeId;
While(Global.PathFindingCurrentNodeId != Global.PathFindingTargetNodeId);
Modify Global Variable(PathFindingResultPath, Append To Array, Global.PathFindingCurrentNodeId);
Global.PathFindingShortestDistance = 999;
Global.BuilderInnerArray = Global.NodeConnections[Global.PathFindingCurrentNodeId];
For Global Variable(LoopIterator1, 0, Count Of(Global.BuilderInnerArray), 1);
If(Array Contains(Global.PathFindingResultPath, Global.BuilderInnerArray[Global.LoopIterator1]));
Continue;
Else If(Global.BuilderInnerArray[Global.LoopIterator1] == Global.PathFindingTargetNodeId);
Modify Global Variable(PathFindingResultPath, Append To Array, Global.PathFindingTargetNodeId);
Global.PathFindingCurrentNodeId = Global.PathFindingTargetNodeId;
Break;
End;
Global.PathFindingCurrentDistance = Global.DistanceMatrix[Global.BuilderInnerArray[Global.LoopIterator1]][Global.PathFindingTargetNodeId];
If(Global.PathFindingCurrentDistance < Global.PathFindingShortestDistance);
Global.PathFindingShortestDistance = Global.PathFindingCurrentDistance;
Global.PathFindingCurrentNodeId = Global.BuilderInnerArray[Global.LoopIterator1];
End;
End;
"IMPOSSIBLE TO REACH TARGET NODE"
If(Count Of(Global.PathFindingResultPath) > 1 && Global.PathFindingResultPath[Count Of(Global.PathFindingResultPath)
- 1] == Global.PathFindingResultPath[Count Of(Global.PathFindingResultPath) - 2]);
Small Message(All Players(All Teams), Custom String("IMPOSSIBLE TO REACH TARGET NODE {0}", Global.PathFindingTargetNodeId));
Global.PathFindingResultPath = Empty Array;
Abort;
End;
"ANTI-CRASH DELAY"
Wait(0.016, Ignore Condition);
End;
}
}
rule("SUBROUTINE: PATH FINDING CREATE TEST BOT")
{
event
{
Subroutine;
PathFindingCreateBot;
}
actions
{
If(!Entity Exists(Global.PathFindingBotId));
Create Dummy Bot(Random Value In Array(All Heroes), Opposite Team Of(Team Of(Event Player)), -1,
Global.NodePositions[Global.PathFindingStartNodeId], Vector(0, 0, 0));
Create Dummy Bot(Random Value In Array(All Heroes), Opposite Team Of(Team Of(Event Player)), -1, Global.PathFindingStartPosition,
Vector(0, 0, 0));
Global.PathFindingBotId = Last Created Entity;
Set Move Speed(Global.PathFindingBotId, Global.PropertyBotMovementSpeed);
Start Forcing Dummy Bot Name(Global.PathFindingBotId, Custom String("TEST BOT"));
Else;
Start Forcing Player To Be Hero(Global.PathFindingBotId, Random Value In Array(All Heroes));
Teleport(Global.PathFindingBotId, Global.NodePositions[Global.PathFindingStartNodeId]);
Teleport(Global.PathFindingBotId, Global.PathFindingStartPosition);
End;
Call Subroutine(PathFindingResetBot);
Call Subroutine(PathFindingTestBotReset);
"ANTI-BUG DELAY"
Wait(0.016, Ignore Condition);
Global.PathFindingBotId.BotTargetPosition = Global.NodePositions[Global.PathFindingTargetNodeId];
Wait(0.100, Ignore Condition);
Global.PathFindingBotId.BotTargetPosition = Global.PathFindingTargetPosition;
}
}
disabled rule("=== TEST BOT ===")
{
event
{
Ongoing - Global;
}
}
rule("SUBROUTINE: RESET TEST BOT")
rule("BOT: INIT")
{
event
{
Player Joined Match;
All;
All;
}
conditions
{
Is Dummy Bot(Event Player) == True;
}
actions
{
Call Subroutine(BotResetPathFinding);
"LINE OF SIGHT TO NEXT NODE"
Create Beam Effect(All Players(All Teams), Good Beam, Update Every Frame(Position Of(Event Player) + Vector(0, 1.600, 0)),
Update Every Frame(Event Player.BotNextNodePosition + Vector(0, 2, 0)), Color(Green), Visible To Position and Radius);
"Y DIFF BETWEEN BOT POS AND NODE POS"
Create Beam Effect(All Players(All Teams), Good Beam, Update Every Frame(Position Of(Event Player)), Update Every Frame(
Position Of(Event Player) + Vector(0, 2, 0)), Color(Red), Visible To Position and Radius);
Create HUD Text(All Players(All Teams), Custom String("TEST BOT INFO\r\nCLOSEST NODE: {0}\r\nCLOSEST NODE IN LOS: {1}\r\n{2}",
Index Of Array Value(Global.NodePositions, Sorted Array(Global.NodePositions, Distance Between(Position Of(Event Player),
Current Array Element))[0]), Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions,
Is In Line of Sight(Eye Position(Event Player), Current Array Element, Barriers Do Not Block LOS) == True), Distance Between(
Position Of(Event Player), Current Array Element))[0]), Custom String("PREV NODE {0}\r\nNEXT NODE {1}\r\n{2}",
Global.PathFindingBotId.BotPrevNodeId, Global.PathFindingBotId.BotNextNodeId, Custom String(
"TARGET NODE {0}\r\nY DIFF {1}\r\nSEE NEXT NODE {2}", Event Player.BotClosestNodeIdToTarget, Y Component Of(Position Of(
Event Player)) - Y Component Of(Global.NodePositions[Event Player.BotNextNodeId]), Is In Line of Sight(Position Of(
Event Player) + Vector(0, 1.600, 0), Global.NodePositions[Event Player.BotNextNodeId] + Vector(0, 2, 0),
Barriers Do Not Block LOS)))), Null, Null, Right, -1, Color(Purple), Color(White), Color(White), Visible To and String,
Default Visibility);
}
}
rule("SUBROUTINE: TEST BOT RESET")
{
event
{
Subroutine;
PathFindingResetBot;
PathFindingTestBotReset;
}
actions
{
Stop Throttle In Direction(Global.PathFindingBotId);
Stop Facing(Global.PathFindingBotId);
Global.PathFindingBotId.BotTargetPlayer = -1;
Global.PathFindingBotId.BotTargetPosition = -1;
Global.PathFindingBotId.BotTargetNodeId = -1;
Global.PathFindingBotId.BotPrevNodeId = -1;
Global.PathFindingBotId.BotClosestNodeIdToTarget = -1;
Global.PathFindingBotId.BotNextNodeId = -1;
Global.PathFindingBotId.BotNextNodePosition = -1;
Global.PathFindingBotId.BotIsPathFinding = False;
Stop Facing(Global.PathFindingBotId);
Stop Throttle In Direction(Global.PathFindingBotId);
}
}