288 lines
7.9 KiB
Ucode
288 lines
7.9 KiB
Ucode
class PipeBombPlaceable extends PipeBombProjectile
|
|
placeable;
|
|
|
|
var(PipeBombProjectile) int TeamIndex; // team which "placed" pipebomb. Use to avoid unnecessary friendly fire
|
|
var(PipeBombProjectile) int EnemyCountdown; // Countdown to explosion after enemy detected
|
|
var(PipeBombProjectile) bool bTriggerOnEnemy; // team which "placed" pipebomb. Use to avoid unnecessary friendly fire
|
|
var(PipeBombProjectile) bool bImmuneToDamage; // team which "placed" pipebomb. Use to avoid unnecessary friendly fire
|
|
var(PipeBombProjectile) float MyDamage;
|
|
var(PipeBombProjectile) float MyDamageRadius;
|
|
var(PipeBombProjectile) float MyMomentumTransfer;
|
|
|
|
static function PreloadAssets()
|
|
{
|
|
}
|
|
|
|
static function bool UnloadAssets()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
simulated function PostBeginPlay()
|
|
{
|
|
if ( Level.NetMode != NM_DedicatedServer)
|
|
{
|
|
BombLight = Spawn(class'PipebombLight',self);
|
|
BombLight.SetBase(self);
|
|
}
|
|
// removed initial velocity
|
|
|
|
Countdown = EnemyCountdown;
|
|
Damage = MyDamage;
|
|
DamageRadius = MyDamageRadius;
|
|
MomentumTransfer = MyMomentumTransfer;
|
|
PlacedTeam = TeamIndex;
|
|
SetTimer(1.0, True); // this projectile is supposed to be placed in a map, so arm it immediately
|
|
}
|
|
|
|
function Timer()
|
|
{
|
|
local Pawn CheckPawn;
|
|
local float ThreatLevel;
|
|
|
|
if( !bHidden && !bTriggered )
|
|
{
|
|
if( ArmingCountDown >= 0 )
|
|
{
|
|
ArmingCountDown -= 0.1;
|
|
if( ArmingCountDown <= 0 )
|
|
{
|
|
SetTimer(1.0,True);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Check for enemies
|
|
if( !bEnemyDetected )
|
|
{
|
|
bAlwaysRelevant=false;
|
|
PlaySound(BeepSound,,0.5,,50.0);
|
|
|
|
if ( bTriggerOnEnemy ) {
|
|
foreach VisibleCollidingActors( class 'Pawn', CheckPawn, DetectionRadius, Location )
|
|
{
|
|
if( CheckPawn == Instigator || KFGameType(Level.Game).FriendlyFireScale > 0 &&
|
|
CheckPawn.PlayerReplicationInfo != none &&
|
|
CheckPawn.PlayerReplicationInfo.Team.TeamIndex == PlacedTeam )
|
|
{
|
|
// Make the thing beep if someone on our team is within the detection radius
|
|
// This gives them a chance to get out of the way
|
|
ThreatLevel += 0.001;
|
|
}
|
|
else
|
|
{
|
|
if( (CheckPawn != Instigator) && (CheckPawn.Role == ROLE_Authority) &&
|
|
((CheckPawn.PlayerReplicationInfo != none && CheckPawn.PlayerReplicationInfo.Team.TeamIndex != PlacedTeam) ||
|
|
CheckPawn.GetTeamNum() != PlacedTeam))
|
|
{
|
|
if( KFMonster(CheckPawn) != none )
|
|
{
|
|
ThreatLevel += KFMonster(CheckPawn).MotionDetectorThreat;
|
|
if( ThreatLevel >= ThreatThreshhold )
|
|
{
|
|
bEnemyDetected=true;
|
|
SetTimer(0.15,True);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bEnemyDetected=true;
|
|
SetTimer(0.15,True);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
if( ThreatLevel >= ThreatThreshhold )
|
|
{
|
|
bEnemyDetected=true;
|
|
SetTimer(0.15,True);
|
|
}
|
|
else if( ThreatLevel > 0 )
|
|
{
|
|
SetTimer(0.5,True);
|
|
}
|
|
else
|
|
{
|
|
SetTimer(1.0,True);
|
|
}
|
|
}
|
|
else {
|
|
SetTimer(1.0,True);
|
|
}
|
|
}
|
|
// Play some fast beeps and blow up
|
|
else
|
|
{
|
|
bAlwaysRelevant=true;
|
|
Countdown--;
|
|
|
|
if( CountDown > 0 )
|
|
{
|
|
PlaySound(BeepSound,SLOT_Misc,2.0,,150.0);
|
|
}
|
|
else
|
|
{
|
|
Explode(Location, vector(Rotation));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Destroy();
|
|
}
|
|
}
|
|
|
|
simulated function Explode(vector HitLocation, vector HitNormal)
|
|
{
|
|
super.Explode(HitLocation, HitNormal);
|
|
TriggerEvent(Event, self, Instigator);
|
|
}
|
|
|
|
|
|
function Trigger( actor Other, pawn EventInstigator )
|
|
{
|
|
if ( !bHidden && !bTriggered ) {
|
|
Instigator = EventInstigator;
|
|
Explode(Location, vector(Rotation));
|
|
}
|
|
}
|
|
|
|
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
|
|
{
|
|
if ( bImmuneToDamage )
|
|
return;
|
|
|
|
Instigator = InstigatedBy;
|
|
super.TakeDamage(Damage, InstigatedBy, Hitlocation, Momentum, damageType, HitIndex);
|
|
}
|
|
|
|
simulated function HurtRadius( float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation )
|
|
{
|
|
local actor Victims;
|
|
local float damageScale, dist;
|
|
local vector dir;
|
|
local int NumKilled;
|
|
local KFMonster KFMonsterVictim;
|
|
local Pawn P;
|
|
local KFPawn KFP;
|
|
local array<Pawn> CheckedPawns;
|
|
local int i;
|
|
local bool bAlreadyChecked;
|
|
|
|
|
|
if ( bHurtEntry )
|
|
return;
|
|
|
|
bHurtEntry = true;
|
|
|
|
foreach CollidingActors (class 'Actor', Victims, DamageRadius, HitLocation)
|
|
{
|
|
// don't let blast damage affect fluid - VisibleCollisingActors doesn't really work for them - jag
|
|
if( (Victims != self) && (Hurtwall != Victims) && (Victims.Role == ROLE_Authority) && !Victims.IsA('FluidSurfaceInfo')
|
|
&& ExtendedZCollision(Victims)==None )
|
|
{
|
|
if( (Instigator==None || Instigator.Health<=0) && KFPawn(Victims)!=None )
|
|
Continue;
|
|
dir = Victims.Location - HitLocation;
|
|
dist = FMax(1,VSize(dir));
|
|
dir = dir/dist;
|
|
damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius);
|
|
|
|
if ( Instigator == None || Instigator.Controller == None )
|
|
{
|
|
Victims.SetDelayedDamageInstigatorController( InstigatorController );
|
|
}
|
|
|
|
P = Pawn(Victims);
|
|
|
|
if( P != none )
|
|
{
|
|
for (i = 0; i < CheckedPawns.Length; i++)
|
|
{
|
|
if (CheckedPawns[i] == P)
|
|
{
|
|
bAlreadyChecked = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( bAlreadyChecked )
|
|
{
|
|
bAlreadyChecked = false;
|
|
P = none;
|
|
continue;
|
|
}
|
|
|
|
KFMonsterVictim = KFMonster(Victims);
|
|
|
|
if( KFMonsterVictim != none && KFMonsterVictim.Health <= 0 )
|
|
{
|
|
KFMonsterVictim = none;
|
|
}
|
|
|
|
KFP = KFPawn(Victims);
|
|
|
|
if( KFMonsterVictim != none )
|
|
{
|
|
damageScale *= KFMonsterVictim.GetExposureTo(Location + 15 * -Normal(PhysicsVolume.Gravity));
|
|
}
|
|
else if( KFP != none )
|
|
{
|
|
// don't hurt the same team
|
|
if ( KFP.PlayerReplicationInfo != none && KFP.PlayerReplicationInfo.Team != none
|
|
&& KFP.PlayerReplicationInfo.Team.TeamIndex == PlacedTeam )
|
|
damageScale = 0;
|
|
else {
|
|
damageScale *= KFP.GetExposureTo(Location + 15 * -Normal(PhysicsVolume.Gravity));
|
|
// Reduce damage to poeple so I can make the damage radius a bit bigger for killing zeds
|
|
damageScale *= 0.5;
|
|
}
|
|
}
|
|
|
|
CheckedPawns[CheckedPawns.Length] = P;
|
|
|
|
if ( damageScale <= 0)
|
|
{
|
|
P = none;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
//Victims = P;
|
|
P = none;
|
|
}
|
|
}
|
|
|
|
Victims.TakeDamage(damageScale * DamageAmount,Instigator,Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius)
|
|
* dir,(damageScale * Momentum * dir),DamageType);
|
|
|
|
if( Role == ROLE_Authority && KFMonsterVictim != none && KFMonsterVictim.Health <= 0 )
|
|
{
|
|
NumKilled++;
|
|
}
|
|
|
|
if (Vehicle(Victims) != None && Vehicle(Victims).Health > 0)
|
|
{
|
|
Vehicle(Victims).DriverRadiusDamage(DamageAmount, DamageRadius, InstigatorController, DamageType, Momentum, HitLocation);
|
|
}
|
|
}
|
|
}
|
|
|
|
bHurtEntry = false;
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
TeamIndex=255
|
|
EnemyCountdown=5
|
|
bTriggerOnEnemy=True
|
|
MyDamage=1500.000000
|
|
ArmingCountDown=0.000000
|
|
ExplodeSounds(0)=SoundGroup'Inf_Weapons.antitankmine.antitankmine_explode01'
|
|
ExplodeSounds(1)=SoundGroup'Inf_Weapons.antitankmine.antitankmine_explode02'
|
|
ExplodeSounds(2)=SoundGroup'Inf_Weapons.antitankmine.antitankmine_explode03'
|
|
StaticMesh=StaticMesh'KF_pickups2_Trip.Supers.Pipebomb_Pickup'
|
|
}
|