Skip to content

Commit cceaaa8

Browse files
committed
Fix stale ptr access (and do an initial euclidean distance early-out)
1 parent 847a794 commit cceaaa8

File tree

1 file changed

+47
-39
lines changed

1 file changed

+47
-39
lines changed

Data/Base.rte/AI/HumanBehaviors.lua

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -974,30 +974,35 @@ function HumanBehaviors.WeaponSearch(AI, Owner, Abort)
974974
local devicesToPickUp = {};
975975
for _, deviceEntry in pairs(devices) do
976976
local device = deviceEntry.device;
977-
if MovableMan:ValidMO(device) then
978-
SceneMan.Scene:CalculatePathAsync(
979-
function(pathRequest)
980-
local pathLength = pathRequest.PathLength;
981-
if pathRequest.Status ~= PathRequest.NoSolution and pathLength < maxPathLength then
982-
local score = pathLength;
983-
if device:HasObjectInGroup("Weapons - Primary") or device:HasObjectInGroup("Weapons - Heavy") then
984-
score = pathLength * 0.4; -- prioritize primary or heavy weapons
985-
elseif device.ClassName == "TDExplosive" then
986-
score = pathLength * 1.4; -- avoid grenades if there are other weapons
987-
elseif device:IsTool() then
988-
if pickupDiggers and device:HasObjectInGroup("Tools - Diggers") then
989-
score = pathLength * 1.8; -- avoid diggers if there are other weapons
990-
else
991-
pathLength = maxPathLength;
992-
end
993-
end
977+
978+
local pathMultipler = 1;
979+
if device:HasObjectInGroup("Weapons - Primary") or device:HasObjectInGroup("Weapons - Heavy") then
980+
pathMultipler = 0.4; -- prioritize primary or heavy weapons
981+
elseif device.ClassName == "TDExplosive" then
982+
pathMultipler = 1.4; -- avoid grenades if there are other weapons
983+
elseif device:IsTool() then
984+
if pickupDiggers and device:HasObjectInGroup("Tools - Diggers") then
985+
pathMultipler = 1.8; -- avoid diggers if there are other weapons
986+
else
987+
pathMultipler = -1; -- disregard non-digger tools
988+
end
989+
end
990+
991+
if MovableMan:ValidMO(device) and pathMultipler ~= -1 then
992+
local simpleDistance = SceneMan:ShortestDistance(Owner.Pos, device.Pos, false) * pathMultipler;
993+
if simpleDistance < maxPathLength then
994+
local deviceID = device.UniqueID;
995+
SceneMan.Scene:CalculatePathAsync(
996+
function(pathRequest)
997+
local pathLength = pathRequest.PathLength * pathMultipler;
994998
if pathLength < maxPathLength then
995-
table.insert(devicesToPickUp, {device = device, score = score});
999+
table.insert(devicesToPickUp, {deviceId = deviceID, score = score});
9961000
end
997-
end
998-
searchesRemaining = searchesRemaining - 1;
999-
end
1000-
, Owner.Pos, device.Pos, false, Owner.DigStrength, Owner.Team);
1001+
searchesRemaining = searchesRemaining - 1;
1002+
end,
1003+
Owner.Pos, device.Pos, false, Owner.DigStrength, Owner.Team
1004+
);
1005+
end
10011006
end
10021007
end
10031008

@@ -1009,8 +1014,9 @@ function HumanBehaviors.WeaponSearch(AI, Owner, Abort)
10091014
AI.PickupHD = nil;
10101015
table.sort(devicesToPickUp, function(A,B) return A.score < B.score end);
10111016
for _, deviceToPickupEntry in ipairs(devicesToPickUp) do
1012-
if MovableMan:ValidMO(deviceToPickupEntry.device) and deviceToPickupEntry.device:IsDevice() then
1013-
AI.PickupHD = deviceToPickupEntry.device;
1017+
local device = MovableMan:FindObjectByUniqueID(deviceToPickupEntry.deviceId);
1018+
if MovableMan:ValidMO(device) and device:IsDevice() then
1019+
AI.PickupHD = device;
10141020
break;
10151021
end
10161022
end
@@ -1072,10 +1078,6 @@ function HumanBehaviors.ToolSearch(AI, Owner, Abort)
10721078
local mosSearched = 0;
10731079
for movableObject in MovableMan:GetMOsInRadius(Owner.Pos, maxSearchDistance, -1, true) do
10741080
mosSearched = mosSearched + 1;
1075-
if mosSearched % 30 == 0 then
1076-
local _ai, _ownr, _abrt = coroutine.yield();
1077-
if _abrt then return true end
1078-
end
10791081

10801082
if IsHeldDevice(movableObject) and MovableMan:ValidMO(movableObject) then
10811083
local device = ToHeldDevice(movableObject);
@@ -1105,15 +1107,20 @@ function HumanBehaviors.ToolSearch(AI, Owner, Abort)
11051107
for _, deviceEntry in pairs(devices) do
11061108
local device = deviceEntry.device;
11071109
if MovableMan:ValidMO(device) then
1108-
SceneMan.Scene:CalculatePathAsync(
1109-
function(pathRequest)
1110-
local pathLength = pathRequest.PathLength;
1111-
if pathRequest.Status ~= PathRequest.NoSolution and pathLength < maxPathLength then
1112-
table.insert(devicesToPickUp, {device = device, score = pathLength});
1113-
end
1114-
searchesRemaining = searchesRemaining - 1;
1115-
end
1116-
, Owner.Pos, device.Pos, false, Owner.DigStrength, Owner.Team);
1110+
local simpleDistance = SceneMan:ShortestDistance(Owner.Pos, device.Pos, false);
1111+
if simpleDistance < maxPathLength then
1112+
local deviceId = device.UniqueID;
1113+
SceneMan.Scene:CalculatePathAsync(
1114+
function(pathRequest)
1115+
local pathLength = pathRequest.PathLength;
1116+
if pathRequest.Status ~= PathRequest.NoSolution and pathLength < maxPathLength then
1117+
table.insert(devicesToPickUp, {deviceId = deviceId, score = pathLength});
1118+
end
1119+
searchesRemaining = searchesRemaining - 1;
1120+
end,
1121+
Owner.Pos, device.Pos, false, Owner.DigStrength, Owner.Team
1122+
);
1123+
end
11171124
end
11181125
end
11191126

@@ -1125,8 +1132,9 @@ function HumanBehaviors.ToolSearch(AI, Owner, Abort)
11251132
AI.PickupHD = nil;
11261133
table.sort(devicesToPickUp, function(A,B) return A.score < B.score end); -- sort the items in order of discounted distance
11271134
for _, deviceToPickupEntry in ipairs(devicesToPickUp) do
1128-
if MovableMan:ValidMO(deviceToPickupEntry.device) and deviceToPickupEntry.device:IsDevice() then
1129-
AI.PickupHD = deviceToPickupEntry.device;
1135+
local device = MovableMan:FindObjectByUniqueID(deviceToPickupEntry.deviceId);
1136+
if MovableMan:ValidMO(device) and device:IsDevice() then
1137+
AI.PickupHD = device;
11301138
break;
11311139
end
11321140
end

0 commit comments

Comments
 (0)