Throwback Monday: Reloading Enforcers (UT99)

Good Morning.

The Unreal Engine appears to be where it’s at, and considering that game developers is presently the second most sought after professional (second only to data miners,) I wanted to revisit this coding thing. I wanted to start simple by trying to replicate something that has, in some degree, already been done, but I’m having some difficulty here.

I revisited UT99 due to its simplicity, and decided I wanted to make the Enforcers reload. I anticipated being a rather easy procedure, as the animations are already there (just not used.) I looked over the OlWeapons.OlAutomag script from Oldskool, and used that as a starting point.

So far, I’ve been moderately successful. After removing the timer that forced the slave to fire immediately after the master, and teaching the weapon to reference which weapon fired last, I began injecting the clipcount code. Everything initially went smoothly until the second enforcer was picked up. Now after both weapons go to the NewClip state, the slave’s clipcount isn’t actually resetting – and then the weapon locks up.

I’m hoping someone can look over this and tell me what I’m not seeing.

Thanks,
JB


//=============================================================================
// Enforcer
//=============================================================================
class Enforcer extends TournamentWeapon;

#exec TEXTURE IMPORT NAME=IconAutoM FILE=TEXTURES\HUD\WpnAutoM.PCX GROUP="Icons" MIPS=OFF
#exec TEXTURE IMPORT NAME=UseAutoM FILE=TEXTURES\HUD\UseAutoM.PCX GROUP="Icons" MIPS=OFF

#exec TEXTURE IMPORT NAME=Muz1 FILE=MODELS\muz1.PCX GROUP="Skins"  LODSET=2
#exec TEXTURE IMPORT NAME=Muz2 FILE=MODELS\muz2.PCX GROUP="Skins"  LODSET=2
#exec TEXTURE IMPORT NAME=Muz3 FILE=MODELS\muz3.PCX GROUP="Skins"  LODSET=2
#exec TEXTURE IMPORT NAME=Muz4 FILE=MODELS\muz4.PCX GROUP="Skins"  LODSET=2
#exec TEXTURE IMPORT NAME=Muz5 FILE=MODELS\muz5.PCX GROUP="Skins"  LODSET=2

// pickup version
#exec MESH IMPORT MESH=MagPick ANIVFILE=MODELS\autopick_a.3D DATAFILE=MODELS\autopick_d.3D X=0 Y=0 Z=0
#exec MESH ORIGIN MESH=MagPick X=0 Y=0 Z=0 YAW=64
#exec MESH SEQUENCE MESH=MagPick SEQ=All  STARTFRAME=0  NUMFRAMES=1
#exec TEXTURE IMPORT NAME=Jautot1 FILE=MODELS\mag0.PCX GROUP="Skins"  LODSET=2
#exec MESHMAP SCALE MESHMAP=MagPick X=0.05 Y=0.05 Z=0.1
#exec MESHMAP SETTEXTURE MESHMAP=MagPick NUM=1 TEXTURE=Jautot1

// 3rd person perspective version 
#exec MESH IMPORT MESH=AutoHand ANIVFILE=MODELS\autopick_a.3D DATAFILE=MODELS\autopick_d.3D X=0 Y=0 Z=0
#exec MESH ORIGIN MESH=AutoHand X=0 Y=250 Z=-60 YAW=64 PITCH=0 ROLL=0
#exec MESH SEQUENCE MESH=AutoHand SEQ=All  STARTFRAME=0    NUMFRAMES=6
#exec MESH SEQUENCE MESH=AutoHand SEQ=Still  STARTFRAME=0  NUMFRAMES=1
#exec MESH SEQUENCE MESH=AutoHand SEQ=Shoot  STARTFRAME=1  NUMFRAMES=6
#exec MESH SEQUENCE MESH=AutoHand SEQ=Shot2  STARTFRAME=1  NUMFRAMES=6
#exec MESHMAP SCALE MESHMAP=AutoHand X=0.025 Y=0.025 Z=0.05
#exec MESHMAP SETTEXTURE MESHMAP=AutoHand NUM=1 TEXTURE=Jautot1

//  player view version
#exec MESH IMPORT MESH=AutoML ANIVFILE=MODELS\mag_a.3D DATAFILE=MODELS\mag_d.3D unmirror=1
#exec MESH ORIGIN MESH=AutoML X=0 Y=0 Z=0 YAW=64 ROLL=0

#exec MESH DROPFRAMES MESH=AutoML STARTFRAME=130    NUMFRAMES=35
#exec MESH DROPFRAMES MESH=AutoML STARTFRAME=144    NUMFRAMES=10

#exec MESH SEQUENCE MESH=AutoML SEQ=All     STARTFRAME=0  NUMFRAMES=151
#exec MESH SEQUENCE MESH=AutoML SEQ=Still   STARTFRAME=0  NUMFRAMES=1
#exec MESH SEQUENCE MESH=AutoML SEQ=Shoot   STARTFRAME=6  NUMFRAMES=10
#exec MESH SEQUENCE MESH=AutoML SEQ=Eject   STARTFRAME=22  NUMFRAMES=28
#exec MESH SEQUENCE MESH=AutoML SEQ=Select  STARTFRAME=60  NUMFRAMES=28 RATE=36 GROUP=Select
#exec MESH SEQUENCE MESH=AutoML SEQ=Twiddle STARTFRAME=87  NUMFRAMES=25
#exec MESH SEQUENCE MESH=AutoML SEQ=Sway    STARTFRAME=86  NUMFRAMES=2 RATE=3
#exec MESH SEQUENCE MESH=AutoML SEQ=Down    STARTFRAME=115  NUMFRAMES=12 RATE=45
#exec MESH SEQUENCE MESH=AutoML SEQ=T1      STARTFRAME=130  NUMFRAMES=6
#exec MESH SEQUENCE MESH=AutoML SEQ=Shot2   STARTFRAME=136  NUMFRAMES=8
#exec MESH SEQUENCE MESH=AutoML SEQ=T2      STARTFRAME=144  NUMFRAMES=7
#exec TEXTURE IMPORT NAME=Jtutot1 FILE=MODELS\mag1.PCX GROUP="Skins"   LODSET=2
#exec TEXTURE IMPORT NAME=Jtutot2 FILE=MODELS\mag2.PCX GROUP="Skins"   LODSET=2
#exec TEXTURE IMPORT NAME=Jtutot3 FILE=MODELS\mag3.PCX GROUP="Skins"   LODSET=2
#exec TEXTURE IMPORT NAME=Jtutot4 FILE=MODELS\mag4.PCX GROUP="Skins"   LODSET=2
#exec MESHMAP SCALE MESHMAP=AutoML X=0.007 Y=0.0045 Z=0.012
#exec MESHMAP SETTEXTURE MESHMAP=AutoML NUM=0 TEXTURE=Jtutot1
#exec MESHMAP SETTEXTURE MESHMAP=AutoML NUM=1 TEXTURE=Jtutot2
#exec MESHMAP SETTEXTURE MESHMAP=AutoML NUM=2 TEXTURE=Jtutot3
#exec MESHMAP SETTEXTURE MESHMAP=AutoML NUM=3 TEXTURE=Jtutot4

