Higor
05-12-2012, 07:00 PM
Looking into sgProtector and sgSProtector's enemy finding methods.
ShouldAttack:
function bool ShouldAttack(Pawn enemy)
{
local UT_Invisibility inv;
local bool bInv;
local Inventory RubberSuit;
RubberSuit = enemy.FindInventoryType(class'WildcardsRubberSuit' );
if ( enemy == None )
return false;
if ( !FastTrace(enemy.Location) )
return false;
if ( ScriptedPawn(enemy) != None && enemy.Health > 10 )
return true;
if ( sgBuilding(enemy) != None )
{
if ( sgBuilding(enemy).Team == Team || sgBuilding(enemy).Energy < 0 )
return false;
}
else if ( enemy.PlayerReplicationInfo == None ||
enemy.PlayerReplicationInfo.Team == Team ||
enemy.Health <= 10 || RubberSuit != none ||
!enemy.bProjTarget)
return false;
return true;
}
This function is called within a RadiusActors iterator, so we don't need to check for (Enemy == none).
Second, we shouldn't try finding the rubbersuit until all the other checks have failed.
Third, we should use FastTrace as final positive check, so we use it the least amount of times.
We'll also remove some unused variables.
Suggested code:
function bool ShouldAttack(Pawn enemy)
{
if ( ScriptedPawn(enemy) != None )
{
if ( enemy.Health < 10 )
return false;
return FastTrace( enemy.Location);
}
if ( sgBuilding(enemy) != None )
{
if ( sgBuilding(enemy).Team == Team || sgBuilding(enemy).Energy < 0 )
return false;
}
else if ( enemy.PlayerReplicationInfo == None ||
enemy.PlayerReplicationInfo.Team == Team ||
enemy.Health <= 10 || !enemy.bProjTarget || (enemy.FindInventoryType(class'WildcardsRubberSuit ') != none) )
return false;
return FastTrace(enemy.Location);
}
No new variablies initialized, RubberSuit is found right if when need to find it and the trace checks are done as final condition.
EDIT 1:
FindEnemy:
function Pawn FindEnemy()
{
local Pawn p, target;
SightRadius = 1000 + 1750*Grade;
foreach RadiusActors(class'Pawn', p, SightRadius)
if ( ShouldAttack(p) && (target == None ||
VSize(p.Location - Location) < VSize(target.Location - Location)) )
target = p;
return target;
}
ShouldAttack requires more resources than the distance checks, we should invert these checks.
We shouldn't search further away from current enemy if we have one.
Suggested code:
function Pawn FindEnemy()
{
local Pawn p;
local float eDist;
//Should be applied during upgrade, does the function Upgraded() properly work?
// SightRadius = 1000 + 1750*Grade;
if ( Enemy != none )
{
eDist = VSize( Enemy.Location - Location);
if ( (eDist > SightRadius) || !ShouldAttack(Enemy) )
Enemy = none;
else
{
eDist -= 1;
foreach RadiusActors(class'Pawn', p, eDist)
if ( (VSize(p.Location - Location) < VSize(Enemy.Location - Location)) && ShouldAttack(p) )
Enemy = p;
return Enemy;
}
}
foreach RadiusActors(class'Pawn', p, SightRadius)
if ( (Enemy == None || VSize(p.Location - Location) < VSize(Enemy.Location - Location)) && ShouldAttack(p) )
Enemy = p;
return Enemy;
}
We store Enemy for future uses, if enemy is still valid, we try finding one at a closer distance.
Expensive checks placed last as well.
Other changes:
Add:
simulated function Upgraded()
{
SightRadius = 1000 + 1750*Grade;
}
And in the defaultproperties block add:
SightRadius = 1000;
Checking on sgSProtector:
function bool ShouldAttack(Pawn enemy)
{
return Super.ShouldAttack(enemy);
}
sgSProtector is subclass of sgProtector, you should remove this.
ShouldAttack:
function bool ShouldAttack(Pawn enemy)
{
local UT_Invisibility inv;
local bool bInv;
local Inventory RubberSuit;
RubberSuit = enemy.FindInventoryType(class'WildcardsRubberSuit' );
if ( enemy == None )
return false;
if ( !FastTrace(enemy.Location) )
return false;
if ( ScriptedPawn(enemy) != None && enemy.Health > 10 )
return true;
if ( sgBuilding(enemy) != None )
{
if ( sgBuilding(enemy).Team == Team || sgBuilding(enemy).Energy < 0 )
return false;
}
else if ( enemy.PlayerReplicationInfo == None ||
enemy.PlayerReplicationInfo.Team == Team ||
enemy.Health <= 10 || RubberSuit != none ||
!enemy.bProjTarget)
return false;
return true;
}
This function is called within a RadiusActors iterator, so we don't need to check for (Enemy == none).
Second, we shouldn't try finding the rubbersuit until all the other checks have failed.
Third, we should use FastTrace as final positive check, so we use it the least amount of times.
We'll also remove some unused variables.
Suggested code:
function bool ShouldAttack(Pawn enemy)
{
if ( ScriptedPawn(enemy) != None )
{
if ( enemy.Health < 10 )
return false;
return FastTrace( enemy.Location);
}
if ( sgBuilding(enemy) != None )
{
if ( sgBuilding(enemy).Team == Team || sgBuilding(enemy).Energy < 0 )
return false;
}
else if ( enemy.PlayerReplicationInfo == None ||
enemy.PlayerReplicationInfo.Team == Team ||
enemy.Health <= 10 || !enemy.bProjTarget || (enemy.FindInventoryType(class'WildcardsRubberSuit ') != none) )
return false;
return FastTrace(enemy.Location);
}
No new variablies initialized, RubberSuit is found right if when need to find it and the trace checks are done as final condition.
EDIT 1:
FindEnemy:
function Pawn FindEnemy()
{
local Pawn p, target;
SightRadius = 1000 + 1750*Grade;
foreach RadiusActors(class'Pawn', p, SightRadius)
if ( ShouldAttack(p) && (target == None ||
VSize(p.Location - Location) < VSize(target.Location - Location)) )
target = p;
return target;
}
ShouldAttack requires more resources than the distance checks, we should invert these checks.
We shouldn't search further away from current enemy if we have one.
Suggested code:
function Pawn FindEnemy()
{
local Pawn p;
local float eDist;
//Should be applied during upgrade, does the function Upgraded() properly work?
// SightRadius = 1000 + 1750*Grade;
if ( Enemy != none )
{
eDist = VSize( Enemy.Location - Location);
if ( (eDist > SightRadius) || !ShouldAttack(Enemy) )
Enemy = none;
else
{
eDist -= 1;
foreach RadiusActors(class'Pawn', p, eDist)
if ( (VSize(p.Location - Location) < VSize(Enemy.Location - Location)) && ShouldAttack(p) )
Enemy = p;
return Enemy;
}
}
foreach RadiusActors(class'Pawn', p, SightRadius)
if ( (Enemy == None || VSize(p.Location - Location) < VSize(Enemy.Location - Location)) && ShouldAttack(p) )
Enemy = p;
return Enemy;
}
We store Enemy for future uses, if enemy is still valid, we try finding one at a closer distance.
Expensive checks placed last as well.
Other changes:
Add:
simulated function Upgraded()
{
SightRadius = 1000 + 1750*Grade;
}
And in the defaultproperties block add:
SightRadius = 1000;
Checking on sgSProtector:
function bool ShouldAttack(Pawn enemy)
{
return Super.ShouldAttack(enemy);
}
sgSProtector is subclass of sgProtector, you should remove this.