Fix formatting #1 #27
@ -12,6 +12,7 @@
|
|||||||
// E-mail: dkanus@gmail.com
|
// E-mail: dkanus@gmail.com
|
||||||
//======================================================================================================================
|
//======================================================================================================================
|
||||||
class NiceBullet extends Actor;
|
class NiceBullet extends Actor;
|
||||||
|
|
||||||
// Link to interaction with the server
|
// Link to interaction with the server
|
||||||
var NiceReplicationInfo niceRI;
|
var NiceReplicationInfo niceRI;
|
||||||
// Controller of our instigator
|
// Controller of our instigator
|
||||||
@ -20,7 +21,6 @@ var NicePlayerController nicePlayer;
|
|||||||
var NicePlayerController localPlayer;
|
var NicePlayerController localPlayer;
|
||||||
// Link to our mutator
|
// Link to our mutator
|
||||||
var NicePack niceMutator;
|
var NicePack niceMutator;
|
||||||
|
|
||||||
//======================================================================================================================
|
//======================================================================================================================
|
||||||
// Battle bullet characteristic
|
// Battle bullet characteristic
|
||||||
var float charOrigDamage;
|
var float charOrigDamage;
|
||||||
@ -180,22 +180,29 @@ var string ambientSoundRef;
|
|||||||
//======================================================================================================================
|
//======================================================================================================================
|
||||||
// Functions
|
// Functions
|
||||||
static function PreloadAssets() {
|
static function PreloadAssets() {
|
||||||
if(default.ambientSound == none && default.ambientSoundRef != "")
|
if (default.ambientSound == none && default.ambientSoundRef != "") {
|
||||||
default.ambientSound = sound(DynamicLoadObject(default.ambientSoundRef, class'Sound', true));
|
default.ambientSound = sound(DynamicLoadObject(default.ambientSoundRef, class'Sound', true));
|
||||||
if(default.staticMesh == none && default.staticMeshRef != "")
|
}
|
||||||
|
if (default.staticMesh == none && default.staticMeshRef != "") {
|
||||||
UpdateDefaultStaticMesh(StaticMesh(DynamicLoadObject(default.staticMeshRef, class'StaticMesh', true)));
|
UpdateDefaultStaticMesh(StaticMesh(DynamicLoadObject(default.staticMeshRef, class'StaticMesh', true)));
|
||||||
if(default.mesh == none && default.meshRef != "")
|
}
|
||||||
|
if (default.mesh == none && default.meshRef != "") {
|
||||||
UpdateDefaultMesh(Mesh(DynamicLoadObject(default.meshRef, class'Mesh', true)));
|
UpdateDefaultMesh(Mesh(DynamicLoadObject(default.meshRef, class'Mesh', true)));
|
||||||
if(default.regularImpact.noise == none && default.regularImpact.noiseRef != "")
|
}
|
||||||
|
if (default.regularImpact.noise == none && default.regularImpact.noiseRef != "") {
|
||||||
default.regularImpact.noise =
|
default.regularImpact.noise =
|
||||||
sound(DynamicLoadObject(default.regularImpact.noiseRef, class'Sound', true));
|
sound(DynamicLoadObject(default.regularImpact.noiseRef, class'Sound', true));
|
||||||
if(default.explosionImpact.noise == none && default.explosionImpact.noiseRef != "")
|
}
|
||||||
|
if (default.explosionImpact.noise == none && default.explosionImpact.noiseRef != "") {
|
||||||
default.explosionImpact.noise =
|
default.explosionImpact.noise =
|
||||||
sound(DynamicLoadObject(default.explosionImpact.noiseRef, class'Sound', true));
|
sound(DynamicLoadObject(default.explosionImpact.noiseRef, class'Sound', true));
|
||||||
if(default.disintegrationImpact.noise == none && default.disintegrationImpact.noiseRef != "")
|
}
|
||||||
|
if (default.disintegrationImpact.noise == none && default.disintegrationImpact.noiseRef != "") {
|
||||||
default.disintegrationImpact.noise =
|
default.disintegrationImpact.noise =
|
||||||
sound(DynamicLoadObject(default.disintegrationImpact.noiseRef, class'Sound', true));
|
sound(DynamicLoadObject(default.disintegrationImpact.noiseRef, class'Sound', true));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static function bool UnloadAssets() {
|
static function bool UnloadAssets() {
|
||||||
default.AmbientSound = none;
|
default.AmbientSound = none;
|
||||||
UpdateDefaultStaticMesh(none);
|
UpdateDefaultStaticMesh(none);
|
||||||
@ -205,20 +212,26 @@ static function bool UnloadAssets(){
|
|||||||
default.disintegrationImpact.noise = none;
|
default.disintegrationImpact.noise = none;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function PostBeginPlay() {
|
function PostBeginPlay() {
|
||||||
super.PostBeginPlay();
|
super.PostBeginPlay();
|
||||||
bounceHeadMod = 1.0;
|
bounceHeadMod = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function UpdateTrails() {
|
function UpdateTrails() {
|
||||||
local Actor trailBase;
|
local Actor trailBase;
|
||||||
|
|
||||||
// Do nothing on dedicated server
|
// Do nothing on dedicated server
|
||||||
if(Level.NetMode == NM_DedicatedServer)
|
if (Level.NetMode == NM_DedicatedServer) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
// Spawn necessary trails first
|
// Spawn necessary trails first
|
||||||
if(trailClass != none && bulletTrail == none)
|
if (trailClass != none && bulletTrail == none) {
|
||||||
bulletTrail = Spawn(trailClass, self);
|
bulletTrail = Spawn(trailClass, self);
|
||||||
if(trailXClass != none && bulletXTrail == none)
|
}
|
||||||
|
if (trailXClass != none && bulletXTrail == none) {
|
||||||
bulletXTrail = Spawn(trailXClass, self);
|
bulletXTrail = Spawn(trailXClass, self);
|
||||||
|
}
|
||||||
// Handle positioning differently for stuck and regular projectiles
|
// Handle positioning differently for stuck and regular projectiles
|
||||||
if (bStuck && base != none) {
|
if (bStuck && base != none) {
|
||||||
if (bUseBone) {
|
if (bUseBone) {
|
||||||
@ -235,25 +248,30 @@ function UpdateTrails(){
|
|||||||
bulletXTrail.SetRelativeRotation(relativeRotation);
|
bulletXTrail.SetRelativeRotation(relativeRotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
trailBase = self;
|
trailBase = self;
|
||||||
|
}
|
||||||
|
|
||||||
// Update lifetime and base (latter is for non-bone attachments only)
|
// Update lifetime and base (latter is for non-bone attachments only)
|
||||||
if (bulletTrail != none) {
|
if (bulletTrail != none) {
|
||||||
if(trailBase != none)
|
if (trailBase != none) {
|
||||||
bulletTrail.SetBase(trailBase);
|
bulletTrail.SetBase(trailBase);
|
||||||
|
}
|
||||||
bulletTrail.lifespan = lifeSpan;
|
bulletTrail.lifespan = lifeSpan;
|
||||||
}
|
}
|
||||||
if (bulletXTrail != none) {
|
if (bulletXTrail != none) {
|
||||||
if(trailBase != none)
|
if (trailBase != none) {
|
||||||
bulletXTrail.SetBase(trailBase);
|
bulletXTrail.SetBase(trailBase);
|
||||||
|
}
|
||||||
bulletXTrail.lifespan = lifeSpan;
|
bulletXTrail.lifespan = lifeSpan;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ResetPathBuilding() {
|
function ResetPathBuilding() {
|
||||||
finishedSegmentPart = -1.0;
|
finishedSegmentPart = -1.0;
|
||||||
shiftPoint = location;
|
shiftPoint = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resets default values for this bullet.
|
// Resets default values for this bullet.
|
||||||
// Must be called before each new use of a bullet.
|
// Must be called before each new use of a bullet.
|
||||||
function Renew() {
|
function Renew() {
|
||||||
@ -266,98 +284,129 @@ function Renew(){
|
|||||||
ResetIgnoreList();
|
ResetIgnoreList();
|
||||||
ResetPathBuilding();
|
ResetPathBuilding();
|
||||||
}
|
}
|
||||||
|
|
||||||
simulated function Tick(float delta) {
|
simulated function Tick(float delta) {
|
||||||
super.Tick(delta);
|
super.Tick(delta);
|
||||||
if(localPlayer == none)
|
|
||||||
|
if (localPlayer == none) {
|
||||||
localPlayer = NicePlayerController(Level.GetLocalPlayerController());
|
localPlayer = NicePlayerController(Level.GetLocalPlayerController());
|
||||||
|
}
|
||||||
|
|
||||||
if (charFuseTime > 0) {
|
if (charFuseTime > 0) {
|
||||||
charFuseTime -= delta;
|
charFuseTime -= delta;
|
||||||
if (charFuseTime < 0) {
|
if (charFuseTime < 0) {
|
||||||
if (charExplodeOnFuse && !charIsDud) {
|
if (charExplodeOnFuse && !charIsDud) {
|
||||||
GenerateImpactEffects(explosionImpact, location, movementDirection);
|
GenerateImpactEffects(explosionImpact, location, movementDirection);
|
||||||
if(bStuck)
|
if (bStuck) {
|
||||||
class'NiceBulletAdapter'.static.Explode(self, niceRI, location, base);
|
class'NiceBulletAdapter'.static.Explode(self, niceRI, location, base);
|
||||||
else
|
} else {
|
||||||
class'NiceBulletAdapter'.static.Explode(self, niceRI, location);
|
class'NiceBulletAdapter'.static.Explode(self, niceRI, location);
|
||||||
}
|
}
|
||||||
if(!charExplodeOnFuse)
|
}
|
||||||
|
if (!charExplodeOnFuse) {
|
||||||
GenerateImpactEffects(disintegrationImpact, location, movementDirection);
|
GenerateImpactEffects(disintegrationImpact, location, movementDirection);
|
||||||
|
}
|
||||||
KillBullet();
|
KillBullet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bInitFinished && !bInitFinishDetected) {
|
if (bInitFinished && !bInitFinishDetected) {
|
||||||
bInitFinishDetected = true;
|
bInitFinishDetected = true;
|
||||||
UpdateTrails();
|
UpdateTrails();
|
||||||
}
|
}
|
||||||
if(bInitFinished && !bBulletDead && !bStuck)
|
if (bInitFinished && !bBulletDead && !bStuck) {
|
||||||
DoProcessMovement(delta);
|
DoProcessMovement(delta);
|
||||||
|
}
|
||||||
if (bInitFinished && bStuck) {
|
if (bInitFinished && bStuck) {
|
||||||
if(base == none || (KFMonster(base) != none && KFMonster(base).health <= 0))
|
if (base == none || (KFMonster(base) != none && KFMonster(base).health <= 0)) {
|
||||||
nicePlayer.ExplodeStuckBullet(stuckID);
|
nicePlayer.ExplodeStuckBullet(stuckID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Extracts pawn actor from it's auxiliary collision
|
// Extracts pawn actor from it's auxiliary collision
|
||||||
// @param other Actor we collided with
|
// @param other Actor we collided with
|
||||||
// @return Pawn we're interested in
|
// @return Pawn we're interested in
|
||||||
function Actor GetMainActor(Actor other) {
|
function Actor GetMainActor(Actor other) {
|
||||||
if(other == none)
|
if (other == none) {
|
||||||
return none;
|
return none;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!other.IsA('KFPawn') && !other.IsA('KFMonster')) {
|
||||||
// Try owner
|
// Try owner
|
||||||
if( KFPawn(other) == none && KFMonster(other) == none
|
if (other.owner.IsA('KFPawn') || other.owner.IsA('KFMonster')) {
|
||||||
&& (KFPawn(other.owner) != none || KFMonster(other.owner) != none) )
|
return other.owner;
|
||||||
other = other.owner;
|
}
|
||||||
// Try base
|
// Try base
|
||||||
if( KFPawn(other) == none && KFMonster(other) == none
|
if (other.base.IsA('KFPawn') || other.base.IsA('KFMonster')) {
|
||||||
&& (KFPawn(other.base) != none || KFMonster(other.base) != none) )
|
return other.base;
|
||||||
other = other.base;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return other;
|
return other;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns 'true' if passed actor is either world geometry, 'Level' itself or nothing ('none')
|
// Returns 'true' if passed actor is either world geometry, 'Level' itself or nothing ('none')
|
||||||
// Neither of these related to pawn damage dealing
|
// Neither of these related to pawn damage dealing
|
||||||
function bool IsLevelActor(Actor other) {
|
function bool IsLevelActor(Actor other) {
|
||||||
if(other == none)
|
if (other == none) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return (other.bWorldGeometry || other == Level);
|
return (other.bWorldGeometry || other == Level);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds given actor and every colliding object connected to it to ignore list
|
// Adds given actor and every colliding object connected to it to ignore list
|
||||||
// Removes their collision in case ignore is active (see 'bIgnoreIsActive')
|
// Removes their collision in case ignore is active (see 'bIgnoreIsActive')
|
||||||
function TotalIgnore(Actor other) {
|
function TotalIgnore(Actor other) {
|
||||||
// These mark what objects, associated with 'other' we also need to ignore
|
// These mark what objects, associated with 'other' we also need to ignore
|
||||||
local KFPawn pawnOther;
|
local KFPawn pawnOther;
|
||||||
local KFMonster zedOther;
|
local KFMonster zedOther;
|
||||||
if(other == none)
|
|
||||||
|
if (other == none) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
// Try to find main actor as KFPawn
|
// Try to find main actor as KFPawn
|
||||||
pawnOther = KFPawn(other);
|
pawnOther = KFPawn(other);
|
||||||
if(pawnOther == none)
|
if (pawnOther == none) {
|
||||||
pawnOther = KFPawn(other.base);
|
pawnOther = KFPawn(other.base);
|
||||||
if(pawnOther == none)
|
}
|
||||||
|
if (pawnOther == none) {
|
||||||
pawnOther = KFPawn(other.owner);
|
pawnOther = KFPawn(other.owner);
|
||||||
|
}
|
||||||
// Try to find main actor as KFMonster
|
// Try to find main actor as KFMonster
|
||||||
zedOther = KFMonster(other);
|
zedOther = KFMonster(other);
|
||||||
if(zedOther == none)
|
if (zedOther == none) {
|
||||||
zedOther = KFMonster(other.base);
|
zedOther = KFMonster(other.base);
|
||||||
if(zedOther == none)
|
}
|
||||||
|
if (zedOther == none) {
|
||||||
zedOther = KFMonster(other.owner);
|
zedOther = KFMonster(other.owner);
|
||||||
|
}
|
||||||
// Ignore everything that's associated with this actor and can have collision
|
// Ignore everything that's associated with this actor and can have collision
|
||||||
IgnoreActor(other);
|
IgnoreActor(other);
|
||||||
IgnoreActor(other.base);
|
IgnoreActor(other.base);
|
||||||
IgnoreActor(other.owner);
|
IgnoreActor(other.owner);
|
||||||
if(pawnOther != none)
|
if (pawnOther != none) {
|
||||||
IgnoreActor(pawnOther.AuxCollisionCylinder);
|
IgnoreActor(pawnOther.AuxCollisionCylinder);
|
||||||
if(zedOther != none)
|
}
|
||||||
|
if (zedOther != none) {
|
||||||
IgnoreActor(zedOther.MyExtCollision);
|
IgnoreActor(zedOther.MyExtCollision);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Adds a given actor to ignore list and removes it's collision in case ignore is active (see 'bIgnoreIsActive')
|
// Adds a given actor to ignore list and removes it's collision in case ignore is active (see 'bIgnoreIsActive')
|
||||||
function IgnoreActor(Actor other) {
|
function IgnoreActor(Actor other) {
|
||||||
local int i;
|
local int i;
|
||||||
local IgnoreEntry newIgnoredEntry;
|
local IgnoreEntry newIgnoredEntry;
|
||||||
|
|
||||||
// Check if that's a non-level actor and not already on the list
|
// Check if that's a non-level actor and not already on the list
|
||||||
if(IsLevelActor(other))
|
if (IsLevelActor(other)) {
|
||||||
return;
|
return;
|
||||||
for(i = 0;i < ignoredActors.Length;i ++)
|
}
|
||||||
if(ignoredActors[i].ignored == other)
|
for (i = 0; i < ignoredActors.Length; i ++) {
|
||||||
|
if (ignoredActors[i].ignored == other) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Add actor to the ignore list & disable collision if needed
|
// Add actor to the ignore list & disable collision if needed
|
||||||
if (other != none) {
|
if (other != none) {
|
||||||
// Make entry
|
// Make entry
|
||||||
@ -365,47 +414,63 @@ function IgnoreActor(Actor other){
|
|||||||
newIgnoredEntry.bExtDisabled = !other.bCollideActors;
|
newIgnoredEntry.bExtDisabled = !other.bCollideActors;
|
||||||
// Add and activate it
|
// Add and activate it
|
||||||
ignoredActors[ignoredActors.Length] = newIgnoredEntry;
|
ignoredActors[ignoredActors.Length] = newIgnoredEntry;
|
||||||
if(bIgnoreIsActive)
|
if (bIgnoreIsActive) {
|
||||||
other.SetCollision(false);
|
other.SetCollision(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Restores ignored state of the actors and zeroes our ignored arrays
|
// Restores ignored state of the actors and zeroes our ignored arrays
|
||||||
function ResetIgnoreList() {
|
function ResetIgnoreList() {
|
||||||
SetIgnoreActive(false);
|
SetIgnoreActive(false);
|
||||||
ignoredActors.Length = 0;
|
ignoredActors.Length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activates/deactivates ignore for actors on the ignore list.
|
// Activates/deactivates ignore for actors on the ignore list.
|
||||||
// Ignore deactivation doesn't restore collision if actor was set to not collide prior most recent ignore activation.
|
// Ignore deactivation doesn't restore collision if actor was set to not collide prior most recent ignore activation.
|
||||||
// Activating ignore when it's already active does nothing; same with deactivation.
|
// Activating ignore when it's already active does nothing; same with deactivation.
|
||||||
// Ignore deactivation is supposed to be used in the same function call in which activation took place before.
|
// Ignore deactivation is supposed to be used in the same function call in which activation took place before.
|
||||||
function SetIgnoreActive(bool bActive) {
|
function SetIgnoreActive(bool bActive) {
|
||||||
local int i;
|
local int i;
|
||||||
|
|
||||||
// Do nothing if we're already in a correct state
|
// Do nothing if we're already in a correct state
|
||||||
if(bActive == bIgnoreIsActive)
|
if (bActive == bIgnoreIsActive) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
// Change ignore state & disable collision for ignored actors
|
// Change ignore state & disable collision for ignored actors
|
||||||
bIgnoreIsActive = bActive;
|
bIgnoreIsActive = bActive;
|
||||||
for(i = 0;i < ignoredActors.Length;i ++)
|
for (i = 0; i < ignoredActors.Length; i ++) {
|
||||||
if (ignoredActors[i].ignored != none) {
|
if (ignoredActors[i].ignored != none) {
|
||||||
// Mark actors that were set to not collide before activation
|
// Mark actors that were set to not collide before activation
|
||||||
if(bActive && !ignoredActors[i].ignored.bCollideActors)
|
if (bActive && !ignoredActors[i].ignored.bCollideActors) {
|
||||||
ignoredActors[i].bExtDisabled = true;
|
ignoredActors[i].bExtDisabled = true;
|
||||||
|
}
|
||||||
// Change collision for actors that weren't externally modified
|
// Change collision for actors that weren't externally modified
|
||||||
if(!ignoredActors[i].bExtDisabled)
|
if (!ignoredActors[i].bExtDisabled) {
|
||||||
ignoredActors[i].ignored.SetCollision(!bActive);
|
ignoredActors[i].ignored.SetCollision(!bActive);
|
||||||
|
}
|
||||||
// After we deactivated our rules - forget about external modifications
|
// After we deactivated our rules - forget about external modifications
|
||||||
if(!bActive)
|
if (!bActive) {
|
||||||
ignoredActors[i].bExtDisabled = false;
|
ignoredActors[i].bExtDisabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function SetHumanPawnCollision(bool bEnable) {
|
function SetHumanPawnCollision(bool bEnable) {
|
||||||
local int i;
|
local int i;
|
||||||
if(niceMutator == none)
|
|
||||||
|
if (niceMutator == none) {
|
||||||
niceMutator = class'NicePack'.static.Myself(Level);
|
niceMutator = class'NicePack'.static.Myself(Level);
|
||||||
for(i = 0;i < niceMutator.recordedHumanPawns.Length;i ++)
|
}
|
||||||
if(niceMutator.recordedHumanPawns[i] != none)
|
|
||||||
|
for (i = 0; i < niceMutator.recordedHumanPawns.Length; i ++) {
|
||||||
|
if (niceMutator.recordedHumanPawns[i] != none) {
|
||||||
niceMutator.recordedHumanPawns[i].bBlockHitPointTraces = bEnable;
|
niceMutator.recordedHumanPawns[i].bBlockHitPointTraces = bEnable;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function float CheckHeadshot(KFMonster kfZed, Vector hitLocation, Vector hitDirection) {
|
function float CheckHeadshot(KFMonster kfZed, Vector hitLocation, Vector hitDirection) {
|
||||||
local float hsMod;
|
local float hsMod;
|
||||||
local float precision;
|
local float precision;
|
||||||
@ -413,6 +478,7 @@ function float CheckHeadshot(KFMonster kfZed, Vector hitLocation, Vector hitDire
|
|||||||
local NiceMonster niceZed;
|
local NiceMonster niceZed;
|
||||||
local KFPlayerReplicationInfo KFPRI;
|
local KFPlayerReplicationInfo KFPRI;
|
||||||
local class<NiceVeterancyTypes> niceVet;
|
local class<NiceVeterancyTypes> niceVet;
|
||||||
|
|
||||||
niceZed = NiceMonster(kfZed);
|
niceZed = NiceMonster(kfZed);
|
||||||
hitDirection = Normal(hitDirection);
|
hitDirection = Normal(hitDirection);
|
||||||
bIsShotgunBullet = ClassIsChildOf(charDamageType, class'NiceDamageTypeVetEnforcer');
|
bIsShotgunBullet = ClassIsChildOf(charDamageType, class'NiceDamageTypeVetEnforcer');
|
||||||
@ -420,27 +486,36 @@ function float CheckHeadshot(KFMonster kfZed, Vector hitLocation, Vector hitDire
|
|||||||
hsMod = bounceHeadMod; // NICETODO: Add bounce and perk and damage type head-shot zones bonuses
|
hsMod = bounceHeadMod; // NICETODO: Add bounce and perk and damage type head-shot zones bonuses
|
||||||
hsMod *= charDamageType.default.headSizeModifier;
|
hsMod *= charDamageType.default.headSizeModifier;
|
||||||
hsMod *= bounceHeadMod;
|
hsMod *= bounceHeadMod;
|
||||||
if(nicePlayer != none)
|
if (nicePlayer != none) {
|
||||||
KFPRI = KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo);
|
KFPRI = KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo);
|
||||||
if(KFPRI != none)
|
}
|
||||||
|
if (KFPRI != none) {
|
||||||
niceVet = class<NiceVeterancyTypes>(KFPRI.ClientVeteranSkill);
|
niceVet = class<NiceVeterancyTypes>(KFPRI.ClientVeteranSkill);
|
||||||
if(niceVet != none)
|
}
|
||||||
|
if (niceVet != none) {
|
||||||
hsMod *= niceVet.static.GetHeadshotCheckMultiplier(KFPRI, charDamageType);
|
hsMod *= niceVet.static.GetHeadshotCheckMultiplier(KFPRI, charDamageType);
|
||||||
|
}
|
||||||
precision = niceZed.IsHeadshotClient(hitLocation, hitDirection, niceZed.clientHeadshotScale * hsMod);
|
precision = niceZed.IsHeadshotClient(hitLocation, hitDirection, niceZed.clientHeadshotScale * hsMod);
|
||||||
if(precision <= 0.0 && bIsShotgunBullet && nicePlayer != none && class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillSupportGraze')){
|
if (
|
||||||
|
precision <= 0.0 &&
|
||||||
|
bIsShotgunBullet &&
|
||||||
|
nicePlayer != none &&
|
||||||
|
class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillSupportGraze')
|
||||||
|
) {
|
||||||
bGrazing = true;
|
bGrazing = true;
|
||||||
hsMod *= class'NiceSkillSupportGraze'.default.hsBonusZoneMult;
|
hsMod *= class'NiceSkillSupportGraze'.default.hsBonusZoneMult;
|
||||||
precision = niceZed.IsHeadshotClient(hitLocation, hitDirection, niceZed.clientHeadshotScale * hsMod);
|
precision = niceZed.IsHeadshotClient(hitLocation, hitDirection, niceZed.clientHeadshotScale * hsMod);
|
||||||
}
|
}
|
||||||
return precision;
|
return precision;
|
||||||
}
|
} else {
|
||||||
else{
|
if (kfZed.IsHeadShot(hitLocation, hitDirection, 1.0)) {
|
||||||
if(kfZed.IsHeadShot(hitLocation, hitDirection, 1.0))
|
|
||||||
return 1.0;
|
return 1.0;
|
||||||
else
|
} else {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Makes bullet trace a directed line segment given by start and end points.
|
// Makes bullet trace a directed line segment given by start and end points.
|
||||||
// All traced actors and geometry are then properly affected by corresponding 'HandleHitPawn', 'HandleHitZed' and
|
// All traced actors and geometry are then properly affected by corresponding 'HandleHitPawn', 'HandleHitZed' and
|
||||||
// 'HandleHitWall' functions.
|
// 'HandleHitWall' functions.
|
||||||
@ -457,6 +532,7 @@ function DoTraceLine(Vector lineStart, Vector lineEnd){
|
|||||||
local array<int> hitPoints;
|
local array<int> hitPoints;
|
||||||
local KFMonster tracedZed;
|
local KFMonster tracedZed;
|
||||||
local KFPawn tracedPawn;
|
local KFPawn tracedPawn;
|
||||||
|
|
||||||
lineDirection = (lineEnd - lineStart);
|
lineDirection = (lineEnd - lineStart);
|
||||||
lineDirection = (lineDirection) / VSize(lineDirection);
|
lineDirection = (lineDirection) / VSize(lineDirection);
|
||||||
// Do not trace for disabled bullets and prevent infinite loops
|
// Do not trace for disabled bullets and prevent infinite loops
|
||||||
@ -464,64 +540,79 @@ function DoTraceLine(Vector lineStart, Vector lineEnd){
|
|||||||
iterationCount++;
|
iterationCount++;
|
||||||
// Trace next object
|
// Trace next object
|
||||||
if (!bGhost || localPlayer == none || localPlayer.tracesThisTick <= localPlayer.tracesPerTickLimit) {
|
if (!bGhost || localPlayer == none || localPlayer.tracesThisTick <= localPlayer.tracesPerTickLimit) {
|
||||||
if(Instigator != none)
|
if (Instigator != none) {
|
||||||
tracedActor = Instigator.Trace(hitLocation, hitNormal, lineEnd, lineStart, true);
|
tracedActor = Instigator.Trace(hitLocation, hitNormal, lineEnd, lineStart, true);
|
||||||
else
|
} else {
|
||||||
tracedActor = none;
|
tracedActor = none;
|
||||||
localPlayer.tracesThisTick ++;
|
|
||||||
}
|
}
|
||||||
else
|
localPlayer.tracesThisTick++;
|
||||||
|
} else {
|
||||||
tracedActor = none;
|
tracedActor = none;
|
||||||
if(charAffectedByScream && !charIsDud && localPlayer != none && localPlayer.localCollisionManager != none && localPlayer.localCollisionManager.IsCollidingWithAnything(lineStart, lineEnd))
|
}
|
||||||
|
if (
|
||||||
|
charAffectedByScream &&
|
||||||
|
!charIsDud &&
|
||||||
|
localPlayer != none &&
|
||||||
|
localPlayer.localCollisionManager != none &&
|
||||||
|
localPlayer.localCollisionManager.IsCollidingWithAnything(lineStart, lineEnd)
|
||||||
|
) {
|
||||||
HandleScream(lineStart, lineDirection);
|
HandleScream(lineStart, lineDirection);
|
||||||
|
}
|
||||||
if (tracedActor != none && IsLevelActor(tracedActor)) {
|
if (tracedActor != none && IsLevelActor(tracedActor)) {
|
||||||
HandleHitWall(tracedActor, hitLocation, hitNormal);
|
HandleHitWall(tracedActor, hitLocation, hitNormal);
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
TotalIgnore(tracedActor);
|
TotalIgnore(tracedActor);
|
||||||
tracedActor = GetMainActor(tracedActor);
|
tracedActor = GetMainActor(tracedActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If tracing between current trace points haven't found anything and tracing step is less than segment's length
|
// If tracing between current trace points haven't found anything and tracing step is less than segment's length
|
||||||
// -- shift tracing bounds
|
// -- shift tracing bounds
|
||||||
if(tracedActor == none)
|
if (tracedActor == none) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// First, try to handle pawn like a zed; if fails, - try to handle it like 'KFPawn'
|
// First, try to handle pawn like a zed; if fails, - try to handle it like 'KFPawn'
|
||||||
tracedZed = KFMonster(tracedActor);
|
tracedZed = KFMonster(tracedActor);
|
||||||
tracedPawn = KFPawn(tracedActor);
|
tracedPawn = KFPawn(tracedActor);
|
||||||
if(tracedPawn != none && NiceHumanPawn(instigator) != none &&
|
if (
|
||||||
(NiceHumanPawn(instigator).ffScale <= 0 && NiceMedicProjectile(self) == none) )
|
tracedPawn != none &&
|
||||||
|
NiceHumanPawn(instigator) != none &&
|
||||||
|
(NiceHumanPawn(instigator).ffScale <= 0 && NiceMedicProjectile(self) == none)
|
||||||
|
) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (tracedZed != none) {
|
if (tracedZed != none) {
|
||||||
if (tracedZed.Health > 0) {
|
if (tracedZed.Health > 0) {
|
||||||
headshotLevel = CheckHeadshot(tracedZed, hitLocation, lineDirection);
|
headshotLevel = CheckHeadshot(tracedZed, hitLocation, lineDirection);
|
||||||
HandleHitZed(tracedZed, hitLocation, lineDirection, headshotLevel);
|
HandleHitZed(tracedZed, hitLocation, lineDirection, headshotLevel);
|
||||||
}
|
}
|
||||||
}
|
} else if (tracedPawn != none && tracedPawn.Health > 0) {
|
||||||
else if(tracedPawn != none && tracedPawn.Health > 0){
|
if (tracedPawn.Health > 0) {
|
||||||
if(tracedPawn.Health > 0)
|
|
||||||
HandleHitPawn(tracedPawn, hitLocation, lineDirection, hitPoints);
|
HandleHitPawn(tracedPawn, hitLocation, lineDirection, hitPoints);
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
HandleHitWall(tracedActor, hitLocation, hitNormal);
|
HandleHitWall(tracedActor, hitLocation, hitNormal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Replaces current path segment with the next one.
|
// Replaces current path segment with the next one.
|
||||||
// Doesn't check whether or not we've finished with the current segment.
|
// Doesn't check whether or not we've finished with the current segment.
|
||||||
function BuildNextPathSegment() {
|
function BuildNextPathSegment() {
|
||||||
// Only set start point to our location when we build path segment for the first time
|
// Only set start point to our location when we build path segment for the first time
|
||||||
// After that we can't even assume that bullet is exactly in the 'pathSegmentE' point
|
// After that we can't even assume that bullet is exactly in the 'pathSegmentE' point
|
||||||
if(finishedSegmentPart < 0.0)
|
if (finishedSegmentPart < 0.0) {
|
||||||
pathSegmentS = Location;
|
pathSegmentS = Location;
|
||||||
else
|
} else {
|
||||||
pathSegmentS = pathSegmentE;
|
pathSegmentS = pathSegmentE;
|
||||||
|
}
|
||||||
movementDirection += (movementAcceleration * trajUpdFreq) / movementSpeed;
|
movementDirection += (movementAcceleration * trajUpdFreq) / movementSpeed;
|
||||||
pathSegmentE = pathSegmentS + movementDirection * movementSpeed * trajUpdFreq;
|
pathSegmentE = pathSegmentS + movementDirection * movementSpeed * trajUpdFreq;
|
||||||
finishedSegmentPart = 0.0;
|
finishedSegmentPart = 0.0;
|
||||||
shiftPoint = pathSegmentS;
|
shiftPoint = pathSegmentS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates 'shiftPoint' to the next bullet position in current segment.
|
// Updates 'shiftPoint' to the next bullet position in current segment.
|
||||||
// Does nothing if current segment is finished or no segment was built at all.
|
// Does nothing if current segment is finished or no segment was built at all.
|
||||||
// @param delta Amount of time bullet has to move through the segment.
|
// @param delta Amount of time bullet has to move through the segment.
|
||||||
@ -531,9 +622,11 @@ function float ShiftInSegment(float delta){
|
|||||||
local float remainingTime;
|
local float remainingTime;
|
||||||
// Part of segment we can pass in a given time
|
// Part of segment we can pass in a given time
|
||||||
local float segmentPartWeCanPass;
|
local float segmentPartWeCanPass;
|
||||||
|
|
||||||
// Exit if there's no segment in progress
|
// Exit if there's no segment in progress
|
||||||
if(finishedSegmentPart < 0.0 || finishedSegmentPart > 1.0)
|
if (finishedSegmentPart < 0.0 || finishedSegmentPart > 1.0) {
|
||||||
return delta;
|
return delta;
|
||||||
|
}
|
||||||
// [movementSpeed * delta] / [movementSpeed * trajUpdFreq] = [delta / trajUpdFreq]
|
// [movementSpeed * delta] / [movementSpeed * trajUpdFreq] = [delta / trajUpdFreq]
|
||||||
segmentPartWeCanPass = delta / trajUpdFreq;
|
segmentPartWeCanPass = delta / trajUpdFreq;
|
||||||
// If we can move through the rest of the segment - move to end point and mark it finished
|
// If we can move through the rest of the segment - move to end point and mark it finished
|
||||||
@ -541,19 +634,20 @@ function float ShiftInSegment(float delta){
|
|||||||
remainingTime = delta - (1.0 - finishedSegmentPart) * trajUpdFreq;
|
remainingTime = delta - (1.0 - finishedSegmentPart) * trajUpdFreq;
|
||||||
finishedSegmentPart = 1.1;
|
finishedSegmentPart = 1.1;
|
||||||
shiftPoint = pathSegmentE;
|
shiftPoint = pathSegmentE;
|
||||||
}
|
} else {
|
||||||
// Otherwise compute new 'shiftPoint' normally
|
// Otherwise compute new 'shiftPoint' normally
|
||||||
else{
|
|
||||||
remainingTime = 0.0;
|
remainingTime = 0.0;
|
||||||
finishedSegmentPart += (delta / trajUpdFreq);
|
finishedSegmentPart += (delta / trajUpdFreq);
|
||||||
shiftPoint = pathSegmentS + movementDirection * movementSpeed * trajUpdFreq * finishedSegmentPart;
|
shiftPoint = pathSegmentS + movementDirection * movementSpeed * trajUpdFreq * finishedSegmentPart;
|
||||||
}
|
}
|
||||||
return remainingTime;
|
return remainingTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves bullet according to settings and decides when and how much tracing should it do.
|
// Moves bullet according to settings and decides when and how much tracing should it do.
|
||||||
// @param delta Amount of time passed after previous bullet movement
|
// @param delta Amount of time passed after previous bullet movement
|
||||||
function DoProcessMovement(float delta) {
|
function DoProcessMovement(float delta) {
|
||||||
local Vector tempVect;
|
local Vector tempVect;
|
||||||
|
|
||||||
SetIgnoreActive(true);
|
SetIgnoreActive(true);
|
||||||
//SetHumanPawnCollision(true);
|
//SetHumanPawnCollision(true);
|
||||||
// Simple linear movement
|
// Simple linear movement
|
||||||
@ -567,12 +661,12 @@ function DoProcessMovement(float delta){
|
|||||||
// If in future complex movement would be re-enabled, - we want to set first point of the path to
|
// If in future complex movement would be re-enabled, - we want to set first point of the path to
|
||||||
// the location of bullet at a time and not use outdated information.
|
// the location of bullet at a time and not use outdated information.
|
||||||
finishedSegmentPart = -1.0;
|
finishedSegmentPart = -1.0;
|
||||||
}
|
} else {
|
||||||
// Non-linear movement support
|
// Non-linear movement support
|
||||||
else{
|
|
||||||
while(delta > 0.0) {
|
while(delta > 0.0) {
|
||||||
if(finishedSegmentPart < 0.0 || finishedSegmentPart > 1.0)
|
if (finishedSegmentPart < 0.0 || finishedSegmentPart > 1.0) {
|
||||||
BuildNextPathSegment();
|
BuildNextPathSegment();
|
||||||
|
}
|
||||||
// Remember current 'shiftPoint'. That's where we stopped tracing last time and where we must resume.
|
// Remember current 'shiftPoint'. That's where we stopped tracing last time and where we must resume.
|
||||||
tempVect = shiftPoint;
|
tempVect = shiftPoint;
|
||||||
// Update 'shiftPoint' (bullet position)
|
// Update 'shiftPoint' (bullet position)
|
||||||
@ -585,20 +679,27 @@ function DoProcessMovement(float delta){
|
|||||||
Move(shiftPoint - location);
|
Move(shiftPoint - location);
|
||||||
}
|
}
|
||||||
SetRotation(Rotator(movementDirection));
|
SetRotation(Rotator(movementDirection));
|
||||||
if(charMinExplosionDist > 0)
|
if (charMinExplosionDist > 0) {
|
||||||
charMinExplosionDist -= VSize(tempVect);
|
charMinExplosionDist -= VSize(tempVect);
|
||||||
|
}
|
||||||
SetIgnoreActive(false);
|
SetIgnoreActive(false);
|
||||||
// SetHumanPawnCollision(false);
|
// SetHumanPawnCollision(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Stick(Actor target, Vector hitLocation) {
|
function Stick(Actor target, Vector hitLocation) {
|
||||||
local NiceMonster targetZed;
|
|
||||||
local name boneStick;
|
|
||||||
local float distToBone;
|
|
||||||
local float t;
|
|
||||||
local Vector boneStrickOrig;
|
local Vector boneStrickOrig;
|
||||||
local ExplosionData expData;
|
local ExplosionData expData;
|
||||||
if(bGhost)
|
local Actor resultTarget;
|
||||||
|
local NiceMonster targetZed;
|
||||||
|
local name boneStick;
|
||||||
|
local float distToBone, t;
|
||||||
|
|
||||||
|
if (bGhost) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
expData.instigator = instigator;
|
||||||
|
expData.sourceWeapon = sourceWeapon;
|
||||||
|
expData.bulletClass = class;
|
||||||
expData.explosionDamageType = charExplosionDamageType;
|
expData.explosionDamageType = charExplosionDamageType;
|
||||||
expData.explosionDamage = charExplosionDamage;
|
expData.explosionDamage = charExplosionDamage;
|
||||||
expData.explosionRadius = charExplosionRadius;
|
expData.explosionRadius = charExplosionRadius;
|
||||||
@ -607,24 +708,20 @@ function Stick(Actor target, Vector hitLocation){
|
|||||||
expData.fuseTime = charFuseTime;
|
expData.fuseTime = charFuseTime;
|
||||||
expData.explodeOnFuse = charExplodeOnFuse;
|
expData.explodeOnFuse = charExplodeOnFuse;
|
||||||
expData.affectedByScream = charAffectedByScream;
|
expData.affectedByScream = charAffectedByScream;
|
||||||
expData.sourceWeapon = sourceWeapon;
|
|
||||||
|
if (!target.IsA('NiceMonster')) {
|
||||||
|
hitLocation -= target.location;
|
||||||
|
boneStick = 'None';
|
||||||
|
resultTarget = target;
|
||||||
|
} else {
|
||||||
targetZed = NiceMonster(target);
|
targetZed = NiceMonster(target);
|
||||||
if(targetZed == none){
|
|
||||||
expData.bulletClass = class;
|
|
||||||
expData.instigator = instigator;
|
|
||||||
niceRI.ServerStickProjectile(KFHumanPawn(instigator), target, 'None', hitLocation - target.location,
|
|
||||||
Rotator(movementDirection), expData);
|
|
||||||
class'NiceProjectileSpawner'.static.StickProjectile(KFHumanPawn(instigator), target, 'None',
|
|
||||||
hitLocation - target.location, Rotator(movementDirection), expData);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
expData.bulletClass = class;
|
|
||||||
expData.instigator = instigator;
|
|
||||||
boneStick = targetZed.GetClosestBone(hitLocation, movementDirection, distToBone);
|
boneStick = targetZed.GetClosestBone(hitLocation, movementDirection, distToBone);
|
||||||
if(CheckHeadshot(targetZed, hitLocation, movementDirection) > 0.0)
|
if (CheckHeadshot(targetZed, hitLocation, movementDirection) > 0.0) {
|
||||||
boneStick = targetZed.HeadBone;
|
boneStick = targetZed.HeadBone;
|
||||||
if(boneStick == targetZed.HeadBone)
|
}
|
||||||
|
if (boneStick == targetZed.HeadBone) {
|
||||||
expData.stuckToHead = true;
|
expData.stuckToHead = true;
|
||||||
|
}
|
||||||
boneStrickOrig = targetZed.GetBoneCoords(boneStick).origin;
|
boneStrickOrig = targetZed.GetBoneCoords(boneStick).origin;
|
||||||
t = movementDirection.x * (boneStrickOrig.x - hitLocation.x) +
|
t = movementDirection.x * (boneStrickOrig.x - hitLocation.x) +
|
||||||
movementDirection.y * (boneStrickOrig.y - hitLocation.y) +
|
movementDirection.y * (boneStrickOrig.y - hitLocation.y) +
|
||||||
@ -632,37 +729,60 @@ function Stick(Actor target, Vector hitLocation){
|
|||||||
t /= VSizeSquared(movementDirection);
|
t /= VSizeSquared(movementDirection);
|
||||||
t *= 0.5;
|
t *= 0.5;
|
||||||
hitLocation = hitLocation + t * movementDirection;
|
hitLocation = hitLocation + t * movementDirection;
|
||||||
niceRI.ServerStickProjectile(KFHumanPawn(instigator), targetZed, boneStick,
|
hitLocation -= boneStrickOrig;
|
||||||
hitLocation - boneStrickOrig, Rotator(movementDirection), expData);
|
resultTarget = targetZed;
|
||||||
class'NiceProjectileSpawner'.static.StickProjectile(KFHumanPawn(instigator), targetZed, boneStick,
|
|
||||||
hitLocation - boneStrickOrig, Rotator(movementDirection), expData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
niceRI.ServerStickProjectile(
|
||||||
|
KFHumanPawn(instigator),
|
||||||
|
resultTarget,
|
||||||
|
boneStick,
|
||||||
|
hitLocation,
|
||||||
|
Rotator(movementDirection),
|
||||||
|
expData
|
||||||
|
);
|
||||||
|
class'NiceProjectileSpawner'.static.StickProjectile(
|
||||||
|
KFHumanPawn(instigator),
|
||||||
|
resultTarget,
|
||||||
|
boneStick,
|
||||||
|
hitLocation,
|
||||||
|
Rotator(movementDirection),
|
||||||
|
expData
|
||||||
|
);
|
||||||
|
|
||||||
KillBullet();
|
KillBullet();
|
||||||
}
|
}
|
||||||
|
|
||||||
function DoExplode(Vector explLocation, Vector impactNormal) {
|
function DoExplode(Vector explLocation, Vector impactNormal) {
|
||||||
if(charIsDud)
|
if (charIsDud) {
|
||||||
return;
|
return;
|
||||||
if(bStuck)
|
}
|
||||||
|
if (bStuck) {
|
||||||
class'NiceBulletAdapter'.static.Explode(self, niceRI, explLocation, base);
|
class'NiceBulletAdapter'.static.Explode(self, niceRI, explLocation, base);
|
||||||
else
|
} else {
|
||||||
class'NiceBulletAdapter'.static.Explode(self, niceRI, explLocation);
|
class'NiceBulletAdapter'.static.Explode(self, niceRI, explLocation);
|
||||||
|
}
|
||||||
GenerateImpactEffects(explosionImpact, explLocation, impactNormal, true, true);
|
GenerateImpactEffects(explosionImpact, explLocation, impactNormal, true, true);
|
||||||
if(bShakeViewOnExplosion)
|
if (bShakeViewOnExplosion) {
|
||||||
ShakeView(explLocation);
|
ShakeView(explLocation);
|
||||||
|
}
|
||||||
KillBullet();
|
KillBullet();
|
||||||
}
|
}
|
||||||
|
|
||||||
function HandleHitWall(Actor wall, Vector hitLocation, Vector hitNormal) {
|
function HandleHitWall(Actor wall, Vector hitLocation, Vector hitNormal) {
|
||||||
local bool bBulletTooWeak;
|
local bool bBulletTooWeak;
|
||||||
|
|
||||||
if (charExplodeOnWallHit && !charIsDud && charMinExplosionDist <= 0.0) {
|
if (charExplodeOnWallHit && !charIsDud && charMinExplosionDist <= 0.0) {
|
||||||
DoExplode(hitLocation, hitNormal);
|
DoExplode(hitLocation, hitNormal);
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
class'NiceBulletAdapter'.static.HitWall(self, niceRI, wall, hitLocation, hitNormal);
|
class'NiceBulletAdapter'.static.HitWall(self, niceRI, wall, hitLocation, hitNormal);
|
||||||
GenerateImpactEffects(regularImpact, hitLocation, hitNormal, true, true);
|
GenerateImpactEffects(regularImpact, hitLocation, hitNormal, true, true);
|
||||||
if(charIsSticky)
|
if (charIsSticky) {
|
||||||
Stick(wall, hitLocation);
|
Stick(wall, hitLocation);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (bShouldBounce && !bDisableComplexMovement) {
|
if (bShouldBounce && !bDisableComplexMovement) {
|
||||||
movementDirection = (movementDirection - 2.0 * hitNormal * (movementDirection dot hitNormal));
|
movementDirection = (movementDirection - 2.0 * hitNormal * (movementDirection dot hitNormal));
|
||||||
bBulletTooWeak = !class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, none, false, false);
|
bBulletTooWeak = !class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, none, false, false);
|
||||||
@ -670,97 +790,133 @@ function HandleHitWall(Actor wall, Vector hitLocation, Vector hitNormal){
|
|||||||
ResetPathBuilding();
|
ResetPathBuilding();
|
||||||
ResetIgnoreList();
|
ResetIgnoreList();
|
||||||
bounceHeadMod *= 2;
|
bounceHeadMod *= 2;
|
||||||
}
|
} else if (movementFallTime > 0.0) {
|
||||||
else if(movementFallTime > 0.0){
|
|
||||||
charIsDud = true;
|
charIsDud = true;
|
||||||
lifeSpan = movementFallTime;
|
lifeSpan = movementFallTime;
|
||||||
movementFallTime = 0.0;
|
movementFallTime = 0.0;
|
||||||
movementDirection = vect(0, 0, 0);
|
movementDirection = vect(0, 0, 0);
|
||||||
ResetPathBuilding();
|
ResetPathBuilding();
|
||||||
ResetIgnoreList();
|
ResetIgnoreList();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
bBulletTooWeak = true;
|
bBulletTooWeak = true;
|
||||||
if(bBulletTooWeak)
|
}
|
||||||
|
|
||||||
|
if (bBulletTooWeak) {
|
||||||
KillBullet();
|
KillBullet();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function HandleHitPawn(KFPawn hitPawn, Vector hitLocation, Vector hitDirection, array<int> hitPoints) {
|
function HandleHitPawn(KFPawn hitPawn, Vector hitLocation, Vector hitDirection, array<int> hitPoints) {
|
||||||
if (charExplodeOnPawnHit && !charIsDud && charMinExplosionDist <= 0.0) {
|
if (charExplodeOnPawnHit && !charIsDud && charMinExplosionDist <= 0.0) {
|
||||||
DoExplode(hitLocation, hitDirection);
|
DoExplode(hitLocation, hitDirection);
|
||||||
GenerateImpactEffects(explosionImpact, hitLocation, hitDirection);
|
GenerateImpactEffects(explosionImpact, hitLocation, hitDirection);
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
class'NiceBulletAdapter'.static.HitPawn(self, niceRI, hitPawn, hitLocation, hitDirection, hitPoints);
|
class'NiceBulletAdapter'.static.HitPawn(self, niceRI, hitPawn, hitLocation, hitDirection, hitPoints);
|
||||||
if(bGenRegEffectOnPawn)
|
if (bGenRegEffectOnPawn) {
|
||||||
GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false);
|
GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, none, false, false)) {
|
if (!class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, none, false, false)) {
|
||||||
charPenetrationCount += 1;
|
charPenetrationCount += 1;
|
||||||
KillBullet();
|
KillBullet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function HandleHitZed(KFMonster targetZed, Vector hitLocation, Vector hitDirection, float headshotLevel) {
|
function HandleHitZed(KFMonster targetZed, Vector hitLocation, Vector hitDirection, float headshotLevel) {
|
||||||
local bool bHitZedCalled;
|
local bool bHitZedCalled;
|
||||||
|
|
||||||
if (class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillDemoDirectApproach')) {
|
if (class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillDemoDirectApproach')) {
|
||||||
class'NiceBulletAdapter'.static.HitZed(self, niceRI, targetZed, hitLocation, hitDirection, headshotLevel);
|
class'NiceBulletAdapter'.static.HitZed(self, niceRI, targetZed, hitLocation, hitDirection, headshotLevel);
|
||||||
if(bGenRegEffectOnPawn)
|
if (bGenRegEffectOnPawn) {
|
||||||
GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false);
|
GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false);
|
||||||
|
}
|
||||||
bHitZedCalled = true;
|
bHitZedCalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (charExplodeOnPawnHit && !charIsDud && charMinExplosionDist <= 0.0) {
|
if (charExplodeOnPawnHit && !charIsDud && charMinExplosionDist <= 0.0) {
|
||||||
class'NiceBulletAdapter'.static.Explode(self, niceRI, hitLocation, targetZed);
|
class'NiceBulletAdapter'.static.Explode(self, niceRI, hitLocation, targetZed);
|
||||||
GenerateImpactEffects(explosionImpact, hitLocation, hitDirection);
|
GenerateImpactEffects(explosionImpact, hitLocation, hitDirection);
|
||||||
if(bShakeViewOnExplosion)
|
if (bShakeViewOnExplosion) {
|
||||||
ShakeView(hitLocation);
|
ShakeView(hitLocation);
|
||||||
|
}
|
||||||
KillBullet();
|
KillBullet();
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
if (!bHitZedCalled) {
|
if (!bHitZedCalled) {
|
||||||
class'NiceBulletAdapter'.static.HitZed(self, niceRI, targetZed, hitLocation, hitDirection, headshotLevel);
|
class'NiceBulletAdapter'.static.HitZed(
|
||||||
if(bGenRegEffectOnPawn)
|
self,
|
||||||
|
niceRI,
|
||||||
|
targetZed,
|
||||||
|
hitLocation,
|
||||||
|
hitDirection,
|
||||||
|
headshotLevel
|
||||||
|
);
|
||||||
|
if (bGenRegEffectOnPawn) {
|
||||||
GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false);
|
GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
bHitZedCalled = true;
|
bHitZedCalled = true;
|
||||||
if (!bGhost && !bAlreadyHitZed) {
|
if (!bGhost && !bAlreadyHitZed) {
|
||||||
bAlreadyHitZed = true;
|
bAlreadyHitZed = true;
|
||||||
if(nicePlayer != none && niceRI != none)
|
if (nicePlayer != none && niceRI != none) {
|
||||||
niceRI.ServerJunkieExtension(nicePlayer, headshotLevel > 0.0);
|
niceRI.ServerJunkieExtension(nicePlayer, headshotLevel > 0.0);
|
||||||
}
|
}
|
||||||
if(charIsSticky)
|
}
|
||||||
|
if (charIsSticky) {
|
||||||
Stick(targetZed, hitLocation);
|
Stick(targetZed, hitLocation);
|
||||||
}
|
}
|
||||||
if(!class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, targetZed, (headshotLevel > 0.0), (headshotLevel > charDamageType.default.prReqPrecise))){
|
}
|
||||||
|
if (!class'NiceBulletAdapter'.static.ZedPenetration(
|
||||||
|
charDamage,
|
||||||
|
self,
|
||||||
|
targetZed,
|
||||||
|
(headshotLevel > 0.0),
|
||||||
|
(headshotLevel > charDamageType.default.prReqPrecise)
|
||||||
|
)
|
||||||
|
) {
|
||||||
charPenetrationCount += 1;
|
charPenetrationCount += 1;
|
||||||
KillBullet();
|
KillBullet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function HandleScream(Vector disintegrationLocation, Vector entryDirection) {
|
function HandleScream(Vector disintegrationLocation, Vector entryDirection) {
|
||||||
if(!charIsDud)
|
if (!charIsDud) {
|
||||||
GenerateImpactEffects(disintegrationImpact, disintegrationLocation, entryDirection);
|
GenerateImpactEffects(disintegrationImpact, disintegrationLocation, entryDirection);
|
||||||
|
}
|
||||||
class'NiceBulletAdapter'.static.HandleScream(self, niceRI, disintegrationLocation, entryDirection);
|
class'NiceBulletAdapter'.static.HandleScream(self, niceRI, disintegrationLocation, entryDirection);
|
||||||
}
|
}
|
||||||
function GenerateImpactEffects(ImpactEffect effect, Vector hitLocation, Vector hitNormal,
|
|
||||||
optional bool bWallImpact, optional bool bGenerateDecal){
|
function GenerateImpactEffects(
|
||||||
|
ImpactEffect effect,
|
||||||
|
Vector hitLocation,
|
||||||
|
Vector hitNormal,
|
||||||
|
optional bool bWallImpact,
|
||||||
|
optional bool bGenerateDecal
|
||||||
|
) {
|
||||||
local float actualCullDistance;
|
local float actualCullDistance;
|
||||||
local float actualImpactShift;
|
local float actualImpactShift;
|
||||||
local bool generatedEffect;
|
local bool generatedEffect;
|
||||||
|
|
||||||
// No need to play visuals on a server, for a dead bullets or in case there's no local player at all
|
// No need to play visuals on a server, for a dead bullets or in case there's no local player at all
|
||||||
if(Level.NetMode == NM_DedicatedServer || bBulletDead || localPlayer == none)
|
if (Level.NetMode == NM_DedicatedServer || bBulletDead || localPlayer == none) {
|
||||||
return;
|
return;
|
||||||
if(!localPlayer.CanSpawnEffect(bGhost) && !effect.bImportanEffect)
|
}
|
||||||
|
if (!localPlayer.CanSpawnEffect(bGhost) && !effect.bImportanEffect) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
// -- Classic effect
|
// -- Classic effect
|
||||||
if(effect.bPlayROEffect && !bBulletDead)
|
if (effect.bPlayROEffect && !bBulletDead) {
|
||||||
Spawn(class'ROBulletHitEffect',,, hitLocation, rotator(-hitNormal));
|
Spawn(class'ROBulletHitEffect',,, hitLocation, rotator(-hitNormal));
|
||||||
|
}
|
||||||
// -- Generate decal
|
// -- Generate decal
|
||||||
if (bGenerateDecal && effect.decalClass != none) {
|
if (bGenerateDecal && effect.decalClass != none) {
|
||||||
// Find appropriate cull distance for this decal
|
// Find appropriate cull distance for this decal
|
||||||
actualCullDistance = effect.decalClass.default.cullDistance;
|
actualCullDistance = effect.decalClass.default.cullDistance;
|
||||||
// Double cull distance if local player is an instigator
|
// Double cull distance if local player is an instigator
|
||||||
if(instigator != none && localPlayer == instigator.Controller)
|
if (instigator != none && localPlayer == instigator.Controller) {
|
||||||
actualCullDistance *= 2; // NICETODO: magic number
|
actualCullDistance *= 2; // NICETODO: magic number
|
||||||
|
}
|
||||||
// Spawn decal
|
// Spawn decal
|
||||||
if (!localPlayer.BeyondViewDistance(hitLocation, actualCullDistance)) {
|
if (!localPlayer.BeyondViewDistance(hitLocation, actualCullDistance)) {
|
||||||
Spawn(effect.decalClass, self,, hitLocation, rotator(- hitNormal));
|
Spawn(effect.decalClass, self,, hitLocation, rotator(- hitNormal));
|
||||||
@ -769,10 +925,11 @@ function GenerateImpactEffects(ImpactEffect effect, Vector hitLocation, Vector h
|
|||||||
}
|
}
|
||||||
// -- Generate custom effect
|
// -- Generate custom effect
|
||||||
if (effect.emitterClass != none && EffectIsRelevant(hitLocation, false)) {
|
if (effect.emitterClass != none && EffectIsRelevant(hitLocation, false)) {
|
||||||
if(bWallImpact)
|
if (bWallImpact) {
|
||||||
actualImpactShift = effect.emitterShiftWall;
|
actualImpactShift = effect.emitterShiftWall;
|
||||||
else
|
} else {
|
||||||
actualImpactShift = effect.emitterShiftPawn;
|
actualImpactShift = effect.emitterShiftPawn;
|
||||||
|
}
|
||||||
Spawn(effect.emitterClass,,, hitLocation - movementDirection * actualImpactShift, rotator(movementDirection));
|
Spawn(effect.emitterClass,,, hitLocation - movementDirection * actualImpactShift, rotator(movementDirection));
|
||||||
generatedEffect = true;
|
generatedEffect = true;
|
||||||
}
|
}
|
||||||
@ -783,28 +940,43 @@ function GenerateImpactEffects(ImpactEffect effect, Vector hitLocation, Vector h
|
|||||||
Spawn(class'NiceSoundCls',,, hitLocation);
|
Spawn(class'NiceSoundCls',,, hitLocation);
|
||||||
generatedEffect = true;
|
generatedEffect = true;
|
||||||
}
|
}
|
||||||
if(generatedEffect)
|
if (generatedEffect) {
|
||||||
localPlayer.AddEffect();
|
localPlayer.AddEffect();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function ShakeView(Vector hitLocation) {
|
function ShakeView(Vector hitLocation) {
|
||||||
local float distance, scale;
|
local float distance, scale;
|
||||||
if(nicePlayer == none || shakeRadiusMult < 0.0)
|
|
||||||
|
if (nicePlayer == none || shakeRadiusMult < 0.0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
distance = VSize(hitLocation - nicePlayer.ViewTarget.Location);
|
distance = VSize(hitLocation - nicePlayer.ViewTarget.Location);
|
||||||
if (distance < charExplosionRadius * shakeRadiusMult) {
|
if (distance < charExplosionRadius * shakeRadiusMult) {
|
||||||
if(distance < charExplosionRadius)
|
if (distance < charExplosionRadius) {
|
||||||
scale = 1.0;
|
scale = 1.0;
|
||||||
else
|
} else {
|
||||||
scale = (charExplosionRadius * ShakeRadiusMult - distance) / (charExplosionRadius);
|
scale = (charExplosionRadius * ShakeRadiusMult - distance) / (charExplosionRadius);
|
||||||
nicePlayer.ShakeView(shakeRotMag*scale, shakeRotRate, shakeRotTime, shakeOffsetMag * scale, shakeOffsetRate, shakeOffsetTime);
|
}
|
||||||
|
nicePlayer.ShakeView(
|
||||||
|
shakeRotMag * scale,
|
||||||
|
shakeRotRate,
|
||||||
|
shakeRotTime,
|
||||||
|
shakeOffsetMag * scale,
|
||||||
|
shakeOffsetRate,
|
||||||
|
shakeOffsetTime
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function KillBullet() {
|
function KillBullet() {
|
||||||
local int i;
|
local int i;
|
||||||
|
|
||||||
if (bulletTrail != none) {
|
if (bulletTrail != none) {
|
||||||
for (i = 0; i < bulletTrail.Emitters.Length; i ++) {
|
for (i = 0; i < bulletTrail.Emitters.Length; i ++) {
|
||||||
if(bulletTrail.Emitters[i] == none)
|
if (bulletTrail.Emitters[i] == none) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
bulletTrail.Emitters[i].ParticlesPerSecond = 0;
|
bulletTrail.Emitters[i].ParticlesPerSecond = 0;
|
||||||
bulletTrail.Emitters[i].InitialParticlesPerSecond = 0;
|
bulletTrail.Emitters[i].InitialParticlesPerSecond = 0;
|
||||||
bulletTrail.Emitters[i].RespawnDeadParticles = false;
|
bulletTrail.Emitters[i].RespawnDeadParticles = false;
|
||||||
@ -812,6 +984,7 @@ function KillBullet(){
|
|||||||
bulletTrail.SetBase(none);
|
bulletTrail.SetBase(none);
|
||||||
bulletTrail.AutoDestroy = true;
|
bulletTrail.AutoDestroy = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bulletXTrail != none) {
|
if (bulletXTrail != none) {
|
||||||
bulletXTrail.mRegen = false;
|
bulletXTrail.mRegen = false;
|
||||||
bulletXTrail.LifeSpan = LifeSpan;
|
bulletXTrail.LifeSpan = LifeSpan;
|
||||||
@ -821,12 +994,12 @@ function KillBullet(){
|
|||||||
SoundVolume = 0;
|
SoundVolume = 0;
|
||||||
LifeSpan = FMin(LifeSpan, 0.1);
|
LifeSpan = FMin(LifeSpan, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
event Destroyed() {
|
event Destroyed() {
|
||||||
KillBullet();
|
KillBullet();
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultproperties
|
defaultproperties {
|
||||||
{
|
|
||||||
insideBouncesLeft=2
|
insideBouncesLeft=2
|
||||||
trajUpdFreq=0.100000
|
trajUpdFreq=0.100000
|
||||||
maxTraceCycles=128
|
maxTraceCycles=128
|
||||||
|
@ -9,57 +9,132 @@
|
|||||||
// E-mail: dkanus@gmail.com
|
// E-mail: dkanus@gmail.com
|
||||||
//======================================================================================================================
|
//======================================================================================================================
|
||||||
class NiceBulletAdapter extends Object;
|
class NiceBulletAdapter extends Object;
|
||||||
|
|
||||||
var const int BigZedMinHealth; // If zed's base Health >= this value, zed counts as Big
|
var const int BigZedMinHealth; // If zed's base Health >= this value, zed counts as Big
|
||||||
var const int MediumZedMinHealth; // If zed's base Health >= this value, zed counts as Medium-size
|
var const int MediumZedMinHealth; // If zed's base Health >= this value, zed counts as Medium-size
|
||||||
static function Explode(NiceBullet bullet, NiceReplicationInfo niceRI, Vector hitLocation, optional Actor explosionTarget){
|
|
||||||
|
static function Explode(
|
||||||
|
NiceBullet bullet,
|
||||||
|
NiceReplicationInfo niceRI,
|
||||||
|
Vector hitLocation,
|
||||||
|
optional Actor explosionTarget
|
||||||
|
) {
|
||||||
if (!bullet.bGhost) {
|
if (!bullet.bGhost) {
|
||||||
niceRI.ServerExplode(bullet.charExplosionDamage, bullet.charExplosionRadius, bullet.charExplosionExponent,
|
niceRI.ServerExplode(
|
||||||
bullet.charExplosionDamageType, bullet.charExplosionMomentum, hitLocation, bullet.instigator, true,
|
bullet.charExplosionDamage,
|
||||||
explosionTarget, Vector(bullet.Rotation));
|
bullet.charExplosionRadius,
|
||||||
if(KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead)
|
bullet.charExplosionExponent,
|
||||||
niceRI.ServerDealDamage(KFMonster(bullet.base), bullet.charExplosionDamage, bullet.instigator, hitLocation,
|
bullet.charExplosionDamageType,
|
||||||
bullet.charExplosionMomentum * vect(0,0,-1), bullet.charExplosionDamageType, 1.0);
|
bullet.charExplosionMomentum,
|
||||||
|
hitLocation,
|
||||||
|
bullet.instigator,
|
||||||
|
true,
|
||||||
|
explosionTarget,
|
||||||
|
Vector(bullet.Rotation)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead) {
|
||||||
|
niceRI.ServerDealDamage(
|
||||||
|
KFMonster(bullet.base),
|
||||||
|
bullet.charExplosionDamage,
|
||||||
|
bullet.instigator,
|
||||||
|
hitLocation,
|
||||||
|
bullet.charExplosionMomentum * vect(0, 0, -1),
|
||||||
|
bullet.charExplosionDamageType,
|
||||||
|
1.0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static function HandleCalibration
|
}
|
||||||
(
|
|
||||||
|
static function HandleCalibration (
|
||||||
bool isHeadshot,
|
bool isHeadshot,
|
||||||
NiceHumanPawn nicePawn,
|
NiceHumanPawn nicePawn,
|
||||||
NiceMonster targetZed
|
NiceMonster targetZed
|
||||||
) {
|
) {
|
||||||
if(nicePawn == none) return;
|
if (nicePawn == none || nicePawn.currentCalibrationState != CALSTATE_ACTIVE) {
|
||||||
if(nicePawn.currentCalibrationState != CALSTATE_ACTIVE) return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nicePawn.ServerUpdateCalibration(isHeadshot, targetZed);
|
nicePawn.ServerUpdateCalibration(isHeadshot, targetZed);
|
||||||
}
|
}
|
||||||
static function HitWall(NiceBullet bullet, NiceReplicationInfo niceRI, Actor targetWall,
|
|
||||||
Vector hitLocation, Vector hitNormal){
|
static function HitWall(
|
||||||
|
NiceBullet bullet,
|
||||||
|
NiceReplicationInfo niceRI,
|
||||||
|
Actor targetWall,
|
||||||
|
Vector hitLocation,
|
||||||
|
Vector hitNormal
|
||||||
|
) {
|
||||||
local NicePlayerController nicePlayer;
|
local NicePlayerController nicePlayer;
|
||||||
|
|
||||||
nicePlayer = NicePlayerController(bullet.Instigator.Controller);
|
nicePlayer = NicePlayerController(bullet.Instigator.Controller);
|
||||||
if(nicePlayer == none)
|
if (nicePlayer == none) {
|
||||||
return;
|
return;
|
||||||
if(!bullet.bAlreadyHitZed)
|
}
|
||||||
|
if (!bullet.bAlreadyHitZed) {
|
||||||
HandleCalibration(false, NiceHumanPawn(bullet.Instigator), none);
|
HandleCalibration(false, NiceHumanPawn(bullet.Instigator), none);
|
||||||
if(!targetWall.bStatic && !targetWall.bWorldGeometry && nicePlayer != none && (nicePlayer.wallHitsLeft > 0 || Projectile(targetWall) != none)){
|
}
|
||||||
niceRI.ServerDealDamage(targetWall, bullet.charOrigDamage, bullet.Instigator, hitLocation,
|
if (
|
||||||
bullet.charMomentumTransfer * hitNormal, bullet.charDamageType);
|
!targetWall.bStatic &&
|
||||||
|
!targetWall.bWorldGeometry &&
|
||||||
|
nicePlayer != none &&
|
||||||
|
(nicePlayer.wallHitsLeft > 0 || Projectile(targetWall) != none)
|
||||||
|
) {
|
||||||
|
niceRI.ServerDealDamage(
|
||||||
|
targetWall,
|
||||||
|
bullet.charOrigDamage,
|
||||||
|
bullet.Instigator,
|
||||||
|
hitLocation,
|
||||||
|
bullet.charMomentumTransfer * hitNormal,
|
||||||
|
bullet.charDamageType
|
||||||
|
);
|
||||||
nicePlayer.wallHitsLeft --;
|
nicePlayer.wallHitsLeft --;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static function HandleScream(NiceBullet bullet, NiceReplicationInfo niceRI, Vector location, Vector entryDirection){
|
|
||||||
|
static function HandleScream(
|
||||||
|
NiceBullet bullet,
|
||||||
|
NiceReplicationInfo niceRI,
|
||||||
|
Vector location,
|
||||||
|
Vector entryDirection
|
||||||
|
) {
|
||||||
bullet.charIsDud = true;
|
bullet.charIsDud = true;
|
||||||
}
|
}
|
||||||
static function HitPawn(NiceBullet bullet, NiceReplicationInfo niceRI, KFPawn targetPawn, Vector hitLocation,
|
|
||||||
Vector hitNormal, array<int> hitPoints){
|
static function HitPawn(
|
||||||
|
NiceBullet bullet,
|
||||||
|
NiceReplicationInfo niceRI,
|
||||||
|
KFPawn targetPawn,
|
||||||
|
Vector hitLocation,
|
||||||
|
Vector hitNormal,
|
||||||
|
array<int> hitPoints
|
||||||
|
) {
|
||||||
local NiceMedicProjectile niceDart;
|
local NiceMedicProjectile niceDart;
|
||||||
|
|
||||||
niceDart = NiceMedicProjectile(bullet);
|
niceDart = NiceMedicProjectile(bullet);
|
||||||
if(niceDart == none)
|
if (niceDart == none) {
|
||||||
niceRI.ServerDealDamage(targetPawn, bullet.charDamage, bullet.instigator, HitLocation,
|
niceRI.ServerDealDamage(
|
||||||
hitNormal * bullet.charMomentumTransfer, bullet.charDamageType);
|
targetPawn,
|
||||||
else
|
bullet.charDamage,
|
||||||
|
bullet.instigator,
|
||||||
|
HitLocation,
|
||||||
|
hitNormal * bullet.charMomentumTransfer,
|
||||||
|
bullet.charDamageType
|
||||||
|
);
|
||||||
|
} else {
|
||||||
niceRI.ServerHealTarget(NiceHumanPawn(targetPawn), bullet.charDamage, bullet.instigator);
|
niceRI.ServerHealTarget(NiceHumanPawn(targetPawn), bullet.charDamage, bullet.instigator);
|
||||||
}
|
}
|
||||||
static function HitZed(NiceBullet bullet, NiceReplicationInfo niceRI, KFMonster kfZed, Vector hitLocation,
|
}
|
||||||
Vector hitNormal, float headshotLevel){
|
|
||||||
|
static function HitZed(
|
||||||
|
NiceBullet bullet,
|
||||||
|
NiceReplicationInfo niceRI,
|
||||||
|
KFMonster kfZed,
|
||||||
|
Vector hitLocation,
|
||||||
|
Vector hitNormal,
|
||||||
|
float headshotLevel
|
||||||
|
) {
|
||||||
local bool bIsHeadshot, bIsPreciseHeadshot;
|
local bool bIsHeadshot, bIsPreciseHeadshot;
|
||||||
local float actualDamage;
|
local float actualDamage;
|
||||||
local int lockonTicks;
|
local int lockonTicks;
|
||||||
@ -68,37 +143,54 @@ static function HitZed(NiceBullet bullet, NiceReplicationInfo niceRI, KFMonster
|
|||||||
local NiceHumanPawn nicePawn;
|
local NiceHumanPawn nicePawn;
|
||||||
local NicePlayerController nicePlayer;
|
local NicePlayerController nicePlayer;
|
||||||
local class<NiceVeterancyTypes> niceVet;
|
local class<NiceVeterancyTypes> niceVet;
|
||||||
|
|
||||||
nicePlayer = NicePlayerController(bullet.Instigator.Controller);
|
nicePlayer = NicePlayerController(bullet.Instigator.Controller);
|
||||||
if ( nicePlayer != none && nicePlayer.abilityManager != none
|
if (
|
||||||
&& nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillEnforcerBruteA'.default.abilityID)) {
|
nicePlayer != none &&
|
||||||
|
nicePlayer.abilityManager != none &&
|
||||||
|
nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillEnforcerBruteA'.default.abilityID)
|
||||||
|
) {
|
||||||
headshotLevel = 0.0;
|
headshotLevel = 0.0;
|
||||||
}
|
}
|
||||||
bIsHeadshot = (headshotLevel > 0.0);
|
bIsHeadshot = (headshotLevel > 0.0);
|
||||||
bIsPreciseHeadshot = (headshotLevel > bullet.charDamageType.default.prReqPrecise);
|
bIsPreciseHeadshot = (headshotLevel > bullet.charDamageType.default.prReqPrecise);
|
||||||
if(!bullet.bAlreadyHitZed || bIsHeadshot)
|
if (!bullet.bAlreadyHitZed || bIsHeadshot) {
|
||||||
HandleCalibration(bIsHeadshot, NiceHumanPawn(bullet.Instigator), NiceMonster(kfZed));
|
HandleCalibration(bIsHeadshot, NiceHumanPawn(bullet.Instigator), NiceMonster(kfZed));
|
||||||
if(bIsHeadshot && bullet.sourceWeapon != none)
|
}
|
||||||
|
if (bIsHeadshot && bullet.sourceWeapon != none) {
|
||||||
bullet.sourceWeapon.lastHeadshotTime = bullet.Level.TimeSeconds;
|
bullet.sourceWeapon.lastHeadshotTime = bullet.Level.TimeSeconds;
|
||||||
if(nicePlayer == none)
|
}
|
||||||
|
if (nicePlayer == none) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
nicePawn = NiceHumanPawn(bullet.instigator);
|
nicePawn = NiceHumanPawn(bullet.instigator);
|
||||||
if( !bIsHeadshot
|
if (
|
||||||
&& nicePawn != none
|
!bIsHeadshot &&
|
||||||
&& nicePlayer.abilityManager != none
|
nicePawn != none &&
|
||||||
&& nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillSharpshooterReaperA'.default.abilityID))
|
nicePlayer.abilityManager != none &&
|
||||||
|
nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillSharpshooterReaperA'.default.abilityID)
|
||||||
|
) {
|
||||||
nicePawn.ServerCooldownAbility(class'NiceSkillSharpshooterReaperA'.default.abilityID);
|
nicePawn.ServerCooldownAbility(class'NiceSkillSharpshooterReaperA'.default.abilityID);
|
||||||
|
}
|
||||||
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
|
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
|
||||||
if(bullet.charCausePain)
|
if (bullet.charCausePain) {
|
||||||
actualDamage = bullet.charOrigDamage;
|
actualDamage = bullet.charOrigDamage;
|
||||||
else
|
} else {
|
||||||
actualDamage = bullet.charDamage;
|
actualDamage = bullet.charDamage;
|
||||||
if(headshotLevel > 0)
|
}
|
||||||
|
if (headshotLevel > 0) {
|
||||||
actualDamage *= bullet.charContiniousBonus;
|
actualDamage *= bullet.charContiniousBonus;
|
||||||
if(bullet.bGrazing)
|
}
|
||||||
|
if (bullet.bGrazing) {
|
||||||
actualDamage *= class'NiceSkillSupportGraze'.default.grazeDamageMult;
|
actualDamage *= class'NiceSkillSupportGraze'.default.grazeDamageMult;
|
||||||
|
}
|
||||||
bullet.bGrazing = false;
|
bullet.bGrazing = false;
|
||||||
if(kfZed == bullet.lockonZed && bullet.lockonTime > bullet.sourceWeapon.stdFireRate
|
if (
|
||||||
&& niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterKillConfirmed')){
|
kfZed == bullet.lockonZed &&
|
||||||
|
bullet.lockonTime > bullet.sourceWeapon.stdFireRate &&
|
||||||
|
niceVet != none &&
|
||||||
|
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterKillConfirmed')
|
||||||
|
) {
|
||||||
lockOnTickRate =class'NiceSkillSharpshooterKillConfirmed'.default.stackDelay;
|
lockOnTickRate =class'NiceSkillSharpshooterKillConfirmed'.default.stackDelay;
|
||||||
lockonTicks = Ceil(bullet.lockonTime / lockOnTickRate) - 1;
|
lockonTicks = Ceil(bullet.lockonTime / lockOnTickRate) - 1;
|
||||||
lockonTicks = Min(class'NiceSkillSharpshooterKillConfirmed'.default.maxStacks, lockonTicks);
|
lockonTicks = Min(class'NiceSkillSharpshooterKillConfirmed'.default.maxStacks, lockonTicks);
|
||||||
@ -107,35 +199,57 @@ static function HitZed(NiceBullet bullet, NiceReplicationInfo niceRI, KFMonster
|
|||||||
// damageMod *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus;
|
// damageMod *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus;
|
||||||
actualDamage *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus;
|
actualDamage *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus;
|
||||||
}
|
}
|
||||||
if(!bullet.bGhost)
|
if (!bullet.bGhost) {
|
||||||
niceRI.ServerDealDamage(kfZed, actualDamage, bullet.instigator, hitLocation,
|
niceRI.ServerDealDamage(
|
||||||
bullet.charMomentumTransfer * hitNormal, bullet.charDamageType, headshotLevel, bullet.lockonTime);
|
kfZed,
|
||||||
|
actualDamage,
|
||||||
|
bullet.instigator,
|
||||||
|
hitLocation,
|
||||||
|
bullet.charMomentumTransfer * hitNormal,
|
||||||
|
bullet.charDamageType,
|
||||||
|
headshotLevel,
|
||||||
|
bullet.lockonTime
|
||||||
|
);
|
||||||
|
}
|
||||||
//// Handle angled shots
|
//// Handle angled shots
|
||||||
angle = asin(hitNormal.Z);
|
angle = asin(hitNormal.Z);
|
||||||
// Apply angled shots
|
// Apply angled shots
|
||||||
if ((angle > 0.8 || angle < -0.45) && bullet.bCanAngleDamage && kfZed != none) {
|
if ((angle > 0.8 || angle < -0.45) && bullet.bCanAngleDamage && kfZed != none) {
|
||||||
bullet.bCanAngleDamage = false;
|
bullet.bCanAngleDamage = false;
|
||||||
bullet.bAlreadyHitZed = true;
|
bullet.bAlreadyHitZed = true;
|
||||||
if(ZedPenetration(bullet.charDamage, bullet, kfZed, bIsHeadshot, bIsPreciseHeadshot))
|
if (ZedPenetration(bullet.charDamage, bullet, kfZed, bIsHeadshot, bIsPreciseHeadshot)) {
|
||||||
HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel);
|
HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//// 'Bore' support skill
|
//// 'Bore' support skill
|
||||||
if( niceVet != none && nicePlayer.IsZedTimeActive() && bullet.insideBouncesLeft > 0
|
if (
|
||||||
&& niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBore')){
|
niceVet != none &&
|
||||||
|
nicePlayer.IsZedTimeActive() &&
|
||||||
|
bullet.insideBouncesLeft > 0 &&
|
||||||
|
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBore')
|
||||||
|
) {
|
||||||
// Count one bounce
|
// Count one bounce
|
||||||
bullet.insideBouncesLeft --;
|
bullet.insideBouncesLeft --;
|
||||||
// Swap head-shot level
|
// Swap head-shot level
|
||||||
if(headshotLevel <= 0.0)
|
if (headshotLevel <= 0.0) {
|
||||||
headshotLevel = class'NiceSkillSupportZEDBore'.default.minHeadshotPrecision;
|
headshotLevel = class'NiceSkillSupportZEDBore'.default.minHeadshotPrecision;
|
||||||
else
|
} else {
|
||||||
headshotLevel = -headshotLevel;
|
headshotLevel = -headshotLevel;
|
||||||
|
}
|
||||||
// Deal next batch of damage
|
// Deal next batch of damage
|
||||||
ZedPenetration(bullet.charDamage, bullet, kfZed, false, false);
|
ZedPenetration(bullet.charDamage, bullet, kfZed, false, false);
|
||||||
HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel);
|
HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel);
|
||||||
}
|
}
|
||||||
bullet.insideBouncesLeft = 2;
|
bullet.insideBouncesLeft = 2;
|
||||||
}
|
}
|
||||||
static function bool ZedPenetration(out float Damage, NiceBullet bullet, KFMonster targetZed, bool bIsHeadshot, bool bIsPreciseHeadshot){
|
|
||||||
|
static function bool ZedPenetration(
|
||||||
|
out float Damage,
|
||||||
|
NiceBullet bullet,
|
||||||
|
KFMonster targetZed,
|
||||||
|
bool bIsHeadshot,
|
||||||
|
bool bIsPreciseHeadshot
|
||||||
|
) {
|
||||||
local float reductionMod;
|
local float reductionMod;
|
||||||
local NiceMonster niceZed;
|
local NiceMonster niceZed;
|
||||||
local NicePlayerController nicePlayer;
|
local NicePlayerController nicePlayer;
|
||||||
@ -144,31 +258,49 @@ static function bool ZedPenetration(out float Damage, NiceBullet bullet, KFMonst
|
|||||||
local class<NiceWeaponDamageType> niceDmgType;
|
local class<NiceWeaponDamageType> niceDmgType;
|
||||||
// True if we can penetrate even body, but now penetrating a head and shouldn't reduce damage too much
|
// True if we can penetrate even body, but now penetrating a head and shouldn't reduce damage too much
|
||||||
local bool bEasyHeadPenetration;
|
local bool bEasyHeadPenetration;
|
||||||
|
|
||||||
// Init variables
|
// Init variables
|
||||||
niceZed = NiceMonster(targetZed);
|
niceZed = NiceMonster(targetZed);
|
||||||
nicePlayer = NicePlayerController(bullet.Instigator.Controller);
|
nicePlayer = NicePlayerController(bullet.Instigator.Controller);
|
||||||
niceVet = none;
|
niceVet = none;
|
||||||
if(nicePlayer != none)
|
if (nicePlayer != none) {
|
||||||
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
|
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
|
||||||
|
}
|
||||||
niceDmgType = bullet.charDamageType;
|
niceDmgType = bullet.charDamageType;
|
||||||
bEasyHeadPenetration = bIsHeadshot && !niceDmgType.default.bPenetrationHSOnly;
|
bEasyHeadPenetration = bIsHeadshot && !niceDmgType.default.bPenetrationHSOnly;
|
||||||
reductionMod = 1.0f;
|
reductionMod = 1.0f;
|
||||||
// Apply zed reduction and perk reduction of reduction`
|
// Apply zed reduction and perk reduction of reduction`
|
||||||
if (niceZed != none) {
|
if (niceZed != none) {
|
||||||
// Railgun skill exception
|
// Railgun skill exception
|
||||||
if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterZEDRailgun') && nicePlayer.IsZedTimeActive())
|
if (
|
||||||
|
niceVet != none &&
|
||||||
|
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterZEDRailgun') &&
|
||||||
|
nicePlayer.IsZedTimeActive()
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
if(niceZed.default.Health >= default.BigZedMinHealth && !bEasyHeadPenetration)
|
}
|
||||||
|
if (niceZed.default.Health >= default.BigZedMinHealth && !bEasyHeadPenetration) {
|
||||||
reductionMod *= niceDmgType.default.BigZedPenDmgReduction;
|
reductionMod *= niceDmgType.default.BigZedPenDmgReduction;
|
||||||
else if(niceZed.default.Health >= default.MediumZedMinHealth && !bEasyHeadPenetration)
|
} else if (niceZed.default.Health >= default.MediumZedMinHealth && !bEasyHeadPenetration) {
|
||||||
reductionMod *= niceDmgType.default.MediumZedPenDmgReduction;
|
reductionMod *= niceDmgType.default.MediumZedPenDmgReduction;
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
reductionMod *= niceDmgType.default.BigZedPenDmgReduction;
|
reductionMod *= niceDmgType.default.BigZedPenDmgReduction;
|
||||||
if(niceVet != none)
|
}
|
||||||
reductionMod = niceVet.static.GetPenetrationDamageMulti(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo), reductionMod, niceDmgType);
|
if (niceVet != none) {
|
||||||
|
reductionMod = niceVet.static.GetPenetrationDamageMulti(
|
||||||
|
KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo),
|
||||||
|
reductionMod,
|
||||||
|
niceDmgType
|
||||||
|
);
|
||||||
|
}
|
||||||
actualMaxPenetrations = niceDmgType.default.maxPenetrations;
|
actualMaxPenetrations = niceDmgType.default.maxPenetrations;
|
||||||
if(niceVet != none && !bullet.charWasHipFired && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterSurgical') && bIsHeadshot){
|
if (
|
||||||
|
niceVet != none &&
|
||||||
|
!bullet.charWasHipFired &&
|
||||||
|
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterSurgical') &&
|
||||||
|
bIsHeadshot
|
||||||
|
) {
|
||||||
actualMaxPenetrations += 1;
|
actualMaxPenetrations += 1;
|
||||||
reductionMod = FMax(reductionMod, class'NiceSkillSharpshooterSurgical'.default.penDmgReduction);
|
reductionMod = FMax(reductionMod, class'NiceSkillSharpshooterSurgical'.default.penDmgReduction);
|
||||||
}
|
}
|
||||||
@ -176,20 +308,24 @@ static function bool ZedPenetration(out float Damage, NiceBullet bullet, KFMonst
|
|||||||
Damage *= reductionMod * niceDmgType.default.PenDmgReduction;
|
Damage *= reductionMod * niceDmgType.default.PenDmgReduction;
|
||||||
bullet.decapMod *= reductionMod * niceDmgType.default.PenDecapReduction;
|
bullet.decapMod *= reductionMod * niceDmgType.default.PenDecapReduction;
|
||||||
bullet.incapMod *= reductionMod * niceDmgType.default.PenIncapReduction;
|
bullet.incapMod *= reductionMod * niceDmgType.default.PenIncapReduction;
|
||||||
if(niceVet != none && actualMaxPenetrations >= 0)
|
if (niceVet != none && actualMaxPenetrations >= 0) {
|
||||||
actualMaxPenetrations +=
|
actualMaxPenetrations +=
|
||||||
niceVet.static.GetAdditionalPenetrationAmount(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
|
niceVet.static.GetAdditionalPenetrationAmount(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
|
||||||
if(!bIsHeadshot && niceDmgType.default.bPenetrationHSOnly)
|
}
|
||||||
|
if (!bIsHeadshot && niceDmgType.default.bPenetrationHSOnly) {
|
||||||
return false;
|
return false;
|
||||||
if(actualMaxPenetrations < 0)
|
}
|
||||||
|
if (actualMaxPenetrations < 0) {
|
||||||
return true;
|
return true;
|
||||||
if(Damage / bullet.charOrigDamage < (niceDmgType.default.PenDmgReduction ** (actualMaxPenetrations + 1)) + 0.0001 || Damage < 1)
|
}
|
||||||
|
if (Damage / bullet.charOrigDamage < (niceDmgType.default.PenDmgReduction ** (actualMaxPenetrations + 1)) + 0.0001 || Damage < 1) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultproperties
|
defaultproperties {
|
||||||
{
|
|
||||||
BigZedMinHealth=1000
|
BigZedMinHealth=1000
|
||||||
MediumZedMinHealth=500
|
MediumZedMinHealth=500
|
||||||
}
|
}
|
@ -1,76 +1,160 @@
|
|||||||
class NiceProjectileSpawner extends Actor
|
class NiceProjectileSpawner extends Actor
|
||||||
dependson(NiceBullet);
|
dependson(NiceBullet);
|
||||||
|
|
||||||
// NICETODO: use flags correctly
|
// NICETODO: use flags correctly
|
||||||
static function MakeProjectile(Vector start, Rotator dir, NiceFire.ShotType shotParams, NiceFire.FireModeContext fireContext, optional bool bForceComplexTraj,
|
static function MakeProjectile(
|
||||||
optional bool bDuplReal, optional bool bSkipGhosts){
|
Vector start,
|
||||||
|
Rotator dir,
|
||||||
|
NiceFire.ShotType shotParams,
|
||||||
|
NiceFire.FireModeContext fireContext,
|
||||||
|
optional bool bForceComplexTraj,
|
||||||
|
optional bool bDuplReal,
|
||||||
|
optional bool bSkipGhosts
|
||||||
|
) {
|
||||||
local int i;
|
local int i;
|
||||||
local NicePack niceMut;
|
local NicePack niceMut;
|
||||||
|
|
||||||
niceMut = class'NicePack'.static.Myself(fireContext.Instigator.Level);
|
niceMut = class'NicePack'.static.Myself(fireContext.Instigator.Level);
|
||||||
if(niceMut == none)
|
if (niceMut == none) {
|
||||||
return;
|
return;
|
||||||
if(fireContext.Instigator.Role < ROLE_Authority || bDuplReal)
|
}
|
||||||
|
if (fireContext.Instigator.Role < ROLE_Authority || bDuplReal) {
|
||||||
SpawnProjectile(Start, Dir, shotParams, fireContext, false, bForceComplexTraj);
|
SpawnProjectile(Start, Dir, shotParams, fireContext, false, bForceComplexTraj);
|
||||||
|
}
|
||||||
if (fireContext.Instigator.Role == ROLE_Authority && niceMut != none && !bSkipGhosts) {
|
if (fireContext.Instigator.Role == ROLE_Authority && niceMut != none && !bSkipGhosts) {
|
||||||
for (i = 0; i < niceMut.playersList.Length; i++) {
|
for (i = 0; i < niceMut.playersList.Length; i++) {
|
||||||
if(niceMut.playersList[i] != fireContext.Instigator.Controller)
|
if (niceMut.playersList[i] != fireContext.Instigator.Controller) {
|
||||||
niceMut.playersList[i].ClientSpawnGhostProjectile(start, dir.pitch, dir.yaw, dir.roll, shotParams, fireContext, bForceComplexTraj);
|
niceMut.playersList[i].ClientSpawnGhostProjectile(
|
||||||
|
start,
|
||||||
|
dir.pitch,
|
||||||
|
dir.yaw,
|
||||||
|
dir.roll,
|
||||||
|
shotParams,
|
||||||
|
fireContext,
|
||||||
|
bForceComplexTraj
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static function StickProjectile(KFHumanPawn instigator, Actor base, name bone, Vector shift, Rotator direction,
|
}
|
||||||
NiceBullet.ExplosionData expData, optional bool bDuplReal, optional bool bSkipGhosts){
|
|
||||||
|
static function StickProjectile(
|
||||||
|
KFHumanPawn instigator,
|
||||||
|
Actor base,
|
||||||
|
name bone,
|
||||||
|
Vector shift,
|
||||||
|
Rotator direction,
|
||||||
|
NiceBullet.ExplosionData expData,
|
||||||
|
optional bool bDuplReal,
|
||||||
|
optional bool bSkipGhosts
|
||||||
|
) {
|
||||||
local int i;
|
local int i;
|
||||||
local NicePack niceMut;
|
local NicePack niceMut;
|
||||||
|
|
||||||
niceMut = class'NicePack'.static.Myself(expData.Instigator.Level);
|
niceMut = class'NicePack'.static.Myself(expData.Instigator.Level);
|
||||||
if(niceMut == none)
|
if (niceMut == none) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
niceMut.stuckCounter ++;
|
niceMut.stuckCounter ++;
|
||||||
if(expData.Instigator.Role < ROLE_Authority)
|
if (expData.Instigator.Role < ROLE_Authority) {
|
||||||
SpawnStuckProjectile(instigator, base, bone, shift, direction, expData, false, niceMut.stuckCounter);
|
SpawnStuckProjectile(
|
||||||
|
instigator,
|
||||||
|
base,
|
||||||
|
bone,
|
||||||
|
shift,
|
||||||
|
direction,
|
||||||
|
expData,
|
||||||
|
false,
|
||||||
|
niceMut.stuckCounter
|
||||||
|
);
|
||||||
|
}
|
||||||
if (expData.Instigator.Role == ROLE_Authority && niceMut != none) {
|
if (expData.Instigator.Role == ROLE_Authority && niceMut != none) {
|
||||||
for (i = 0; i < niceMut.playersList.Length; i++) {
|
for (i = 0; i < niceMut.playersList.Length; i++) {
|
||||||
if( (niceMut.playersList[i] != expData.Instigator.Controller && !bSkipGhosts)
|
if (
|
||||||
|| (niceMut.playersList[i] == expData.Instigator.Controller && bDuplReal) )
|
(niceMut.playersList[i] != expData.Instigator.Controller && !bSkipGhosts) ||
|
||||||
niceMut.playersList[i].ClientStickGhostProjectile(instigator, base, bone, shift, direction, expData,
|
(niceMut.playersList[i] == expData.Instigator.Controller && bDuplReal)
|
||||||
niceMut.stuckCounter);
|
) {
|
||||||
|
niceMut.playersList[i].ClientStickGhostProjectile(
|
||||||
|
instigator,
|
||||||
|
base,
|
||||||
|
bone,
|
||||||
|
shift,
|
||||||
|
direction,
|
||||||
|
expData,
|
||||||
|
niceMut.stuckCounter
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static function NiceBullet SpawnProjectile(Vector Start, Rotator Dir, NiceFire.ShotType shotParams, NiceFire.FireModeContext fireContext, optional bool bIsGhost, optional bool bForceComplexTraj){
|
}
|
||||||
|
|
||||||
|
static function NiceBullet SpawnProjectile(
|
||||||
|
Vector Start,
|
||||||
|
Rotator Dir,
|
||||||
|
NiceFire.ShotType shotParams,
|
||||||
|
NiceFire.FireModeContext fireContext,
|
||||||
|
optional bool bIsGhost,
|
||||||
|
optional bool bForceComplexTraj
|
||||||
|
) {
|
||||||
local Actor other;
|
local Actor other;
|
||||||
local NiceBullet niceProj;
|
local NiceBullet niceProj;
|
||||||
local Vector HitLocation, HitNormal;
|
local Vector HitLocation, HitNormal;
|
||||||
local NicePlayerController nicePlayer;
|
local NicePlayerController nicePlayer;
|
||||||
local class<NiceVeterancyTypes> niceVet;
|
local class<NiceVeterancyTypes> niceVet;
|
||||||
|
|
||||||
// No class - no projectile
|
// No class - no projectile
|
||||||
if(shotParams.bulletClass == none)
|
if (shotParams.bulletClass == none) {
|
||||||
return none;
|
return none;
|
||||||
|
}
|
||||||
// Try to spawn
|
// Try to spawn
|
||||||
if(fireContext.Instigator != none)
|
if (fireContext.Instigator != none) {
|
||||||
niceProj = fireContext.Instigator.Spawn(shotParams.bulletClass,,, Start, Dir);
|
niceProj = fireContext.Instigator.Spawn(shotParams.bulletClass,,, Start, Dir);
|
||||||
|
}
|
||||||
// Try harder
|
// Try harder
|
||||||
if (niceProj == none && fireContext.Instigator != none) {
|
if (niceProj == none && fireContext.Instigator != none) {
|
||||||
other = fireContext.Instigator.Trace(HitLocation, HitNormal, Start, fireContext.Instigator.Location + fireContext.Instigator.EyePosition(), false, Vect(0,0,1));
|
other = fireContext.Instigator.Trace(
|
||||||
if(other != none)
|
HitLocation,
|
||||||
|
HitNormal,
|
||||||
|
Start,
|
||||||
|
fireContext.Instigator.Location + fireContext.Instigator.EyePosition(),
|
||||||
|
false,
|
||||||
|
Vect(0, 0, 1)
|
||||||
|
);
|
||||||
|
if (other != none) {
|
||||||
Start = HitLocation;
|
Start = HitLocation;
|
||||||
|
}
|
||||||
niceProj = fireContext.Instigator.Spawn(shotParams.bulletClass,,, Start, Dir);
|
niceProj = fireContext.Instigator.Spawn(shotParams.bulletClass,,, Start, Dir);
|
||||||
}
|
}
|
||||||
// Give up if failed after these two attempts
|
// Give up if failed after these two attempts
|
||||||
if(niceProj == none)
|
if (niceProj == none) {
|
||||||
return none;
|
return none;
|
||||||
|
}
|
||||||
niceProj.Renew();
|
niceProj.Renew();
|
||||||
// Initialize projectile
|
// Initialize projectile
|
||||||
if(fireContext.Instigator != none)
|
if (fireContext.Instigator != none) {
|
||||||
nicePlayer = NicePlayerController(fireContext.Instigator.Controller);
|
nicePlayer = NicePlayerController(fireContext.Instigator.Controller);
|
||||||
if(nicePlayer != none)
|
}
|
||||||
|
if (nicePlayer != none) {
|
||||||
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(nicePlayer.PlayerReplicationInfo);
|
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(nicePlayer.PlayerReplicationInfo);
|
||||||
|
}
|
||||||
niceProj.bGhost = bIsGhost;
|
niceProj.bGhost = bIsGhost;
|
||||||
// Fill-up data about what damage should projectile deal
|
// Fill-up data about what damage should projectile deal
|
||||||
niceProj.charDamage = shotParams.damage;
|
niceProj.charDamage = shotParams.damage;
|
||||||
if(niceVet != none && fireContext.bIsBursting && niceVet.static.hasSkill(nicePlayer, class'NiceSkillCommandoExplosivePower'))
|
if (
|
||||||
|
niceVet != none &&
|
||||||
|
fireContext.bIsBursting &&
|
||||||
|
niceVet.static.hasSkill(nicePlayer, class'NiceSkillCommandoExplosivePower')
|
||||||
|
) {
|
||||||
niceProj.charDamage *= class'NiceSkillCommandoExplosivePower'.default.dmgMod;
|
niceProj.charDamage *= class'NiceSkillCommandoExplosivePower'.default.dmgMod;
|
||||||
if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBulletStorm') && nicePlayer.IsZedTimeActive())
|
}
|
||||||
|
if (
|
||||||
|
niceVet != none &&
|
||||||
|
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBulletStorm') &&
|
||||||
|
nicePlayer.IsZedTimeActive()
|
||||||
|
) {
|
||||||
niceProj.charDamage = shotParams.damage * class'NiceSkillSupportZEDBulletStorm'.default.damageCut;
|
niceProj.charDamage = shotParams.damage * class'NiceSkillSupportZEDBulletStorm'.default.damageCut;
|
||||||
|
}
|
||||||
|
|
||||||
niceProj.charOrigDamage = niceProj.charDamage;
|
niceProj.charOrigDamage = niceProj.charDamage;
|
||||||
niceProj.charDamageType = shotParams.shotDamageType;
|
niceProj.charDamageType = shotParams.shotDamageType;
|
||||||
niceProj.charExplosionDamageType = shotParams.explosionDamageType;
|
niceProj.charExplosionDamageType = shotParams.explosionDamageType;
|
||||||
@ -92,8 +176,9 @@ static function NiceBullet SpawnProjectile(Vector Start, Rotator Dir, NiceFire.S
|
|||||||
niceProj.charContiniousBonus = fireContext.continiousBonus;
|
niceProj.charContiniousBonus = fireContext.continiousBonus;
|
||||||
// Fill-up data about at what speed should projectile travel
|
// Fill-up data about at what speed should projectile travel
|
||||||
niceProj.movementSpeed = shotParams.projSpeed;
|
niceProj.movementSpeed = shotParams.projSpeed;
|
||||||
if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoOnperk'))
|
if (niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoOnperk')) {
|
||||||
niceProj.movementSpeed *= class'NiceSkillDemoOnperk'.default.speedBonus;
|
niceProj.movementSpeed *= class'NiceSkillDemoOnperk'.default.speedBonus;
|
||||||
|
}
|
||||||
niceProj.movementDirection = Vector(niceProj.rotation);
|
niceProj.movementDirection = Vector(niceProj.rotation);
|
||||||
niceProj.charAffectedByScream = shotParams.projAffectedByScream;
|
niceProj.charAffectedByScream = shotParams.projAffectedByScream;
|
||||||
niceProj.charIsSticky = shotParams.bShouldStick;
|
niceProj.charIsSticky = shotParams.bShouldStick;
|
||||||
@ -103,29 +188,47 @@ static function NiceBullet SpawnProjectile(Vector Start, Rotator Dir, NiceFire.S
|
|||||||
niceProj.charExplosionExponent *= class'NiceSkillDemoVolatile'.default.falloffMult;
|
niceProj.charExplosionExponent *= class'NiceSkillDemoVolatile'.default.falloffMult;
|
||||||
niceProj.charMinExplosionDist *= class'NiceSkillDemoVolatile'.default.safeDistanceMult;
|
niceProj.charMinExplosionDist *= class'NiceSkillDemoVolatile'.default.safeDistanceMult;
|
||||||
}
|
}
|
||||||
if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoZEDFullBlast') && nicePlayer.IsZedTimeActive()){
|
if (
|
||||||
|
niceVet != none &&
|
||||||
|
niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoZEDFullBlast') &&
|
||||||
|
nicePlayer.IsZedTimeActive()
|
||||||
|
) {
|
||||||
niceProj.charExplosionRadius *= class'NiceSkillDemoZEDFullBlast'.default.explRadiusMult;
|
niceProj.charExplosionRadius *= class'NiceSkillDemoZEDFullBlast'.default.explRadiusMult;
|
||||||
niceProj.charExplosionExponent = 0.0;
|
niceProj.charExplosionExponent = 0.0;
|
||||||
}
|
}
|
||||||
if(bForceComplexTraj)
|
if (bForceComplexTraj) {
|
||||||
niceProj.bDisableComplexMovement = false;
|
niceProj.bDisableComplexMovement = false;
|
||||||
if(niceProj.Instigator != none && NicePlayerController(niceProj.Instigator.Controller) != none)
|
}
|
||||||
|
if (niceProj.Instigator != none && NicePlayerController(niceProj.Instigator.Controller) != none) {
|
||||||
niceProj.niceRI = NicePlayerController(niceProj.Instigator.Controller).NiceRI;
|
niceProj.niceRI = NicePlayerController(niceProj.Instigator.Controller).NiceRI;
|
||||||
|
}
|
||||||
// And some leftovers
|
// And some leftovers
|
||||||
//niceProj.bShouldBounce = shotParams.bShouldBounce;
|
//niceProj.bShouldBounce = shotParams.bShouldBounce;
|
||||||
niceProj.bInitFinished = true;
|
niceProj.bInitFinished = true;
|
||||||
|
|
||||||
return niceProj;
|
return niceProj;
|
||||||
}
|
}
|
||||||
static function SpawnStuckProjectile(KFHumanPawn instigator, Actor base, name bone, Vector shift, Rotator direction,
|
|
||||||
NiceBullet.ExplosionData expData, bool bIsGhost, int stuckID){
|
static function SpawnStuckProjectile(
|
||||||
|
KFHumanPawn instigator,
|
||||||
|
Actor base,
|
||||||
|
name bone,
|
||||||
|
Vector shift,
|
||||||
|
Rotator direction,
|
||||||
|
NiceBullet.ExplosionData expData,
|
||||||
|
bool bIsGhost,
|
||||||
|
int stuckID
|
||||||
|
) {
|
||||||
local Pawn justPawn;
|
local Pawn justPawn;
|
||||||
local NiceFire.ShotType shotParams;
|
local NiceFire.ShotType shotParams;
|
||||||
local NiceFire.FireModeContext fireContext;
|
local NiceFire.FireModeContext fireContext;
|
||||||
local NiceBullet spawnedBullet;
|
local NiceBullet spawnedBullet;
|
||||||
local NicePlayerController nicePlayer;
|
local NicePlayerController nicePlayer;
|
||||||
|
|
||||||
nicePlayer = NicePlayerController(instigator.Controller);
|
nicePlayer = NicePlayerController(instigator.Controller);
|
||||||
if(base == none || nicePlayer == none)
|
if (base == none || nicePlayer == none) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
justPawn = Pawn(base);
|
justPawn = Pawn(base);
|
||||||
fireContext.instigator = NiceHumanPawn(instigator);
|
fireContext.instigator = NiceHumanPawn(instigator);
|
||||||
fireContext.sourceWeapon = expData.sourceWeapon;
|
fireContext.sourceWeapon = expData.sourceWeapon;
|
||||||
@ -139,8 +242,9 @@ static function SpawnStuckProjectile(KFHumanPawn instigator, Actor base, name bo
|
|||||||
shotParams.explodeOnFuse = expData.explodeOnFuse;
|
shotParams.explodeOnFuse = expData.explodeOnFuse;
|
||||||
shotParams.projAffectedByScream = expData.affectedByScream;
|
shotParams.projAffectedByScream = expData.affectedByScream;
|
||||||
spawnedBullet = SpawnProjectile(base.location, direction, shotParams, fireContext, bIsGhost);
|
spawnedBullet = SpawnProjectile(base.location, direction, shotParams, fireContext, bIsGhost);
|
||||||
if(spawnedBullet == none)
|
if (spawnedBullet == none) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
spawnedBullet.stuckID = stuckID;
|
spawnedBullet.stuckID = stuckID;
|
||||||
spawnedBullet.bStuck = true;
|
spawnedBullet.bStuck = true;
|
||||||
nicePlayer.RegisterStuckBullet(spawnedBullet);
|
nicePlayer.RegisterStuckBullet(spawnedBullet);
|
||||||
@ -152,15 +256,13 @@ static function SpawnStuckProjectile(KFHumanPawn instigator, Actor base, name bo
|
|||||||
spawnedBullet.SetRelativeRotation(Rotator(Vector(direction) << justPawn.GetBoneRotation(bone, 0)));
|
spawnedBullet.SetRelativeRotation(Rotator(Vector(direction) << justPawn.GetBoneRotation(bone, 0)));
|
||||||
spawnedBullet.bUseBone = true;
|
spawnedBullet.bUseBone = true;
|
||||||
spawnedBullet.stuckBone = bone;
|
spawnedBullet.stuckBone = bone;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
spawnedBullet.SetBase(base);
|
spawnedBullet.SetBase(base);
|
||||||
spawnedBullet.SetRelativeLocation(shift);
|
spawnedBullet.SetRelativeLocation(shift);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultproperties
|
defaultproperties {
|
||||||
{
|
|
||||||
bHidden=True
|
bHidden=True
|
||||||
RemoteRole=ROLE_SimulatedProxy
|
RemoteRole=ROLE_SimulatedProxy
|
||||||
LifeSpan=1.000000
|
LifeSpan=1.000000
|
||||||
|
Loading…
Reference in New Issue
Block a user