Hanfling wrote:Check for AISendEvent(). Another idea would be that they do not avoid the teargas, but rather the player using a weapon.
AISendEvent() is not related. Nor should the weapon used be (it looks for the projectile, not the weapon).
From what I can make out, what happens is if bAvoidHarm is true, then AI attempt to avoid projectiles if within range (gasclouds extend DeusEx Projectile).
This function in scriptedpawn determines if the projectile is dangerous and should be avoided:
Code: Select all
function int GetProjectileList(out NearbyProjectileList projList, vector Location)
{
local float dist;
local int count;
local DeusExProjectile curProj;
local ThrownProjectile throwProj;
local Cloud cloudProj;
local vector HitNormal, HitLocation;
local vector extent;
local vector traceEnd;
local Actor hitActor;
local float range;
local vector pos;
local float time;
local float maxTime;
local float elasticity;
local int i;
local bool bValid;
for (i=0; i<ArrayCount(projList.list); i++)
projList.list[i].projectile = None;
projList.center = Location;
maxTime = 2.0;
foreach RadiusActors(Class'DeusExProjectile', curProj, 1000)
{
if (IsProjectileDangerous(curProj))
{
throwProj = ThrownProjectile(curProj);
cloudProj = Cloud(curProj);
extent = vect(1,1,0)*curProj.CollisionRadius;
extent.Z = curProj.CollisionHeight;
range = VSize(extent);
if (curProj.bExplodes)
if (range < curProj.blastRadius)
range = curProj.blastRadius;
if (cloudProj != None)
if (range < cloudProj.cloudRadius)
range = cloudProj.cloudRadius;
range += CollisionRadius+60;
if (throwProj != None)
elasticity = throwProj.Elasticity;
else
elasticity = 0.2;
bValid = true;
if (throwProj != None)
if (throwProj.bProximityTriggered) // HACK!!!
bValid = false;
if (((curProj.Physics == PHYS_Falling) || (curProj.Physics == PHYS_Projectile) || (curProj.Physics == PHYS_None)) &&
bValid)
{
pos = curProj.Location;
dist = VSize(Location - curProj.Location);
AddProjectileToList(projList, curProj, pos, dist, range);
if (curProj.Physics == PHYS_Projectile)
{
traceEnd = curProj.Location + curProj.Velocity*maxTime;
hitActor = Trace(HitLocation, HitNormal, traceEnd, curProj.Location, true, extent);
if (hitActor == None)
pos = traceEnd;
else
pos = HitLocation;
dist = VSize(Location - pos);
AddProjectileToList(projList, curProj, pos, dist, range);
}
else if (curProj.Physics == PHYS_Falling)
{
time = ParabolicTrace(pos, curProj.Velocity, curProj.Location, true, extent, maxTime,
elasticity, curProj.bBounce, 60);
if (time > 0)
{
dist = VSize(Location - pos);
AddProjectileToList(projList, curProj, pos, dist, range);
}
}
}
}
}
count = 0;
for (i=0; i<ArrayCount(projList.list); i++)
if (projList.list[i].projectile != None)
count++;
return (count);
}
This function returns true if the function above spits out a valid projectile, and said valid projectile is in range to the NPC:
Code: Select all
// ----------------------------------------------------------------------
// IsLocationDangerous()
// ----------------------------------------------------------------------
function bool IsLocationDangerous(NearbyProjectileList projList,
vector Location)
{
local bool bDanger;
local int i;
local float dist;
bDanger = false;
for (i=0; i<ArrayCount(projList.list); i++)
{
if (projList.list[i].projectile == None)
break;
if (projList.center == Location)
dist = projList.list[i].dist;
else
dist = VSize(projList.list[i].location - Location);
if (dist < projList.list[i].range)
{
bDanger = true;
break;
}
}
return (bDanger);
}
Then bDanger is used in other functions for telling the Pawn to get the fuck away from the projectile (movement code, PickDestination()).
I don't get what could possibly saying pepper gun tear gas should be avoided, but feel free to run into gas grenade-spawned gas. I hate AI code.