You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
267 lines
5.9 KiB
267 lines
5.9 KiB
15 years ago
|
//=============================================================================
|
||
|
// Shield Gun
|
||
|
//=============================================================================
|
||
|
class ShieldGun extends Weapon
|
||
|
config(user);
|
||
|
|
||
|
#EXEC OBJ LOAD FILE=InterfaceContent.utx
|
||
|
|
||
|
var Sound ShieldHitSound;
|
||
|
var String ShieldHitForce;
|
||
|
|
||
|
replication
|
||
|
{
|
||
|
reliable if (Role == ROLE_Authority)
|
||
|
ClientTakeHit;
|
||
|
}
|
||
|
|
||
|
simulated function DoAutoSwitch()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
simulated event RenderOverlays( Canvas Canvas )
|
||
|
{
|
||
|
local int m;
|
||
|
|
||
|
if ((Hand < -1.0) || (Hand > 1.0))
|
||
|
{
|
||
|
for (m = 0; m < NUM_FIRE_MODES; m++)
|
||
|
{
|
||
|
if (FireMode[m] != None)
|
||
|
{
|
||
|
FireMode[m].DrawMuzzleFlash(Canvas);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
Super.RenderOverlays(Canvas);
|
||
|
}
|
||
|
|
||
|
// AI Interface
|
||
|
function GiveTo(Pawn Other, optional Pickup Pickup)
|
||
|
{
|
||
|
Super.GiveTo(Other, Pickup);
|
||
|
|
||
|
if ( Bot(Other.Controller) != None )
|
||
|
Bot(Other.Controller).bHasImpactHammer = true;
|
||
|
}
|
||
|
|
||
|
function bool CanAttack(Actor Other)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
simulated function Timer()
|
||
|
{
|
||
|
local Bot B;
|
||
|
|
||
|
if (ClientState == WS_BringUp)
|
||
|
{
|
||
|
// check if owner is bot waiting to do impact jump
|
||
|
B = Bot(Instigator.Controller);
|
||
|
if ( (B != None) && B.bPreparingMove && (B.ImpactTarget != None) )
|
||
|
{
|
||
|
B.ImpactJump();
|
||
|
B = None;
|
||
|
}
|
||
|
}
|
||
|
Super.Timer();
|
||
|
if ( (B != None) && (B.Enemy != None) )
|
||
|
BotFire(false);
|
||
|
}
|
||
|
|
||
|
function FireHack(byte Mode)
|
||
|
{
|
||
|
if ( Mode == 0 )
|
||
|
{
|
||
|
FireMode[0].PlayFiring();
|
||
|
FireMode[0].FlashMuzzleFlash();
|
||
|
FireMode[0].StartMuzzleSmoke();
|
||
|
IncrementFlashCount(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* BestMode()
|
||
|
choose between regular or alt-fire
|
||
|
*/
|
||
|
function byte BestMode()
|
||
|
{
|
||
|
local float EnemyDist;
|
||
|
local bot B;
|
||
|
|
||
|
B = Bot(Instigator.Controller);
|
||
|
if ( (B == None) || (B.Enemy == None) )
|
||
|
return 1;
|
||
|
|
||
|
EnemyDist = VSize(B.Enemy.Location - Instigator.Location);
|
||
|
if ( EnemyDist > 2 * Instigator.GroundSpeed )
|
||
|
return 1;
|
||
|
if ( (B.MoveTarget != B.Enemy) && ((EnemyDist > 0.5 * Instigator.GroundSpeed)
|
||
|
|| (((B.Enemy.Location - Instigator.Location) Dot vector(Instigator.Rotation)) <= 0)) )
|
||
|
return 1;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// super desireable for bot waiting to impact jump
|
||
|
function float GetAIRating()
|
||
|
{
|
||
|
local Bot B;
|
||
|
local float EnemyDist;
|
||
|
|
||
|
B = Bot(Instigator.Controller);
|
||
|
if ( B == None )
|
||
|
return AIRating;
|
||
|
|
||
|
if ( B.bPreparingMove && (B.ImpactTarget != None) )
|
||
|
return 9;
|
||
|
|
||
|
if ( B.PlayerReplicationInfo.HasFlag != None )
|
||
|
{
|
||
|
if ( Instigator.Health < 50 )
|
||
|
return AIRating + 0.35;
|
||
|
return AIRating + 0.25;
|
||
|
}
|
||
|
|
||
|
if ( B.Enemy == None )
|
||
|
return AIRating;
|
||
|
|
||
|
EnemyDist = VSize(B.Enemy.Location - Instigator.Location);
|
||
|
if ( B.Stopped() && (EnemyDist > 100) )
|
||
|
return 0.1;
|
||
|
|
||
|
if ( (EnemyDist < 750) && (B.Skill <= 2) && !B.Enemy.IsA('Bot') && (ShieldGun(B.Enemy.Weapon) != None) )
|
||
|
return FClamp(300/(EnemyDist + 1), 0.6, 0.75);
|
||
|
|
||
|
if ( EnemyDist > 400 )
|
||
|
return 0.1;
|
||
|
if ( (Instigator.Weapon != self) && (EnemyDist < 120) )
|
||
|
return 0.25;
|
||
|
|
||
|
return ( FMin(0.6, 90/(EnemyDist + 1)) );
|
||
|
}
|
||
|
|
||
|
// End AI interface
|
||
|
|
||
|
function AdjustPlayerDamage( out int Damage, Pawn InstigatedBy, Vector HitLocation,
|
||
|
out Vector Momentum, class<DamageType> DamageType)
|
||
|
{
|
||
|
local int Drain;
|
||
|
local vector Reflect;
|
||
|
local vector HitNormal;
|
||
|
local float DamageMax;
|
||
|
|
||
|
DamageMax = 100.0;
|
||
|
if ( DamageType == class'Fell' )
|
||
|
DamageMax = 20.0;
|
||
|
else if( !DamageType.default.bArmorStops || (DamageType == class'DamTypeShieldImpact' && InstigatedBy == Instigator) )
|
||
|
return;
|
||
|
|
||
|
if ( CheckReflect(HitLocation, HitNormal, 0) )
|
||
|
{
|
||
|
Drain = Min( Ammo[1].AmmoAmount*2, Damage );
|
||
|
Drain = Min(Drain,DamageMax);
|
||
|
Reflect = MirrorVectorByNormal( Normal(Location - HitLocation), Vector(Instigator.Rotation) );
|
||
|
Damage -= Drain;
|
||
|
Momentum *= 1.25;
|
||
|
Ammo[1].UseAmmo(Drain/2);
|
||
|
DoReflectEffect(Drain/2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function DoReflectEffect(int Drain)
|
||
|
{
|
||
|
PlaySound(ShieldHitSound, SLOT_None);
|
||
|
ShieldAltFire(FireMode[1]).TakeHit(Drain);
|
||
|
ClientTakeHit(Drain);
|
||
|
}
|
||
|
|
||
|
simulated function ClientTakeHit(int Drain)
|
||
|
{
|
||
|
ClientPlayForceFeedback(ShieldHitForce);
|
||
|
ShieldAltFire(FireMode[1]).TakeHit(Drain);
|
||
|
}
|
||
|
|
||
|
function bool CheckReflect( Vector HitLocation, out Vector RefNormal, int AmmoDrain )
|
||
|
{
|
||
|
local Vector HitDir;
|
||
|
local Vector FaceDir;
|
||
|
|
||
|
if (!FireMode[1].bIsFiring || Ammo[0].AmmoAmount == 0) return false;
|
||
|
|
||
|
FaceDir = Vector(Instigator.Controller.Rotation);
|
||
|
HitDir = Normal(Instigator.Location - HitLocation + Vect(0,0,8));
|
||
|
//Log(self@"HitDir"@(FaceDir dot HitDir));
|
||
|
|
||
|
RefNormal = FaceDir;
|
||
|
|
||
|
if ( FaceDir dot HitDir < -0.37 ) // 68 degree protection arc
|
||
|
{
|
||
|
if (AmmoDrain > 0)
|
||
|
Ammo[0].UseAmmo(AmmoDrain);
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
function AnimEnd(int channel)
|
||
|
{
|
||
|
if (FireMode[0].bIsFiring)
|
||
|
{
|
||
|
LoopAnim('Charged');
|
||
|
}
|
||
|
else if (!FireMode[1].bIsFiring)
|
||
|
{
|
||
|
Super.AnimEnd(channel);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function float SuggestAttackStyle()
|
||
|
{
|
||
|
return 0.8;
|
||
|
}
|
||
|
|
||
|
function float SuggestDefenseStyle()
|
||
|
{
|
||
|
return -0.8;
|
||
|
}
|
||
|
|
||
|
simulated function float ChargeBar()
|
||
|
{
|
||
|
return FMin(1,FireMode[0].HoldTime/ShieldFire(FireMode[0]).FullyChargedTime);
|
||
|
}
|
||
|
|
||
|
defaultproperties
|
||
|
{
|
||
|
ItemName="Shield Gun"
|
||
|
IconMaterial=Material'InterfaceContent.Hud.SkinA'
|
||
|
IconCoords=(X1=200,Y1=281,X2=321,Y2=371)
|
||
|
|
||
|
bShowChargingBar=true
|
||
|
bCanThrow=false
|
||
|
FireModeClass(0)=ShieldFire
|
||
|
FireModeClass(1)=ShieldAltFire
|
||
|
InventoryGroup=1
|
||
|
Mesh=mesh'Weapons.ShieldGun_1st'
|
||
|
BobDamping=2.2
|
||
|
PickupClass=class'ShieldGunPickup'
|
||
|
EffectOffset=(X=15.0,Y=6.7,Z=1.2)
|
||
|
bMeleeWeapon=true
|
||
|
ShieldHitSound=Sound'WeaponSounds.ShieldGun.ShieldReflection'
|
||
|
DrawScale=0.4
|
||
|
PutDownAnim=PutDown
|
||
|
DisplayFOV=60
|
||
|
PlayerViewOffset=(X=2,Y=-0.7,Z=-2.7)
|
||
|
PlayerViewPivot=(Pitch=500,Roll=0,Yaw=500)
|
||
|
|
||
|
UV2Texture=Material'XGameShaders.WeaponEnvShader'
|
||
|
|
||
|
AttachmentClass=class'ShieldAttachment'
|
||
|
SelectSound=Sound'WeaponSounds.ShieldGun_change'
|
||
|
SelectForce="ShieldGun_change"
|
||
|
ShieldHitForce="ShieldReflection"
|
||
|
|
||
|
AIRating=0.35
|
||
|
CurrentRating=0.35
|
||
|
|
||
|
DefaultPriority=2
|
||
|
}
|