PDA

View Full Version : Code review: Poison Guardian



Higor
08-24-2012, 02:12 AM
Class: WildcardsPoisonGuardian.

Replace all code with this one, leave DefaultProperties as they are.

//================================================== ===========================
// WildcardsPoisonGuardian.
//
// Optimized by Higor
//================================================== ===========================
class WildcardsPoisonGuardian expands sgGuardian;

var() texture TextureRed;
var() texture TextureBlue;
var() byte MFXFatness;

//Higor: faster than RADIUSACTORS
var PoisonPlayer Poisoned[16];
var int iPoisoned;
var() config bool bNoToxinProtection;

simulated event Timer()
{
Super.Timer();

if ( SCount > 0 || (Role != ROLE_Authority) )
return;

if ( FRand() < 1/(6/(Grade+1)) && !bDisabledByEMP)
Damage();
}

function bool CanAttackPlayer( pawn P)
{
if (p.bIsPlayer && p.Health > 0 && (p.PlayerReplicationInfo != None) && (p.PlayerReplicationInfo.Team != Team) && !p.PlayerReplicationInfo.bIsSpectator
|| (ScriptedPawn(p) != None) )
if ( FastTrace(p.Location) )
{
if ( !bNoToxinProtection && (P.FindInventoryType(class'ToxinSuit') != none) )
return false;
return true;
}
return false;
}

function bool AlreadyPoisoned( Pawn Other)
{
local int i;

While ( i < iPoisoned )
{
if ( (Poisoned[i] == none) || Poisoned[i].bDeleteMe )
{
iPoisoned--;
if ( i != iPoisoned )
Poisoned[i] = Poisoned[iPoisoned];
continue;
}
if ( Poisoned[i].PoisonedPlayer == Other )
return true;
}
return false;
}

function Damage()
{
local float dist, moScale;
local vector dir;
local Pawn p;
local float ShockSize;
local PoisonPlayer Poison;

ShockSize = ((Grade+1)* 20)+100;

foreach RadiusActors(class 'Pawn', p, ShockSize )
{
if ( CanAttackPlayer(p) )
{
dir = normal( Location - p.Location);
dist = VSize( Location - p.Location);
MoScale = (((ShockSize)-dist)/(ShockSize))+0.1;

if ( AlreadyPoisoned(p) )
{
Poison = Spawn(Class'PoisonPlayer', Owner, , Location);
Poison.PoisonedPlayer = p;
Poisoned[iPoisoned++] = Poison;

switch ( int(Grade) )
{
case 0:
Poison.Slowness = 0.5;
Poison.RecoverRate = 0.800;
break;
case 1:
Poison.Slowness = 1;
Poison.RecoverRate = 0.600;
break;
case 2:
Poison.Slowness = 1.5;
Poison.RecoverRate = 0.400;
break;
case 3:
Poison.Slowness = 2;
Poison.RecoverRate = 0.200;
break;
case 4:
Poison.Slowness = 2.5;
Poison.RecoverRate = 0.100;
break;
case 5:
Poison.Slowness = 3;
Poison.RecoverRate = 0.050;
break;
}
}

p.TakeDamage(moScale*10, Instigator, 0.5 * (p.CollisionHeight + p.CollisionRadius)*dir, vect(0,0,0), 'sgSpecial');
if ( FRand() < 0.25)
{
PlaySound(sound'PoisonGasHiss',,4.0);
Spawn( class'PoisonCloud',, '', VRand() * vect(100,100,40) + Location, RotRand()).DrawScale *= (0.5+2*frand());
}
}
else if ( (sgBuilding(p) != none) && (sgBuilding(p).Team != Team) && (p.Health > 0) && FastTrace(p.Location) )
{
dir = normal( Location - p.Location);
dist = VSize( Location - p.Location);
MoScale = (((ShockSize)-dist)/(ShockSize))+0.1;

p.TakeDamage(moScale*10, Instigator, 0.5 * (p.CollisionHeight + p.CollisionRadius)*dir,vect(0,0,0), 'sgSpecial');

if ( FRand() < 0.15)
{
PlaySound(sound'PoisonGasHiss',,4.0);
Spawn( class'PoisonCloud',, '', VRand() * vect(100,100,40) + Location, RotRand()).DrawScale *= (0.5+2*frand());
}
}
}
}

function Upgraded()
{
AmbientGlow=255/(6-Grade);
}

simulated function FinishBuilding()
{
MultiSkins[4] = TextureRed;
MultiSkins[5] = TextureBlue;
MultiSkins[6] = texture'sgMedia2.sgEnvSkinT3';
MultiSkins[7] = texture'sgMedia.sgEnvSkinT0';
JustFinishBuilding();
}

simulated function JustFinishBuilding()
{
local int i;
local WildcardsMeshFX newFX;

DrawScale = SpriteScale;

if ( Role == ROLE_Authority )
Spawn(class'sgFlash');

if ( Level.NetMode == NM_DedicatedServer )
return;

if ( myFX == None && Model != None )
for ( i = 0; i < numOfMFX; i++ )
{
newFX = Spawn(class'WildcardsMeshFX', Self,,,
rotator(vect(0,0,0)));
//newFX.WcNextFX = myFX;
myFX = newFX;
myFX.Mesh = Model;
myFX.DrawScale = DSofMFX;
myFX.Fatness = MFXFatness;
myFX.RotationRate.Pitch = MFXrotX.Pitch*FRand();
myFX.RotationRate.Roll = MFXrotX.Roll*FRand();
myFX.RotationRate.Yaw = MFXrotX.Yaw*FRand();

}
}

This makes the Damage() function more readable, specially on the conditions for attacking players and finding a poison affector.
Also, the attacking conditions can check for a player's Toxin Suit, it is optional and can be tweaked on the server INI files.
Deleted nested RadiusActors iterations, cause slowdowns when more than 3 players enter the PG's damage radius on slower setups.
Deleted another unnecessary RadiusActor iteration to check for buildings, all checks are done in a single iterator now.
The affectors are now found in a simple 16 element array, which will most likely be filled by 1 or 2 elements during normal gameplay. (a lot faster).
Turned a variety of function into one-liners.