Fix formatting #1 #27

Merged
dkanus merged 4 commits from harpoon into master 2023-05-23 12:17:15 +03:00
3 changed files with 1316 additions and 905 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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 MediumZedMinHealth; // If zed's base Health >= this value, zed counts as Medium-size var const int BigZedMinHealth; // If zed's base Health >= this value, zed counts as Big
static function Explode(NiceBullet bullet, NiceReplicationInfo niceRI, Vector hitLocation, optional Actor explosionTarget){ var const int MediumZedMinHealth; // If zed's base Health >= this value, zed counts as Medium-size
if(!bullet.bGhost){
niceRI.ServerExplode(bullet.charExplosionDamage, bullet.charExplosionRadius, bullet.charExplosionExponent, static function Explode(
bullet.charExplosionDamageType, bullet.charExplosionMomentum, hitLocation, bullet.instigator, true, NiceBullet bullet,
explosionTarget, Vector(bullet.Rotation)); NiceReplicationInfo niceRI,
if(KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead) Vector hitLocation,
niceRI.ServerDealDamage(KFMonster(bullet.base), bullet.charExplosionDamage, bullet.instigator, hitLocation, optional Actor explosionTarget
bullet.charExplosionMomentum * vect(0,0,-1), bullet.charExplosionDamageType, 1.0); ) {
if (!bullet.bGhost) {
niceRI.ServerExplode(
bullet.charExplosionDamage,
bullet.charExplosionRadius,
bullet.charExplosionExponent,
bullet.charExplosionDamageType,
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) }
HandleCalibration(false, NiceHumanPawn(bullet.Instigator), none); if (!bullet.bAlreadyHitZed) {
if(!targetWall.bStatic && !targetWall.bWorldGeometry && nicePlayer != none && (nicePlayer.wallHitsLeft > 0 || Projectile(targetWall) != none)){ HandleCalibration(false, NiceHumanPawn(bullet.Instigator), none);
niceRI.ServerDealDamage(targetWall, bullet.charOrigDamage, bullet.Instigator, hitLocation, }
bullet.charMomentumTransfer * hitNormal, bullet.charDamageType); if (
nicePlayer.wallHitsLeft --; !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 --;
} }
} }
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,
niceRI.ServerHealTarget(NiceHumanPawn(targetPawn), bullet.charDamage, bullet.instigator); bullet.instigator,
HitLocation,
hitNormal * bullet.charMomentumTransfer,
bullet.charDamageType
);
} else {
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,74 +143,113 @@ 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) }
bullet.sourceWeapon.lastHeadshotTime = bullet.Level.TimeSeconds; if (bIsHeadshot && bullet.sourceWeapon != none) {
if(nicePlayer == none) bullet.sourceWeapon.lastHeadshotTime = bullet.Level.TimeSeconds;
return; }
nicePawn = NiceHumanPawn(bullet.instigator); if (nicePlayer == none) {
if( !bIsHeadshot return;
&& nicePawn != none }
&& nicePlayer.abilityManager != none nicePawn = NiceHumanPawn(bullet.instigator);
&& nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillSharpshooterReaperA'.default.abilityID)) if (
nicePawn.ServerCooldownAbility(class'NiceSkillSharpshooterReaperA'.default.abilityID); !bIsHeadshot &&
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo)); nicePawn != none &&
if(bullet.charCausePain) nicePlayer.abilityManager != none &&
actualDamage = bullet.charOrigDamage; nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillSharpshooterReaperA'.default.abilityID)
else ) {
actualDamage = bullet.charDamage; nicePawn.ServerCooldownAbility(class'NiceSkillSharpshooterReaperA'.default.abilityID);
if(headshotLevel > 0) }
actualDamage *= bullet.charContiniousBonus; niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
if(bullet.bGrazing) if (bullet.charCausePain) {
actualDamage *= class'NiceSkillSupportGraze'.default.grazeDamageMult; actualDamage = bullet.charOrigDamage;
bullet.bGrazing = false; } else {
if(kfZed == bullet.lockonZed && bullet.lockonTime > bullet.sourceWeapon.stdFireRate actualDamage = bullet.charDamage;
&& niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterKillConfirmed')){ }
lockOnTickRate =class'NiceSkillSharpshooterKillConfirmed'.default.stackDelay; if (headshotLevel > 0) {
lockonTicks = Ceil(bullet.lockonTime / lockOnTickRate) - 1; actualDamage *= bullet.charContiniousBonus;
lockonTicks = Min(class'NiceSkillSharpshooterKillConfirmed'.default.maxStacks, lockonTicks); }
//actualDamage *= 1.0 + if (bullet.bGrazing) {
// 0.5 * lockonTicks * (lockonTicks + 1) * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus; actualDamage *= class'NiceSkillSupportGraze'.default.grazeDamageMult;
//damageMod *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus; }
actualDamage *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus; bullet.bGrazing = false;
if (
kfZed == bullet.lockonZed &&
bullet.lockonTime > bullet.sourceWeapon.stdFireRate &&
niceVet != none &&
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterKillConfirmed')
) {
lockOnTickRate =class'NiceSkillSharpshooterKillConfirmed'.default.stackDelay;
lockonTicks = Ceil(bullet.lockonTime / lockOnTickRate) - 1;
lockonTicks = Min(class'NiceSkillSharpshooterKillConfirmed'.default.maxStacks, lockonTicks);
// actualDamage *= 1.0 +
// 0.5 * lockonTicks * (lockonTicks + 1) * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus;
// damageMod *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus;
actualDamage *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus;
}
if (!bullet.bGhost) {
niceRI.ServerDealDamage(
kfZed,
actualDamage,
bullet.instigator,
hitLocation,
bullet.charMomentumTransfer * hitNormal,
bullet.charDamageType,
headshotLevel,
bullet.lockonTime
);
} }
if(!bullet.bGhost)
niceRI.ServerDealDamage(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 &&
// Count one bounce nicePlayer.IsZedTimeActive() &&
bullet.insideBouncesLeft --; bullet.insideBouncesLeft > 0 &&
// Swap head-shot level niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBore')
if(headshotLevel <= 0.0) ) {
headshotLevel = class'NiceSkillSupportZEDBore'.default.minHeadshotPrecision; // Count one bounce
else bullet.insideBouncesLeft --;
headshotLevel = -headshotLevel; // Swap head-shot level
// Deal next batch of damage if (headshotLevel <= 0.0) {
ZedPenetration(bullet.charDamage, bullet, kfZed, false, false); headshotLevel = class'NiceSkillSupportZEDBore'.default.minHeadshotPrecision;
HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel); } else {
headshotLevel = -headshotLevel;
}
// Deal next batch of damage
ZedPenetration(bullet.charDamage, bullet, kfZed, false, false);
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,52 +258,74 @@ 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 (
return true; niceVet != none &&
if(niceZed.default.Health >= default.BigZedMinHealth && !bEasyHeadPenetration) niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterZEDRailgun') &&
reductionMod *= niceDmgType.default.BigZedPenDmgReduction; nicePlayer.IsZedTimeActive()
else if(niceZed.default.Health >= default.MediumZedMinHealth && !bEasyHeadPenetration) ) {
reductionMod *= niceDmgType.default.MediumZedPenDmgReduction; return true;
} }
else if (niceZed.default.Health >= default.BigZedMinHealth && !bEasyHeadPenetration) {
reductionMod *= niceDmgType.default.BigZedPenDmgReduction;
} else if (niceZed.default.Health >= default.MediumZedMinHealth && !bEasyHeadPenetration) {
reductionMod *= niceDmgType.default.MediumZedPenDmgReduction;
}
} else {
reductionMod *= niceDmgType.default.BigZedPenDmgReduction; reductionMod *= niceDmgType.default.BigZedPenDmgReduction;
if(niceVet != none) }
reductionMod = niceVet.static.GetPenetrationDamageMulti(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo), reductionMod, niceDmgType); if (niceVet != none) {
actualMaxPenetrations = niceDmgType.default.maxPenetrations; reductionMod = niceVet.static.GetPenetrationDamageMulti(
if(niceVet != none && !bullet.charWasHipFired && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterSurgical') && bIsHeadshot){ KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo),
actualMaxPenetrations += 1; reductionMod,
reductionMod = FMax(reductionMod, class'NiceSkillSharpshooterSurgical'.default.penDmgReduction); niceDmgType
} );
}
actualMaxPenetrations = niceDmgType.default.maxPenetrations;
if (
niceVet != none &&
!bullet.charWasHipFired &&
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterSurgical') &&
bIsHeadshot
) {
actualMaxPenetrations += 1;
reductionMod = FMax(reductionMod, class'NiceSkillSharpshooterSurgical'.default.penDmgReduction);
}
// Assign new damage value and tell us if we should stop with penetration // Assign new damage value and tell us if we should stop with penetration
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) }
return false; if (!bIsHeadshot && niceDmgType.default.bPenetrationHSOnly) {
if(actualMaxPenetrations < 0) return false;
return true; }
if(Damage / bullet.charOrigDamage < (niceDmgType.default.PenDmgReduction ** (actualMaxPenetrations + 1)) + 0.0001 || Damage < 1) if (actualMaxPenetrations < 0) {
return false; return true;
}
if (Damage / bullet.charOrigDamage < (niceDmgType.default.PenDmgReduction ** (actualMaxPenetrations + 1)) + 0.0001 || Damage < 1) {
return false;
}
return true; return true;
} }
defaultproperties defaultproperties {
{ BigZedMinHealth=1000
BigZedMinHealth=1000 MediumZedMinHealth=500
MediumZedMinHealth=500 }
}

