Fix new line symbol issues

This commit is contained in:
Anton Tarasenko 2020-04-19 00:44:48 +07:00
commit d66d86b2b1
846 changed files with 33896 additions and 12983 deletions

View file

@ -1,88 +1,162 @@
// ScrN copy
class NiceCryoNade extends Nade;
#exec OBJ LOAD FILE=KF_GrenadeSnd.uax
#exec OBJ LOAD FILE=Inf_WeaponsTwo.uax
#exec OBJ LOAD FILE=KF_LAWSnd.uax
// How many times do freezing
var int totalFreezes;
// How often to do freezeing
var float freezeRate;
// The next time that this nade will freeze
var float nextFreezeTime;
// The sound of nade's explosion
var sound explosionSound;
// Whether or not effects have been played yet
var bool bNeedToPlayEffects;
replication
{
reliable if (Role==ROLE_Authority) bNeedToPlayEffects;
}
simulated function PostNetReceive()
{
super.PostNetReceive();
if(!bHasExploded && bNeedToPlayEffects){ bNeedToPlayEffects = false; Explode(Location, vect(0,0,1));
}
}
simulated function Explode(vector hitLocation, vector hitNormal){
bHasExploded = true;
BlowUp(hitLocation);
PlaySound(ExplosionSound,,TransientSoundVolume);
if(Role == ROLE_Authority){ bNeedToPlayEffects = true; AmbientSound=Sound'Inf_WeaponsTwo.smoke_loop';
}
if(EffectIsRelevant(location, false)){ Spawn(class'NiceCryoNadeCloud',,, hitLocation, rotator(vect(0,0,1))); Spawn(explosionDecal, self,, hitLocation, rotator(-hitNormal)); if(level.detailMode >= DM_High) Spawn(class'NiceNitroGroundEffect', self,, location);
}
}
function Timer(){
if(!bHidden){ if(!bHasExploded) Explode(location, vect(0,0,1));
}
else if(bDisintegrated){ AmbientSound = none; Destroy();
}
}
simulated function BlowUp(vector hitLocation){
DoFreeze(damage, damageRadius, MyDamageType, momentumTransfer, hitLocation);
if(role == ROLE_Authority) MakeNoise(1.0);
}
function DoFreeze( float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation){
local NiceMonster niceZed;
if(bHurtEntry) return;
bHurtEntry = true;
nextFreezeTime = level.timeSeconds + freezeRate;
foreach CollidingActors(class 'NiceMonster', niceZed, damageRadius, hitLocation){ if(niceZed.Health <= 0) continue; if(instigator == none || instigator.controller == none) niceZed.SetDelayedDamageInstigatorController(instigatorController); niceZed.TakeDamage( damageAmount, instigator, niceZed.location, vect(0,0,0), damageType);
}
bHurtEntry = false;
}
function TakeDamage(int Damage, Pawn InstigatedBy, Vector hitlocation, Vector momentum, class<DamageType> damageType, optional int HitIndex){
if(damageType == class'SirenScreamDamage') Disintegrate(HitLocation, vect(0,0,1));
}
// Overridden to tweak the handling of the impact sound
simulated function HitWall(vector hitNormal, Actor wall){
local Vector vnorm;
local PlayerController player;
if(Pawn(wall) != none || GameObjective(wall) != none){ Explode(Location, HitNormal); return;
}
if(!bTimerSet){ SetTimer(ExplodeTimer, false); bTimerSet = true;
}
// Reflect off Wall w/damping
vnorm = (velocity dot hitNormal) * hitNormal;
Velocity = -vnorm * DampenFactor + (Velocity - vnorm) * dampenFactorParallel;
RandSpin(100000);
desiredRotation.roll = 0;
RotationRate.roll = 0;
speed = VSize(velocity);
if(speed < 20){ bBounce = False; PrePivot.Z = -1.5; SetPhysics(PHYS_None); Timer(); SetTimer(0.0,False); desiredRotation = Rotation; desiredRotation.Roll = 0; desiredRotation.Pitch = 0; SetRotation(desiredRotation); if(trail != none) trail.mRegen = false; return;
}
if(level.NetMode != NM_DedicatedServer && Speed > 50) PlaySound(ImpactSound, SLOT_Misc );
else{ bFixedRotationDir = false; bRotateToDesired = true; DesiredRotation.Pitch = 0; RotationRate.Pitch = 50000;
}
if(level.bDropDetail || level.DetailMode == DM_Low) return;
if( (level.TimeSeconds - lastSparkTime > 0.5) && EffectIsRelevant(location, false)){ player = level.GetLocalPlayerController(); if( player.viewTarget != none && VSize(player.viewTarget.location - location) < 6000) Spawn(HitEffectClass,,, Location, Rotator(HitNormal)); LastSparkTime = Level.TimeSeconds;
}
}
function Tick(float deltaTime){
if( totalFreezes > 0 && nextFreezeTime > 0 && nextFreezeTime < level.timeSeconds){ totalFreezes--; DoFreeze(damage, damageRadius, myDamageType, momentumTransfer, location); if(totalFreezes == 0) ambientSound = none;
}
}
defaultproperties
{ totalFreezes=100 freezeRate=0.030000 ExplosionSound=SoundGroup'KF_GrenadeSnd.NadeBase.MedicNade_Explode' Damage=0.000000 DamageRadius=175.000000 MyDamageType=Class'NicePack.NiceDamTypeCryoNade' ExplosionDecal=Class'NicePack.NiceNitroDecal' StaticMesh=StaticMesh'KF_pickups5_Trip.nades.MedicNade_Pickup' LifeSpan=8.000000 DrawScale=1.000000 SoundVolume=150 SoundRadius=100.000000 TransientSoundVolume=2.000000 TransientSoundRadius=200.000000
}
// ScrN copy
class NiceCryoNade extends Nade;
#exec OBJ LOAD FILE=KF_GrenadeSnd.uax
#exec OBJ LOAD FILE=Inf_WeaponsTwo.uax
#exec OBJ LOAD FILE=KF_LAWSnd.uax
// How many times do freezing
var int totalFreezes;
// How often to do freezeing
var float freezeRate;
// The next time that this nade will freeze
var float nextFreezeTime;
// The sound of nade's explosion
var sound explosionSound;
// Whether or not effects have been played yet
var bool bNeedToPlayEffects;
replication
{
reliable if (Role==ROLE_Authority)
bNeedToPlayEffects;
}
simulated function PostNetReceive()
{
super.PostNetReceive();
if(!bHasExploded && bNeedToPlayEffects){
bNeedToPlayEffects = false;
Explode(Location, vect(0,0,1));
}
}
simulated function Explode(vector hitLocation, vector hitNormal){
bHasExploded = true;
BlowUp(hitLocation);
PlaySound(ExplosionSound,,TransientSoundVolume);
if(Role == ROLE_Authority){
bNeedToPlayEffects = true;
AmbientSound=Sound'Inf_WeaponsTwo.smoke_loop';
}
if(EffectIsRelevant(location, false)){
Spawn(class'NiceCryoNadeCloud',,, hitLocation, rotator(vect(0,0,1)));
Spawn(explosionDecal, self,, hitLocation, rotator(-hitNormal));
if(level.detailMode >= DM_High)
Spawn(class'NiceNitroGroundEffect', self,, location);
}
}
function Timer(){
if(!bHidden){
if(!bHasExploded)
Explode(location, vect(0,0,1));
}
else if(bDisintegrated){
AmbientSound = none;
Destroy();
}
}
simulated function BlowUp(vector hitLocation){
DoFreeze(damage, damageRadius, MyDamageType, momentumTransfer, hitLocation);
if(role == ROLE_Authority)
MakeNoise(1.0);
}
function DoFreeze( float DamageAmount, float DamageRadius,
class<DamageType> DamageType,
float Momentum, vector HitLocation){
local NiceMonster niceZed;
if(bHurtEntry)
return;
bHurtEntry = true;
nextFreezeTime = level.timeSeconds + freezeRate;
foreach CollidingActors(class 'NiceMonster', niceZed,
damageRadius, hitLocation){
if(niceZed.Health <= 0) continue;
if(instigator == none || instigator.controller == none)
niceZed.SetDelayedDamageInstigatorController(instigatorController);
niceZed.TakeDamage( damageAmount, instigator, niceZed.location,
vect(0,0,0), damageType);
}
bHurtEntry = false;
}
function TakeDamage(int Damage, Pawn InstigatedBy, Vector hitlocation,
Vector momentum, class<DamageType> damageType,
optional int HitIndex){
if(damageType == class'SirenScreamDamage')
Disintegrate(HitLocation, vect(0,0,1));
}
// Overridden to tweak the handling of the impact sound
simulated function HitWall(vector hitNormal, Actor wall){
local Vector vnorm;
local PlayerController player;
if(Pawn(wall) != none || GameObjective(wall) != none){
Explode(Location, HitNormal);
return;
}
if(!bTimerSet){
SetTimer(ExplodeTimer, false);
bTimerSet = true;
}
// Reflect off Wall w/damping
vnorm = (velocity dot hitNormal) * hitNormal;
Velocity = -vnorm * DampenFactor +
(Velocity - vnorm) * dampenFactorParallel;
RandSpin(100000);
desiredRotation.roll = 0;
RotationRate.roll = 0;
speed = VSize(velocity);
if(speed < 20){
bBounce = False;
PrePivot.Z = -1.5;
SetPhysics(PHYS_None);
Timer();
SetTimer(0.0,False);
desiredRotation = Rotation;
desiredRotation.Roll = 0;
desiredRotation.Pitch = 0;
SetRotation(desiredRotation);
if(trail != none)
trail.mRegen = false;
return;
}
if(level.NetMode != NM_DedicatedServer && Speed > 50)
PlaySound(ImpactSound, SLOT_Misc );
else{
bFixedRotationDir = false;
bRotateToDesired = true;
DesiredRotation.Pitch = 0;
RotationRate.Pitch = 50000;
}
if(level.bDropDetail || level.DetailMode == DM_Low)
return;
if( (level.TimeSeconds - lastSparkTime > 0.5)
&& EffectIsRelevant(location, false)){
player = level.GetLocalPlayerController();
if( player.viewTarget != none
&& VSize(player.viewTarget.location - location) < 6000)
Spawn(HitEffectClass,,, Location, Rotator(HitNormal));
LastSparkTime = Level.TimeSeconds;
}
}
function Tick(float deltaTime){
if( totalFreezes > 0 && nextFreezeTime > 0
&& nextFreezeTime < level.timeSeconds){
totalFreezes--;
DoFreeze(damage, damageRadius, myDamageType, momentumTransfer, location);
if(totalFreezes == 0)
ambientSound = none;
}
}
defaultproperties
{
totalFreezes=100
freezeRate=0.030000
ExplosionSound=SoundGroup'KF_GrenadeSnd.NadeBase.MedicNade_Explode'
Damage=0.000000
DamageRadius=175.000000
MyDamageType=Class'NicePack.NiceDamTypeCryoNade'
ExplosionDecal=Class'NicePack.NiceNitroDecal'
StaticMesh=StaticMesh'KF_pickups5_Trip.nades.MedicNade_Pickup'
LifeSpan=8.000000
DrawScale=1.000000
SoundVolume=150
SoundRadius=100.000000
TransientSoundVolume=2.000000
TransientSoundRadius=200.000000
}

