function thePlague.SpreadInfection()
local sickTable = thePlague.sickPeople
for index,sickPerson in ipairs(sickTable) do
for indexPlayer,ply in ipairs( player.GetAll() ) do
if ply:GetPos():Distance(sickPerson:GetPos()) < 200 and not thePlague.IsSick(ply) then
thePlague.Infect(ply)
end
end
end
end
When I am close enough to the player, game crashes. But if I remove this and change it with something else, it works.
thePlague.Infect(ply)
Here is the Infect function:
function thePlague.Infect(ply)
table.insert(thePlague.sickPeople, ply)
ply:ChatPrint("You are infected!")
ply:ChatPrint("Contain yourself or infect others.")
print(ply:GetName().. " is infected!")
end
FYI the reason it was a problem is because you were adding keys to a table you were iterating over with pairs or ipairs. According to the Lua documentation, this is undefined behavior. Removing keys is fine, but adding keys is bad. You don't need to make a copy of your sickPeople table. The newSickPeople table avoids the issue just fine on it's own.
If you are interested in speeding it up a little, you could use Vector:DistToSqr() instead of Vector:Distance(). Vector:DistToSqr() gets you the squared distance, which avoids an expensive square root calculation.
If you want to do something more advanced to speed it up, you can reduce iterations by maintaining your own table of non-infected players instead of using player.GetAll() every time (make use of hooks to handle players joining and leaving). This will reduce the number of iterations that are wasted because the target player is already sick to zero, so you also won't need that check anymore. If you go this route, you should also put the players into the tables as keys instead of values, so that you won't need to iterate them to remove players.
Sorry, you need to Log In to post a reply to this thread.