// right handed player view version
#exec MESH IMPORT MESH=AutoMR ANIVFILE=MODELS\mag_a.3D DATAFILE=MODELS\mag_d.3D
#exec MESH ORIGIN MESH=AutoMR X=0 Y=0 Z=0 YAW=64 ROLL=0

#exec MESH DROPFRAMES MESH=AutoMR STARTFRAME=130    NUMFRAMES=35
#exec MESH DROPFRAMES MESH=AutoMR STARTFRAME=144    NUMFRAMES=10

#exec MESH SEQUENCE MESH=AutoMR SEQ=All     STARTFRAME=0  NUMFRAMES=151
#exec MESH SEQUENCE MESH=AutoMR SEQ=Still   STARTFRAME=0  NUMFRAMES=1
#exec MESH SEQUENCE MESH=AutoMR SEQ=Shoot   STARTFRAME=6  NUMFRAMES=10
#exec MESH SEQUENCE MESH=AutoMR SEQ=Eject   STARTFRAME=22  NUMFRAMES=28
#exec MESH SEQUENCE MESH=AutoMR SEQ=Select  STARTFRAME=60  NUMFRAMES=28 RATE=36 GROUP=Select
#exec MESH SEQUENCE MESH=AutoMR SEQ=Twiddle STARTFRAME=87  NUMFRAMES=25
#exec MESH SEQUENCE MESH=AutoMR SEQ=Sway   STARTFRAME=86  NUMFRAMES=2   RATE=3
#exec MESH SEQUENCE MESH=AutoMR SEQ=Down    STARTFRAME=115  NUMFRAMES=12 RATE=45
#exec MESH SEQUENCE MESH=AutoMR SEQ=T1      STARTFRAME=130  NUMFRAMES=6
#exec MESH SEQUENCE MESH=AutoMR SEQ=Shot2   STARTFRAME=136  NUMFRAMES=8
#exec MESH SEQUENCE MESH=AutoMR SEQ=T2      STARTFRAME=144  NUMFRAMES=7
#exec MESHMAP SCALE MESHMAP=AutoMR X=0.007 Y=0.0045 Z=0.012
#exec MESHMAP SETTEXTURE MESHMAP=AutoMR NUM=0 TEXTURE=Jtutot1
#exec MESHMAP SETTEXTURE MESHMAP=AutoMR NUM=1 TEXTURE=Jtutot2
#exec MESHMAP SETTEXTURE MESHMAP=AutoMR NUM=2 TEXTURE=Jtutot3
#exec MESHMAP SETTEXTURE MESHMAP=AutoMR NUM=3 TEXTURE=Jtutot4

#exec TEXTURE IMPORT NAME=EMuz1 FILE=MODELS\muz1.PCX GROUP="Skins"

#exec AUDIO IMPORT FILE="..\UnrealShare\Sounds\automag\cocking.WAV" NAME="Cocking" GROUP="enforcer"
#exec AUDIO IMPORT FILE="Sounds\Enforcer\enforcershot.WAV" NAME="E_Shot" GROUP="enforcer"
#exec AUDIO IMPORT FILE="..\UnrealShare\Sounds\flak\click.WAV" NAME="click" GROUP="flak"
#exec AUDIO IMPORT FILE="..\UnrealShare\Sounds\automag\reload1.WAV" NAME="Reload" GROUP="enforcer"

#exec MESH IMPORT MESH=muzzEF3 ANIVFILE=MODELS\muzzle2_a.3d DATAFILE=MODELS\Muzzle2_d.3d X=0 Y=0 Z=0
#exec MESH LODPARAMS MESH=muzzEF3 MINVERTS=8 STRENGTH=0.7 ZDISP=800.0

#exec MESH ORIGIN MESH=muzzEF3 X=0 Y=740 Z=-90 YAW=64
#exec MESH SEQUENCE MESH=muzzEF3 SEQ=All                      STARTFRAME=0 NUMFRAMES=3
#exec MESH SEQUENCE MESH=muzzEF3 SEQ=Shoot                   STARTFRAME=0 NUMFRAMES=3
#exec MESHMAP NEW   MESHMAP=muzzEF3 MESH=muzzEF3
#exec MESHMAP SCALE MESHMAP=muzzEF3 X=0.02 Y=0.05 Z=0.04
#exec TEXTURE IMPORT NAME=Muzzy2 FILE=MODELS\Muzzy2.PCX GROUP=Skins

var() int hitdamage;
var() localized string DoubleName;
var() texture MuzzleFlashVariations[5];
var bool bBringingUp;
var bool bFirstFire;
var bool bIsSlave;
var bool bSetup;
var bool MasterFired;
var bool SlavePrevent;
var bool SlaveRequestReload;
var bool trytick;
var Enforcer SlaveEnforcer, MasterEnforcer;
var float AltAccuracy;
var int ClipCount;
var int DoubleSwitchPriority;
var int SlaveClipCount;

replication
{
	reliable if ( bNetOwner && (Role == ROLE_Authority) )
		SlaveEnforcer, bIsSlave, bBringingUp;
}

function Destroyed()
{
	Super.Destroyed();
	if ( SlaveEnforcer != None )
		SlaveEnforcer.Destroy();
}

simulated function AnimEnd()
{
	if ( (Level.NetMode == NM_Client) && bBringingUp  && (Mesh != PickupViewMesh) )
	{
		bBringingUp = false;
		PlaySelect();
	}
	else
		Super.AnimEnd();
}

function bool WeaponSet(Pawn Other)
{
	if ( bIsSlave )
		return false;
	else
		Super.WeaponSet(Other);
}

function SetSwitchPriority(pawn Other)
{
	local int i;
	local name temp, carried;

	if ( PlayerPawn(Other) != None )
	{
		Super.SetSwitchPriority(Other);

		// also set double switch priority

		for ( i=0; i<20; i++)
			if ( PlayerPawn(Other).WeaponPriority* == 'doubleenforcer' )
			{
				DoubleSwitchPriority = i;
				return;
			}
	}		
}