View file

@ -1,23 +1,57 @@
// ScrN copy
class NiceCryoNadeCloud extends Emitter;
var bool bFlashed;
simulated function PostBeginPlay(){
super.PostBeginPlay();
NadeLight();
}
simulated function NadeLight(){
if(instigator == none) return;
if(Level.bDropDetail) return;
if( (Level.TimeSeconds - LastRenderTime < 0.2) || (PlayerController(instigator.controller) != none)){
bDynamicLight = true;
SetTimer(0.25, false);
}
else Timer();
}
simulated function Timer(){
bDynamicLight = false;
}
defaultproperties
{ Begin Object Class=SpriteEmitter Name=SpriteEmitter0 UseColorScale=True RespawnDeadParticles=False SpinParticles=True UseSizeScale=True UseRegularSizeScale=False UniformSize=True AutomaticInitialSpawning=False BlendBetweenSubdivisions=True ColorScale(0)=(Color=(B=255,G=235,R=215,A=255)) ColorScale(1)=(RelativeTime=1.000000,Color=(B=245,G=225,R=205,A=255)) FadeOutFactor=(W=0.000000,X=0.000000,Y=0.000000,Z=0.000000) FadeOutStartTime=5.000000 SpinsPerSecondRange=(Y=(Min=0.050000,Max=0.100000),Z=(Min=0.050000,Max=0.100000)) StartSpinRange=(X=(Min=-0.500000,Max=0.500000),Y=(Max=1.000000),Z=(Max=1.000000)) SizeScale(0)=(RelativeSize=1.000000) SizeScale(1)=(RelativeTime=1.000000,RelativeSize=5.000000) StartSizeRange=(X=(Min=40.000000,Max=40.000000),Y=(Min=40.000000,Max=40.000000),Z=(Min=40.000000,Max=40.000000)) InitialParticlesPerSecond=5000.000000 DrawStyle=PTDS_AlphaBlend Texture=Texture'kf_fx_trip_t.Misc.smoke_animated' TextureUSubdivisions=8 TextureVSubdivisions=8 LifetimeRange=(Min=3.000000,Max=3.000000) StartVelocityRange=(X=(Min=-750.000000,Max=750.000000),Y=(Min=-750.000000,Max=750.000000)) VelocityLossRange=(X=(Min=10.000000,Max=10.000000),Y=(Min=10.000000,Max=10.000000),Z=(Min=10.000000,Max=10.000000)) End Object Emitters(0)=SpriteEmitter'NicePack.NiceCryoNadeCloud.SpriteEmitter0'
AutoDestroy=True bNoDelete=False RemoteRole=ROLE_SimulatedProxy bNotOnDedServer=False
}
// ScrN copy
class NiceCryoNadeCloud extends Emitter;
var bool bFlashed;
simulated function PostBeginPlay(){
super.PostBeginPlay();
NadeLight();
}
simulated function NadeLight(){
if(instigator == none) return;
if(Level.bDropDetail) return;
if( (Level.TimeSeconds - LastRenderTime < 0.2)
|| (PlayerController(instigator.controller) != none)){
bDynamicLight = true;
SetTimer(0.25, false);
}
else
Timer();
}
simulated function Timer(){
bDynamicLight = false;
}
defaultproperties
{
Begin Object Class=SpriteEmitter Name=SpriteEmitter0
UseColorScale=True
RespawnDeadParticles=False
SpinParticles=True
UseSizeScale=True
UseRegularSizeScale=False
UniformSize=True
AutomaticInitialSpawning=False
BlendBetweenSubdivisions=True
ColorScale(0)=(Color=(B=255,G=235,R=215,A=255))
ColorScale(1)=(RelativeTime=1.000000,Color=(B=245,G=225,R=205,A=255))
FadeOutFactor=(W=0.000000,X=0.000000,Y=0.000000,Z=0.000000)
FadeOutStartTime=5.000000
SpinsPerSecondRange=(Y=(Min=0.050000,Max=0.100000),Z=(Min=0.050000,Max=0.100000))
StartSpinRange=(X=(Min=-0.500000,Max=0.500000),Y=(Max=1.000000),Z=(Max=1.000000))
SizeScale(0)=(RelativeSize=1.000000)
SizeScale(1)=(RelativeTime=1.000000,RelativeSize=5.000000)
StartSizeRange=(X=(Min=40.000000,Max=40.000000),Y=(Min=40.000000,Max=40.000000),Z=(Min=40.000000,Max=40.000000))
InitialParticlesPerSecond=5000.000000
DrawStyle=PTDS_AlphaBlend
Texture=Texture'kf_fx_trip_t.Misc.smoke_animated'
TextureUSubdivisions=8
TextureVSubdivisions=8
LifetimeRange=(Min=3.000000,Max=3.000000)
StartVelocityRange=(X=(Min=-750.000000,Max=750.000000),Y=(Min=-750.000000,Max=750.000000))
VelocityLossRange=(X=(Min=10.000000,Max=10.000000),Y=(Min=10.000000,Max=10.000000),Z=(Min=10.000000,Max=10.000000))
End Object
Emitters(0)=SpriteEmitter'NicePack.NiceCryoNadeCloud.SpriteEmitter0'
AutoDestroy=True
bNoDelete=False
RemoteRole=ROLE_SimulatedProxy
bNotOnDedServer=False
}

View file

@ -1,5 +1,6 @@
class NiceDamTypeCryoNade extends NiceWeaponDamageType
abstract;
defaultproperties
{ freezePower=200.000000
}
class NiceDamTypeCryoNade extends NiceWeaponDamageType
abstract;
defaultproperties
{
freezePower=200.000000
}

View file

@ -1,5 +1,9 @@
class NiceDamTypeFlameNade extends NiceDamTypeFire
abstract;
defaultproperties
{ WeaponClass=None DeathString="%k incinerated %o (flame grenade)." FemaleSuicide="%o roasted herself alive (flame grenade)." MaleSuicide="%o roasted himself alive (flame grenade)."
}
class NiceDamTypeFlameNade extends NiceDamTypeFire
abstract;
defaultproperties
{
WeaponClass=None
DeathString="%k incinerated %o (flame grenade)."
FemaleSuicide="%o roasted herself alive (flame grenade)."
MaleSuicide="%o roasted himself alive (flame grenade)."
}

View file

