@@ -1353,114 +1353,74 @@ function HumanBehaviors.GoToWpt(AI, Owner, Abort)
1353
1353
if WptList then
1354
1354
local NextWptPos = WptList [1 ].Pos ;
1355
1355
Dist = SceneMan :ShortestDistance (Owner .Pos , NextWptPos , false );
1356
- if Dist .Y < - 25 and math.abs (Dist .X ) < 30 then -- avoid any corners if the next waypoint is above us
1357
- local cornerType ;
1358
- local CornerPos = Vector (NextWptPos .X , NextWptPos .Y );
1359
- if Owner .Pos .X > CornerPos .X then
1360
- CornerPos = CornerPos + Vector (25 , - 40 );
1361
- cornerType = " right" ;
1362
- else
1363
- CornerPos = CornerPos + Vector (- 25 , - 40 );
1364
- cornerType = " left" ;
1365
- end
1366
-
1356
+ Waypoint = table.remove (WptList , 1 );
1357
+ if Waypoint .Type ~= " air" then
1367
1358
local Free = Vector ();
1368
- Dist = SceneMan :ShortestDistance (NextWptPos , CornerPos , false );
1369
- -- make sure the corner waypoint is not inside terrain
1370
- local pixels = SceneMan :CastObstacleRay (NextWptPos , Dist , Vector (), Free , Owner .ID , Owner .IgnoresWhichTeam , rte .grassID , 3 );
1371
- if pixels == 0 then
1372
- break ; -- the waypoint is inside terrain, plot a new path
1373
- elseif pixels > 0 then
1374
- CornerPos = (NextWptPos + Free ) / 2 ; -- compensate for obstacles
1375
- end
1376
-
1377
- -- check if we have LOS
1378
- Dist = SceneMan :ShortestDistance (Owner .Pos , CornerPos , false );
1379
- if 0 <= SceneMan :CastObstacleRay (Owner .Pos , Dist , Vector (), Vector (), Owner .ID , Owner .IgnoresWhichTeam , rte .grassID , 2 ) then
1380
- -- CornerPos is blocked
1381
- CornerPos .X = Owner .Pos .X ; -- move CornerPos straight above us
1382
- cornerType = " air" ;
1383
- end
1384
-
1385
- Waypoint = {Pos = CornerPos , Type = cornerType };
1386
- if WptList [2 ] and not WptList [1 ].Type then -- remove the waypoint after the corner if possible
1387
- table.remove (WptList , 1 );
1388
- Owner :RemoveMovePathBeginning (); -- clean up the graphical representation of the path
1389
- end
1390
1359
1391
- if not Owner .MOMoveTarget then
1392
- Owner :AddToMovePathBeginning (Waypoint .Pos );
1393
- end
1394
- else
1395
- Waypoint = table.remove (WptList , 1 );
1396
- if Waypoint .Type ~= " air" then
1397
- local Free = Vector ();
1398
-
1399
- -- only if we have a digging tool
1400
- if Waypoint .Type ~= " drop" and Owner :HasObjectInGroup (" Tools - Diggers" ) then
1401
- local PathSegRay = SceneMan :ShortestDistance (PrevWptPos , Waypoint .Pos , false ); -- detect material blocking the path and start digging through it
1402
- if AI .teamBlockState ~= Actor .BLOCKED and SceneMan :CastStrengthRay (PrevWptPos , PathSegRay , 4 , Free , 2 , rte .doorID , true ) then
1403
- if SceneMan :ShortestDistance (Owner .Pos , Free , false ):MagnitudeIsLessThan (Owner .Height * 0.4 ) then -- check that we're close enough to start digging
1404
- digState = AHuman .STARTDIG ;
1405
- AI .deviceState = AHuman .DIGGING ;
1406
- obstacleState = Actor .DIGPAUSING ;
1407
- nextLatMove = Actor .LAT_STILL ;
1408
- sweepRange = math.min (math.pi * 0.2 , Owner .AimRange );
1409
- StuckTimer :SetSimTimeLimitMS (6000 );
1410
- AI .Ctrl .AnalogAim = SceneMan :ShortestDistance (Owner .Pos , Waypoint .Pos , false ).Normalized ; -- aim in the direction of the next waypoint
1411
- else
1412
- digState = AHuman .NOTDIGGING ;
1413
- obstacleState = Actor .PROCEEDING ;
1414
- end
1415
-
1416
- local _ai , _ownr , _abrt = coroutine.yield (); -- wait until next frame
1417
- if _abrt then return true end
1360
+ -- only if we have a digging tool
1361
+ if Waypoint .Type ~= " drop" and Owner :HasObjectInGroup (" Tools - Diggers" ) then
1362
+ local PathSegRay = SceneMan :ShortestDistance (PrevWptPos , Waypoint .Pos , false ); -- detect material blocking the path and start digging through it
1363
+ if AI .teamBlockState ~= Actor .BLOCKED and SceneMan :CastStrengthRay (PrevWptPos , PathSegRay , 4 , Free , 2 , rte .doorID , true ) then
1364
+ if SceneMan :ShortestDistance (Owner .Pos , Free , false ):MagnitudeIsLessThan (Owner .Height * 0.4 ) then -- check that we're close enough to start digging
1365
+ digState = AHuman .STARTDIG ;
1366
+ AI .deviceState = AHuman .DIGGING ;
1367
+ obstacleState = Actor .DIGPAUSING ;
1368
+ nextLatMove = Actor .LAT_STILL ;
1369
+ sweepRange = math.min (math.pi * 0.2 , Owner .AimRange );
1370
+ StuckTimer :SetSimTimeLimitMS (6000 );
1371
+ AI .Ctrl .AnalogAim = SceneMan :ShortestDistance (Owner .Pos , Waypoint .Pos , false ).Normalized ; -- aim in the direction of the next waypoint
1418
1372
else
1419
1373
digState = AHuman .NOTDIGGING ;
1420
1374
obstacleState = Actor .PROCEEDING ;
1421
- StuckTimer :SetSimTimeLimitMS (1000 );
1422
1375
end
1423
- end
1424
1376
1425
- if digState == AHuman .NOTDIGGING and AI .deviceState ~= AHuman .DIGGING then
1426
- -- if our path isn't blocked enough to dig, but the headroom is too little, start crawling to get through
1427
- local heading = SceneMan :ShortestDistance (Owner .Pos , Waypoint .Pos , false ):SetMagnitude (Owner .Height * 0.5 );
1377
+ local _ai , _ownr , _abrt = coroutine.yield (); -- wait until next frame
1378
+ if _abrt then return true end
1379
+ else
1380
+ digState = AHuman .NOTDIGGING ;
1381
+ obstacleState = Actor .PROCEEDING ;
1382
+ StuckTimer :SetSimTimeLimitMS (1000 );
1383
+ end
1384
+ end
1428
1385
1429
- -- This gets the angle of the heading vector relative to flat (i.e, straight along the X axis)
1430
- -- This gives a range of [0, 90]
1431
- -- 0 is pointing straight left/right, and 90 is pointing straight up/down.
1432
- local angleRadians = math.abs (math.atan2 (- (heading .X * heading .Y ), heading .X * heading .X ));
1433
- local angleDegrees = angleRadians * (180 / math.pi );
1386
+ if digState == AHuman .NOTDIGGING and AI .deviceState ~= AHuman .DIGGING then
1387
+ -- if our path isn't blocked enough to dig, but the headroom is too little, start crawling to get through
1388
+ local heading = SceneMan :ShortestDistance (Owner .Pos , Waypoint .Pos , false ):SetMagnitude (Owner .Height * 0.5 );
1434
1389
1435
- -- We only crawl it it's quite flat, otherwise climb
1436
- local crawlThresholdDegrees = 30 ;
1437
- if angleDegrees <= crawlThresholdDegrees and Owner .Head and Owner .Head :IsAttached () then
1438
- local topHeadPos = Owner .Head .Pos - Vector (0 , Owner .Head .Radius * 0.7 );
1390
+ -- This gets the angle of the heading vector relative to flat (i.e, straight along the X axis)
1391
+ -- This gives a range of [0, 90]
1392
+ -- 0 is pointing straight left/right, and 90 is pointing straight up/down.
1393
+ local angleRadians = math.abs (math.atan2 (- (heading .X * heading .Y ), heading .X * heading .X ));
1394
+ local angleDegrees = angleRadians * (180 / math.pi );
1439
1395
1440
- -- first check up to the top of the head, and then from there forward
1441
- if SceneMan :CastStrengthRay (Owner .Pos , topHeadPos - Owner .Pos , 5 , Free , 4 , rte .doorID , true ) or SceneMan :CastStrengthRay (topHeadPos , heading , 5 , Free , 4 , rte .doorID , true ) then
1442
- AI .proneState = AHuman .PRONE ;
1443
- else
1444
- AI .proneState = AHuman .NOTPRONE ;
1445
- end
1396
+ -- We only crawl it it's quite flat, otherwise climb
1397
+ local crawlThresholdDegrees = 30 ;
1398
+ if angleDegrees <= crawlThresholdDegrees and Owner .Head and Owner .Head :IsAttached () then
1399
+ local topHeadPos = Owner .Head .Pos - Vector (0 , Owner .Head .Radius * 0.7 );
1446
1400
1447
- local _ai , _ownr , _abrt = coroutine.yield (); -- wait until next frame
1448
- if _abrt then return true end
1401
+ -- first check up to the top of the head, and then from there forward
1402
+ if SceneMan :CastStrengthRay (Owner .Pos , topHeadPos - Owner .Pos , 5 , Free , 4 , rte .doorID , true ) or SceneMan :CastStrengthRay (topHeadPos , heading , 5 , Free , 4 , rte .doorID , true ) then
1403
+ AI .proneState = AHuman .PRONE ;
1449
1404
else
1450
1405
AI .proneState = AHuman .NOTPRONE ;
1451
1406
end
1407
+
1408
+ local _ai , _ownr , _abrt = coroutine.yield (); -- wait until next frame
1409
+ if _abrt then return true end
1410
+ else
1411
+ AI .proneState = AHuman .NOTPRONE ;
1452
1412
end
1453
1413
end
1414
+ end
1454
1415
1455
- if not WptList [1 ] then
1456
- WptList = nil ; -- update the path
1457
- end
1416
+ if not WptList [1 ] then
1417
+ WptList = nil ; -- update the path
1458
1418
end
1459
1419
1460
1420
if not Waypoint .Type then
1461
1421
ArrivedTimer :SetSimTimeLimitMS (100 );
1462
1422
elseif Waypoint .Type == " last" then
1463
- ArrivedTimer :SetSimTimeLimitMS (600 );
1423
+ ArrivedTimer :SetSimTimeLimitMS (300 );
1464
1424
else -- air or corner wpt
1465
1425
ArrivedTimer :SetSimTimeLimitMS (0 );
1466
1426
end
@@ -1743,7 +1703,7 @@ function HumanBehaviors.GoToWpt(AI, Owner, Abort)
1743
1703
if Owner .Jetpack and Owner .Head and Owner .Head :IsAttached () then
1744
1704
if Owner .Jetpack .JetTimeLeft < AI .minBurstTime then
1745
1705
AI .jump = false ; -- not enough fuel left, no point in jumping yet
1746
- if not AI .flying or Owner .Vel .Y > 1 then
1706
+ if not AI .flying or Owner .Vel .Y > 4 then
1747
1707
AI .refuel = true ;
1748
1708
end
1749
1709
else
0 commit comments