// Return the switch priority of the weapon (normally AutoSwitchPriority, but may be
// modified by environment (or by other factors for bots)
function float SwitchPriority() 
{
	local float temp;
	local int bTemp;

	if ( bIsSlave )
		return -10;
	if ( !Owner.IsA('PlayerPawn') )
		return RateSelf(bTemp);
	else if ( (AmmoType != None) && (AmmoType.AmmoAmount<=0) )
	{
		if ( Pawn(Owner).Weapon == self )
			return -0.5;
		else
			return -1;
	}
	else if ( SlaveEnforcer != None )
		return DoubleSwitchPriority;
	else
		return AutoSwitchPriority;
}

function DropFrom(vector StartLocation)
{
	if ( !SetLocation(StartLocation) )
		return; 
	if ( SlaveEnforcer != None )
		SlaveEnforcer.Destroy();
	AIRating = Default.AIRating;
	SlaveEnforcer = None;
	Super.DropFrom(StartLocation);
}

function SetDisplayProperties(ERenderStyle NewStyle, texture NewTexture, bool bLighting, bool bEnviroMap )
{
	if ( !bSetup )
	{
		bSetup = true;
		if ( SlaveEnforcer != None )
			SlaveEnforcer.SetDisplayProperties(NewStyle, NewTexture, bLighting, bEnviromap);
		bSetup = false;
	}			
	Super.SetDisplayProperties(NewStyle, NewTexture, bLighting, bEnviromap);
}

function SetDefaultDisplayProperties()
{
	if ( !bSetup )
	{
		bSetup = true;
		if ( SlaveEnforcer != None )
			SlaveEnforcer.SetDefaultDisplayProperties();
		bSetup = false;
	}			
	Super.SetDefaultDisplayProperties();
}

event float BotDesireability(Pawn Bot)
{
	local Enforcer AlreadyHas;
	local float desire;

	desire = MaxDesireability + Bot.AdjustDesireFor(self);
	AlreadyHas = Enforcer(Bot.FindInventoryType(class));
	if ( AlreadyHas != None )
	{
		if ( (!bHeldItem || bTossedOut) && bWeaponStay )
			return 0;
		if ( AlreadyHas.SlaveEnforcer != None )
		{
			if ( (RespawnTime < 10)
				&& ( bHidden || (AlreadyHas.AmmoType == None)
					|| (AlreadyHas.AmmoType.AmmoAmount < AlreadyHas.AmmoType.MaxAmmo)) )
				return 0;
			if ( AlreadyHas.AmmoType == None )
				return 0.25 * desire;

			if ( AlreadyHas.AmmoType.AmmoAmount > 0 )
				return FMax( 0.25 * desire, 
						AlreadyHas.AmmoType.MaxDesireability
						 * FMin(1, 0.15 * AlreadyHas.AmmoType.MaxAmmo/AlreadyHas.AmmoType.AmmoAmount) ); 
		}
	}
	if ( (Bot.Weapon == None) || (Bot.Weapon.AIRating <= 0.4) )
		return 2*desire;

	return desire;
}

function ProcessTraceHit(Actor Other, Vector HitLocation, Vector HitNormal, Vector X, Vector Y, Vector Z)
{
	local UT_Shellcase s;
	local vector realLoc;

	realLoc = Owner.Location + CalcDrawOffset();
	s = Spawn(class'UT_ShellCase',, '', realLoc + 20 * X + FireOffset.Y * Y + Z);
	if ( s != None )
		s.Eject(((FRand()*0.3+0.4)*X + (FRand()*0.2+0.2)*Y + (FRand()*0.3+1.0) * Z)*160);              
	if (Other == Level) 
	{
		if ( bIsSlave || (SlaveEnforcer != None) )
			Spawn(class'UT_LightWallHitEffect',,, HitLocation+HitNormal, Rotator(HitNormal));
		else
			Spawn(class'UT_WallHit',,, HitLocation+HitNormal, Rotator(HitNormal));
	}
	else if ((Other != self) && (Other != Owner) && (Other != None) ) 
	{
		if ( FRand() < 0.2 )
			X *= 5;
		Other.TakeDamage(HitDamage, Pawn(Owner), HitLocation, 3000.0*X, MyDamageType);
		if ( !Other.bIsPawn && !Other.IsA('Carcass') )
			spawn(class'UT_SpriteSmokePuff',,,HitLocation+HitNormal*9);
		else
			Other.PlaySound(Sound 'ChunkHit',, 4.0,,100);

	}		
}

function bool HandlePickupQuery( inventory Item )
{
	local Pawn P;
	local Inventory Copy;

	if ( (Item.class == class) && (SlaveEnforcer == None) ) 
	{
		P = Pawn(Owner);
		// spawn a double
		Copy = Spawn(class, P);
		Copy.BecomeItem();
		ItemName = DoubleName;
		SlaveEnforcer = Enforcer(Copy);
		SetTwoHands();
		AIRating = 0.4;
		SlaveEnforcer.SetUpSlave( Pawn(Owner).Weapon == self );
		SlaveEnforcer.SetDisplayProperties(Style, Texture, bUnlit, bMeshEnviromap);
		SetTwoHands();
		P.ReceiveLocalizedMessage( class'PickupMessagePlus', 0, None, None, Self.Class );
		Item.PlaySound(Item.PickupSound);
		if (Level.Game.LocalLog != None)
			Level.Game.LocalLog.LogPickup(Item, Pawn(Owner));
		if (Level.Game.WorldLog != None)
			Level.Game.WorldLog.LogPickup(Item, Pawn(Owner));
		Item.SetRespawn();
		return true;
	}
	return Super.HandlePickupQuery(Item);
}

function SetUpSlave(bool bBringUp)
{
	bIsSlave = true;
	ItemName = DoubleName;
	GiveAmmo(Pawn(Owner));
	AmbientGlow = 0;
	if ( bBringUp )
		BringUp();
	else
		GotoState('Idle2');
}

function SetTwoHands()
{
	if ( SlaveEnforcer == None )
		return;

	if ( (PlayerPawn(Owner) != None) && (PlayerPawn(Owner).Handedness == 2) )
	{
		SetHand(2);
		return;
	}

	if ( Mesh == mesh'AutoML' )
		SetHand(1);
	else
		SetHand(-1);
}