@ -1,166 +1,373 @@
//=============================================================================
// MedicNade
//=============================================================================
// Medic grenade that heals friends and hurts enemies
//=============================================================================
// Killing Floor Source
// Copyright (C) 2012 Tripwire Interactive
// Author - John "Ramm-Jaeger" Gibson
//=============================================================================
class NiceMedicNade extends Nade;
#exec OBJ LOAD FILE=KF_GrenadeSnd.uax
#exec OBJ LOAD FILE=Inf_WeaponsTwo.uax
#exec OBJ LOAD FILE=KF_LAWSnd.uax
var() int HealBoostAmount;// How much we heal a player by default with the medic nade
var int TotalHeals; // The total number of times this nade has healed (or hurt enemies)
var() int MaxHeals; // The total number of times this nade will heal (or hurt enemies) until its done healing
var float NextHealTime; // The next time that this nade will heal friendlies or hurt enemies
var() float HealInterval; // How often to do healing
var() sound ExplosionSound; // The sound of the rocket exploding
var localized string SuccessfulHealMessage;
var int MaxNumberOfPlayers;
var bool bNeedToPlayEffects; // Whether or not effects have been played yet
replication
{
reliable if (Role==ROLE_Authority) bNeedToPlayEffects;
}
simulated function PostNetReceive()
{
super.PostNetReceive();
if( !bHasExploded && bNeedToPlayEffects )
{ bNeedToPlayEffects = false; Explode(Location, vect(0,0,1));
}
}
simulated function Explode(vector HitLocation, vector HitNormal)
{
bHasExploded = True;
BlowUp(HitLocation);
PlaySound(ExplosionSound,,TransientSoundVolume);
if( Role == ROLE_Authority )
{ bNeedToPlayEffects = true; AmbientSound=Sound'Inf_WeaponsTwo.smoke_loop';
}
if ( EffectIsRelevant(Location,false) )
{ Spawn(Class'NicePack.NiceNadeHealing',,, HitLocation, rotator(vect(0,0,1)));
}
}
function Timer()
{
if( !bHidden )
{ if( !bHasExploded ) { Explode(Location, vect(0,0,1)); }
}
else if( bDisintegrated )
{ AmbientSound=none; Destroy();
}
}
simulated function BlowUp(vector HitLocation)
{
HealOrHurt(Damage,DamageRadius, MyDamageType, MomentumTransfer, HitLocation);
if ( Role == ROLE_Authority ) MakeNoise(1.0);
}
function HealOrHurt(float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation)
{
local actor Victims;
local float damageScale;
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;
// Healing
local KFPlayerReplicationInfo PRI;
local int MedicReward;
local float HealSum; // for modifying based on perks
local int PlayersHealed;
if ( bHurtEntry ) return;
NextHealTime = Level.TimeSeconds + HealInterval;
bHurtEntry = true;
if( Fear != none )
{ Fear.StartleBots();
}
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;
damageScale = 1.0;
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 ) { damageScale *= KFP.GetExposureTo(Location + 15 * -Normal(PhysicsVolume.Gravity)); }
CheckedPawns[CheckedPawns.Length] = P;
if ( damageScale <= 0) { P = none; continue; } else { //Victims = P; P = none; } } else { continue; }
if( KFP == none ) { //log(Level.TimeSeconds@"Hurting "$Victims$" for "$(damageScale * DamageAmount)$" damage");
if( Pawn(Victims) != none && Pawn(Victims).Health > 0 ) { 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++; } } } else { if(Instigator != none && KFP.Health > 0) { if ( KFP.bCanBeHealed ) { PlayersHealed += 1; MedicReward = HealBoostAmount;
PRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if ( PRI != none && PRI.ClientVeteranSkill != none ) { MedicReward *= PRI.ClientVeteranSkill.Static.GetHealPotency(PRI); }
HealSum = MedicReward;
if ( (KFP.Health + KFP.healthToGive + MedicReward) > KFP.HealthMax ) { MedicReward = KFP.HealthMax - (KFP.Health + KFP.healthToGive); if ( MedicReward < 0 ) { MedicReward = 0; } }
//log(Level.TimeSeconds@"Healing "$KFP$" for "$HealSum$" base healamount "$HealBoostAmount$" health"); KFP.GiveHealth(HealSum, KFP.HealthMax); KFP.ShieldStrength += HealSum * 0.25; if(KFP.ShieldStrength > KFP.ShieldStrengthMax) KFP.ShieldStrength = KFP.ShieldStrengthMax;
if ( PRI != none ) { if ( MedicReward > 0 && KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements) != none ) { KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements).AddDamageHealed(MedicReward, false, true); }
// Give the medic reward money as a percentage of how much of the person's health they healed MedicReward = int((FMin(float(MedicReward),KFP.HealthMax)/KFP.HealthMax) * 60);
PRI.ReceiveRewardForHealing( MedicReward, KFP );
if ( KFHumanPawn(Instigator) != none ) { KFHumanPawn(Instigator).AlphaAmount = 255; }
if( PlayerController(Instigator.Controller) != none ) { PlayerController(Instigator.Controller).ClientMessage(SuccessfulHealMessage$KFP.GetPlayerName(), 'CriticalEvent'); } } } } }
KFP = none; }
if (PlayersHealed >= MaxNumberOfPlayers) { if (PRI != none) { KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements).HealedTeamWithMedicGrenade(); } }
}
bHurtEntry = false;
}
// Shoot nades in mid-air
// Alex
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
if ( Monster(instigatedBy) != none || instigatedBy == Instigator )
{ if( damageType == class'SirenScreamDamage') { Disintegrate(HitLocation, vect(0,0,1)); }
}
}
// Overridden to tweak the handling of the impact sound
simulated function HitWall( vector HitNormal, actor Wall )
{
local Vector VNorm;
local PlayerController PC;
if ( (Pawn(Wall) != none) || (GameObjective(Wall) != none) )
{ Explode(Location, HitNormal); return;
}
if (!bTimerSet)
{ SetTimer(ExplodeTimer, false); bTimerSet = true;
}
// Reflect off Wall w/damping
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
RandSpin(100000);
DesiredRotation.Roll = 0;
RotationRate.Roll = 0;
Speed = VSize(Velocity);
if ( Speed < 20 )
{ bBounce = False; PrePivot.Z = -1.5; SetPhysics(PHYS_none); Timer(); SetTimer(0.0,False); DesiredRotation = Rotation; DesiredRotation.Roll = 0; DesiredRotation.Pitch = 0; SetRotation(DesiredRotation);
if( Fear == none ) { //(jc) Changed to use MedicNade-specific grenade that's overridden to not make the ringmaster fear it Fear = Spawn(class'AvoidMarker_MedicNade'); Fear.SetCollisionSize(DamageRadius,DamageRadius); Fear.StartleBots(); }
if ( Trail != none ) Trail.mRegen = false; // stop the emitter from regenerating
}
else
{ if ( (Level.NetMode != NM_DedicatedServer) && (Speed > 50) ) PlaySound(ImpactSound, SLOT_Misc ); else { bFixedRotationDir = false; bRotateToDesired = true; DesiredRotation.Pitch = 0; RotationRate.Pitch = 50000; } if ( !Level.bDropDetail && (Level.DetailMode != DM_Low) && (Level.TimeSeconds - LastSparkTime > 0.5) && EffectIsRelevant(Location,false) ) { PC = Level.GetLocalPlayerController(); if ( (PC.ViewTarget != none) && VSize(PC.ViewTarget.Location - Location) < 6000 ) Spawn(HitEffectClass,,, Location, Rotator(HitNormal)); LastSparkTime = Level.TimeSeconds; }
}
}
function Tick( float DeltaTime )
{
if( Role < ROLE_Authority )
{ return;
}
// if( class'ROEngine.ROLevelInfo'.static.RODebugMode() )
// {
// DrawDebugSphere( Location, DamageRadius, 12, 255, 0, 0);
// }
if( TotalHeals < MaxHeals && NextHealTime > 0 && NextHealTime < Level.TimeSeconds )
{ TotalHeals += 1;
HealOrHurt(Damage,DamageRadius, MyDamageType, MomentumTransfer, Location);
if( TotalHeals >= MaxHeals ) { AmbientSound=none; }
}
}
defaultproperties
{ HealBoostAmount=10 MaxHeals=8 HealInterval=1.000000 ExplosionSound=SoundGroup'KF_GrenadeSnd.NadeBase.MedicNade_Explode' SuccessfulHealMessage="You healed " MaxNumberOfPlayers=6 Damage=50.000000 DamageRadius=175.000000 MyDamageType=Class'KFMod.DamTypeMedicNade' StaticMesh=StaticMesh'KF_pickups5_Trip.nades.MedicNade_Pickup' DrawScale=1.000000 SoundVolume=150 SoundRadius=100.000000 TransientSoundVolume=2.000000 TransientSoundRadius=200.000000
}
//=============================================================================
// MedicNade
//=============================================================================
// Medic grenade that heals friends and hurts enemies
//=============================================================================
// Killing Floor Source
// Copyright (C) 2012 Tripwire Interactive
// Author - John "Ramm-Jaeger" Gibson
//=============================================================================
class NiceMedicNade extends Nade;
#exec OBJ LOAD FILE=KF_GrenadeSnd.uax
#exec OBJ LOAD FILE=Inf_WeaponsTwo.uax
#exec OBJ LOAD FILE=KF_LAWSnd.uax
var() int HealBoostAmount;// How much we heal a player by default with the medic nade
var int TotalHeals; // The total number of times this nade has healed (or hurt enemies)
var() int MaxHeals; // The total number of times this nade will heal (or hurt enemies) until its done healing
var float NextHealTime; // The next time that this nade will heal friendlies or hurt enemies
var() float HealInterval; // How often to do healing
var() sound ExplosionSound; // The sound of the rocket exploding
var localized string SuccessfulHealMessage;
var int MaxNumberOfPlayers;
var bool bNeedToPlayEffects; // Whether or not effects have been played yet
replication
{
reliable if (Role==ROLE_Authority)
bNeedToPlayEffects;
}
simulated function PostNetReceive()
{
super.PostNetReceive();
if( !bHasExploded && bNeedToPlayEffects )
{
bNeedToPlayEffects = false;
Explode(Location, vect(0,0,1));
}
}
simulated function Explode(vector HitLocation, vector HitNormal)
{
bHasExploded = True;
BlowUp(HitLocation);
PlaySound(ExplosionSound,,TransientSoundVolume);
if( Role == ROLE_Authority )
{
bNeedToPlayEffects = true;
AmbientSound=Sound'Inf_WeaponsTwo.smoke_loop';
}
if ( EffectIsRelevant(Location,false) )
{
Spawn(Class'NicePack.NiceNadeHealing',,, HitLocation, rotator(vect(0,0,1)));
}
}
function Timer()
{
if( !bHidden )
{
if( !bHasExploded )
{
Explode(Location, vect(0,0,1));
}
}
else if( bDisintegrated )
{
AmbientSound=none;
Destroy();
}
}
simulated function BlowUp(vector HitLocation)
{
HealOrHurt(Damage,DamageRadius, MyDamageType, MomentumTransfer, HitLocation);
if ( Role == ROLE_Authority )
MakeNoise(1.0);
}
function HealOrHurt(float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation)
{
local actor Victims;
local float damageScale;
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;
// Healing
local KFPlayerReplicationInfo PRI;
local int MedicReward;
local float HealSum; // for modifying based on perks
local int PlayersHealed;
if ( bHurtEntry )
return;
NextHealTime = Level.TimeSeconds + HealInterval;
bHurtEntry = true;
if( Fear != none )
{
Fear.StartleBots();
}
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;
damageScale = 1.0;
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 )
{
damageScale *= KFP.GetExposureTo(Location + 15 * -Normal(PhysicsVolume.Gravity));
}
CheckedPawns[CheckedPawns.Length] = P;
if ( damageScale <= 0)
{
P = none;
continue;
}
else
{
//Victims = P;
P = none;
}
}
else
{
continue;
}
if( KFP == none )
{
//log(Level.TimeSeconds@"Hurting "$Victims$" for "$(damageScale * DamageAmount)$" damage");
if( Pawn(Victims) != none && Pawn(Victims).Health > 0 )
{
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++;
}
}
}
else
{
if(Instigator != none && KFP.Health > 0)
{
if ( KFP.bCanBeHealed )
{
PlayersHealed += 1;
MedicReward = HealBoostAmount;
PRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if ( PRI != none && PRI.ClientVeteranSkill != none )
{
MedicReward *= PRI.ClientVeteranSkill.Static.GetHealPotency(PRI);
}
HealSum = MedicReward;
if ( (KFP.Health + KFP.healthToGive + MedicReward) > KFP.HealthMax )
{
MedicReward = KFP.HealthMax - (KFP.Health + KFP.healthToGive);
if ( MedicReward < 0 )
{
MedicReward = 0;
}
}
//log(Level.TimeSeconds@"Healing "$KFP$" for "$HealSum$" base healamount "$HealBoostAmount$" health");
KFP.GiveHealth(HealSum, KFP.HealthMax);
KFP.ShieldStrength += HealSum * 0.25;
if(KFP.ShieldStrength > KFP.ShieldStrengthMax)
KFP.ShieldStrength = KFP.ShieldStrengthMax;
if ( PRI != none )
{
if ( MedicReward > 0 && KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements) != none )
{
KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements).AddDamageHealed(MedicReward, false, true);
}
// Give the medic reward money as a percentage of how much of the person's health they healed
MedicReward = int((FMin(float(MedicReward),KFP.HealthMax)/KFP.HealthMax) * 60);
PRI.ReceiveRewardForHealing( MedicReward, KFP );
if ( KFHumanPawn(Instigator) != none )
{
KFHumanPawn(Instigator).AlphaAmount = 255;
}
if( PlayerController(Instigator.Controller) != none )
{
PlayerController(Instigator.Controller).ClientMessage(SuccessfulHealMessage$KFP.GetPlayerName(), 'CriticalEvent');
}
}
}
}
}
KFP = none;
}
if (PlayersHealed >= MaxNumberOfPlayers)
{
if (PRI != none)
{
KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements).HealedTeamWithMedicGrenade();
}
}
}
bHurtEntry = false;
}
// Shoot nades in mid-air
// Alex
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
if ( Monster(instigatedBy) != none || instigatedBy == Instigator )
{
if( damageType == class'SirenScreamDamage')
{
Disintegrate(HitLocation, vect(0,0,1));
}
}
}
// Overridden to tweak the handling of the impact sound
simulated function HitWall( vector HitNormal, actor Wall )
{
local Vector VNorm;
local PlayerController PC;
if ( (Pawn(Wall) != none) || (GameObjective(Wall) != none) )
{
Explode(Location, HitNormal);
return;
}
if (!bTimerSet)
{
SetTimer(ExplodeTimer, false);
bTimerSet = true;
}
// Reflect off Wall w/damping
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
RandSpin(100000);
DesiredRotation.Roll = 0;
RotationRate.Roll = 0;
Speed = VSize(Velocity);
if ( Speed < 20 )
{
bBounce = False;
PrePivot.Z = -1.5;
SetPhysics(PHYS_none);
Timer();
SetTimer(0.0,False);
DesiredRotation = Rotation;
DesiredRotation.Roll = 0;
DesiredRotation.Pitch = 0;
SetRotation(DesiredRotation);
if( Fear == none )
{
//(jc) Changed to use MedicNade-specific grenade that's overridden to not make the ringmaster fear it
Fear = Spawn(class'AvoidMarker_MedicNade');
Fear.SetCollisionSize(DamageRadius,DamageRadius);
Fear.StartleBots();
}
if ( Trail != none )
Trail.mRegen = false; // stop the emitter from regenerating
}
else
{
if ( (Level.NetMode != NM_DedicatedServer) && (Speed > 50) )
PlaySound(ImpactSound, SLOT_Misc );
else
{
bFixedRotationDir = false;
bRotateToDesired = true;
DesiredRotation.Pitch = 0;
RotationRate.Pitch = 50000;
}
if ( !Level.bDropDetail && (Level.DetailMode != DM_Low) && (Level.TimeSeconds - LastSparkTime > 0.5) && EffectIsRelevant(Location,false) )
{
PC = Level.GetLocalPlayerController();
if ( (PC.ViewTarget != none) && VSize(PC.ViewTarget.Location - Location) < 6000 )
Spawn(HitEffectClass,,, Location, Rotator(HitNormal));
LastSparkTime = Level.TimeSeconds;
}
}
}
function Tick( float DeltaTime )
{
if( Role < ROLE_Authority )
{
return;
}
// if( class'ROEngine.ROLevelInfo'.static.RODebugMode() )
// {
// DrawDebugSphere( Location, DamageRadius, 12, 255, 0, 0);
// }
if( TotalHeals < MaxHeals && NextHealTime > 0 && NextHealTime < Level.TimeSeconds )
{
TotalHeals += 1;
HealOrHurt(Damage,DamageRadius, MyDamageType, MomentumTransfer, Location);
if( TotalHeals >= MaxHeals )
{
AmbientSound=none;
}
}
}
defaultproperties
{
HealBoostAmount=10
MaxHeals=8
HealInterval=1.000000
ExplosionSound=SoundGroup'KF_GrenadeSnd.NadeBase.MedicNade_Explode'
SuccessfulHealMessage="You healed "
MaxNumberOfPlayers=6
Damage=50.000000
DamageRadius=175.000000
MyDamageType=Class'KFMod.DamTypeMedicNade'
StaticMesh=StaticMesh'KF_pickups5_Trip.nades.MedicNade_Pickup'
DrawScale=1.000000
SoundVolume=150
SoundRadius=100.000000
TransientSoundVolume=2.000000
TransientSoundRadius=200.000000
}

