Change explosives mechanics
This commit is contained in:
parent
08c7d99de9
commit
e79d49ce0d
@ -71,6 +71,7 @@ simulated function CalculateDamageScales( out float scale1, out float scale2,
|
|||||||
local Vector victimPoint1, victimPoint2;
|
local Vector victimPoint1, victimPoint2;
|
||||||
local float swap;
|
local float swap;
|
||||||
victimPoint1 = victim.location;
|
victimPoint1 = victim.location;
|
||||||
|
victimPoint2.z += victim.CollisionHeight * 0.25;
|
||||||
victimPoint2 = victim.location;
|
victimPoint2 = victim.location;
|
||||||
victimPoint2.z += victim.CollisionHeight * 0.75;
|
victimPoint2.z += victim.CollisionHeight * 0.75;
|
||||||
scale1 = GetDamageScale(victim, explosionLocation, victimPoint1,
|
scale1 = GetDamageScale(victim, explosionLocation, victimPoint1,
|
||||||
@ -93,9 +94,9 @@ simulated function ServerExplode
|
|||||||
float momentum,
|
float momentum,
|
||||||
Vector explLocation,
|
Vector explLocation,
|
||||||
Pawn instigator,
|
Pawn instigator,
|
||||||
optional bool allowDoubleExplosion,
|
|
||||||
optional Actor explosionTarget,
|
optional Actor explosionTarget,
|
||||||
optional vector explosiveDirection
|
optional vector explosiveDirection,
|
||||||
|
optional bool preventProximityHeadDamage
|
||||||
){
|
){
|
||||||
local Actor victim;
|
local Actor victim;
|
||||||
local int numKilled;
|
local int numKilled;
|
||||||
@ -109,26 +110,33 @@ simulated function ServerExplode
|
|||||||
if(victim.role < ROLE_Authority) continue;
|
if(victim.role < ROLE_Authority) continue;
|
||||||
if(ExtendedZCollision(victim) != none) continue;
|
if(ExtendedZCollision(victim) != none) continue;
|
||||||
if(Trigger(victim) != none) continue;
|
if(Trigger(victim) != none) continue;
|
||||||
|
|
||||||
|
niceVictim = NiceMonster(victim);
|
||||||
dirToVictim = Normal(victim.location - explLocation);
|
dirToVictim = Normal(victim.location - explLocation);
|
||||||
hitLocation = victim.location - 0.5 *
|
hitLocation = victim.location - 0.5 *
|
||||||
(victim.collisionHeight + victim.collisionRadius) * dirToVictim;
|
(victim.collisionHeight + victim.collisionRadius) * dirToVictim;
|
||||||
CalculateDamageScales( scale1, scale2,
|
CalculateDamageScales( scale1, scale2,
|
||||||
victim, explLocation, explRadius, explExp);
|
victim, explLocation, explRadius, explExp);
|
||||||
|
// Deal head damage if explosion is close enough to the victim's head
|
||||||
|
if ( niceVictim != none && !preventProximityHeadDamage
|
||||||
|
&& niceVictim.GetDistanceToHead(explLocation) <= explRadius * 0.1)
|
||||||
|
{
|
||||||
|
ServerDealDamage( victim, explDamage, instigator,
|
||||||
|
hitLocation, 0.0 * dirToVictim,
|
||||||
|
explDmgType, 0.5);
|
||||||
|
}
|
||||||
// Deal main damage
|
// Deal main damage
|
||||||
if(scale1 > 0){
|
if(scale1 > 0 || scale2 > 0) {
|
||||||
ServerDealDamage( victim, explDamage * scale1, instigator,
|
ServerDealDamage(
|
||||||
hitLocation, scale1 * momentum * dirToVictim,
|
victim,
|
||||||
explDmgType);
|
explDamage * FMax(scale1, scale2),
|
||||||
|
instigator,
|
||||||
|
hitLocation,
|
||||||
|
FMax(scale1, scale2) * momentum * dirToVictim,
|
||||||
|
explDmgType);
|
||||||
}
|
}
|
||||||
// Deal secondary damage
|
if(niceVictim != none) {
|
||||||
if(allowDoubleExplosion && victim != none && scale2 > 0){
|
if (niceVictim.health <= 0) {
|
||||||
ServerDealDamage( victim, explDamage * scale2, instigator,
|
|
||||||
hitLocation, scale2 * momentum * dirToVictim,
|
|
||||||
explDmgType);
|
|
||||||
}
|
|
||||||
niceVictim = NiceMonster(victim);
|
|
||||||
if(NiceMonster(victim) != none) {
|
|
||||||
if (NiceMonster(victim).health <= 0) {
|
|
||||||
numKilled += 1;
|
numKilled += 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -128,7 +128,7 @@ function bool PreventDeath(Pawn Killed, Controller Killer, class<DamageType> dam
|
|||||||
class'NiceSkillDemoReactiveArmor'.default.explExponent,
|
class'NiceSkillDemoReactiveArmor'.default.explExponent,
|
||||||
class'NiceDamTypeDemoSafeExplosion',
|
class'NiceDamTypeDemoSafeExplosion',
|
||||||
class'NiceSkillDemoReactiveArmor'.default.explMomentum,
|
class'NiceSkillDemoReactiveArmor'.default.explMomentum,
|
||||||
killed.location, killed, true
|
killed.location, killed
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,9 @@ static function Explode(
|
|||||||
bullet.charExplosionMomentum,
|
bullet.charExplosionMomentum,
|
||||||
hitLocation,
|
hitLocation,
|
||||||
bullet.instigator,
|
bullet.instigator,
|
||||||
true,
|
|
||||||
explosionTarget,
|
explosionTarget,
|
||||||
Vector(bullet.Rotation)
|
Vector(bullet.Rotation),
|
||||||
|
bullet.bStuck
|
||||||
);
|
);
|
||||||
|
|
||||||
if (KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead) {
|
if (KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead) {
|
||||||
|
@ -19,7 +19,7 @@ defaultproperties
|
|||||||
StereoFireSoundRef="KF_LAWSnd.LAW_FireST"
|
StereoFireSoundRef="KF_LAWSnd.LAW_FireST"
|
||||||
NoAmmoSoundRef="KF_LAWSnd.LAW_DryFire"
|
NoAmmoSoundRef="KF_LAWSnd.LAW_DryFire"
|
||||||
DamageType=class'NiceDamTypeLAWBlunt'
|
DamageType=class'NiceDamTypeLAWBlunt'
|
||||||
DamageMax=750
|
DamageMax=350
|
||||||
bSplashDamage=True
|
bSplashDamage=True
|
||||||
bRecommendSplashDamage=True
|
bRecommendSplashDamage=True
|
||||||
bWaitForRelease=True
|
bWaitForRelease=True
|
||||||
|
@ -39,114 +39,32 @@ function TakeDamage(int Damage, Pawn InstigatedBy, Vector HitLocation, Vector Mo
|
|||||||
Explode(HitLocation, vect(0,0,1));
|
Explode(HitLocation, vect(0,0,1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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 bool bMonster;
|
|
||||||
local Pawn P;
|
|
||||||
local KFPawn KFP;
|
|
||||||
local array<Pawn> CheckedPawns;
|
|
||||||
local int i;
|
|
||||||
local bool bAlreadyChecked;
|
|
||||||
local SRStatsBase Stats;
|
|
||||||
|
|
||||||
if ( bHurtEntry )
|
simulated function HurtRadius(
|
||||||
return;
|
float damageAmount,
|
||||||
bHurtEntry = true;
|
float damageRadius,
|
||||||
|
class<DamageType> damageType,
|
||||||
|
float momentum,
|
||||||
|
Vector hitLocation
|
||||||
|
) {
|
||||||
|
local NicePlayerController niceController;
|
||||||
|
local NiceReplicationInfo niceRI;
|
||||||
|
|
||||||
if( Role == ROLE_Authority && Instigator != none && Instigator.PlayerReplicationInfo != none )
|
if (instigator == none) return;
|
||||||
Stats = SRStatsBase(Instigator.PlayerReplicationInfo.SteamStatsAndAchievements);
|
niceController = NicePlayerController(instigator.controller);
|
||||||
|
if (niceController == none) return;
|
||||||
|
niceRI = niceController.niceRI;
|
||||||
|
if (niceRI == none) return;
|
||||||
|
|
||||||
foreach CollidingActors (class 'Actor', Victims, DamageRadius, HitLocation)
|
Destroy();
|
||||||
{
|
|
||||||
P = none;
|
|
||||||
KFMonsterVictim = none;
|
|
||||||
bMonster = false;
|
|
||||||
KFP = none;
|
|
||||||
bAlreadyChecked = false;
|
|
||||||
|
|
||||||
// don't let blast damage affect fluid - VisibleCollisingActors doesn't really work for them - jag
|
niceRI.ServerExplode(damageAmount,
|
||||||
if( (Victims != self) && (Hurtwall != Victims) && (Victims.Role == ROLE_Authority) && !Victims.IsA('FluidSurfaceInfo')
|
damageRadius,
|
||||||
&& ExtendedZCollision(Victims)==None )
|
1.0,
|
||||||
{
|
niceExplosiveDamage,
|
||||||
if( (Instigator==None || Instigator.Health<=0) && KFPawn(Victims)!=None )
|
momentum,
|
||||||
Continue;
|
hitLocation,
|
||||||
dir = Victims.Location - HitLocation;
|
instigator);
|
||||||
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 )
|
|
||||||
continue;
|
|
||||||
CheckedPawns[CheckedPawns.Length] = P;
|
|
||||||
|
|
||||||
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));
|
|
||||||
bMonster = true; // in case TakeDamage() and further Die() deletes the monster
|
|
||||||
}
|
|
||||||
else if( KFP != none ) {
|
|
||||||
damageScale *= KFP.GetExposureTo(Location + 15 * -Normal(PhysicsVolume.Gravity));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( damageScale <= 0)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(NiceMonster(Victims) != none)
|
|
||||||
Victims.TakeDamage(damageScale * DamageAmount,Instigator,Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir
|
|
||||||
,(damageScale * Momentum * dir), niceExplosiveDamage);
|
|
||||||
else
|
|
||||||
Victims.TakeDamage(damageScale * DamageAmount,Instigator,Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir
|
|
||||||
,(damageScale * Momentum * dir), DamageType);
|
|
||||||
|
|
||||||
if( bMonster && (KFMonsterVictim == none || KFMonsterVictim.Health < 1) ) {
|
|
||||||
NumKilled++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Vehicle(Victims) != None && Vehicle(Victims).Health > 0)
|
|
||||||
{
|
|
||||||
Vehicle(Victims).DriverRadiusDamage(DamageAmount, DamageRadius, InstigatorController, DamageType, Momentum, HitLocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Role == ROLE_Authority )
|
|
||||||
{
|
|
||||||
if ( bBlewInHands && NumKilled >= 5 && Stats != none )
|
|
||||||
class'ScrnAchievements'.static.ProgressAchievementByID(Stats.Rep, 'SuicideBomber', 1);
|
|
||||||
|
|
||||||
if ( NumKilled >= 4 )
|
|
||||||
{
|
|
||||||
KFGameType(Level.Game).DramaticEvent(0.05);
|
|
||||||
}
|
|
||||||
else if ( NumKilled >= 2 )
|
|
||||||
{
|
|
||||||
KFGameType(Level.Game).DramaticEvent(0.03);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bHurtEntry = false;
|
|
||||||
}
|
}
|
||||||
// Overridden to spawn different AvoidMarker
|
// Overridden to spawn different AvoidMarker
|
||||||
simulated function HitWall( vector HitNormal, actor Wall ){
|
simulated function HitWall( vector HitNormal, actor Wall ){
|
||||||
|
@ -681,6 +681,22 @@ simulated function float IsHeadshotClient( Vector Loc,
|
|||||||
return 1.0 - (distance / (headRadius * headScale * additionalScale));
|
return 1.0 - (distance / (headRadius * headScale * additionalScale));
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
// Calculates distance from `location` to this zed's head.
|
||||||
|
simulated function float GetDistanceToHead(Vector location) {
|
||||||
|
local Coords headBoneCoords;
|
||||||
|
local Vector headLocation;
|
||||||
|
|
||||||
|
local Vector AToLineOrig;
|
||||||
|
local Vector lineDir;
|
||||||
|
|
||||||
|
if(headBone == '') {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
headBoneCoords = GetBoneCoords(headBone);
|
||||||
|
headLocation =
|
||||||
|
headBoneCoords.Origin + headHeight * headScale * headBoneCoords.XAxis;
|
||||||
|
return VSize(location - headLocation);
|
||||||
|
}
|
||||||
// In case of a future modifications:
|
// In case of a future modifications:
|
||||||
// check if it's a player doing damage before relying on it
|
// check if it's a player doing damage before relying on it
|
||||||
function ModDamage( out int damage,
|
function ModDamage( out int damage,
|
||||||
|
Loading…
Reference in New Issue
Block a user