View File

@ -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) }
SpawnProjectile(Start, Dir, shotParams, fireContext, false, bForceComplexTraj); if (fireContext.Instigator.Role < ROLE_Authority || bDuplReal) {
if(fireContext.Instigator.Role == ROLE_Authority && niceMut != none && !bSkipGhosts){ SpawnProjectile(Start, Dir, shotParams, fireContext, false, bForceComplexTraj);
for(i = 0;i < niceMut.playersList.Length;i ++){ }
if(niceMut.playersList[i] != fireContext.Instigator.Controller) if (fireContext.Instigator.Role == ROLE_Authority && niceMut != none && !bSkipGhosts) {
niceMut.playersList[i].ClientSpawnGhostProjectile(start, dir.pitch, dir.yaw, dir.roll, shotParams, fireContext, bForceComplexTraj); for (i = 0; i < niceMut.playersList.Length; i++) {
} if (niceMut.playersList[i] != fireContext.Instigator.Controller) {
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(
if(expData.Instigator.Role == ROLE_Authority && niceMut != none){ instigator,
for(i = 0;i < niceMut.playersList.Length;i ++){ base,
if( (niceMut.playersList[i] != expData.Instigator.Controller && !bSkipGhosts) bone,
|| (niceMut.playersList[i] == expData.Instigator.Controller && bDuplReal) ) shift,
niceMut.playersList[i].ClientStickGhostProjectile(instigator, base, bone, shift, direction, expData, direction,
niceMut.stuckCounter); expData,
} false,
niceMut.stuckCounter
);
}
if (expData.Instigator.Role == ROLE_Authority && niceMut != none) {
for (i = 0; i < niceMut.playersList.Length; i++) {
if (
(niceMut.playersList[i] != expData.Instigator.Controller && !bSkipGhosts) ||
(niceMut.playersList[i] == expData.Instigator.Controller && bDuplReal)
) {
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,
Start = HitLocation; HitNormal,
niceProj = fireContext.Instigator.Spawn(shotParams.bulletClass,,, Start, Dir); Start,
fireContext.Instigator.Location + fireContext.Instigator.EyePosition(),
false,
Vect(0, 0, 1)
);
if (other != none) {
Start = HitLocation;
}
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) }
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(nicePlayer.PlayerReplicationInfo); if (nicePlayer != none) {
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,76 +176,94 @@ 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;
niceProj.nicePlayer = nicePlayer; niceProj.nicePlayer = nicePlayer;
if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoVolatile')){ if (niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoVolatile')) {
niceProj.charExplosionRadius *= class'NiceSkillDemoVolatile'.default.explRangeMult; niceProj.charExplosionRadius *= class'NiceSkillDemoVolatile'.default.explRangeMult;
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 (
niceProj.charExplosionRadius *= class'NiceSkillDemoZEDFullBlast'.default.explRadiusMult; niceVet != none &&
niceProj.charExplosionExponent = 0.0; niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoZEDFullBlast') &&
nicePlayer.IsZedTimeActive()
) {
niceProj.charExplosionRadius *= class'NiceSkillDemoZEDFullBlast'.default.explRadiusMult;
niceProj.charExplosionExponent = 0.0;
}
if (bForceComplexTraj) {
niceProj.bDisableComplexMovement = false;
}
if (niceProj.Instigator != none && NicePlayerController(niceProj.Instigator.Controller) != none) {
niceProj.niceRI = NicePlayerController(niceProj.Instigator.Controller).NiceRI;
} }
if(bForceComplexTraj)
niceProj.bDisableComplexMovement = false;
if(niceProj.Instigator != none && NicePlayerController(niceProj.Instigator.Controller) != none)
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(
local Pawn justPawn; KFHumanPawn instigator,
local NiceFire.ShotType shotParams; Actor base,
local NiceFire.FireModeContext fireContext; name bone,
local NiceBullet spawnedBullet; Vector shift,
local NicePlayerController nicePlayer; Rotator direction,
NiceBullet.ExplosionData expData,
bool bIsGhost,
int stuckID
) {
local Pawn justPawn;
local NiceFire.ShotType shotParams;
local NiceFire.FireModeContext fireContext;
local NiceBullet spawnedBullet;
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;
shotParams.bulletClass = expData.bulletClass; shotParams.bulletClass = expData.bulletClass;
shotParams.explosionDamageType = expData.explosionDamageType; shotParams.explosionDamageType = expData.explosionDamageType;
shotParams.explosionDamage = expData.explosionDamage; shotParams.explosionDamage = expData.explosionDamage;
shotParams.explosionRadius = expData.explosionRadius; shotParams.explosionRadius = expData.explosionRadius;
shotParams.explosionExponent = expData.explosionExponent; shotParams.explosionExponent = expData.explosionExponent;
shotParams.explosionMomentum = expData.explosionMomentum; shotParams.explosionMomentum = expData.explosionMomentum;
shotParams.fuseTime = expData.fuseTime; shotParams.fuseTime = expData.fuseTime;
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);
if(justPawn != none){ if (justPawn != none) {
spawnedBullet.bStuckToHead = expData.stuckToHead; spawnedBullet.bStuckToHead = expData.stuckToHead;
spawnedBullet.SetBase(base); spawnedBullet.SetBase(base);
justPawn.AttachToBone(spawnedBullet, bone); justPawn.AttachToBone(spawnedBullet, bone);
spawnedBullet.SetRelativeLocation(shift); spawnedBullet.SetRelativeLocation(shift);
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 }
}