View file

@ -1,158 +1,365 @@
class NiceMedicNadePoison extends Nade;
#exec OBJ LOAD FILE=KF_GrenadeSnd.uax
#exec OBJ LOAD FILE=Inf_WeaponsTwo.uax
#exec OBJ LOAD FILE=KF_LAWSnd.uax
var() int HealBoostAmount;// How much we heal a player by default with the medic nade
var int TotalHeals; // The total number of times this nade has healed (or hurt enemies)
var() int MaxHeals; // The total number of times this nade will heal (or hurt enemies) until its done healing
var float NextHealTime; // The next time that this nade will heal friendlies or hurt enemies
var() float HealInterval; // How often to do healing
var() sound ExplosionSound; // The sound of the rocket exploding
var localized string SuccessfulHealMessage;
var int MaxNumberOfPlayers;
var bool bNeedToPlayEffects; // Whether or not effects have been played yet
replication
{
reliable if (Role==ROLE_Authority) bNeedToPlayEffects;
}
simulated function PostNetReceive()
{
super.PostNetReceive();
if( !bHasExploded && bNeedToPlayEffects )
{ bNeedToPlayEffects = false; Explode(Location, vect(0,0,1));
}
}
simulated function Explode(vector HitLocation, vector HitNormal)
{
bHasExploded = True;
BlowUp(HitLocation);
PlaySound(ExplosionSound,,TransientSoundVolume);
if( Role == ROLE_Authority )
{ bNeedToPlayEffects = true; AmbientSound=Sound'Inf_WeaponsTwo.smoke_loop';
}
if ( EffectIsRelevant(Location,false) )
{ Spawn(Class'NicePack.NiceNadeHealingFast',,, HitLocation, rotator(vect(0,0,1)));
}
}
function Timer()
{
if( !bHidden )
{ if( !bHasExploded ) { Explode(Location, vect(0,0,1)); }
}
else if( bDisintegrated )
{ AmbientSound=none; Destroy();
}
}
simulated function BlowUp(vector HitLocation)
{
HealOrHurt(Damage,DamageRadius, MyDamageType, MomentumTransfer, HitLocation);
if ( Role == ROLE_Authority ) MakeNoise(1.0);
}
function HealOrHurt(float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation)
{
local actor Victims;
local float damageScale;
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;
// Healing
local KFPlayerReplicationInfo PRI;
local int MedicReward;
local float HealSum; // for modifying based on perks
local int PlayersHealed;
local NiceMonster niceZed;
if ( bHurtEntry ) return;
NextHealTime = Level.TimeSeconds + HealInterval;
bHurtEntry = true;
if( Fear != none )
{ Fear.StartleBots();
}
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;
damageScale = 1.0;
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 ) { damageScale *= KFP.GetExposureTo(Location + 15 * -Normal(PhysicsVolume.Gravity)); }
CheckedPawns[CheckedPawns.Length] = P;
if ( damageScale <= 0) { P = none; continue; } else { //Victims = P; P = none; } } else { continue; }
if( KFP == none ) { //log(Level.TimeSeconds@"Hurting "$Victims$" for "$(damageScale * DamageAmount)$" damage");
if(Pawn(Victims) != none && Pawn(Victims).Health > 0){ niceZed = NiceMonster(Victims); if(niceZed != none && niceZed.default.Health <= 500){ niceZed.madnessCountDown = FMax(5.0, niceZed.madnessCountDown); KFMonsterController(niceZed.Controller).FindNewEnemy(); } 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 ++; } } else { if( Instigator != none && KFP.Health > 0 && KFP.Health < KFP.HealthMax ) { if ( KFP.bCanBeHealed ) { PlayersHealed += 1; MedicReward = HealBoostAmount;
PRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if ( PRI != none && PRI.ClientVeteranSkill != none ) { MedicReward *= PRI.ClientVeteranSkill.Static.GetHealPotency(PRI); }
HealSum = MedicReward;
if ( (KFP.Health + KFP.healthToGive + MedicReward) > KFP.HealthMax ) { MedicReward = KFP.HealthMax - (KFP.Health + KFP.healthToGive); if ( MedicReward < 0 ) { MedicReward = 0; } }
//log(Level.TimeSeconds@"Healing "$KFP$" for "$HealSum$" base healamount "$HealBoostAmount$" health"); KFP.GiveHealth(HealSum, KFP.HealthMax);
if ( PRI != none ) { if ( MedicReward > 0 && KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements) != none ) { KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements).AddDamageHealed(MedicReward, false, true); }
// Give the medic reward money as a percentage of how much of the person's health they healed MedicReward = int((FMin(float(MedicReward),KFP.HealthMax)/KFP.HealthMax) * 60);
PRI.ReceiveRewardForHealing( MedicReward, KFP );
if ( KFHumanPawn(Instigator) != none ) { KFHumanPawn(Instigator).AlphaAmount = 255; }
if( PlayerController(Instigator.Controller) != none ) { PlayerController(Instigator.Controller).ClientMessage(SuccessfulHealMessage$KFP.GetPlayerName(), 'CriticalEvent'); } } } } }
KFP = none; }
if (PlayersHealed >= MaxNumberOfPlayers) { if (PRI != none) { KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements).HealedTeamWithMedicGrenade(); } }
}
bHurtEntry = false;
}
// Shoot nades in mid-air
// Alex
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
if ( Monster(instigatedBy) != none || instigatedBy == Instigator )
{ if( damageType == class'SirenScreamDamage') { Disintegrate(HitLocation, vect(0,0,1)); }
}
}
// Overridden to tweak the handling of the impact sound
simulated function HitWall( vector HitNormal, actor Wall )
{
local Vector VNorm;
local PlayerController PC;
if ( (Pawn(Wall) != none) || (GameObjective(Wall) != none) )
{ Explode(Location, HitNormal); return;
}
if (!bTimerSet)
{ SetTimer(ExplodeTimer, false); bTimerSet = true;
}
// Reflect off Wall w/damping
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
RandSpin(100000);
DesiredRotation.Roll = 0;
RotationRate.Roll = 0;
Speed = VSize(Velocity);
if ( Speed < 20 )
{ bBounce = False; PrePivot.Z = -1.5; SetPhysics(PHYS_none); Timer(); SetTimer(0.0,False); DesiredRotation = Rotation; DesiredRotation.Roll = 0; DesiredRotation.Pitch = 0; SetRotation(DesiredRotation);
if( Fear == none ) { //(jc) Changed to use MedicNade-specific grenade that's overridden to not make the ringmaster fear it Fear = Spawn(class'AvoidMarker_MedicNade'); Fear.SetCollisionSize(DamageRadius,DamageRadius); Fear.StartleBots(); }
if ( Trail != none ) Trail.mRegen = false; // stop the emitter from regenerating
}
else
{ if ( (Level.NetMode != NM_DedicatedServer) && (Speed > 50) ) PlaySound(ImpactSound, SLOT_Misc ); else { bFixedRotationDir = false; bRotateToDesired = true; DesiredRotation.Pitch = 0; RotationRate.Pitch = 50000; } if ( !Level.bDropDetail && (Level.DetailMode != DM_Low) && (Level.TimeSeconds - LastSparkTime > 0.5) && EffectIsRelevant(Location,false) ) { PC = Level.GetLocalPlayerController(); if ( (PC.ViewTarget != none) && VSize(PC.ViewTarget.Location - Location) < 6000 ) Spawn(HitEffectClass,,, Location, Rotator(HitNormal)); LastSparkTime = Level.TimeSeconds; }
}
}
function Tick( float DeltaTime )
{
if( Role < ROLE_Authority )
{ return;
}
// if( class'ROEngine.ROLevelInfo'.static.RODebugMode() )
// {
// DrawDebugSphere( Location, DamageRadius, 12, 255, 0, 0);
// }
if( TotalHeals < MaxHeals && NextHealTime > 0 && NextHealTime < Level.TimeSeconds )
{ TotalHeals += 1;
HealOrHurt(Damage,DamageRadius, MyDamageType, MomentumTransfer, Location);
if( TotalHeals >= MaxHeals ) { AmbientSound=none; }
}
}
defaultproperties
{ HealBoostAmount=10 MaxHeals=4 HealInterval=1.000000 ExplosionSound=SoundGroup'KF_GrenadeSnd.NadeBase.MedicNade_Explode' SuccessfulHealMessage="You healed " MaxNumberOfPlayers=6 Damage=50.000000 DamageRadius=175.000000 MyDamageType=Class'KFMod.DamTypeMedicNade' StaticMesh=StaticMesh'KF_pickups5_Trip.nades.MedicNade_Pickup' LifeSpan=8.000000 DrawScale=1.000000 SoundVolume=150 SoundRadius=100.000000 TransientSoundVolume=2.000000 TransientSoundRadius=200.000000
}
class NiceMedicNadePoison extends Nade;
#exec OBJ LOAD FILE=KF_GrenadeSnd.uax
#exec OBJ LOAD FILE=Inf_WeaponsTwo.uax
#exec OBJ LOAD FILE=KF_LAWSnd.uax
var() int HealBoostAmount;// How much we heal a player by default with the medic nade
var int TotalHeals; // The total number of times this nade has healed (or hurt enemies)
var() int MaxHeals; // The total number of times this nade will heal (or hurt enemies) until its done healing
var float NextHealTime; // The next time that this nade will heal friendlies or hurt enemies
var() float HealInterval; // How often to do healing
var() sound ExplosionSound; // The sound of the rocket exploding
var localized string SuccessfulHealMessage;
var int MaxNumberOfPlayers;
var bool bNeedToPlayEffects; // Whether or not effects have been played yet
replication
{
reliable if (Role==ROLE_Authority)
bNeedToPlayEffects;
}
simulated function PostNetReceive()
{
super.PostNetReceive();
if( !bHasExploded && bNeedToPlayEffects )
{
bNeedToPlayEffects = false;
Explode(Location, vect(0,0,1));
}
}
simulated function Explode(vector HitLocation, vector HitNormal)
{
bHasExploded = True;
BlowUp(HitLocation);
PlaySound(ExplosionSound,,TransientSoundVolume);
if( Role == ROLE_Authority )
{
bNeedToPlayEffects = true;
AmbientSound=Sound'Inf_WeaponsTwo.smoke_loop';
}
if ( EffectIsRelevant(Location,false) )
{
Spawn(Class'NicePack.NiceNadeHealingFast',,, HitLocation, rotator(vect(0,0,1)));
}
}
function Timer()
{
if( !bHidden )
{
if( !bHasExploded )
{
Explode(Location, vect(0,0,1));
}
}
else if( bDisintegrated )
{
AmbientSound=none;
Destroy();
}
}
simulated function BlowUp(vector HitLocation)
{
HealOrHurt(Damage,DamageRadius, MyDamageType, MomentumTransfer, HitLocation);
if ( Role == ROLE_Authority )
MakeNoise(1.0);
}
function HealOrHurt(float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation)
{
local actor Victims;
local float damageScale;
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;
// Healing
local KFPlayerReplicationInfo PRI;
local int MedicReward;
local float HealSum; // for modifying based on perks
local int PlayersHealed;
local NiceMonster niceZed;
if ( bHurtEntry )
return;
NextHealTime = Level.TimeSeconds + HealInterval;
bHurtEntry = true;
if( Fear != none )
{
Fear.StartleBots();
}
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;
damageScale = 1.0;
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 )
{
damageScale *= KFP.GetExposureTo(Location + 15 * -Normal(PhysicsVolume.Gravity));
}
CheckedPawns[CheckedPawns.Length] = P;
if ( damageScale <= 0)
{
P = none;
continue;
}
else
{
//Victims = P;
P = none;
}
}
else
{
continue;
}
if( KFP == none )
{
//log(Level.TimeSeconds@"Hurting "$Victims$" for "$(damageScale * DamageAmount)$" damage");
if(Pawn(Victims) != none && Pawn(Victims).Health > 0){
niceZed = NiceMonster(Victims);
if(niceZed != none && niceZed.default.Health <= 500){
niceZed.madnessCountDown = FMax(5.0, niceZed.madnessCountDown);
KFMonsterController(niceZed.Controller).FindNewEnemy();
}
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 ++;
}
}
else
{
if( Instigator != none && KFP.Health > 0 && KFP.Health < KFP.HealthMax )
{
if ( KFP.bCanBeHealed )
{
PlayersHealed += 1;
MedicReward = HealBoostAmount;
PRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if ( PRI != none && PRI.ClientVeteranSkill != none )
{
MedicReward *= PRI.ClientVeteranSkill.Static.GetHealPotency(PRI);
}
HealSum = MedicReward;
if ( (KFP.Health + KFP.healthToGive + MedicReward) > KFP.HealthMax )
{
MedicReward = KFP.HealthMax - (KFP.Health + KFP.healthToGive);
if ( MedicReward < 0 )
{
MedicReward = 0;
}
}
//log(Level.TimeSeconds@"Healing "$KFP$" for "$HealSum$" base healamount "$HealBoostAmount$" health");
KFP.GiveHealth(HealSum, KFP.HealthMax);
if ( PRI != none )
{
if ( MedicReward > 0 && KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements) != none )
{
KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements).AddDamageHealed(MedicReward, false, true);
}
// Give the medic reward money as a percentage of how much of the person's health they healed
MedicReward = int((FMin(float(MedicReward),KFP.HealthMax)/KFP.HealthMax) * 60);
PRI.ReceiveRewardForHealing( MedicReward, KFP );
if ( KFHumanPawn(Instigator) != none )
{
KFHumanPawn(Instigator).AlphaAmount = 255;
}
if( PlayerController(Instigator.Controller) != none )
{
PlayerController(Instigator.Controller).ClientMessage(SuccessfulHealMessage$KFP.GetPlayerName(), 'CriticalEvent');
}
}
}
}
}
KFP = none;
}
if (PlayersHealed >= MaxNumberOfPlayers)
{
if (PRI != none)
{
KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements).HealedTeamWithMedicGrenade();
}
}
}
bHurtEntry = false;
}
// Shoot nades in mid-air
// Alex
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
if ( Monster(instigatedBy) != none || instigatedBy == Instigator )
{
if( damageType == class'SirenScreamDamage')
{
Disintegrate(HitLocation, vect(0,0,1));
}
}
}
// Overridden to tweak the handling of the impact sound
simulated function HitWall( vector HitNormal, actor Wall )
{
local Vector VNorm;
local PlayerController PC;
if ( (Pawn(Wall) != none) || (GameObjective(Wall) != none) )
{
Explode(Location, HitNormal);
return;
}
if (!bTimerSet)
{
SetTimer(ExplodeTimer, false);
bTimerSet = true;
}
// Reflect off Wall w/damping
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
RandSpin(100000);
DesiredRotation.Roll = 0;
RotationRate.Roll = 0;
Speed = VSize(Velocity);
if ( Speed < 20 )
{
bBounce = False;
PrePivot.Z = -1.5;
SetPhysics(PHYS_none);
Timer();
SetTimer(0.0,False);
DesiredRotation = Rotation;
DesiredRotation.Roll = 0;
DesiredRotation.Pitch = 0;
SetRotation(DesiredRotation);
if( Fear == none )
{
//(jc) Changed to use MedicNade-specific grenade that's overridden to not make the ringmaster fear it
Fear = Spawn(class'AvoidMarker_MedicNade');
Fear.SetCollisionSize(DamageRadius,DamageRadius);
Fear.StartleBots();
}
if ( Trail != none )
Trail.mRegen = false; // stop the emitter from regenerating
}
else
{
if ( (Level.NetMode != NM_DedicatedServer) && (Speed > 50) )
PlaySound(ImpactSound, SLOT_Misc );
else
{
bFixedRotationDir = false;
bRotateToDesired = true;
DesiredRotation.Pitch = 0;
RotationRate.Pitch = 50000;
}
if ( !Level.bDropDetail && (Level.DetailMode != DM_Low) && (Level.TimeSeconds - LastSparkTime > 0.5) && EffectIsRelevant(Location,false) )
{
PC = Level.GetLocalPlayerController();
if ( (PC.ViewTarget != none) && VSize(PC.ViewTarget.Location - Location) < 6000 )
Spawn(HitEffectClass,,, Location, Rotator(HitNormal));
LastSparkTime = Level.TimeSeconds;
}
}
}
function Tick( float DeltaTime )
{
if( Role < ROLE_Authority )
{
return;
}
// if( class'ROEngine.ROLevelInfo'.static.RODebugMode() )
// {
// DrawDebugSphere( Location, DamageRadius, 12, 255, 0, 0);
// }
if( TotalHeals < MaxHeals && NextHealTime > 0 && NextHealTime < Level.TimeSeconds )
{
TotalHeals += 1;
HealOrHurt(Damage,DamageRadius, MyDamageType, MomentumTransfer, Location);
if( TotalHeals >= MaxHeals )
{
AmbientSound=none;
}
}
}
defaultproperties
{
HealBoostAmount=10
MaxHeals=4
HealInterval=1.000000
ExplosionSound=SoundGroup'KF_GrenadeSnd.NadeBase.MedicNade_Explode'
SuccessfulHealMessage="You healed "
MaxNumberOfPlayers=6
Damage=50.000000
DamageRadius=175.000000
MyDamageType=Class'KFMod.DamTypeMedicNade'
StaticMesh=StaticMesh'KF_pickups5_Trip.nades.MedicNade_Pickup'
LifeSpan=8.000000
DrawScale=1.000000
SoundVolume=150
SoundRadius=100.000000
TransientSoundVolume=2.000000
TransientSoundRadius=200.000000
}