function setHand(float Hand)
{
	local rotator newRot;

	if ( Hand == 2 )
	{
		bHideWeapon = true;
		Super.SetHand(Hand);
		return;
	}

	if ( SlaveEnforcer != None )
	{
		if ( Hand == 0 )
			Hand = -1;
		SlaveEnforcer.SetHand(-1 * Hand);
	}
	bHideWeapon = false;
	Super.SetHand(Hand);
	if ( Hand == 1 )
		Mesh = mesh'AutoML';
	else
		Mesh = mesh'AutoMR';
}

function BringUp()
{
	if (SlaveEnforcer != none ) 
	{
		SetTwoHands();
		SlaveEnforcer.BringUp();
	}
	bBringingUp = true;
	Super.BringUp();
}

function TraceFire( float Accuracy )
{
	local vector RealOffset;

	RealOffset = FireOffset;
	FireOffset *= 0.35;
	if ( (SlaveEnforcer != None) || bIsSlave )
		Accuracy = FClamp(3*Accuracy,0.75,3);
	else if ( Owner.IsA('Bot') && !Bot(Owner).bNovice )
		Accuracy = FMax(Accuracy, 0.45);

	Super.TraceFire(Accuracy);
	FireOffset = RealOffset;
}

/*simulated function tick (float deltatime)
	{
		local bool mastertostate;
		super.tick(deltatime);
		if (bisslave||role==role_authority||playerpawn(owner)==none||pawn(owner).weapon!=self)
			return;
		if (SlaveEnforcer==none)
			{
				if (Playerpawn(owner)!=None&&(PlayerPawn(Owner).bExtra3!=0)&&(20-clipcount<AmmoType.AmmoAmount)&&(clipcount!=0)&&bcanclientfire&&!(Isinstate('clientfiring'))&&!Isinstate('clientaltfiring')&&!Isinstate('clientnewclip'))
					Gotostate('clientnewclip');
			}
		else
			{
				if (Playerpawn(owner)!=None&&(PlayerPawn(Owner).bExtra3!=0)&&(40-(clipcount+slaveclipcount)<ammotype.ammoamount)&&(clipcount!=0)&&bcanclientfire&&!(Isinstate('clientfiring'))&&!Isinstate('clientaltfiring')&&!Isinstate('clientnewclip'))
					{
						Gotostate('clientnewclip');
						mastertostate=true;
					}
				if (Playerpawn(owner)!=None&&(PlayerPawn(Owner).bExtra3!=0)&&(40-(clipcount+slaveclipcount)<ammotype.ammoamount)&&(slaveclipcount!=0)&&bcanclientfire&&!(Isinstate('clientfiring'))&&!Isinstate('clientaltfiring')&&(!Isinstate('clientnewclip')||MasterToState))
					{
						if (!mastertostate)
							slavemag.gotostate('clientnewclip');
						else
							slaverequestreload=true;
					}
			}
	}*/

/*
`7MM"""YMM               `7MM"""YMM db                   
  MM    `7                 MM    `7                      
  MM   d `7MMpMMMb.        MM   d `7MM  `7Mb,od8 .gP"Ya  
  MM""MM   MM    MM        MM""MM   MM    MM' "',M'   Yb 
  MM   Y   MM    MM        MM   Y   MM    MM    8M"""""" 
  MM       MM    MM        MM       MM    MM    YM.    , 
.JMML.   .JMML  JMML.    .JMML.   .JMML..JMML.   `Mbmmd'
*/

function Fire(float Value)
{
	if ( SlaveEnforcer != None && SlaveEnforcer.IsInState('NewClip') )
		Return;
	if ( AmmoType == None )
	{
		// ammocheck
		GiveAmmo(Pawn(Owner));
	}

	if ( AmmoType.UseAmmo(1) )
	{
		GotoState('NormalFire');
		bCanClientFire = true;
		bPointing=True;
		ClientFire(value);
		if ( SlaveEnforcer != None )
			Pawn(Owner).PlayRecoil(2 * FiringSpeed);
		else if ( !bIsSlave )
			Pawn(Owner).PlayRecoil(FiringSpeed);
		TraceFire(0.2);
	}
}

simulated function PlayFiring()
{
}

simulated function PlayAltFiring()
{
	PlayAnim('T1', 1.0, 0.05);
	if (SlaveEnforcer != None)
		SlaveEnforcer.PlayAnim('T1', 1.0, 0.05);
	bFirstFire = true;
}

simulated function PlayRepeatFiring()
{
	if ( Affector != None )
		Affector.FireEffect();
	if ( PlayerPawn(Owner) != None )
	{
		PlayerPawn(Owner).ClientInstantFlash( -0.2, vect(325, 225, 95));
		PlayerPawn(Owner).ShakeView(ShakeTime, ShakeMag, ShakeVert);
	}
	PlayOwnedSound(FireSound, SLOT_None,2.0*Pawn(Owner).SoundDampening);
	PlayAnim( 'Shot2',1.0,0.05);
	bMuzzleFlash++;
}

function AltFire( float Value )
{
	if ( SlaveEnforcer != None && SlaveEnforcer.IsInState('NewClip') )
	Return;
	bPointing=True;
	bCanClientFire = true;
	AltAccuracy = 0.4;
	if ( AmmoType == None )
	{
		// ammocheck
		GiveAmmo(Pawn(Owner));
	}

	if (AmmoType.AmmoAmount>0)
	{
		if ( SlaveEnforcer != None )
			Pawn(Owner).PlayRecoil(3 * FiringSpeed);
		else if ( !bIsSlave )
			Pawn(Owner).PlayRecoil(1.5 * FiringSpeed);
		ClientAltFire(value);
		GotoState('AltFiring');
	}
}

function Finish()
	{
		if ( bChangeWeapon )
			GotoState('DownWeapon');
		else if ( PlayerPawn(Owner) == None )
			Super.Finish();
		else if ( (AmmoType.AmmoAmount<=0) || (Pawn(Owner).Weapon != self) )
			GotoState('Idle');
		else if (ClipCount>=20)
			GoToState('NewClip');
		else if (Pawn(Owner).bFire!=0 )
			Global.Fire(0);
		else if (Pawn(Owner).bAltFire!=0 )
			Global.AltFire(0);
		else 
			GotoState('Idle');
	}

/*
      db               mm     db                    
     ;MM:              MM                           
    ,V^MM.    ,p6"bo mmMMmm `7MM `7M'   `MF'.gP"Ya  
   ,M  `MM   6M'  OO   MM     MM   VA   ,V ,M'   Yb 
   AbmmmqMA  8M        MM     MM    VA ,V  8M"""""" 
  A'     VML YM.    ,  MM     MM     VVV   YM.    , 
.AMA.   .AMMA.YMbmd'   `Mbmo.JMML.    W     `Mbmmd' 
*/

