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 float swap;
|
||||
victimPoint1 = victim.location;
|
||||
victimPoint2.z += victim.CollisionHeight * 0.25;
|
||||
victimPoint2 = victim.location;
|
||||
victimPoint2.z += victim.CollisionHeight * 0.75;
|
||||
scale1 = GetDamageScale(victim, explosionLocation, victimPoint1,
|
||||
@ -93,9 +94,9 @@ simulated function ServerExplode
|
||||
float momentum,
|
||||
Vector explLocation,
|
||||
Pawn instigator,
|
||||
optional bool allowDoubleExplosion,
|
||||
optional Actor explosionTarget,
|
||||
optional vector explosiveDirection
|
||||
optional vector explosiveDirection,
|
||||
optional bool preventProximityHeadDamage
|
||||
){
|
||||
local Actor victim;
|
||||
local int numKilled;
|
||||
@ -109,26 +110,33 @@ simulated function ServerExplode
|
||||
if(victim.role < ROLE_Authority) continue;
|
||||
if(ExtendedZCollision(victim) != none) continue;
|
||||
if(Trigger(victim) != none) continue;
|
||||
|
||||
niceVictim = NiceMonster(victim);
|
||||
dirToVictim = Normal(victim.location - explLocation);
|
||||
hitLocation = victim.location - 0.5 *
|
||||
(victim.collisionHeight + victim.collisionRadius) * dirToVictim;
|
||||
CalculateDamageScales( scale1, scale2,
|
||||
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
|
||||
if(scale1 > 0){
|
||||
ServerDealDamage( victim, explDamage * scale1, instigator,
|
||||
hitLocation, scale1 * momentum * dirToVictim,
|
||||
explDmgType);
|
||||
if(scale1 > 0 || scale2 > 0) {
|
||||
ServerDealDamage(
|
||||
victim,
|
||||
explDamage * FMax(scale1, scale2),
|
||||
instigator,
|
||||
hitLocation,
|
||||
FMax(scale1, scale2) * momentum * dirToVictim,
|
||||
explDmgType);
|
||||
}
|
||||
// Deal secondary damage
|
||||
if(allowDoubleExplosion && victim != none && scale2 > 0){
|
||||
ServerDealDamage( victim, explDamage * scale2, instigator,
|
||||
hitLocation, scale2 * momentum * dirToVictim,
|
||||
explDmgType);
|
||||
}
|
||||
niceVictim = NiceMonster(victim);
|
||||
if(NiceMonster(victim) != none) {
|
||||
if (NiceMonster(victim).health <= 0) {
|
||||
if(niceVictim != none) {
|
||||
if (niceVictim.health <= 0) {
|
||||
numKilled += 1;
|
||||
}
|
||||
else {
|
||||
|
@ -128,7 +128,7 @@ function bool PreventDeath(Pawn Killed, Controller Killer, class<DamageType> dam
|
||||
class'NiceSkillDemoReactiveArmor'.default.explExponent,
|
||||
class'NiceDamTypeDemoSafeExplosion',
|
||||
class'NiceSkillDemoReactiveArmor'.default.explMomentum,
|
||||
killed.location, killed, true
|
||||
killed.location, killed
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
@ -28,9 +28,9 @@ static function Explode(
|
||||
bullet.charExplosionMomentum,
|
||||
hitLocation,
|
||||
bullet.instigator,
|
||||
true,
|
||||
explosionTarget,
|
||||
Vector(bullet.Rotation)
|
||||
Vector(bullet.Rotation),
|
||||
bullet.bStuck
|
||||
);
|
||||
|
||||
if (KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead) {
|
||||
|
@ -19,7 +19,7 @@ defaultproperties
|
||||
StereoFireSoundRef="KF_LAWSnd.LAW_FireST"
|
||||
NoAmmoSoundRef="KF_LAWSnd.LAW_DryFire"
|
||||
DamageType=class'NiceDamTypeLAWBlunt'
|
||||
DamageMax=750
|
||||
DamageMax=350
|
||||
bSplashDamage=True
|
||||
bRecommendSplashDamage=True
|
||||
bWaitForRelease=True
|
||||
|
@ -39,114 +39,32 @@ function TakeDamage(int Damage, Pawn InstigatedBy, Vector HitLocation, Vector Mo
|
||||
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 )
|
||||
return;
|
||||
bHurtEntry = true;
|
||||
|
||||
if( Role == ROLE_Authority && Instigator != none && Instigator.PlayerReplicationInfo != none )
|
||||
Stats = SRStatsBase(Instigator.PlayerReplicationInfo.SteamStatsAndAchievements);
|
||||
|
||||
foreach CollidingActors (class 'Actor', Victims, DamageRadius, HitLocation)
|
||||
{
|
||||
P = none;
|
||||
KFMonsterVictim = none;
|
||||
bMonster = false;
|
||||
KFP = none;
|
||||
bAlreadyChecked = false;
|
||||
simulated function HurtRadius(
|
||||
float damageAmount,
|
||||
float damageRadius,
|
||||
class<DamageType> damageType,
|
||||
float momentum,
|
||||
Vector hitLocation
|
||||
) {
|
||||
local NicePlayerController niceController;
|
||||
local NiceReplicationInfo niceRI;
|
||||
|
||||
// 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) return;
|
||||
niceController = NicePlayerController(instigator.controller);
|
||||
if (niceController == none) return;
|
||||
niceRI = niceController.niceRI;
|
||||
if (niceRI == none) return;
|
||||
|
||||
if ( Instigator == None || Instigator.Controller == None )
|
||||
{
|
||||
Victims.SetDelayedDamageInstigatorController( InstigatorController );
|
||||
}
|
||||
Destroy();
|
||||
|
||||
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;
|
||||
niceRI.ServerExplode(damageAmount,
|
||||
damageRadius,
|
||||
1.0,
|
||||
niceExplosiveDamage,
|
||||
momentum,
|
||||
hitLocation,
|
||||
instigator);
|
||||
}
|
||||
// Overridden to spawn different AvoidMarker
|
||||
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 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:
|
||||
// check if it's a player doing damage before relying on it
|
||||
function ModDamage( out int damage,
|
||||
|
Loading…
Reference in New Issue
Block a user