View file

@ -1,91 +1,215 @@
class NiceNade extends ScrnNade;
var class<NiceAvoidMarker> AvoidMarkerClass;
var class<NiceWeaponDamageType> niceExplosiveDamage;
// Overloaded to implement nade skills
simulated function Explode(vector HitLocation, vector HitNormal){
local PlayerController LocalPlayer;
local Projectile P;
local byte i;
bHasExploded = true;
BlowUp(HitLocation);
// null reference fix
if(ExplodeSounds.length > 0) PlaySound(ExplodeSounds[rand(ExplodeSounds.length)],,2.0);
for(i = Rand(6);i < 10;i ++){ P = Spawn(ShrapnelClass,,,,RotRand(True)); if(P != none) P.RemoteRole = ROLE_None;
}
for(i = Rand(6);i < 10;i ++){ P = Spawn(ShrapnelClass,,,,RotRand(True)); if(P != none) P.RemoteRole = ROLE_none;
}
if(EffectIsRelevant(Location,false)){ Spawn(Class'KFmod.KFNadeExplosion',,, HitLocation, rotator(vect(0,0,1))); Spawn(ExplosionDecal, self,, HitLocation, rotator(-HitNormal));
}
// Shake nearby players screens
LocalPlayer = Level.GetLocalPlayerController();
if((LocalPlayer != none) && (VSize(Location - LocalPlayer.ViewTarget.Location) < (DamageRadius * 1.5))) LocalPlayer.ShakeView(RotMag, RotRate, RotTime, OffsetMag, OffsetRate, OffsetTime);
Destroy();
}
function TakeDamage(int Damage, Pawn InstigatedBy, Vector HitLocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex){
if(Monster(instigatedBy) != none || instigatedBy == Instigator){ if(DamageType == class'SirenScreamDamage') Disintegrate(HitLocation, vect(0,0,1)); else 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;
// 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 ) 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;
// Scrake Nader ach if ( Role == ROLE_Authority && KFMonsterVictim != none && ZombieScrake(KFMonsterVictim) != none ) { // need to check Scrake's stun before dealing damage, because he can unstun by himself from damage received ScrakeNader(damageScale * DamageAmount, ZombieScrake(KFMonsterVictim), Stats); } } 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'ScrnBalanceSrv.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
simulated function HitWall( vector HitNormal, actor Wall ){
local Vector VNorm;
local PlayerController PC;
if((Pawn(Wall) != none) || (GameObjective(Wall) != none)){ Explode(Location, HitNormal); return;
}
if(!bTimerSet){ SetTimer(ExplodeTimer, false); bTimerSet = true;
}
// Reflect off Wall w/damping
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
RandSpin(100000);
DesiredRotation.Roll = 0;
RotationRate.Roll = 0;
Speed = VSize(Velocity);
if(Speed < 20){ bBounce = false; PrePivot.Z = -1.5; SetPhysics(PHYS_none); DesiredRotation = Rotation; DesiredRotation.Roll = 0; DesiredRotation.Pitch = 0; SetRotation(DesiredRotation);
if(Fear == none){ Fear = Spawn(AvoidMarkerClass); Fear.SetCollisionSize(DamageRadius, DamageRadius); Fear.StartleBots(); }
if(Trail != none) Trail.mRegen = false; // stop the emitter from regenerating
}
else{ if((Level.NetMode != NM_DedicatedServer) && (Speed > 50)) PlaySound(ImpactSound, SLOT_Misc ); else{ bFixedRotationDir = false; bRotateToDesired = true; DesiredRotation.Pitch = 0; RotationRate.Pitch = 50000; } if(!Level.bDropDetail && (Level.DetailMode != DM_Low) && (Level.TimeSeconds - LastSparkTime > 0.5) && EffectIsRelevant(Location,false)){ PC = Level.GetLocalPlayerController(); if ( (PC.ViewTarget != none) && VSize(PC.ViewTarget.Location - Location) < 6000 ) Spawn(HitEffectClass,,, Location, Rotator(HitNormal)); LastSparkTime = Level.TimeSeconds; }
}
}
defaultproperties
{ AvoidMarkerClass=Class'NicePack.NiceAvoidMarkerExplosive' niceExplosiveDamage=Class'NicePack.NiceDamTypeDemoExplosion'
}
class NiceNade extends ScrnNade;
var class<NiceAvoidMarker> AvoidMarkerClass;
var class<NiceWeaponDamageType> niceExplosiveDamage;
// Overloaded to implement nade skills
simulated function Explode(vector HitLocation, vector HitNormal){
local PlayerController LocalPlayer;
local Projectile P;
local byte i;
bHasExploded = true;
BlowUp(HitLocation);
// null reference fix
if(ExplodeSounds.length > 0)
PlaySound(ExplodeSounds[rand(ExplodeSounds.length)],,2.0);
for(i = Rand(6);i < 10;i ++){
P = Spawn(ShrapnelClass,,,,RotRand(True));
if(P != none)
P.RemoteRole = ROLE_None;
}
for(i = Rand(6);i < 10;i ++){
P = Spawn(ShrapnelClass,,,,RotRand(True));
if(P != none)
P.RemoteRole = ROLE_none;
}
if(EffectIsRelevant(Location,false)){
Spawn(Class'KFmod.KFNadeExplosion',,, HitLocation, rotator(vect(0,0,1)));
Spawn(ExplosionDecal, self,, HitLocation, rotator(-HitNormal));
}
// Shake nearby players screens
LocalPlayer = Level.GetLocalPlayerController();
if((LocalPlayer != none) && (VSize(Location - LocalPlayer.ViewTarget.Location) < (DamageRadius * 1.5)))
LocalPlayer.ShakeView(RotMag, RotRate, RotTime, OffsetMag, OffsetRate, OffsetTime);
Destroy();
}
function TakeDamage(int Damage, Pawn InstigatedBy, Vector HitLocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex){
if(Monster(instigatedBy) != none || instigatedBy == Instigator){
if(DamageType == class'SirenScreamDamage')
Disintegrate(HitLocation, vect(0,0,1));
else
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;
// 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 )
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;
// Scrake Nader ach
if ( Role == ROLE_Authority && KFMonsterVictim != none && ZombieScrake(KFMonsterVictim) != none ) {
// need to check Scrake's stun before dealing damage, because he can unstun by himself from damage received
ScrakeNader(damageScale * DamageAmount, ZombieScrake(KFMonsterVictim), Stats);
}
}
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'ScrnBalanceSrv.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
simulated function HitWall( vector HitNormal, actor Wall ){
local Vector VNorm;
local PlayerController PC;
if((Pawn(Wall) != none) || (GameObjective(Wall) != none)){
Explode(Location, HitNormal);
return;
}
if(!bTimerSet){
SetTimer(ExplodeTimer, false);
bTimerSet = true;
}
// Reflect off Wall w/damping
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
RandSpin(100000);
DesiredRotation.Roll = 0;
RotationRate.Roll = 0;
Speed = VSize(Velocity);
if(Speed < 20){
bBounce = false;
PrePivot.Z = -1.5;
SetPhysics(PHYS_none);
DesiredRotation = Rotation;
DesiredRotation.Roll = 0;
DesiredRotation.Pitch = 0;
SetRotation(DesiredRotation);
if(Fear == none){
Fear = Spawn(AvoidMarkerClass);
Fear.SetCollisionSize(DamageRadius, DamageRadius);
Fear.StartleBots();
}
if(Trail != none)
Trail.mRegen = false; // stop the emitter from regenerating
}
else{
if((Level.NetMode != NM_DedicatedServer) && (Speed > 50))
PlaySound(ImpactSound, SLOT_Misc );
else{
bFixedRotationDir = false;
bRotateToDesired = true;
DesiredRotation.Pitch = 0;
RotationRate.Pitch = 50000;
}
if(!Level.bDropDetail && (Level.DetailMode != DM_Low) && (Level.TimeSeconds - LastSparkTime > 0.5) && EffectIsRelevant(Location,false)){
PC = Level.GetLocalPlayerController();
if ( (PC.ViewTarget != none) && VSize(PC.ViewTarget.Location - Location) < 6000 )
Spawn(HitEffectClass,,, Location, Rotator(HitNormal));
LastSparkTime = Level.TimeSeconds;
}
}
}
defaultproperties
{
AvoidMarkerClass=Class'NicePack.NiceAvoidMarkerExplosive'
niceExplosiveDamage=Class'NicePack.NiceDamTypeDemoExplosion'
}

View file

@ -1,22 +1,57 @@
class NiceNadeHealing extends Emitter;
var bool bFlashed;
simulated function PostBeginPlay()
{
Super.Postbeginplay();
NadeLight();
}
simulated function NadeLight()
{
if ( !Level.bDropDetail && (Instigator != none) && ((Level.TimeSeconds - LastRenderTime < 0.2) || (PlayerController(Instigator.Controller) != none)) )
{ bDynamicLight = true; SetTimer(0.25, false);
}
else Timer();
}
simulated function Timer()
{
bDynamicLight = false;
}
defaultproperties
{ Begin Object Class=SpriteEmitter Name=SpriteEmitter0 UseColorScale=True RespawnDeadParticles=False SpinParticles=True UseSizeScale=True UseRegularSizeScale=False UniformSize=True AutomaticInitialSpawning=False BlendBetweenSubdivisions=True ColorScale(0)=(Color=(B=255,G=128,A=255)) ColorScale(1)=(RelativeTime=1.000000,Color=(B=161,G=61,R=61,A=255)) FadeOutFactor=(W=0.000000,X=0.000000,Y=0.000000,Z=0.000000) FadeOutStartTime=5.000000 SpinsPerSecondRange=(Y=(Min=0.050000,Max=0.100000),Z=(Min=0.050000,Max=0.100000)) StartSpinRange=(X=(Min=-0.500000,Max=0.500000),Y=(Max=1.000000),Z=(Max=1.000000)) SizeScale(0)=(RelativeSize=1.000000) SizeScale(1)=(RelativeTime=1.000000,RelativeSize=5.000000) StartSizeRange=(X=(Min=40.000000,Max=40.000000),Y=(Min=40.000000,Max=40.000000),Z=(Min=40.000000,Max=40.000000)) InitialParticlesPerSecond=5000.000000 DrawStyle=PTDS_AlphaBlend Texture=Texture'kf_fx_trip_t.Misc.smoke_animated' TextureUSubdivisions=8 TextureVSubdivisions=8 LifetimeRange=(Min=7.000000,Max=7.000000) StartVelocityRange=(X=(Min=-750.000000,Max=750.000000),Y=(Min=-750.000000,Max=750.000000)) VelocityLossRange=(X=(Min=10.000000,Max=10.000000),Y=(Min=10.000000,Max=10.000000),Z=(Min=10.000000,Max=10.000000)) End Object Emitters(0)=SpriteEmitter'NicePack.NiceNadeHealing.SpriteEmitter0'
AutoDestroy=True bNoDelete=False RemoteRole=ROLE_SimulatedProxy bNotOnDedServer=False
}
class NiceNadeHealing extends Emitter;
var bool bFlashed;
simulated function PostBeginPlay()
{
Super.Postbeginplay();
NadeLight();
}
simulated function NadeLight()
{
if ( !Level.bDropDetail && (Instigator != none)
&& ((Level.TimeSeconds - LastRenderTime < 0.2) || (PlayerController(Instigator.Controller) != none)) )
{
bDynamicLight = true;
SetTimer(0.25, false);
}
else Timer();
}
simulated function Timer()
{
bDynamicLight = false;
}
defaultproperties
{
Begin Object Class=SpriteEmitter Name=SpriteEmitter0
UseColorScale=True
RespawnDeadParticles=False
SpinParticles=True
UseSizeScale=True
UseRegularSizeScale=False
UniformSize=True
AutomaticInitialSpawning=False
BlendBetweenSubdivisions=True
ColorScale(0)=(Color=(B=255,G=128,A=255))
ColorScale(1)=(RelativeTime=1.000000,Color=(B=161,G=61,R=61,A=255))
FadeOutFactor=(W=0.000000,X=0.000000,Y=0.000000,Z=0.000000)
FadeOutStartTime=5.000000
SpinsPerSecondRange=(Y=(Min=0.050000,Max=0.100000),Z=(Min=0.050000,Max=0.100000))
StartSpinRange=(X=(Min=-0.500000,Max=0.500000),Y=(Max=1.000000),Z=(Max=1.000000))
SizeScale(0)=(RelativeSize=1.000000)
SizeScale(1)=(RelativeTime=1.000000,RelativeSize=5.000000)
StartSizeRange=(X=(Min=40.000000,Max=40.000000),Y=(Min=40.000000,Max=40.000000),Z=(Min=40.000000,Max=40.000000))
InitialParticlesPerSecond=5000.000000
DrawStyle=PTDS_AlphaBlend
Texture=Texture'kf_fx_trip_t.Misc.smoke_animated'
TextureUSubdivisions=8
TextureVSubdivisions=8
LifetimeRange=(Min=7.000000,Max=7.000000)
StartVelocityRange=(X=(Min=-750.000000,Max=750.000000),Y=(Min=-750.000000,Max=750.000000))
VelocityLossRange=(X=(Min=10.000000,Max=10.000000),Y=(Min=10.000000,Max=10.000000),Z=(Min=10.000000,Max=10.000000))
End Object
Emitters(0)=SpriteEmitter'NicePack.NiceNadeHealing.SpriteEmitter0'
AutoDestroy=True
bNoDelete=False
RemoteRole=ROLE_SimulatedProxy
bNotOnDedServer=False
}

View file

@ -1,22 +1,57 @@
class NiceNadeHealingFast extends Emitter;
var bool bFlashed;
simulated function PostBeginPlay()
{
Super.Postbeginplay();
NadeLight();
}
simulated function NadeLight()
{
if ( !Level.bDropDetail && (Instigator != none) && ((Level.TimeSeconds - LastRenderTime < 0.2) || (PlayerController(Instigator.Controller) != none)) )
{ bDynamicLight = true; SetTimer(0.25, false);
}
else Timer();
}
simulated function Timer()
{
bDynamicLight = false;
}
defaultproperties
{ Begin Object Class=SpriteEmitter Name=SpriteEmitter0 UseColorScale=True RespawnDeadParticles=False SpinParticles=True UseSizeScale=True UseRegularSizeScale=False UniformSize=True AutomaticInitialSpawning=False BlendBetweenSubdivisions=True ColorScale(0)=(Color=(G=255,R=200,A=255)) ColorScale(1)=(RelativeTime=1.000000,Color=(B=61,G=105,R=105,A=255)) FadeOutFactor=(W=0.000000,X=0.000000,Y=0.000000,Z=0.000000) FadeOutStartTime=5.000000 SpinsPerSecondRange=(Y=(Min=0.050000,Max=0.100000),Z=(Min=0.050000,Max=0.100000)) StartSpinRange=(X=(Min=-0.500000,Max=0.500000),Y=(Max=1.000000),Z=(Max=1.000000)) SizeScale(0)=(RelativeSize=1.000000) SizeScale(1)=(RelativeTime=1.000000,RelativeSize=5.000000) StartSizeRange=(X=(Min=40.000000,Max=40.000000),Y=(Min=40.000000,Max=40.000000),Z=(Min=40.000000,Max=40.000000)) InitialParticlesPerSecond=5000.000000 DrawStyle=PTDS_AlphaBlend Texture=Texture'kf_fx_trip_t.Misc.smoke_animated' TextureUSubdivisions=8 TextureVSubdivisions=8 LifetimeRange=(Min=3.000000,Max=3.000000) StartVelocityRange=(X=(Min=-750.000000,Max=750.000000),Y=(Min=-750.000000,Max=750.000000)) VelocityLossRange=(X=(Min=10.000000,Max=10.000000),Y=(Min=10.000000,Max=10.000000),Z=(Min=10.000000,Max=10.000000)) End Object Emitters(0)=SpriteEmitter'NicePack.NiceNadeHealingFast.SpriteEmitter0'
AutoDestroy=True bNoDelete=False RemoteRole=ROLE_SimulatedProxy bNotOnDedServer=False
}
class NiceNadeHealingFast extends Emitter;
var bool bFlashed;
simulated function PostBeginPlay()
{
Super.Postbeginplay();
NadeLight();
}
simulated function NadeLight()
{
if ( !Level.bDropDetail && (Instigator != none)
&& ((Level.TimeSeconds - LastRenderTime < 0.2) || (PlayerController(Instigator.Controller) != none)) )
{
bDynamicLight = true;
SetTimer(0.25, false);
}
else Timer();
}
simulated function Timer()
{
bDynamicLight = false;
}
defaultproperties
{
Begin Object Class=SpriteEmitter Name=SpriteEmitter0
UseColorScale=True
RespawnDeadParticles=False
SpinParticles=True
UseSizeScale=True
UseRegularSizeScale=False
UniformSize=True
AutomaticInitialSpawning=False
BlendBetweenSubdivisions=True
ColorScale(0)=(Color=(G=255,R=200,A=255))
ColorScale(1)=(RelativeTime=1.000000,Color=(B=61,G=105,R=105,A=255))
FadeOutFactor=(W=0.000000,X=0.000000,Y=0.000000,Z=0.000000)
FadeOutStartTime=5.000000
SpinsPerSecondRange=(Y=(Min=0.050000,Max=0.100000),Z=(Min=0.050000,Max=0.100000))
StartSpinRange=(X=(Min=-0.500000,Max=0.500000),Y=(Max=1.000000),Z=(Max=1.000000))
SizeScale(0)=(RelativeSize=1.000000)
SizeScale(1)=(RelativeTime=1.000000,RelativeSize=5.000000)
StartSizeRange=(X=(Min=40.000000,Max=40.000000),Y=(Min=40.000000,Max=40.000000),Z=(Min=40.000000,Max=40.000000))
InitialParticlesPerSecond=5000.000000
DrawStyle=PTDS_AlphaBlend
Texture=Texture'kf_fx_trip_t.Misc.smoke_animated'
TextureUSubdivisions=8
TextureVSubdivisions=8
LifetimeRange=(Min=3.000000,Max=3.000000)
StartVelocityRange=(X=(Min=-750.000000,Max=750.000000),Y=(Min=-750.000000,Max=750.000000))
VelocityLossRange=(X=(Min=10.000000,Max=10.000000),Y=(Min=10.000000,Max=10.000000),Z=(Min=10.000000,Max=10.000000))
End Object
Emitters(0)=SpriteEmitter'NicePack.NiceNadeHealingFast.SpriteEmitter0'
AutoDestroy=True
bNoDelete=False
RemoteRole=ROLE_SimulatedProxy
bNotOnDedServer=False
}