state Active
{
	function bool PutDown()
	{
		if ( bWeaponUp || (AnimFrame < 0.75) ) 
			GotoState('DownWeapon');
		else
			bChangeWeapon = true;
		return True;
	}

	function BeginState()
	{
		bChangeWeapon = false;
	}

	function EndState()
	{
		Super.EndState();
		bBringingUp = false;
	}

Begin:
	if ( ammotype != none && !bIsSlave)
	{
		if ( SlaveEnforcer == None)
		{
			if ( 19 < ammotype.ammoamount )
				ClipCount = 0;
			else
				ClipCount = 20 - ammotype.ammoamount;
		}
		else
		{
			if ( 39 < ammotype.ammoamount )
			{
				ClipCount = 0;
				SlaveClipCount = 0;
			}
			else
			{
				if ( MasterFired == False )
				{
					ClipCount = (40 - AmmoType.AmmoAmount) / 2;
					SlaveClipCount = (40 - AmmoType.AmmoAmount ) - ClipCount;
				}
				else
				{
					SlaveClipCount = ( 40 - AmmoType.AmmoAmount ) / 2;
					ClipCount = ( 40 - AmmoType.AmmoAmount ) - SlaveClipCount;
				}
			}
		}
	}
	if ( bIsSlave )
		GoToState('');
	else
	{
		FinishAnim();
		if ( bChangeWeapon )
			GotoState('DownWeapon');
		bWeaponUp = True;
		bCanClientFire = true;
		if ( !bIsSlave && (Level.Netmode != NM_Standalone) && (Owner != None)
			&& Owner.IsA('TournamentPlayer')
			&& (PlayerPawn(Owner).Player != None)
			&& !PlayerPawn(Owner).Player.IsA('ViewPort') )
		{
			if ( Pawn(Owner).bFire != 0 )
				TournamentPlayer(Owner).SendFire(self);
			else if ( Pawn(Owner).bAltFire != 0 )
				TournamentPlayer(Owner).SendAltFire(self);
			else if ( !bChangeWeapon )
				TournamentPlayer(Owner).UpdateRealWeapon(self);
		} 
	}
	Finish();
}

/*
`7MMF'    `7MM  `7MM          
  MM        MM    MM          
  MM   ,M""bMM    MM  .gP"Ya  
  MM ,AP    MM    MM ,M'   Yb 
  MM 8MI    MM    MM 8M"""""" 
  MM `Mb    MM    MM YM.    , 
.JMML.`Wbmd"MML..JMML.`Mbmmd'
*/

state Idle
{
	function AnimEnd()
	{
		PlayIdleAnim();
	}

	function bool PutDown()
	{
		GotoState('DownWeapon');
		return True;
	}
	
	event Tick(float DeltaTime)
		{
			local bool mastertostate;
			if (ammotype==none)
				{
					log("ammotype fawked up!"); return;
				}
			if (pawn(owner)==none)
				return;
			if (bisslave)
				return;
			if (SlaveEnforcer==none)
				{
					if (((Playerpawn(owner)!=None&&(playerpawn(owner).bextra3!=0))||(Playerpawn(owner)==none&&Pawn(Owner).enemy==None))&&(20-clipcount<AmmoType.AmmoAmount)&&(clipcount!=0))
						Gotostate('newclip');
				}
			else
				{
					if (((Playerpawn(owner)!=None&&(playerpawn(owner).bextra3!=0))||(Playerpawn(owner)==none&&Pawn(Owner).enemy==None))&&(40-(clipcount+slaveclipcount)<ammotype.ammoamount)&&(clipcount!=0))
						{
							//RepFire=true;
							Gotostate('newclip');
							mastertostate=true;
						}
					if (((Playerpawn(owner)!=None&&(playerpawn(owner).bextra3!=0))||(Playerpawn(owner)==none&&Pawn(Owner).enemy==None))&&(40-(clipcount+slaveclipcount)<ammotype.ammoamount)&&(slaveclipcount!=0))
						{
							if (!mastertostate)
								SlaveEnforcer.gotostate('newclip');
							else
								slaverequestreload=true;
						}
				}
		}

Begin:
	bPointing=False;
	if ( (AmmoType != None) && (AmmoType.AmmoAmount<=0) ) 
		Pawn(Owner).SwitchToBestWeapon();  //Goto Weapon that has Ammo
	if ( SlaveEnforcer != None && !SlaveEnforcer.IsInState('NewClip'))
		SlaveEnforcer.LoopAnim('Sway',0.2,0.1);
	LoopAnim('Sway',0.2, 0.1);
	if ( Pawn(Owner).bFire!=0 ) Global.Fire(0.0);
	if ( Pawn(Owner).bAltFire!=0 ) Global.AltFire(0.0);	
}

/*
`7MN.   `7MF'                                           `7MM      `7MM"""YMM db                   
  MMN.    M                                               MM        MM    `7                      
  M YMb   M  ,pW"Wq.`7Mb,od8 `7MMpMMMb.pMMMb.   ,6"Yb.    MM        MM   d `7MM  `7Mb,od8 .gP"Ya  
  M  `MN. M 6W'   `Wb MM' "'   MM    MM    MM  8)   MM    MM        MM""MM   MM    MM' "',M'   Yb 
  M   `MM.M 8M     M8 MM       MM    MM    MM   ,pm9MM    MM        MM   Y   MM    MM    8M"""""" 
  M     YMM YA.   ,A9 MM       MM    MM    MM  8M   MM    MM        MM       MM    MM    YM.    , 
.JML.    YM  `Ybmd9'.JMML.   .JMML  JMML  JMML.`Moo9^Yo..JMML.    .JMML.   .JMML..JMML.   `Mbmmd'
*/

