Create
Return to post

Comparing difference between and

View raw
  • 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);
  • }
  • }
Join the Workshop.codes Discord