state NormalFire
{
ignores Fire, AltFire, AnimEnd;

	function EndState()
	{
		Super.EndState();
		OldFlashCount = FlashCount;
	}

Begin:
	FlashCount++;
	if (MasterFired == False || SlaveEnforcer == None)
		{
			if (SlaveEnforcer != None)
				Sleep(0.01);
			PlayAnim('Shoot', 1.0, 0.05);
			PlayOwnedSound(FireSound, SLOT_None,2.0*Pawn(Owner).SoundDampening);
			if ( ClipCount &gt; 14 )
				PlayOwnedSound(Misc1Sound, SLOT_None, 3.5*Pawn(Owner).SoundDampening);
			bMuzzleFlash++;
			if ( ClipCount &lt; 20 )
				ClipCount++;
			if (SlaveEnforcer != None)
				Sleep(0.25);
			else FinishAnim();
			MasterFired = True;
		}
	else
		{
			SlaveEnforcer.PlayAnim('Shoot', 1.0, 0.05);
			PlayOwnedSound(FireSound, SLOT_None,2.0*Pawn(Owner).SoundDampening);
			if ( SlaveClipCount &gt; 14 )
				PlayOwnedSound(Misc1Sound, SLOT_None, 3.5*Pawn(Owner).SoundDampening);
			SlaveEnforcer.bMuzzleFlash++;
			if ( SlaveClipCount &lt; 20 )
				SlaveClipCount++;
			Sleep(0.25);
			MasterFired = False;
		}
	if ( ClipCount &gt;= 20 && ( SlaveEnforcer == None || SlaveClipCount &gt;= 20 ) )
	{
		if ( SlaveEnforcer != None )
			SlaveRequestReload = True;
		GoToState('NewClip');
	}
	else if ( ClipCount &gt;= 20 && SlaveClipCount &lt; 20 && SlaveEnforcer != None && MasterFired == False )
	{
		Sleep(0.2);
		MasterFired = True;
		if ( Pawn(Owner).bFire != 0 )
			Global.Fire(0);
		else if ( Pawn(Owner).bAltFire != 0 )
			Global.AltFire(0);
	}
	else if ( Pawn(Owner).bFire != 0 )
		Global.Fire(0);
	else if ( Pawn(Owner).bAltFire != 0 )
		Global.AltFire(0);
	FinishAnim();
	GoToState('Idle');
	Finish();
}

/*
      db      `7MM   mm       `7MM"""YMM db             db                       
     ;MM:       MM   MM         MM    `7                                         
    ,V^MM.      MM mmMMmm       MM   d `7MM  `7Mb,od8 `7MM  `7MMpMMMb.  .P"Ybmmm 
   ,M  `MM      MM   MM         MM""MM   MM    MM' "'   MM    MM    MM :MI  I8   
   AbmmmqMA     MM   MM         MM   Y   MM    MM       MM    MM    MM  WmmmP"   
  A'     VML    MM   MM         MM       MM    MM       MM    MM    MM 8M        
.AMA.   .AMMA..JMML. `Mbmo    .JMML.   .JMML..JMML.   .JMML..JMML  JMML.YMMMMMb  
                                                                       6'     dP 
                                                                       Ybmmmd'  
*/

state AltFiring
{
ignores Fire, AltFire, AnimEnd;

	function EndState()
	{
		Super.EndState();
		OldFlashCount = FlashCount;
	}

Begin:
	FinishAnim();
/*	if ( SlaveEnforcer != None )
		SlaveEnforcer.PlayAltFiring();
	PlayAltFiring();
	FinishAnim();*/  //Not sure why, but there appears to be a double call occurring, so that's why the master was kicking back to T1.
	
Repeater:	
	if (AmmoType.UseAmmo(1)) 
	{
		FlashCount++;
		if ( SlaveEnforcer != None )
			Pawn(Owner).PlayRecoil(3 * FiringSpeed);
		else if ( !bIsSlave )
			Pawn(Owner).PlayRecoil(1.5 * FiringSpeed);
		TraceFire(AltAccuracy);
		if (MasterFired == False || SlaveEnforcer == None)
			{
				/*if (SlaveEnforcer != None)
					Sleep(0.01);*/
				PlayRepeatFiring();
				if (SlaveEnforcer != None)
					Sleep(0.25);
				else FinishAnim();
				MasterFired = True;
			}
		Else
			{
				SlaveEnforcer.PlayRepeatFiring();
				Sleep(0.25);
				MasterFired = False;
			}
		//FinishAnim();
	}

	if ( AltAccuracy < 3 ) 
		AltAccuracy += 0.5;
	if ( bIsSlave )
	{
		if ( (Pawn(Owner).bAltFire!=0) 
			&& AmmoType.AmmoAmount>0 )
			Goto('Repeater');
	}
	else if ( bChangeWeapon )
		GotoState('DownWeapon');
	else if ( (Pawn(Owner).bAltFire!=0) 
		&& AmmoType.AmmoAmount>0 )
	{
		if ( PlayerPawn(Owner) == None )
			Pawn(Owner).bAltFire = int( FRand() < AltReFireRate );
		Goto('Repeater');	
	}
	PlayAnim('T2', 0.9, 0.05);
	if ( SlaveEnforcer != None )
		SlaveEnforcer.PlayAnim('T2',0.9,0.05);
	FinishAnim();
	Finish();
}

/*
`7MN.   `7MF'                               .g8"""bgd `7MM    db            
  MMN.    M                               .dP'     `M   MM                  
  M YMb   M  .gP"Ya `7M'    ,A    `MF'    dM'       `   MM  `7MM `7MMpdMAo. 
  M  `MN. M ,M'   Yb  VA   ,VAA   ,V      MM            MM    MM   MM   `Wb 
  M   `MM.M 8M""""""   VA ,V  VA ,V       MM.           MM    MM   MM    M8 
  M     YMM YM.    ,    VVV    VVV        `Mb.     ,'   MM    MM   MM   ,AP 
.JML.    YM  `Mbmmd'     W      W           `"bmmmd'  .JMML..JMML. MMbmmd'  
                                                                   MM       
                                                                 .JMML. 
*/

state NewClip
{
	ignores Fire, AltFire, AnimEnd;
	
		function tick(float delta)
			{
			if (trytick&&!bisslave&&!slaveprevent)
				{
					trytick=false;
					if ( bChangeWeapon )
						GotoState('DownWeapon');
					else if ( Pawn(Owner).bFire!=0 )
						Global.Fire(0);
					else if ( Pawn(Owner).bAltFire!=0 )
						Global.AltFire(0);
					else
						GotoState('Idle');
				}
			}

	begin:
		PlayAnim('Eject', 1.0, 0.02);
		PlayOwnedSound(Misc2Sound,Slot_None,1.0*Pawn(Owner).SoundDampening);
		FinishAnim();
		if ( !bIsSlave && SlaveEnforcer == None )
		{
			if ( 19 &lt; AmmoType.AmmoAmount )
				ClipCount = 0;
			else
				ClipCount = 20 - AmmoType.AmmoAmount;
		}
		else
		{
			if ( !bIsSlave && 39 &lt; AmmoType.AmmoAmount )
				ClipCount = 0;
			else if ( bIsSlave && 39 &lt; Ammotype.AmmoAmount )
				SlaveClipCount = 0;
			else
			{
				if ( !bIsSlave )
					ClipCount = (40 - AmmoType.AmmoAmount)/2;
				else
					SlaveClipCount = (40 - AmmoType.AmmoAmount)-ClipCount;
			}
		}
		if ( !bIsSlave && SlaveRequestReload && SlaveEnforcer != None)
		{
			SlaveRequestReload = False;
			SlaveEnforcer.GoToState('NewClip');
			SlavePrevent = True;
		}
		PlayAnim('Select', 1.0, 0.02);
		PlayOwnedSound(SelectSound, SLOT_None,1.0*Pawn(Owner).SoundDampening);
		FinishAnim();
		if ( bIsSlave )
		{
			SlavePrevent = False;
			PlayIdleAnim();
			GoToState('');
		}
		else
			trytick = true;
}

/*
`7MM"""Yb.                                             `7MMF'     A     `7MF'                                             
  MM    `Yb.                                             `MA     ,MA     ,V                                               
  MM     `Mb  ,pW"Wq.`7M'    ,A    `MF'`7MMpMMMb.         VM:   ,VVM:   ,V .gP"Ya   ,6"Yb. `7MMpdMAo.  ,pW"Wq.`7MMpMMMb.  
  MM      MM 6W'   `Wb VA   ,VAA   ,V    MM    MM          MM.  M' MM.  M',M'   Yb 8)   MM   MM   `Wb 6W'   `Wb MM    MM  
  MM     ,MP 8M     M8  VA ,V  VA ,V     MM    MM          `MM A'  `MM A' 8M""""""  ,pm9MM   MM    M8 8M     M8 MM    MM  
  MM    ,dP' YA.   ,A9   VVV    VVV      MM    MM           :MM;    :MM;  YM.    , 8M   MM   MM   ,AP YA.   ,A9 MM    MM  
.JMMmmmdP'    `Ybmd9'     W      W     .JMML  JMML.          VF      VF    `Mbmmd' `Moo9^Yo. MMbmmd'   `Ybmd9'.JMML  JMML.
                                                                                             MM                           
                                                                                           .JMML.  
*/
																						   
State DownWeapon
{
ignores Fire, AltFire, Animend;

	function BeginState()
	{
		Super.BeginState();
		if ( Slaveenforcer != none )
			Slaveenforcer.GoToState('DownWeapon');
	}
}

/*
  .g8"""bgd `7MM    db                     mm        .M"""bgd `7MM          db   mm    
.dP'     `M   MM                           MM       ,MI    "Y   MM               MM    
dM'       `   MM  `7MM  .gP"Ya `7MMpMMMb.mmMMmm     `MMb.       MMpMMMb.  `7MM mmMMmm  
MM            MM    MM ,M'   Yb  MM    MM  MM         `YMMNq.   MM    MM    MM   MM    
MM.           MM    MM 8M""""""  MM    MM  MM       .     `MM   MM    MM    MM   MM    
`Mb.     ,'   MM    MM YM.    ,  MM    MM  MM       Mb     dM   MM    MM    MM   MM    
  `"bmmmd'  .JMML..JMML.`Mbmmd'.JMML  JMML.`Mbmo    P"Ybmmd"  .JMML  JMML..JMML. `Mbmo 
  */
  
state ClientFiring
{
	simulated function bool ClientAltFire(float Value)
	{
		if ( bIsSlave )
			Global.ClientAltFire(Value);
		return false;
	}

	simulated function Timer()
	{
		if ( (SlaveEnforcer != none) && SlaveEnforcer.ClientFire(0) )
			return;
		SetTimer(0.5, false);
	}

	simulated function AnimEnd()
	{
		if ( (Pawn(Owner) == None) || (Ammotype.AmmoAmount <= 0) )
		{
			PlayIdleAnim();
			GotoState('');
		}
		else if ( !bIsSlave && !bCanClientFire )
			GotoState('');
		else if ( bFirstFire || (Pawn(Owner).bAltFire != 0) )
		{
			PlayRepeatFiring();
			bFirstFire = false;
		}
		else if ( Pawn(Owner).bFire != 0 )
			Global.ClientFire(0);
		else
		{
			PlayIdleAnim();
			GotoState('');
		}
	}

	simulated function BeginState()
	{
		Super.BeginState();
		if ( SlaveEnforcer != None )
			SetTimer(0.2, false);
		else 
			SetTimer(0.5, false);
	}

	simulated function EndState()
	{
		Super.EndState();
		if ( SlaveEnforcer != None )
			SlaveEnforcer.GotoState('');
	}
}

state ClientAltFiring
{
	simulated function bool ClientFire(float Value)
	{
		if ( bIsSlave )
			Global.ClientFire(Value);
		return false;
	}

	simulated function Timer()
	{
		if ( (SlaveEnforcer != none) && SlaveEnforcer.ClientAltFire(0) )
			return;
		SetTimer(0.5, false);
	}

	simulated function AnimEnd()
	{
		if ( Pawn(Owner) == None )
			GotoState('');
		else if ( Ammotype.AmmoAmount <= 0 )
		{
			PlayAnim('T2', 1.0, 0.05);	
			GotoState('');
		}
		else if ( !bIsSlave && !bCanClientFire )
			GotoState('');
		else if ( bFirstFire || (Pawn(Owner).bAltFire != 0) )
		{
			PlayRepeatFiring();
			bFirstFire = false;
		}
		else if ( Pawn(Owner).bFire != 0 )
			Global.ClientFire(0);
		else
		{
			PlayAnim('T2', 1.0, 0.05);	
			GotoState('');
		}
	}

	simulated function BeginState()
	{
		Super.BeginState();
		if ( SlaveEnforcer != None )
			SetTimer(0.2, false);
		else 
			SetTimer(0.5, false);
	}

	simulated function EndState()
	{
		Super.EndState();
		if ( SlaveEnforcer != None )
			SlaveEnforcer.GotoState('');
	}
}

simulated event RenderOverlays(canvas Canvas)
{
	local PlayerPawn PlayerOwner;
	local int realhand;

	if ( (bMuzzleFlash > 0) && !Level.bDropDetail )
		MFTexture = MuzzleFlashVariations[Rand(5)];
	PlayerOwner = PlayerPawn(Owner);
	if ( PlayerOwner != None )
	{
		if ( PlayerOwner.DesiredFOV != PlayerOwner.DefaultFOV )
			return;
		realhand = PlayerOwner.Handedness;
		if (  (Level.NetMode == NM_Client) && (realHand == 2) )
		{
			bHideWeapon = true;
			return;
		}
		if ( !bHideWeapon )
		{
			if ( Mesh == mesh'AutoML' )
				PlayerOwner.Handedness = 1;
			else if ( bIsSlave || (SlaveEnforcer != None) )
				PlayerOwner.Handedness = -1;
		}
	}
	if ( (PlayerOwner == None) || (PlayerOwner.Handedness == 0) )
	{
		if ( AnimSequence == 'Shot2' )
		{
			FlashO = -2 * Default.FlashO;
			FlashY = Default.FlashY * 2.5;
		}
		else
		{
			FlashO = 1.9 * Default.FlashO;
			FlashY = Default.FlashY;
		}
	}
	else if ( AnimSequence == 'Shot2' )
	{
		FlashO = Default.FlashO * 0.3;
		FlashY = Default.FlashY * 2.5;
	}
	else
	{
		FlashO = Default.FlashO;
		FlashY = Default.FlashY;
	}
	if ( !bHideWeapon && ( (SlaveEnforcer != None) || bIsSlave ) )
	{
		if ( PlayerOwner == None )
			bMuzzleFlash = 0;

		Super.RenderOverlays(Canvas);
		if ( SlaveEnforcer != None )
		{
			if ( SlaveEnforcer.bBringingUp )
			{
				SlaveEnforcer.bBringingUp = false;
				SlaveEnforcer.PlaySelect();
			}
			SlaveEnforcer.RenderOverlays(Canvas);
		}
	}
	else
		Super.RenderOverlays(Canvas);

	if ( PlayerOwner != None )
		PlayerOwner.Handedness = realhand;
}

simulated function PlayIdleAnim()
{
	if ( Mesh == PickupViewMesh )
		return;
	if ( (FRand()>0.96) && (AnimSequence != 'Twiddle') ) 
		PlayAnim('Twiddle',0.6,0.3);
	else 
		LoopAnim('Sway',0.2, 0.3);
}

State ClientActive
{
	simulated function AnimEnd()
	{
		bBringingUp = false;
		if ( !bIsSlave )
		{
			Super.AnimEnd();
			if ( (SlaveEnforcer != None) && !IsInState('ClientActive') )
			{
				if ( (GetStateName() == 'None') || (GetStateName() == 'Enforcer') )
					SlaveEnforcer.GotoState('');
				else
					SlaveEnforcer.GotoState(GetStateName());
			}
		}
	}

	simulated function BeginState()
	{
		Super.BeginState();
		bBringingUp = false;
		if ( SlaveEnforcer != None )
			SlaveEnforcer.GotoState('ClientActive');
	}
}

State ClientDown
{
	simulated function AnimEnd()
	{
		if ( !bIsSlave )
			Super.AnimEnd();
	}

	simulated function EndState()
	{
		if ( SlaveEnforcer != None )
			SlaveEnforcer.GotoState('');
	}
}

simulated function PostRender( canvas Canvas )
{
  local PlayerPawn P;
  local float multiplier;
  P = PlayerPawn(Owner);
  if  (P != None)  
  {
      if (P.myhud!=none&&P.myhud.isa('challengehud'))
      multiplier=0.8;
      else
      multiplier=0.9;
        Canvas.DrawColor.B = 0;
    If (SlaveEnforcer !=none){
  //reverse if left side...)
  if(P.Handedness != 1){
        if (clipcount > 15){       //set colour according to shots left.....
    Canvas.DrawColor.R = 255;
    Canvas.DrawColor.G = 0;}
    else{
    Canvas.DrawColor.R = 0;
    Canvas.DrawColor.G = 255;}
    Canvas.SetPos(0.85 * Canvas.ClipX , multiplier* Canvas.ClipY);
            Canvas.Style = ERenderStyle.STY_Translucent;
            Canvas.Font = Canvas.SmallFont;
            Canvas.DrawText("Clip: "$20-clipcount);
            if (slaveclipcount > 15){       //set colour according to shots left.....
    Canvas.DrawColor.R = 255;
    Canvas.DrawColor.G = 0;}
    else{
    Canvas.DrawColor.R = 0;
    Canvas.DrawColor.G = 255;}
    Canvas.SetPos(0.05 * Canvas.ClipX ,multiplier * Canvas.ClipY);
            Canvas.Style = ERenderStyle.STY_Translucent;
            Canvas.Font = Canvas.SmallFont;
         Canvas.DrawText("Clip: "$20-slaveclipcount);}
    else{
                if (slaveclipcount > 15){       //set colour according to shots left.....
    Canvas.DrawColor.R = 255;
    Canvas.DrawColor.G = 0;}
    else{
    Canvas.DrawColor.R = 0;
    Canvas.DrawColor.G = 255;}
        Canvas.SetPos(0.85 * Canvas.ClipX , multiplier * Canvas.ClipY);
            Canvas.Style = ERenderStyle.STY_Translucent;
            Canvas.Font = Canvas.SmallFont;
            Canvas.DrawText("Clip: "$20-slaveclipcount);
            if (clipcount > 15){       //set colour according to shots left.....
    Canvas.DrawColor.R = 255;
    Canvas.DrawColor.G = 0;}
    else{
    Canvas.DrawColor.R = 0;
    Canvas.DrawColor.G = 255;}
    Canvas.SetPos(0.05 * Canvas.ClipX , multiplier * Canvas.ClipY);
            Canvas.Style = ERenderStyle.STY_Translucent;
            Canvas.Font = Canvas.SmallFont;
            Canvas.DrawText("Clip: "$20-clipcount); }}
    else { //doesn't have 2
            if (clipcount > 15){       //set colour according to shots left.....
    Canvas.DrawColor.R = 255;
    Canvas.DrawColor.G = 0;}
    else{
    Canvas.DrawColor.R = 0;
    Canvas.DrawColor.G = 255;}
    if(P.Handedness != 1){
    Canvas.SetPos(0.05 * Canvas.ClipX , multiplier * Canvas.ClipY);
            Canvas.Style = ERenderStyle.STY_Translucent;
            Canvas.Font = Canvas.SmallFont;  }
            else {
            Canvas.SetPos(0.85 * Canvas.ClipX ,multiplier * Canvas.ClipY);
            Canvas.Style = ERenderStyle.STY_Translucent;
            Canvas.Font = Canvas.SmallFont; }
            Canvas.DrawText("Clip: "$20-clipcount);}
            }        }

// End Class
//=============================================================================



Hi JBurby,

As this is UT99 related and actually Unreal script (Not C++ or Unreal Engine 4) - it belongs on the new UT forums here: https://forums.unrealtournament.com/ <- There is a board there for UT99 related stuff.

I’ve locked this thread but if you have any Q’s, shoot me a PM :slight_smile:

Thanks!