Revert weapon conversion

This patch reverts first step of global weapon conversion
that would have halted the release of the next version for too long.
This commit is contained in:
Anton Tarasenko 2020-04-17 23:06:41 +07:00
parent 3c46801714
commit 12d95e387e
757 changed files with 10758 additions and 4016 deletions

View File

@ -62,8 +62,8 @@ simulated function bool IsZedExtentionsRecorded(NiceMonster niceZed){
} }
function ReplaceRequiredEquipment(){ function ReplaceRequiredEquipment(){
Super.ReplaceRequiredEquipment(); Super.ReplaceRequiredEquipment();
RequiredEquipment[0] = String(class'ScrnBalanceSrv.ScrnKnife');//String(class'NicePack.NiceKnife'); RequiredEquipment[0] = String(class'NicePack.NiceKnife');
RequiredEquipment[1] = String(class'NicePack.NiceWinchester');//String(class'NicePack.Nice9mmPlus'); RequiredEquipment[1] = String(class'NicePack.Nice9mmPlus');
RequiredEquipment[2] = String(class'ScrnBalanceSrv.ScrnFrag'); RequiredEquipment[2] = String(class'ScrnBalanceSrv.ScrnFrag');
RequiredEquipment[3] = String(class'ScrnBalanceSrv.ScrnSyringe'); RequiredEquipment[3] = String(class'ScrnBalanceSrv.ScrnSyringe');
RequiredEquipment[4] = String(class'KFMod.Welder'); RequiredEquipment[4] = String(class'KFMod.Welder');
@ -359,7 +359,7 @@ simulated function Tick(float deltaTime){
holsteredReloadCountDown = 0.25; holsteredReloadCountDown = 0.25;
} }
} }
/*function ServerBuyWeapon(class<Weapon> WClass, float ItemWeight){ function ServerBuyWeapon(class<Weapon> WClass, float ItemWeight){
local Inventory I; local Inventory I;
local NiceSingle nicePistol; local NiceSingle nicePistol;
local class<NiceWeaponPickup> WP; local class<NiceWeaponPickup> WP;
@ -435,7 +435,7 @@ function ServerSellWeapon(class<Weapon> WClass){
SetTraderUpdate(); SetTraderUpdate();
} }
} }
}*/ }
// NICETODO: do we even need this one? // NICETODO: do we even need this one?
simulated function ClientChangeWeapon(NiceWeapon newWeap){ simulated function ClientChangeWeapon(NiceWeapon newWeap){
weapon = newWeap; weapon = newWeap;
@ -535,15 +535,14 @@ simulated function ThrowGrenade(){
} }
simulated function HandleNadeThrowAnim() simulated function HandleNadeThrowAnim()
{ {
if(NiceWinchester(Weapon) != none) if(NiceM14EBRBattleRifle(Weapon) != none || NiceMaulerRifle(Weapon) != none)
SetAnimAction('Frag_Winchester');
/*if(NiceM14EBRBattleRifle(Weapon) != none || NiceMaulerRifle(Weapon) != none)
SetAnimAction('Frag_M14'); SetAnimAction('Frag_M14');
else else if(NiceWinchester(Weapon) != none)
SetAnimAction('Frag_Winchester');
else if(Crossbow(Weapon) != none) else if(Crossbow(Weapon) != none)
SetAnimAction('Frag_Crossbow'); SetAnimAction('Frag_Crossbow');
else if(NiceM99SniperRifle(Weapon) != none) else if(NiceM99SniperRifle(Weapon) != none)
SetAnimAction('Frag_M4203');//MEANTODO SetAnimAction('Frag_M4203');
else if(NiceAK47AssaultRifle(Weapon) != none) else if(NiceAK47AssaultRifle(Weapon) != none)
SetAnimAction('Frag_AK47'); SetAnimAction('Frag_AK47');
else if(NiceBullpup(Weapon) != none || NiceNailGun(Weapon) != none) else if(NiceBullpup(Weapon) != none || NiceNailGun(Weapon) != none)
@ -559,7 +558,7 @@ simulated function HandleNadeThrowAnim()
else if(NiceM4AssaultRifle(Weapon) != none || NiceMKb42AssaultRifle(Weapon) != none) else if(NiceM4AssaultRifle(Weapon) != none || NiceMKb42AssaultRifle(Weapon) != none)
SetAnimAction('Frag_M4'); SetAnimAction('Frag_M4');
else if(NiceThompsonDrumSMG(Weapon) != none) else if(NiceThompsonDrumSMG(Weapon) != none)
SetAnimAction('Frag_IJC_spThompson_Drum');*/ SetAnimAction('Frag_IJC_spThompson_Drum');
Super.HandleNadeThrowAnim(); Super.HandleNadeThrowAnim();
} }
// Remove blur for sharpshooter with a right skill // Remove blur for sharpshooter with a right skill
@ -788,7 +787,7 @@ function Timer(){
hmgShieldLevel ++; hmgShieldLevel ++;
} }
} }
/*simulated function Fire(optional float F){ simulated function Fire(optional float F){
local bool bRecManualReload; local bool bRecManualReload;
local NiceSingle singleWeap; local NiceSingle singleWeap;
local ScrnPlayerController PC; local ScrnPlayerController PC;
@ -802,7 +801,7 @@ function Timer(){
} }
else else
super.Fire(F); super.Fire(F);
}*/ }
function float AssessThreatTo(KFMonsterController Monster, optional bool CheckDistance){ function float AssessThreatTo(KFMonsterController Monster, optional bool CheckDistance){
return super(SRHumanPawn).AssessThreatTo(Monster, CheckDistance); return super(SRHumanPawn).AssessThreatTo(Monster, CheckDistance);
} }
@ -824,14 +823,15 @@ function VeterancyChanged(){
super.VeterancyChanged(); super.VeterancyChanged();
} }
/*simulated function AltFire(optional float F){ simulated function AltFire(optional float F){
if(NiceMedicGun(Weapon) != none) if(NiceMedicGun(Weapon) != none)
super(SRHumanPawn).AltFire(F); super(SRHumanPawn).AltFire(F);
else else
super.AltFire(F); super.AltFire(F);
}*/ }
defaultproperties defaultproperties
{ {
defaultInvincibilityDuration=2.000000 defaultInvincibilityDuration=2.000000
BaseMeleeIncrease=0.000000 BaseMeleeIncrease=0.000000
} }

View File

@ -62,10 +62,6 @@ struct WeaponSelector{
var int selectorNumber; var int selectorNumber;
var array< class<KFWeapon> > weaponList; var array< class<KFWeapon> > weaponList;
}; };
// Alternative input flags
var byte bNiceFire, bNiceAltFire;
var bool hasZeroSelector; var bool hasZeroSelector;
var bool bUsesMouseWheel; var bool bUsesMouseWheel;
var bool bMouseWheelLoops; var bool bMouseWheelLoops;
@ -100,7 +96,7 @@ struct StuckBulletRecord{
var NiceBullet bullet; var NiceBullet bullet;
var float registrationTime; var float registrationTime;
}; };
//var array<StuckBulletRecord> stuckBulletsSet; var array<StuckBulletRecord> stuckBulletsSet;
var NicePack NicePackMutator; var NicePack NicePackMutator;
var string SteamID64; var string SteamID64;
var bool hasExpConverted; var bool hasExpConverted;
@ -130,13 +126,13 @@ replication{
sirenScreamMod; sirenScreamMod;
reliable if(Role == ROLE_Authority) reliable if(Role == ROLE_Authority)
ClientSetSkill, ClientLoadSettings, ClientSaveConfig, ClientSetKey, ClientUpdatePlayedWithDatabase, ClientReceiveSkill, ClientBroadcastEnded, ClientLog, ClientUpdatePawnMaxHealth, ClientSetNiceWeapManagement, ClientSetSkill, ClientLoadSettings, ClientSaveConfig, ClientSetKey, ClientUpdatePlayedWithDatabase, ClientReceiveSkill, ClientBroadcastEnded, ClientLog, ClientUpdatePawnMaxHealth, ClientSetNiceWeapManagement,
ClientSpawnSirenBall, ClientRemoveSirenBall, /*ClientNailsExplosion,*/ ClientSetZedStun, ClientShowScrnMenu; ClientSpawnSirenBall, ClientRemoveSirenBall, ClientNailsExplosion, ClientStickGhostProjectile, ClientSetZedStun, ClientShowScrnMenu;
unreliable if(Role == ROLE_Authority) unreliable if(Role == ROLE_Authority)
ClientSpawnGhosts, ClientPrint; ClientSpawnGhostProjectile, ClientPrint;
reliable if(Role < ROLE_Authority) reliable if(Role < ROLE_Authority)
ServerSetSkill, ServerSetPendingSkill, ServerSetAltSwitchesModes, ServerSetUseServerReload, ServerSetSkill, ServerSetPendingSkill, ServerSetAltSwitchesModes, ServerSetUseServerReload,
ServerSetHLMessages, ServerMarkSettingsLoaded, ServerStartleZeds, ServerSetDisplayCounters, ServerSetHLMessages, ServerMarkSettingsLoaded, ServerStartleZeds, ServerSetDisplayCounters,
ServerSetDisplayWeaponProgress, ActivateAbility, ServerSetFireFlags; ServerSetDisplayWeaponProgress, ActivateAbility;
} }
// Called on server only! // Called on server only!
function PostLogin(){ function PostLogin(){
@ -1217,7 +1213,7 @@ function ViewTargetChanged(){
OldViewTarget = ViewTarget; OldViewTarget = ViewTarget;
} }
// Reloaded to add nice single/dual classes // Reloaded to add nice single/dual classes
/*function LoadDualWieldables(){ function LoadDualWieldables(){
local ClientPerkRepLink CPRL; local ClientPerkRepLink CPRL;
local class<NiceWeaponPickup> WP; local class<NiceWeaponPickup> WP;
local class<NiceSingle> W; local class<NiceSingle> W;
@ -1235,10 +1231,10 @@ function ViewTargetChanged(){
AddDualWieldable(W, W.default.DualClass); AddDualWieldable(W, W.default.DualClass);
} }
super.LoadDualWieldables(); super.LoadDualWieldables();
}*/ }
// If player only has one pistol out of two possible, then return 'false' // If player only has one pistol out of two possible, then return 'false'
// Because he's got the right one and new one is the left one; completely different stuff // Because he's got the right one and new one is the left one; completely different stuff
/*function bool IsInInventory(class<Pickup> PickupToCheck, bool bCheckForEquivalent, bool bCheckForVariant){ function bool IsInInventory(class<Pickup> PickupToCheck, bool bCheckForEquivalent, bool bCheckForVariant){
local bool bResult; local bool bResult;
local Inventory CurInv; local Inventory CurInv;
local NiceSingle singlePistol; local NiceSingle singlePistol;
@ -1254,7 +1250,7 @@ function ViewTargetChanged(){
break; break;
} }
return bResult; return bResult;
}*/ }
state Spectating{ state Spectating{
exec function Use(){ exec function Use(){
local vector HitLocation, HitNormal, TraceEnd, TraceStart; local vector HitLocation, HitNormal, TraceEnd, TraceStart;
@ -1268,12 +1264,17 @@ state Spectating{
ServerSetViewTarget(A); ServerSetViewTarget(A);
} }
} }
simulated function ClientSpawnGhosts(int amount, Vector start, int pitch, int yaw, int roll, float spread, NiceFire.NWFireType fireType, NiceFire.NWCFireState fireState){ simulated function ClientSpawnGhostProjectile(Vector Start, int pitch, int yaw, int roll, NiceFire.ShotType shotParams, NiceFire.FireModeContext fireContext, bool bForceComplexTraj){
local Rotator bulletDir; local Rotator projectileDir;
bulletDir.Pitch = pitch; projectileDir.Pitch = pitch;
bulletDir.Yaw = yaw; projectileDir.Yaw = yaw;
bulletDir.Roll = roll; projectileDir.Roll = roll;
class'NiceBulletSpawner'.static.SpawnBullets(amount, start, bulletDir, spread, fireType, fireState); class'NiceProjectileSpawner'.static.SpawnProjectile(Start, projectileDir, shotParams, fireContext, true, bForceComplexTraj);
}
simulated function ClientStickGhostProjectile(KFHumanPawn instigator, Actor base, name bone, Vector shift, Rotator rot,
NiceBullet.ExplosionData expData, int stuckID){
class'NiceProjectileSpawner'.static.SpawnStuckProjectile(instigator, base, bone, shift, rot, expData, true,
stuckID);
} }
simulated function SpawnSirenBall(NiceZombieSiren siren){ simulated function SpawnSirenBall(NiceZombieSiren siren){
if(NicePackMutator == none || siren == none) if(NicePackMutator == none || siren == none)
@ -1292,13 +1293,12 @@ simulated function ClientRemoveSirenBall(int ID){
return; return;
localCollisionManager.RemoveSphereCollision(ID); localCollisionManager.RemoveSphereCollision(ID);
} }
//NICETODO: do we need this? simulated function ClientNailsExplosion(int amount, Vector start, NiceFire.ShotType shotParams,
/*simulated function ClientNailsExplosion(int amount, Vector start, NiceFire.ShotType shotParams,
NiceFire.FireModeContext fireContext, optional bool bIsGhost){ NiceFire.FireModeContext fireContext, optional bool bIsGhost){
local int i; local int i;
for(i = 0;i < amount;i ++) for(i = 0;i < amount;i ++)
class'NiceProjectileSpawner'.static.SpawnProjectile(start, RotRand(true), shotParams, fireContext, bIsGhost); class'NiceProjectileSpawner'.static.SpawnProjectile(start, RotRand(true), shotParams, fireContext, bIsGhost);
}*/ }
simulated function AddEffect(){ simulated function AddEffect(){
effectsSpawned[currentEffectTimeWindow] ++; effectsSpawned[currentEffectTimeWindow] ++;
} }
@ -1317,7 +1317,7 @@ simulated function bool CanSpawnEffect(bool bIsGhost){
return false; return false;
return true; return true;
} }
/*simulated function RegisterStuckBullet(NiceBullet bullet){ simulated function RegisterStuckBullet(NiceBullet bullet){
local StuckBulletRecord newRecord; local StuckBulletRecord newRecord;
if(bullet == none) if(bullet == none)
return; return;
@ -1348,9 +1348,9 @@ simulated function FreeOldStuckBullets(){
else if(stuckBulletsSet[i].bullet != none) else if(stuckBulletsSet[i].bullet != none)
stuckBulletsSet[i].bullet.KillBullet(); stuckBulletsSet[i].bullet.KillBullet();
stuckBulletsSet = newSet; stuckBulletsSet = newSet;
}*/ }
// Dualies functions // Dualies functions
/*exec function SwitchDualies(){ exec function SwitchDualies(){
local NiceSingle singlePistol; local NiceSingle singlePistol;
local NiceDualies dualPistols; local NiceDualies dualPistols;
if(Pawn != none){ if(Pawn != none){
@ -1382,7 +1382,7 @@ exec function FireRightGun(){
dualPistols = NiceDualies(Pawn.Weapon); dualPistols = NiceDualies(Pawn.Weapon);
if(dualPistols != none) if(dualPistols != none)
dualPistols.FireGivenGun(false); dualPistols.FireGivenGun(false);
}*/ }
exec function ActivateAbility(int abilityIndex){ exec function ActivateAbility(int abilityIndex){
if(abilityIndex < 0) if(abilityIndex < 0)
return; return;
@ -1438,37 +1438,32 @@ exec simulated function Siren(float value)
sirenScreamMod = value; sirenScreamMod = value;
} }
function ServerSetFireFlags(byte bNewFire, byte bNewAltFire){
bNiceFire = bNewFire;
bNiceAltFire = bNewAltFire;
}
defaultproperties defaultproperties
{ {
sirenScreamMod=1.0 nicePlayerInfoVersionNumber=1
nicePlayerInfoVersionNumber=1 bAltSwitchesModes=True
bAltSwitchesModes=True bAdvReloadCheck=True
bAdvReloadCheck=True bRelCancelByFire=True
bRelCancelByFire=True bRelCancelBySwitching=True
bRelCancelBySwitching=True bRelCancelByNades=True
bRelCancelByNades=True bRelCancelByAiming=True
bRelCancelByAiming=True bNiceWeaponManagement=True
bNiceWeaponManagement=True bDisplayCounters=True
bDisplayCounters=True bDisplayWeaponProgress=True
bDisplayWeaponProgress=True bShowScrnMenu=True
bShowScrnMenu=True maxPlayedWithRecords=100
maxPlayedWithRecords=100 WeapGroupMeleeName="Melee"
WeapGroupMeleeName="Melee" WeapGroupNonMeleeName="NonMelee"
WeapGroupNonMeleeName="NonMelee" WeapGroupPistolsName="Pistols"
WeapGroupPistolsName="Pistols" WeapGroupGeneralName="General"
WeapGroupGeneralName="General" WeapGroupToolsName="Tools"
WeapGroupToolsName="Tools" WeapPresetDefaultName="Default"
WeapPresetDefaultName="Default" WeapPresetGunslingerName="Gunslinger"
WeapPresetGunslingerName="Gunslinger" tracesPerTickLimit=1000
tracesPerTickLimit=1000 effectsLimitSoft=100
effectsLimitSoft=100 effectsLimitHard=200
effectsLimitHard=200 sirenScreamMod=1.000000
TSCLobbyMenuClassString="NicePack.NiceTSCLobbyMenu" TSCLobbyMenuClassString="NicePack.NiceTSCLobbyMenu"
LobbyMenuClassString="NicePack.NiceLobbyMenu" LobbyMenuClassString="NicePack.NiceLobbyMenu"
PawnClass=Class'NicePack.NiceHumanPawn' PawnClass=Class'NicePack.NiceHumanPawn'
} }

View File

@ -15,10 +15,10 @@ replication{
reliable if(Role < ROLE_Authority) reliable if(Role < ROLE_Authority)
ServerDamagePawn, ServerDealDamage, ServerDealMeleeDamage, ServerDamagePawn, ServerDealDamage, ServerDealMeleeDamage,
ServerUpdateHit, ServerExplode, ServerJunkieExtension, ServerUpdateHit, ServerExplode, ServerJunkieExtension,
/*ServerStickProjectile*/ServerHealTarget; ServerStickProjectile, ServerHealTarget;
} }
// Makes server to spawn a sticked projectile. // Makes server to spawn a sticked projectile.
/*simulated function ServerStickProjectile simulated function ServerStickProjectile
( (
KFHumanPawn instigator, KFHumanPawn instigator,
Actor base, Actor base,
@ -29,7 +29,7 @@ replication{
){ ){
class'NiceProjectileSpawner'.static. class'NiceProjectileSpawner'.static.
StickProjectile(instigator, base, bone, shift, direction, expData); StickProjectile(instigator, base, bone, shift, direction, expData);
}*/ }
// Returns scale value that determines how to scale explosion damage to // Returns scale value that determines how to scale explosion damage to
// given victim. // given victim.
// Method assumes that a valid victim was passed. // Method assumes that a valid victim was passed.
@ -216,12 +216,12 @@ simulated function ServerHealTarget(NiceHumanPawn healed, float charPotency,
healTotal = charPotency * healPotency; healTotal = charPotency * healPotency;
healer.AlphaAmount = 255; healer.AlphaAmount = 255;
/* if(NiceMedicGun(healer.weapon) != none) if(NiceMedicGun(healer.weapon) != none)
NiceMedicGun(healer.weapon).ClientSuccessfulHeal(healer, healed); NiceMedicGun(healer.weapon).ClientSuccessfulHeal(healer, healed);
if(healed.health >= healed.healthMax){ if(healed.health >= healed.healthMax){
healed.GiveHealth(healTotal, healed.healthMax); healed.GiveHealth(healTotal, healed.healthMax);
return; return;
}*/ }
HandleNiceHealingMechanicsAndSkills(healer, healed, healPotency); HandleNiceHealingMechanicsAndSkills(healer, healed, healPotency);
if(healed.health < healed.healthMax){ if(healed.health < healed.healthMax){
healed.TakeHealing( healed, healTotal, healPotency, healed.TakeHealing( healed, healTotal, healPotency,
@ -454,6 +454,7 @@ simulated function ServerJunkieExtension( NicePlayerController player,
Mut.JunkieZedTimeExtend(); Mut.JunkieZedTimeExtend();
} }
} }
defaultproperties defaultproperties
{ {
} }

View File

@ -6,12 +6,12 @@ var float justHeadshotReduction;
defaultproperties defaultproperties
{ {
justHeadshotReduction=0.250000 headshotKillReduction(0)=0.500000
headshotKillReduction(0)=0.5f headshotKillReduction(1)=1.000000
headshotKillReduction(1)=1.0f headshotKillReduction(2)=1.250000
headshotKillReduction(2)=1.25f headshotKillReduction(3)=1.500000
headshotKillReduction(3)=1.5f headshotKillReduction(4)=2.000000
headshotKillReduction(4)=2.0f justHeadshotReduction=0.250000
SkillName="Ardour" SkillName="Ardour"
SkillEffects="Head-shotting enemies reduces your cooldowns." SkillEffects="Head-shotting enemies reduces your cooldowns."
} }

View File

@ -1,13 +1,14 @@
class NiceSkillSharpshooterDieAlready extends NiceSkill class NiceSkillSharpshooterDieAlready extends NiceSkill
abstract; abstract;
var float bleedOutTime[5]; var float bleedOutTime[5];
defaultproperties defaultproperties
{ {
BleedOutTime(0)=2.0f BleedOutTime(0)=2.000000
BleedOutTime(1)=1.5f BleedOutTime(1)=1.500000
BleedOutTime(2)=1.25f BleedOutTime(2)=1.250000
BleedOutTime(3)=1.0f BleedOutTime(3)=1.000000
BleedOutTime(4)=0.25f BleedOutTime(4)=0.250000
SkillName="Die already" SkillName="Die already"
SkillEffects="All zeds decapitated by you drop faster." SkillEffects="All zeds decapitated by you drop faster."
} }

View File

@ -18,14 +18,15 @@ function static SkillDeSelected(NicePlayerController nicePlayer){
if(nicePlayer.abilityManager == none) return; if(nicePlayer.abilityManager == none) return;
nicePlayer.abilityManager.RemoveAbility(default.abilityID); nicePlayer.abilityManager.RemoveAbility(default.abilityID);
} }
defaultproperties defaultproperties
{ {
abilityID="Gunslinger" abilityID="Gunslinger"
cooldown=80.000000 cooldown=80.000000
Duration=15.000000 Duration=15.000000
reloadMult=1.500000 reloadMult=1.500000
movementMult=1.2500000 movementMult=1.250000
fireRateMult=1.300000 fireRateMult=1.300000
SkillName="Gunslinger" SkillName="Gunslinger"
SkillEffects="Reload, fire and move faster. All with no recoil." SkillEffects="Reload, fire and move faster. All with no recoil."
} }

View File

@ -5,13 +5,14 @@ var float zoomSpeedBonus;
var float reloadBonus; var float reloadBonus;
var float fireRateBonus; var float fireRateBonus;
var float recoilMult; var float recoilMult;
defaultproperties defaultproperties
{ {
zoomBonus=0.750000 zoomBonus=0.750000
zoomSpeedBonus=0.500000 zoomSpeedBonus=0.500000
ReloadBonus=0.500000 ReloadBonus=0.500000
fireRateBonus=0.300000 fireRateBonus=0.300000
recoilMult=0.500000 recoilMult=0.500000
SkillName="Hard work" SkillName="Hard work"
SkillEffects="Reload up to 50% faster, shoot up to 30% faster and recoil only for half as much. Additionally, you can switch to/from iron sights twice as fast and zoom 25% further while crouched." SkillEffects="Reload up to 50% faster, shoot up to 30% faster and recoil only for half as much. Additionally, you can switch to/from iron sights twice as fast and zoom 25% further while crouched."
} }

View File

@ -35,16 +35,17 @@ function static int UpdateCounterValue(string counterName, NicePlayerController
if(niceF == none) if(niceF == none)
return 0; return 0;
lockOnTickRate = class'NiceSkillSharpshooterKillConfirmed'.default.stackDelay; lockOnTickRate = class'NiceSkillSharpshooterKillConfirmed'.default.stackDelay;
lockonTicks = Ceil(niceF.fireState.lockon.time / lockOnTickRate) - 1; lockonTicks = Ceil(niceF.currentContext.lockonTime / lockOnTickRate) - 1;
lockonTicks = Min(class'NiceSkillSharpshooterKillConfirmed'.default.maxStacks, lockonTicks); lockonTicks = Min(class'NiceSkillSharpshooterKillConfirmed'.default.maxStacks, lockonTicks);
lockonTicks = Max(lockonTicks, 0); lockonTicks = Max(lockonTicks, 0);
return lockonTicks; return lockonTicks;
} }
defaultproperties defaultproperties
{ {
damageBonus=1.000000 damageBonus=1.000000
stackDelay=1.000000 stackDelay=1.000000
maxStacks=1 maxStacks=1
SkillName="Kill confirmed" SkillName="Kill confirmed"
SkillEffects="Aiming at zed's head for a second doubles the damage of the shot." SkillEffects="Aiming at zed's head for a second doubles the damage of the shot."
} }

View File

@ -17,10 +17,11 @@ function static SkillDeSelected(NicePlayerController nicePlayer){
if(nicePlayer.abilityManager == none) return; if(nicePlayer.abilityManager == none) return;
nicePlayer.abilityManager.RemoveAbility(default.abilityID); nicePlayer.abilityManager.RemoveAbility(default.abilityID);
} }
defaultproperties defaultproperties
{ {
abilityID="Reaper" abilityID="Reaper"
cooldown=24.000000 cooldown=24.000000
SkillName="Reaper" SkillName="Reaper"
SkillEffects="If it would take 2 head-shot to kill the zed, - it'll die from one." SkillEffects="If it would take 2 head-shot to kill the zed, - it'll die from one."
} }

View File

@ -1,5 +1,8 @@
class NiceSkillSharpshooterStability extends NiceSkill class NiceSkillSharpshooterStability extends NiceSkill
abstract; abstract;
defaultproperties defaultproperties
{ SkillName="Stability" SkillEffects="Have zero recoil while shooting in ironsights with perked weapons." {
SkillName="Stability"
SkillEffects="Have zero recoil while shooting in ironsights with perked weapons."
} }

View File

@ -1,9 +1,10 @@
class NiceSkillSharpshooterSurgical extends NiceSkill class NiceSkillSharpshooterSurgical extends NiceSkill
abstract; abstract;
var float penDmgReduction; var float penDmgReduction;
defaultproperties defaultproperties
{ {
PenDmgReduction=0.900000 PenDmgReduction=0.900000
SkillName="Surgical precision" SkillName="Surgical precision"
SkillEffects="While you're aiming down sights your bullets and projectiles gain additional head penetration with only 10% damage loss." SkillEffects="While you're aiming down sights your bullets and projectiles gain additional head penetration with only 10% damage loss."
} }

View File

@ -1,7 +1,8 @@
class NiceSkillSharpshooterTalent extends NiceSkill class NiceSkillSharpshooterTalent extends NiceSkill
abstract; abstract;
defaultproperties defaultproperties
{ {
SkillName="Talent" SkillName="Talent"
SkillEffects="You gain additional up to 30% headshot damage bonus." SkillEffects="You gain additional up to 30% headshot damage bonus."
} }

View File

@ -4,24 +4,33 @@ function static SkillSelected(NicePlayerController nicePlayer){
local NicePack niceMutator; local NicePack niceMutator;
super.SkillSelected(nicePlayer); super.SkillSelected(nicePlayer);
niceMutator = class'NicePack'.static.Myself(nicePlayer.Level); niceMutator = class'NicePack'.static.Myself(nicePlayer.Level);
if(niceMutator == none || niceMutator.Role == Role_AUTHORITY) return; if(niceMutator == none || niceMutator.Role == Role_AUTHORITY)
return;
niceMutator.AddCounter("npGunsAdrenaline", Texture'NicePackT.HudCounter.variant', false, default.class); niceMutator.AddCounter("npGunsAdrenaline", Texture'NicePackT.HudCounter.variant', false, default.class);
} }
function static SkillDeSelected(NicePlayerController nicePlayer){ function static SkillDeSelected(NicePlayerController nicePlayer){
local NicePack niceMutator; local NicePack niceMutator;
super.SkillDeSelected(nicePlayer); super.SkillDeSelected(nicePlayer);
niceMutator = class'NicePack'.static.Myself(nicePlayer.Level); niceMutator = class'NicePack'.static.Myself(nicePlayer.Level);
if(niceMutator == none || niceMutator.Role == Role_AUTHORITY) return; if(niceMutator == none || niceMutator.Role == Role_AUTHORITY)
return;
niceMutator.RemoveCounter("npGunsAdrenaline"); niceMutator.RemoveCounter("npGunsAdrenaline");
} }
function static int UpdateCounterValue(string counterName, NicePlayerController nicePlayer){ function static int UpdateCounterValue(string counterName, NicePlayerController nicePlayer){
local NicePack niceMutator; local NicePack niceMutator;
if(nicePlayer == none || counterName != "npGunsAdrenaline" || !nicePlayer.IsZedTimeActive()) return 0; if(nicePlayer == none || counterName != "npGunsAdrenaline" || !nicePlayer.IsZedTimeActive())
if(nicePlayer.bJunkieExtFailed) return 0; return 0;
if(nicePlayer.Pawn != none) niceMutator = class'NicePack'.static.Myself(nicePlayer.Pawn.Level); if(nicePlayer.bJunkieExtFailed)
if(niceMutator == none) return 0; return 0;
if(nicePlayer.Pawn != none)
niceMutator = class'NicePack'.static.Myself(nicePlayer.Pawn.Level);
if(niceMutator == none)
return 0;
return niceMutator.junkieNextGoal - niceMutator.junkieDoneHeadshots; return niceMutator.junkieNextGoal - niceMutator.junkieDoneHeadshots;
} }
defaultproperties defaultproperties
{ SkillName="Adrenaline junkie" SkillEffects="Prolong zed-time by making head-shots. Each consecutive extension requires 1 more head-shot than a previous one. Body-shotting removes your ability to prolong zed-time." {
SkillName="Adrenaline junkie"
SkillEffects="Prolong zed-time by making head-shots. Each consecutive extension requires 1 more head-shot than a previous one. Body-shotting removes your ability to prolong zed-time."
} }

View File

@ -1,5 +1,8 @@
class NiceSkillSharpshooterZEDHundredGauntlets extends NiceSkill class NiceSkillSharpshooterZEDHundredGauntlets extends NiceSkill
abstract; abstract;
defaultproperties defaultproperties
{ SkillName="Hundred Gauntlets" SkillEffects="You don't waste ammo during zed-time." {
SkillName="Hundred Gauntlets"
SkillEffects="You don't waste ammo during zed-time."
} }

View File

@ -1,6 +1,10 @@
class NiceSkillSharpshooterZEDOverkill extends NiceSkill class NiceSkillSharpshooterZEDOverkill extends NiceSkill
abstract; abstract;
var float damageBonus; var float damageBonus;
defaultproperties defaultproperties
{ damageBonus=2.250000 SkillName="Overkill" SkillEffects="Deal 225% head-shot damage during zed-time." {
damageBonus=2.250000
SkillName="Overkill"
SkillEffects="Deal 225% head-shot damage during zed-time."
} }

View File

@ -1,5 +1,8 @@
class NiceSkillSharpshooterZEDRailgun extends NiceSkill class NiceSkillSharpshooterZEDRailgun extends NiceSkill
abstract; abstract;
defaultproperties defaultproperties
{ SkillName="Railgun" SkillEffects="Your bullets pass through everything without losing damage during zed-time." {
SkillName="Railgun"
SkillEffects="Your bullets pass through everything without losing damage during zed-time."
} }

View File

@ -0,0 +1,306 @@
class NiceAssaultRifle extends NiceWeapon;
var bool newStatesLoaded;
var bool bAutoFireEnabled;
var bool bSemiAutoFireEnabled;
var bool bBurstFireEnabled;
var bool bIsBursting;
var bool bIsAltSwitches;
var bool bMustSwitchMode; // Switch between auto and semi-auto/burst modes as soon as possible
var Pawn rememberedOwner;
enum EFireType{
ETYPE_NONE,
ETYPE_AUTO,
ETYPE_SEMI,
ETYPE_BURST
};
var EFireType MainFire;
var EFireType SndFire;
var EFireType PendingFire;
replication
{
reliable if(Role < ROLE_Authority)
ServerForceBurst, ServerApplyFireModes, ServerChangeFireTypes;
reliable if(Role == ROLE_Authority)
MainFire, SndFire, PendingFire, ClientNiceChangeFireMode, ClientChangeBurstLength;
}
simulated function EFireType GetComplimentaryFire(EFireType type){
if(type == ETYPE_AUTO || type == ETYPE_none)
return ETYPE_AUTO;
if(type == ETYPE_SEMI)
return ETYPE_BURST;
return ETYPE_SEMI;
}
simulated function int AmountOfActiveModes(){
if(bAutoFireEnabled && bSemiAutoFireEnabled && bBurstFireEnabled)
return 3;
else if(!bAutoFireEnabled && !bSemiAutoFireEnabled && !bBurstFireEnabled)
return 0;
else if( (bAutoFireEnabled && bSemiAutoFireEnabled) || (bAutoFireEnabled && bBurstFireEnabled) || (bSemiAutoFireEnabled && bBurstFireEnabled) )
return 2;
return 1;
}
function ServerApplyFireModes(){
local NiceFire niceRifleFire;
local NicePlayerController nicePlayer;
niceRifleFire = NiceFire(FireMode[0]);
if(Instigator != none)
nicePlayer = NicePlayerController(Instigator.Controller);
if(niceRifleFire == none)
return;
if(MainFire == ETYPE_AUTO)
niceRifleFire.bWaitForRelease = false;
else if(MainFire == ETYPE_SEMI){
niceRifleFire.bSemiMustBurst = false;
niceRifleFire.bWaitForRelease = true;
}
else if(MainFire == ETYPE_BURST){
niceRifleFire.bSemiMustBurst = true;
niceRifleFire.bWaitForRelease = true;
niceRifleFire.currentContext.burstLength = niceRifleFire.MaxBurstLength;
if(SndFire == ETYPE_SEMI)
SndFire = ETYPE_BURST;
}
if(nicePlayer != none && !nicePlayer.bFlagAltSwitchesModes){
if(SndFire == ETYPE_SEMI)
niceRifleFire.currentContext.burstLength = 1;
else if(SndFire == ETYPE_BURST)
niceRifleFire.currentContext.burstLength = niceRifleFire.MaxBurstLength;
}
if(!bIsReloading && IsFiring()){
StopFire(0);
StopFire(1);
}
ClientNiceChangeFireMode(niceRifleFire.bWaitForRelease, niceRifleFire.bSemiMustBurst);
ClientChangeBurstLength(niceRifleFire.currentContext.burstLength);
}
simulated function ResetFireModes(){
local int modesCount;
local NicePlayerController nicePlayer;
modesCount = AmountOfActiveModes();
nicePlayer = NicePlayerController(Instigator.Controller);
if(modesCount <= 0 || nicePlayer == none)
return;
if(nicePlayer.bFlagAltSwitchesModes){
if(modesCount == 1){
if(bAutoFireEnabled)
MainFire = ETYPE_AUTO;
else if(bSemiAutoFireEnabled)
MainFire = ETYPE_SEMI;
else if(bBurstFireEnabled)
MainFire = ETYPE_BURST;
}
else if(modesCount == 2){
if(bAutoFireEnabled){
MainFire = ETYPE_AUTO;
if(bSemiAutoFireEnabled)
PendingFire = ETYPE_SEMI;
else if(bBurstFireEnabled)
PendingFire = ETYPE_BURST;
}
else{
MainFire = ETYPE_SEMI;
PendingFire = ETYPE_BURST;
}
}
else{
MainFire = ETYPE_AUTO;
PendingFire = ETYPE_SEMI;
}
}
else{
if(modesCount == 1){
if(bAutoFireEnabled)
MainFire = ETYPE_AUTO;
else if(bSemiAutoFireEnabled)
MainFire = ETYPE_SEMI;
else if(bBurstFireEnabled)
MainFire = ETYPE_BURST;
SndFire = ETYPE_none;
}
else if(modesCount == 2){
if(bAutoFireEnabled){
MainFire = ETYPE_AUTO;
if(bSemiAutoFireEnabled)
SndFire = ETYPE_SEMI;
else if(bBurstFireEnabled)
SndFire = ETYPE_BURST;
}
else{
MainFire = ETYPE_SEMI;
SndFire = ETYPE_BURST;
}
}
else{
MainFire = ETYPE_AUTO;
SndFire = ETYPE_SEMI;
}
}
ServerChangeFireTypes(MainFire, SndFire, PendingFire);
ServerApplyFireModes();
}
function ServerChangeFireTypes(EFireType newMain, EFireType newSnd, EFireType newPending){
MainFire = newMain;
SndFire = newSnd;
PendingFire = newPending;
}
function ServerForceBurst(){
local NiceFire niceRifleFire;
niceRifleFire = NiceFire(FireMode[0]);
if(niceRifleFire != none)
niceRifleFire.DoBurst();
}
// Use alt fire to switch fire modes
simulated function AltFire(float F){
local NiceFire niceRifleFire;
local NicePlayerController nicePlayer;
niceRifleFire = NiceFire(FireMode[0]);
nicePlayer = NicePlayerController(Instigator.Controller);
if(nicePlayer != none && niceRifleFire != none && SndFire != ETYPE_NONE){
if(FireModeClass[1] == class'KFMod.NoFire'){
if(nicePlayer.bFlagAltSwitchesModes)
SwitchModes();
else{
niceRifleFire.DoBurst();
ServerForceBurst();
super.AltFire(F);
}
return;
}
}
super.AltFire(F);
}
exec simulated function SwitchModes(){
if(Role < ROLE_Authority && AmountOfActiveModes() > 1)
bMustSwitchMode = !bMustSwitchMode;
}
simulated function DoToggle(){
local EFireType tempType;
local PlayerController player;
if(IsFiring())
return;
player = Level.GetLocalPlayerController();
if(player != none && AmountOfActiveModes() > 1){
tempType = MainFire;
MainFire = PendingFire;
PendingFire = tempType;
player.bFire = 0;
player.bAltFire = 0;
ServerChangeFireTypes(MainFire, SndFire, PendingFire);
ServerApplyFireModes();
PlayOwnedSound(ToggleSound, SLOT_none, 2.0,,,, false);
if(MainFire == ETYPE_AUTO)
player.ReceiveLocalizedMessage(class'NicePack.NiceAssaultRifleMessage', 1);
else if(MainFire == ETYPE_SEMI)
player.ReceiveLocalizedMessage(class'NicePack.NiceAssaultRifleMessage', 0);
else if(MainFire == ETYPE_BURST)
player.ReceiveLocalizedMessage(class'NicePack.NiceAssaultRifleMessage', 2);
}
}
simulated function SecondDoToggle(){
local EFireType choosenType;
local NiceFire niceRifleFire;
local NicePlayerController nicePlayer;
if(FireModeClass[1] != class'KFMod.NoFire'){
DoToggle();
return;
}
niceRifleFire = NiceFire(FireMode[0]);
nicePlayer = NicePlayerController(Instigator.Controller);
if(IsFiring() || AmountOfActiveModes() < 3 || nicePlayer == none || niceRifleFire == none)
return;
if(nicePlayer.bFlagAltSwitchesModes){
if(MainFire == ETYPE_AUTO){
PendingFire = GetComplimentaryFire(PendingFire);
choosenType = PendingFire;
}
else{
MainFire = GetComplimentaryFire(MainFire);
choosenType = MainFire;
}
}
else{
SndFire = GetComplimentaryFire(SndFire);
choosenType = SndFire;
}
ServerChangeFireTypes(MainFire, SndFire, PendingFire);
ServerApplyFireModes();
PlayOwnedSound(ToggleSound, SLOT_none, 2.0,,,, false);
if(choosenType == ETYPE_SEMI)
nicePlayer.ReceiveLocalizedMessage(class'NicePack.NiceAssaultRifleMessage', 4);
else
nicePlayer.ReceiveLocalizedMessage(class'NicePack.NiceAssaultRifleMessage', 5);
}
simulated function ClientNiceChangeFireMode(bool bNewWaitForRelease, bool bNewSemiMustBurst){
local NiceFire niceF;
if(!bIsReloading && IsFiring()){
StopFire(0);
StopFire(1);
}
niceF = NiceFire(FireMode[0]);
FireMode[0].bWaitForRelease = bNewWaitForRelease;
FireMode[0].bNowWaiting = bNewWaitForRelease;
if(niceF != none)
niceF.bSemiMustBurst = bNewSemiMustBurst;
}
simulated function ClientChangeBurstLength(int newBurstLength){
if(NiceFire(FireMode[0]) != none)
NiceFire(FireMode[0]).currentContext.burstLength = newBurstLength;
}
simulated function bool AltFireCanForceInterruptReload(){
local NicePlayerController nicePlayer;
nicePlayer = NicePlayerController(Instigator.Controller);
if(nicePlayer != none)
return (!nicePlayer.bFlagAltSwitchesModes) && (GetMagazineAmmo() > 0);
return false;
}
simulated function WeaponTick(float dt){
local NicePlayerController nicePlayer;
super.WeaponTick(dt);
if(bMustSwitchMode && FireMode[0].NextFireTime /*+ 0.1*/ < Level.TimeSeconds && Role < ROLE_Authority){
DoToggle();
bMustSwitchMode = false;
}
nicePlayer = NicePlayerController(Instigator.Controller);
if(Role == ROLE_Authority && nicePlayer != none && (bIsAltSwitches != nicePlayer.bFlagAltSwitchesModes || (rememberedOwner != Instigator))){
if(newStatesLoaded)
ServerApplyFireModes();
else
ResetFireModes();
bIsAltSwitches = nicePlayer.bFlagAltSwitchesModes;
rememberedOwner = Instigator;
}
}
function NicePlainData.Data GetNiceData(){
local NicePlainData.Data transferData;
transferData = super.GetNiceData();
class'NicePlainData'.static.SetInt(transferData, "MainFire", int(MainFire));
class'NicePlainData'.static.SetInt(transferData, "SndFire", int(SndFire));
class'NicePlainData'.static.SetInt(transferData, "PendingFire", int(PendingFire));
return transferData;
}
function SetNiceData(NicePlainData.Data transferData, optional NiceHumanPawn newOwner){
local EFireType newFireType;
super.SetNiceData(transferData, newOwner);
newStatesLoaded = false;
if(class'NicePlainData'.static.LookupVar(transferData, "MainFire") < 0)
ResetFireModes();
else{
newFireType = EFireType(class'NicePlainData'.static.GetInt(transferData, "MainFire"));
MainFire = newFireType;
newFireType = EFireType(class'NicePlainData'.static.GetInt(transferData, "SndFire"));
SndFire = newFireType;
newFireType = EFireType(class'NicePlainData'.static.GetInt(transferData, "PendingFire"));
PendingFire = newFireType;
newStatesLoaded = true;
}
}
defaultproperties
{
bAutoFireEnabled=True
bSemiAutoFireEnabled=True
MainFire=ETYPE_AUTO
SndFire=ETYPE_SEMI
PendingFire=ETYPE_BURST
bUseFlashlightToToggle=True
}

View File

@ -0,0 +1,9 @@
class NiceAssaultRifleMessage extends BullpupSwitchMessage;
defaultproperties
{
SwitchMessage(2)="Set to Burst Fire."
SwitchMessage(3)="Set to 5-Burst Fire."
SwitchMessage(4)="Secondary mode now set to Semi-Automatic."
SwitchMessage(5)="Secondary mode now set to Burst Fire."
}

View File

@ -0,0 +1,6 @@
class NiceHeavyFire extends NiceFire;
defaultproperties
{
maxBonusContLenght=3
}

View File

@ -0,0 +1,5 @@
class NiceHeavyGun extends NiceWeapon;
defaultproperties
{
}

View File

@ -0,0 +1,57 @@
class NiceMedicDartFire extends NiceFire;
function DoFireEffect(){
local float oldLoad;
oldLoad = Load;
Load = 1;
super.DoFireEffect();
Load = oldLoad;
}
simulated function bool AllowFire(){
local KFPawn kfPwn;
if(currentContext.sourceWeapon == none || Instigator == none)
return false;
if(currentContext.sourceWeapon.secondaryCharge < default.AmmoPerFire)
return false;
// Check reloading
if(currentContext.sourceWeapon.bIsReloading)
return false;
// Check pawn actions
kfPwn = KFPawn(Instigator);
if(kfPwn == none || kfPwn.SecondaryItem != none || kfPwn.bThrowingNade)
return false;
return true;
}
simulated function ReduceAmmoClient(){
local NiceMedicGun sourceMedGun;
currentContext.sourceWeapon.secondaryCharge -= AmmoPerFire;
sourceMedGun = NiceMedicGun(currentContext.sourceWeapon);
if(sourceMedGun != none){
sourceMedGun.ServerSetMedicCharge(currentContext.sourceWeapon.secondaryCharge);
sourceMedGun.ClientSetMedicCharge(currentContext.sourceWeapon.secondaryCharge);
}
}
defaultproperties
{
ProjectileSpeed=12500.000000
bulletClass=Class'NicePack.NiceMedicProjectile'
FireAimedAnim="Fire_Iron"
FireSoundRef="KF_MP7Snd.Medicgun_Fire"
StereoFireSoundRef="KF_MP7Snd.Medicgun_FireST"
NoAmmoSoundRef="KF_PumpSGSnd.SG_DryFire"
DamageMax=30
bWaitForRelease=True
bAttachSmokeEmitter=True
TransientSoundVolume=2.000000
TransientSoundRadius=500.000000
AmmoPerFire=50
ShakeRotMag=(X=50.000000,Y=50.000000,Z=400.000000)
ShakeRotRate=(X=12500.000000,Y=12500.000000,Z=12500.000000)
ShakeRotTime=5.000000
ShakeOffsetMag=(X=6.000000,Y=2.000000,Z=10.000000)
ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000)
ShakeOffsetTime=3.000000
BotRefireRate=0.250000
FlashEmitterClass=Class'ROEffects.MuzzleFlash1stKar'
aimerror=1.000000
}

View File

@ -0,0 +1,91 @@
class NiceMedicGun extends NiceWeapon
abstract;
var const float maxMedicCharge;
var float medicChargeRegenRate;
// This variable is dictated by client.
var float medicCharge;
// Medic charge is replicated on server via these periods
var float medicChargeUpdatePeriod;
// This variable is only relevant on a server, to predict current medic charge in-between new updates
var float lastMedicChargeServerUpdate;
// This variable is only relevant on a client, to predict current medic charge in-between weapon ticks
var float lastMedicChargeClientUpdate;
replication{
reliable if(Role < ROLE_Authority)
ServerSetMedicCharge;
reliable if(Role == ROLE_Authority)
ClientSetMedicCharge, ClientSuccessfulHeal;
}
function NicePlainData.Data GetNiceData(){
local NicePlainData.Data transferData;
transferData = super.GetNiceData();
class'NicePlainData'.static.SetFloat(transferData, "MedicCharge", GetCurrentMedicCharge());
class'NicePlainData'.static.SetFloat(transferData, "MedicChargeUpd", Level.TimeSeconds);
return transferData;
}
function SetNiceData(NicePlainData.Data transferData, optional NiceHumanPawn newOwner){
super.SetNiceData(transferData, newOwner);
medicCharge = class'NicePlainData'.static.GetFloat(transferData, "MedicCharge", 0.0);
lastMedicChargeServerUpdate = class'NicePlainData'.static.GetFloat(transferData, "MedicChargeUpd", -1.0);
if(lastMedicChargeServerUpdate >= 0.0)
medicCharge += (Level.TimeSeconds - lastMedicChargeServerUpdate) * medicChargeRegenRate;
lastMedicChargeServerUpdate = Level.TimeSeconds;
ClientSetMedicCharge(medicCharge);
}
function ServerSetMedicCharge(float newCharge){
medicCharge = newCharge;
lastMedicChargeServerUpdate = Level.TimeSeconds;
}
simulated function ClientSetMedicCharge(float newCharge){
medicCharge = newCharge;
}
// Returns current medic charge
// Uses prediction a server
simulated function float GetCurrentMedicCharge(){
if(Role < ROLE_Authority)
return medicCharge;
else
return medicCharge + (Level.TimeSeconds - lastMedicChargeServerUpdate) * medicChargeRegenRate;
}
simulated function WeaponTick(float dt){
local int prevPeriodsAmount;
local bool bWasBelowMax;
if(Role < ROLE_Authority){
// Remember the old state
bWasBelowMax = (medicCharge < maxMedicCharge);
prevPeriodsAmount = Ceil(medicCharge / medicChargeUpdatePeriod);
// Update medic charge
medicCharge += (Level.TimeSeconds - lastMedicChargeClientUpdate) * medicChargeRegenRate;
lastMedicChargeClientUpdate = Level.TimeSeconds;
medicCharge = FMin(medicCharge, maxMedicCharge);
secondaryCharge = Ceil(medicCharge);
// Replicate to server when necessary
if( (bWasBelowMax && medicCharge >= maxMedicCharge)
|| prevPeriodsAmount < Ceil(medicCharge / medicChargeUpdatePeriod) )
ServerSetMedicCharge(medicCharge);
}
super.WeaponTick(dt);
}
simulated function ClientSuccessfulHeal(NiceHumanPawn healer, NiceHumanPawn healed){
if(healed == none)
return;
if(instigator != none && PlayerController(instigator.controller) != none)
PlayerController(instigator.controller).
ClientMessage("You've healed"@healed.GetPlayerName(), 'CriticalEvent');
if(NiceHumanPawn(instigator) != none && PlayerController(healed.controller) != none)
PlayerController(healed.controller).
ClientMessage("You've been healed by"@healer.GetPlayerName(), 'CriticalEvent');
}
defaultproperties
{
maxMedicCharge=100.000000
medicChargeRegenRate=10.000000
medicChargeUpdatePeriod=10.000000
bShowSecondaryCharge=True
SecondaryCharge=0
bChangeSecondaryIcon=True
hudSecondaryTexture=Texture'KillingFloorHUD.HUD.Hud_Syringe'
activeSlowdown=0.750000
activeSpeedup=2.000000
}

View File

@ -0,0 +1,20 @@
class NiceMedicProjectile extends NiceBullet;
function GenerateImpactEffects(ImpactEffect effect, Vector hitLocation, Vector hitNormal,
optional bool bWallImpact, optional bool bGenerateDecal){
if(bWallImpact){
effect.EmitterClass = none;
effect.bPlayROEffect = true;
effect.bImportanEffect = false;
effect.noise = none;
}
super.GenerateImpactEffects(effect, hitLocation, hitNormal, bWallImpact, bGenerateDecal);
}
defaultproperties
{
trailXClass=None
regularImpact=(bImportanEffect=True,bPlayROEffect=False,decalClass=Class'KFMod.ShotgunDecal',EmitterClass=Class'KFMod.healingFX',emitterShiftWall=20.000000,emitterShiftPawn=20.000000,noiseRef="KF_MP7Snd.MP7_DartImpact",noiseVolume=2.000000)
bGenRegEffectOnPawn=True
StaticMeshRef="KF_pickups2_Trip.MP7_Dart"
AmbientSoundRef="KF_MP7Snd.MP7_DartFlyLoop"
}

View File

@ -0,0 +1,6 @@
class NiceMeleeAttachment extends NiceAttachment;
defaultproperties
{
bDoFiringEffects=False
}

View File

@ -0,0 +1,290 @@
//==============================================================================
// NicePack / NiceMeleeFire
//==============================================================================
// Adjustment of vanilla melee fire class to NicePack.
//==============================================================================
// 'Nice pack' source
// Do whatever the fuck you want with it
// Author: dkanus
// E-mail: dkanus@gmail.com
//==============================================================================
class NiceMeleeFire extends NiceFire;
var float weaponRange;
var float damageDelay;
// How far to rot view?
var vector impactShakeRotMag;
// How fast to rot view?
var vector impactShakeRotRate;
// How much time to rot the instigator's view?
var float impactShakeRotTime;
// Max view offset vertically?
var vector impactShakeOffsetMag;
// How fast to offset view vertically?
var vector impactShakeOffsetRate;
// How much time to offset view?
var float impactShakeOffsetTime;
// Sound for this melee strike hitting a pawn (fleshy hits).
var array<sound> meleeHitSounds;
var float meleeHitVolume;
var array<name> fireAnims;
// The class to spawn for the hit effect for
// this melee weapon hitting the world (not pawns).
var class<KFMeleeHitEffect> hitEffectClass;
var array<string> meleeHitSoundRefs;
// The angle to do sweeping strikes in front of the player.
// If zero, - do no strikes.
var float wideDamageMinHitAngle;
static function PreloadAssets(LevelInfo level, optional KFFire spawned){
local int i;
local NiceMeleeFire niceFire;
super.PreloadAssets(level, spawned);
for(i = 0; i < default.meleeHitSoundRefs.length;i ++){
if(default.meleeHitSoundRefs[i] == "")
continue;
if( default.meleeHitSounds.length >= i + 1
&& default.meleeHitSounds[i] != none)
continue;
default.meleeHitSounds[i] = Sound(
DynamicLoadObject( default.meleeHitSoundRefs[i],
class'Sound', true));
}
niceFire = NiceMeleeFire(spawned);
if(niceFire != none)
for(i = 0; i < default.meleeHitSoundRefs.length;i ++)
niceFire.meleeHitSounds[i] = default.meleeHitSounds[i];
}
static function bool UnloadAssets(){
local int i;
super.UnloadAssets();
for(i = 0; i < default.meleeHitSoundRefs.length;i ++)
default.meleeHitSounds[i] = none;
return true;
}
simulated function DoBurst(optional bool bSkipFirstShot){}
function DoFireEffect(){}
function float MaxRange(){
local bool hasWindCutterSkill;
traceRange = weaponRange;
if(instigator == none) return traceRange;
hasWindCutterSkill = class'NiceVeterancyTypes'.static.
HasSkill( NicePlayerController(instigator.controller),
class'NiceSkillZerkWindCutter');
if(hasWindCutterSkill)
traceRange *= class'NiceSkillZerkWindCutter'.default.rangeBonus;
return traceRange;
}
simulated function bool AllowFire(){
local KFPawn kfPwn;
// Check pawn actions
kfPwn = KFPawn(instigator);
if(kfPwn == none || kfPwn.SecondaryItem != none || kfPwn.bThrowingNade)
return false;
return true;
}
function name GetCorrectAnim(bool bLoop, bool bAimed){
local int AnimToPlay;
if(fireAnims.length > 0){
AnimToPlay = rand(fireAnims.length);
fireAnim = fireAnims[AnimToPlay];
}
return FireAnim;
}
simulated function NiceMonster DealTargetMeleeDamage
(
NiceReplicationInfo niceRI,
class<NiceWeaponDamageType> niceDmgType
){
local float headSizeModifier;
local float headshotLevel;
local NiceMonster niceZed;
local Vector hitLocation, hitNormal;
local KFPlayerReplicationInfo KFPRI;
local class<NiceVeterancyTypes> niceVet;
if(niceRI == none || instigator == none) return none;
KFPRI = KFPlayerReplicationInfo(instigator.PlayerReplicationInfo);
if(KFPRI == none)
return none;
niceVet = class<NiceVeterancyTypes>(KFPRI.ClientVeteranSkill);
if(niceVet == none)
return none;
if(niceDmgType != none)
headSizeModifier = niceDmgType.default.headSizeModifier;
headSizeModifier = 1.0;
headSizeModifier *=
niceVet.static.GetHeadshotCheckMultiplier(KFPRI, niceDmgType);
headshotLevel = TraceZed(niceZed, hitLocation, hitNormal, headSizeModifier);
if(niceZed != none)
HitZed(niceZed, headshotLevel, niceRI, niceDmgType);
else
HitWall(niceRI, niceDmgType);
return niceZed;
}
function HitZed(NiceMonster niceZed,
float headshotLevel,
NiceReplicationInfo niceRI,
class<NiceWeaponDamageType> niceDmgType){
local Vector hitLocation, hitNormal;
local NiceMeleeWeapon niceWeap;
ImpactShakeView();
niceWeap = NiceMeleeWeapon(weapon);
if(niceWeap != none && niceWeap.BloodyMaterial != none)
niceWeap.Skins[niceWeap.BloodSkinSwitchArray] = niceWeap.BloodyMaterial;
niceRI.ServerDealMeleeDamage( niceZed, damageMax, instigator,
hitLocation, -hitNormal,
niceDmgType, true, headshotLevel);
}
function HitWall( NiceReplicationInfo niceRI,
class<NiceWeaponDamageType> niceDmgType){
local Actor wall;
local Vector hitLocation, hitNormal;
local Rotator rotation;
TraceWall(wall, hitLocation, hitNormal);
if(wall != none){
niceRI.ServerDealMeleeDamage( wall, damageMax, instigator,
hitLocation, -hitNormal, niceDmgType,
false);
rotation = Rotator
(
HitLocation - instigator.location - instigator.EyePosition()
);
instigator.spawn(hitEffectClass,,, hitLocation, rotation);
}
}
simulated function DealArcMeleeDamage
(
NiceMonster niceZed,
NiceReplicationInfo niceRI,
class<NiceWeaponDamageType> niceDmgType
){
local NiceMonster otherZed;
local float actualMinAngle, tempRadians;
local bool hasCleave;
if(weapon == none) return;
hasCleave = class'NiceVeterancyTypes'.static.
HasSkill( NicePlayerController(instigator.controller),
class'NiceSkillZerkCleave');
actualMinAngle = wideDamageMinHitAngle;
if(hasCleave){
tempRadians = acos(actualMinAngle);
tempRadians += class'NiceSkillZerkCleave'.default.bonusDegrees;
tempRadians = FMin(tempRadians, Pi);
actualMinAngle = cos(tempRadians);
}
foreach weapon.VisibleCollidingActors(
class'NiceMonster', otherZed, weaponRange * 2,
instigator.location + instigator.EyePosition()){
if(niceZed != none && otherZed == niceZed) continue;
if(otherZed == instigator || otherZed.Health <= 0) continue;
TryHitZedArc(actualMinAngle, otherZed, niceRI, niceDmgType);
}
}
function TryHitZedArc(float minAngle, NiceMonster niceZed,
NiceReplicationInfo niceRI,
class<NiceWeaponDamageType> niceDmgType){
local vector hitLocation, hitNormal;
local vector dir, lookDir;
local float diffAngle, victimDist;
victimDist = VSize(instigator.location - niceZed.location);
if(victimDist + niceZed.CollisionRadius > weaponRange * 1.1)
return;
lookDir = Normal(Vector(instigator.GetViewRotation()));
dir = Normal(niceZed.location - instigator.location);
diffAngle = lookDir dot dir;
if(diffAngle <= minAngle)
return;
hitLocation =
niceZed.location + niceZed.CollisionHeight * vect(0,0,0.7);
niceRI.ServerDealMeleeDamage( niceZed, damageMax * 0.5, instigator,
hitLocation, hitNormal, niceDmgType,
false, 0.0);
if(meleeHitSounds.Length > 0)
niceZed.PlaySound( meleeHitSounds[Rand(meleeHitSounds.length)],
SLOT_None, meleeHitVolume,,,, false);
}
simulated function Timer(){
local NiceMonster niceZed;
local NiceReplicationInfo niceRI;
local class<NiceWeaponDamageType> niceDmgType;
niceRI = GetNiceRI();
niceDmgType = class<NiceWeaponDamageType>(damageType);
if(niceRI == none || instigator == none || niceDmgType == none)
return;
niceZed = DealTargetMeleeDamage(niceRI, niceDmgType);
DealArcMeleeDamage(niceZed, niceRI, niceDmgType);
}
simulated function MDFEffectsClient(float newAmmoPerFire, float rec){
local float fireSpeedMod;
fireSpeedMod = GetFireSpeed();
super.MDFEffectsClient(newAmmoPerFire, rec);
SetTimer(damageDelay / fireSpeedMod, false);
}
function PlayFiring_animation(){
if(weapon == none) return;
if(weapon.Mesh == none) return;
if(fireCount <= 0){
weapon.PlayAnim(GetCorrectAnim(false, false), fireAnimRate, 0.0);
return;
}
if(weapon.HasAnim(FireLoopAnim))
weapon.PlayAnim(GetCorrectAnim(true, false), fireLoopAnimRate, 0.0);
else
weapon.PlayAnim(GetCorrectAnim(false, false), fireAnimRate, 0.0);
}
function PlayFiring(){
local float randPitch;
local bool shouldPlayStereo;
if(weapon == none) return;
if(weapon.instigator == none) return;
PlayFiring_animation();
if(bRandomPitchFireSound){
randPitch = FRand() * RandomPitchAdjustAmt;
if(FRand() < 0.5)
randPitch *= -1.0;
}
shouldPlayStereo = weapon.instigator.IsLocallyControlled()
&& weapon.instigator.IsFirstPerson()
&& StereoFireSound != none;
if(shouldPlayStereo){
weapon.PlayOwnedSound( StereoFireSound, SLOT_Interact,
TransientSoundVolume * 0.85,,
TransientSoundRadius, 1.0 + randPitch, false);
}
else{
weapon.PlayOwnedSound( FireSound, SLOT_Interact, TransientSoundVolume,,
TransientSoundRadius, 1.0 + randPitch, false);
}
ClientPlayForceFeedback(fireForce);
if(!currentContext.bIsBursting)
fireCount ++;
}
function ImpactShakeView(){
local NicePlayerController nicePlayer;
if(instigator == none) return;
nicePlayer = NicePlayerController(instigator.controller);
if(nicePlayer == none)
return;
nicePlayer.WeaponShakeView( impactShakeRotMag, impactShakeRotRate,
impactShakeRotTime, impactShakeOffsetMag,
impactShakeOffsetRate, impactShakeOffsetTime);
}
simulated function HandleRecoil(float Rec){}
defaultproperties
{
weaponRange=70.000000
damageDelay=0.300000
ImpactShakeRotMag=(X=50.000000,Y=50.000000,Z=50.000000)
ImpactShakeRotRate=(X=10000.000000,Y=10000.000000,Z=10000.000000)
ImpactShakeRotTime=2.000000
ImpactShakeOffsetMag=(X=10.000000,Y=10.000000,Z=10.000000)
ImpactShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000)
ImpactShakeOffsetTime=2.000000
MeleeHitVolume=1.000000
HitEffectClass=Class'KFMod.KFMeleeHitEffect'
WideDamageMinHitAngle=1.000000
bFiringDoesntAffectMovement=True
FireEndAnim=
FireForce="ShockRifleFire"
aimerror=100.000000
}

View File

@ -0,0 +1,42 @@
class NiceMeleeWeapon extends NiceWeapon;
var class<damageType> hitDamType;
var float weaponRange;
var Material BloodyMaterial;
var int BloodSkinSwitchArray;
var string BloodyMaterialRef;
static function PreloadAssets(Inventory Inv, optional bool bSkipRefCount){
super.PreloadAssets(Inv, bSkipRefCount);
if(default.BloodyMaterial == none && default.BloodyMaterialRef != "")
default.BloodyMaterial = Combiner(DynamicLoadObject(default.BloodyMaterialRef, class'Combiner', true));
if(NiceMeleeWeapon(Inv) != none)
NiceMeleeWeapon(Inv).BloodyMaterial = default.BloodyMaterial;
}
static function bool UnloadAssets(){
if(super.UnloadAssets())
default.BloodyMaterial = none;
return true;
}
//simulated function IncrementFlashCount(int mode){
//}
simulated function BringUp(optional Weapon PrevWeapon){
if(BloodyMaterial!=none && Skins[BloodSkinSwitchArray] == BloodyMaterial ){
Skins[BloodSkinSwitchArray] = default.Skins[BloodSkinSwitchArray];
Texture = default.Texture;
}
super.BringUp(PrevWeapon);
}
simulated function Fire(float F){
}
simulated function AltFire(float F){
}
simulated function bool HasAmmo(){
return true;
}
defaultproperties
{
weaponRange=70.000000
BloodSkinSwitchArray=2
PutDownAnim="PutDown"
bMeleeWeapon=True
}

View File

@ -0,0 +1,123 @@
class NiceHighROFFire extends NiceFire;
// sound
var sound FireEndSound; // The sound to play at the end of the ambient fire sound
var sound FireEndStereoSound; // The sound to play at the end of the ambient fire sound in first person stereo
var float AmbientFireSoundRadius; // The sound radius for the ambient fire sound
var sound AmbientFireSound; // How loud to play the looping ambient fire sound
var byte AmbientFireVolume; // The ambient fire sound
var string FireEndSoundRef;
var string FireEndStereoSoundRef;
var string AmbientFireSoundRef;
//MEANTODO
/*
static function PreloadAssets(LevelInfo LevelInfo, optional KFFire Spawned){
super.PreloadAssets(LevelInfo, Spawned);
if(default.FireEndSound != none && default.FireEndSoundRef != "")
default.FireEndSound = sound(DynamicLoadObject(default.FireEndSoundRef, class'sound', true));
if(default.FireEndStereoSound == none){
if(default.FireEndStereoSoundRef != "")
default.FireEndStereoSound = sound(DynamicLoadObject(default.FireEndStereoSoundRef, class'Sound', true));
else
default.FireEndStereoSound = default.FireEndSound;
}
if(default.AmbientFireSoundRef != "")
default.AmbientFireSound = sound(DynamicLoadObject(default.AmbientFireSoundRef, class'sound', true));
if(NiceHighROFFire(Spawned) != none){
NiceHighROFFire(Spawned).FireEndSound = default.FireEndSound;
NiceHighROFFire(Spawned).FireEndStereoSound = default.FireEndStereoSound;
NiceHighROFFire(Spawned).AmbientFireSound = default.AmbientFireSound;
}
}
static function bool UnloadAssets(){
super.UnloadAssets();
default.FireEndSound = none;
default.FireEndStereoSound = none;
default.AmbientFireSound = none;
return true;
}
// Sends the fire class to the looping state
function StartFiring(){
if(!bWaitForRelease && !currentContext.bIsBursting)
GotoState('FireLoop');
else
Super.StartFiring();
}
// Handles toggling the weapon attachment's ambient sound on and off
function PlayAmbientSound(Sound aSound){
local WeaponAttachment WA;
WA = WeaponAttachment(Weapon.ThirdPersonActor);
if(Weapon == none || (WA == none))
return;
if(aSound == none){
WA.SoundVolume = WA.default.SoundVolume;
WA.SoundRadius = WA.default.SoundRadius;
}
else{
WA.SoundVolume = AmbientFireVolume;
WA.SoundRadius = AmbientFireSoundRadius;
}
WA.AmbientSound = aSound;
}
// Make sure we are in the fire looping state when we fire
event ModeDoFire(){
if(!bWaitForRelease && !currentContext.bIsBursting){
if(AllowFire() && IsInState('FireLoop'))
Super.ModeDoFire();
}
else
Super.ModeDoFire();
}
state FireLoop
{
function BeginState(){
NextFireTime = Level.TimeSeconds - 0.1;
if(KFWeap.bAimingRifle)
Weapon.LoopAnim(FireLoopAimedAnim, FireLoopAnimRate, TweenTime);
else
Weapon.LoopAnim(FireLoopAnim, FireLoopAnimRate, TweenTime);
PlayAmbientSound(AmbientFireSound);
}
function PlayFiring(){}
function ServerPlayFiring(){}
function EndState(){
Weapon.AnimStopLooping();
PlayAmbientSound(none);
if(Weapon.Instigator != none && Weapon.Instigator.IsLocallyControlled() &&
Weapon.Instigator.IsFirstPerson() && StereoFireSound != none)
Weapon.PlayOwnedSound(FireEndStereoSound,SLOT_none,AmbientFireVolume/127,,AmbientFireSoundRadius,,false);
else
Weapon.PlayOwnedSound(FireEndSound,SLOT_none,AmbientFireVolume/127,,AmbientFireSoundRadius);
Weapon.StopFire(ThisModeNum);
}
function StopFiring(){
GotoState('');
}
function ModeTick(float dt){
Super.ModeTick(dt);
if(!bIsFiring || !AllowFire()){
GotoState('');
return;
}
}
}
function PlayFireEnd(){
if(!bWaitForRelease)
Super.PlayFireEnd();
}*/
defaultproperties
{
AmbientFireSoundRadius=500.000000
AmbientFireVolume=255
FireAimedAnim="Fire_Iron"
FireEndAimedAnim="Fire_Iron_End"
FireLoopAimedAnim="Fire_Iron_Loop"
bAccuracyBonusForSemiAuto=True
bPawnRapidFireAnim=True
TransientSoundVolume=1.800000
FireLoopAnim="Fire_Loop"
FireEndAnim="Fire_End"
TweenTime=0.025000
FireForce="AssaultRifleFire"
BotRefireRate=0.100000
aimerror=30.000000
}

View File

@ -0,0 +1,441 @@
class NiceScopedWeapon extends NiceWeapon
abstract;
#exec OBJ LOAD FILE=ScopeShaders.utx
#exec OBJ LOAD FILE=..\Textures\NicePackT.utx
#exec OBJ LOAD FILE=ScrnWeaponPack_T.utx
#exec OBJ LOAD FILE=ScrnWeaponPack_A.ukx
var() Material ZoomMat;
var() Sound ZoomSound;
var() int lenseMaterialID; // used since material id's seem to change alot
var() float scopePortalFOVHigh; // The FOV to zoom the scope portal by.
var() float scopePortalFOV; // The FOV to zoom the scope portal by.
var() vector XoffsetScoped;
var() vector XoffsetHighDetail;
var() int tileSize;
// 3d Scope vars
var ScriptedTexture ScopeScriptedTexture; // Scripted texture for 3d scopes
var Shader ScopeScriptedShader; // The shader that combines the scripted texture with the sight overlay
var Material ScriptedTextureFallback; // The texture to render if the users system doesn't support shaders
// new scope vars
var Combiner ScriptedScopeCombiner;
var texture TexturedScopeTexture;
var bool bInitializedScope; // Set to true when the scope has been initialized
var string ZoomMatRef;
var string ScriptedTextureFallbackRef;
var texture CrosshairTex;
var string CrosshairTexRef;
static function PreloadAssets(Inventory Inv, optional bool bSkipRefCount){
local NiceScopedWeapon W;
super.PreloadAssets(Inv, bSkipRefCount);
if(default.ZoomMat == none && default.ZoomMatRef != ""){
// Try to load as various types of materials
default.ZoomMat = FinalBlend(DynamicLoadObject(default.ZoomMatRef, class'FinalBlend', true));
if(default.ZoomMat == none)
default.ZoomMat = Combiner(DynamicLoadObject(default.ZoomMatRef, class'Combiner', true));
if(default.ZoomMat == none)
default.ZoomMat = Shader(DynamicLoadObject(default.ZoomMatRef, class'Shader', true));
if(default.ZoomMat == none)
default.ZoomMat = Texture(DynamicLoadObject(default.ZoomMatRef, class'Texture', true));
if(default.ZoomMat == none)
default.ZoomMat = Material(DynamicLoadObject(default.ZoomMatRef, class'Material'));
}
if(default.ScriptedTextureFallback == none && default.ScriptedTextureFallbackRef != "")
default.ScriptedTextureFallback = texture(DynamicLoadObject(default.ScriptedTextureFallbackRef, class'texture'));
if(default.CrosshairTex == none && default.CrosshairTexRef != "")
default.CrosshairTex = Texture(DynamicLoadObject(default.CrosshairTexRef, class'texture'));
W = NiceScopedWeapon(Inv);
if(W != none){
W.ZoomMat = default.ZoomMat;
W.ScriptedTextureFallback = default.ScriptedTextureFallback;
W.CrosshairTex = default.CrosshairTex;
}
}
static function bool UnloadAssets(){
if(super.UnloadAssets()){
default.ZoomMat = none;
default.ScriptedTextureFallback = none;
default.CrosshairTex = none;
}
return true;
}
simulated function bool ShouldDrawPortal()
{
if(bAimingRifle)
return true;
else
return false;
}
simulated function PostBeginPlay()
{
super.PostBeginPlay();
// Get new scope detail value from KFWeapon
KFScopeDetail = class'KFMod.KFWeapon'.default.KFScopeDetail;
UpdateScopeMode();
}
// Handles initializing and swithing between different scope modes
simulated function UpdateScopeMode()
{
if (Level.NetMode != NM_DedicatedServer && Instigator != none && Instigator.IsLocallyControlled() && Instigator.IsHumanControlled()){
if(KFScopeDetail == KF_ModelScope){
scopePortalFOV = default.scopePortalFOV;
ZoomedDisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOV);
if (bUsingSights || bAimingRifle)
PlayerViewOffset = XoffsetScoped;
if(ScopeScriptedTexture == none)
ScopeScriptedTexture = ScriptedTexture(Level.ObjectPool.AllocateObject(class'ScriptedTexture'));
ScopeScriptedTexture.FallBackMaterial = ScriptedTextureFallback;
ScopeScriptedTexture.SetSize(512,512);
ScopeScriptedTexture.Client = Self;
if(ScriptedScopeCombiner == none){
ScriptedScopeCombiner = Combiner(Level.ObjectPool.AllocateObject(class'Combiner'));
ScriptedScopeCombiner.Material1 = CrosshairTex;
ScriptedScopeCombiner.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader';
ScriptedScopeCombiner.CombineOperation = CO_Multiply;
ScriptedScopeCombiner.AlphaOperation = AO_Use_Mask;
ScriptedScopeCombiner.Material2 = ScopeScriptedTexture;
}
if(ScopeScriptedShader == none){
ScopeScriptedShader = Shader(Level.ObjectPool.AllocateObject(class'Shader'));
ScopeScriptedShader.Diffuse = ScriptedScopeCombiner;
ScopeScriptedShader.SelfIllumination = ScriptedScopeCombiner;
ScopeScriptedShader.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader';
}
bInitializedScope = true;
}
else if( KFScopeDetail == KF_ModelScopeHigh )
{
scopePortalFOV = scopePortalFOVHigh;
ZoomedDisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOVHigh);
if(bUsingSights || bAimingRifle)
PlayerViewOffset = XoffsetHighDetail;
if(ScopeScriptedTexture == none)
ScopeScriptedTexture = ScriptedTexture(Level.ObjectPool.AllocateObject(class'ScriptedTexture'));
ScopeScriptedTexture.FallBackMaterial = ScriptedTextureFallback;
ScopeScriptedTexture.SetSize(1024,1024);
ScopeScriptedTexture.Client = Self;
if(ScriptedScopeCombiner == none){
ScriptedScopeCombiner = Combiner(Level.ObjectPool.AllocateObject(class'Combiner'));
ScriptedScopeCombiner.Material1 = CrosshairTex;
ScriptedScopeCombiner.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader';
ScriptedScopeCombiner.CombineOperation = CO_Multiply;
ScriptedScopeCombiner.AlphaOperation = AO_Use_Mask;
ScriptedScopeCombiner.Material2 = ScopeScriptedTexture;
}
if(ScopeScriptedShader == none){
ScopeScriptedShader = Shader(Level.ObjectPool.AllocateObject(class'Shader'));
ScopeScriptedShader.Diffuse = ScriptedScopeCombiner;
ScopeScriptedShader.SelfIllumination = ScriptedScopeCombiner;
ScopeScriptedShader.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader';
}
bInitializedScope = true;
}
else if (KFScopeDetail == KF_TextureScope){
ZoomedDisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOV);
PlayerViewOffset.X = default.PlayerViewOffset.X;
bInitializedScope = true;
}
}
}
simulated event RenderTexture(ScriptedTexture Tex)
{
local rotator RollMod;
RollMod = Instigator.GetViewRotation();
if(Owner != none && Instigator != none && Tex != none && Tex.Client != none)
Tex.DrawPortal(0,0,Tex.USize,Tex.VSize,Owner,(Instigator.Location + Instigator.EyePosition()), RollMod, scopePortalFOV );
}
simulated function SetZoomBlendColor(Canvas c)
{
local Byte val;
local Color clr;
local Color fog;
clr.R = 255;
clr.G = 255;
clr.B = 255;
clr.A = 255;
if(Instigator.Region.Zone.bDistanceFog){
fog = Instigator.Region.Zone.DistanceFogColor;
val = 0;
val = Max(val, fog.R);
val = Max(val, fog.G);
val = Max(val, fog.B);
if(val > 128){
val -= 128;
clr.R -= val;
clr.G -= val;
clr.B -= val;
}
}
c.DrawColor = clr;
}
//Handles all the functionality for zooming in including
// setting the parameters for the weapon, pawn, and playercontroller
simulated function ZoomIn(bool bAnimateTransition)
{
default.ZoomTime = default.recordedZoomTime;
PlayerIronSightFOV = default.PlayerIronSightFOV;
scopePortalFOVHigh = default.scopePortalFOVHigh;
scopePortalFOV = default.scopePortalFOV;
PlayerIronSightFOV = default.PlayerIronSightFOV;
if(instigator != none && instigator.bIsCrouched && class'NiceVeterancyTypes'.static.hasSkill(NicePlayerController(Instigator.Controller), class'NiceSkillSharpshooterHardWork')){
default.ZoomTime *= class'NiceSkillSharpshooterHardWork'.default.zoomSpeedBonus;
if(instigator != none && instigator.bIsCrouched){
PlayerIronSightFOV *= class'NiceSkillSharpshooterHardWork'.default.zoomBonus;
scopePortalFOVHigh *= class'NiceSkillSharpshooterHardWork'.default.zoomBonus;
scopePortalFOV *= class'NiceSkillSharpshooterHardWork'.default.zoomBonus;
PlayerIronSightFOV *= class'NiceSkillSharpshooterHardWork'.default.zoomBonus;
}
}
super(BaseKFWeapon).ZoomIn(bAnimateTransition);
bAimingRifle = True;
if(KFHumanPawn(Instigator) != none)
KFHumanPawn(Instigator).SetAiming(True);
if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none ){
if(AimInSound != none)
PlayOwnedSound(AimInSound, SLOT_Interact,,,,, false);
}
}
// Handles all the functionality for zooming out including
// setting the parameters for the weapon, pawn, and playercontroller
simulated function ZoomOut(bool bAnimateTransition)
{
default.ZoomTime = default.recordedZoomTime;
PlayerIronSightFOV = default.PlayerIronSightFOV;
scopePortalFOVHigh = default.scopePortalFOVHigh;
scopePortalFOV = default.scopePortalFOV;
PlayerIronSightFOV = default.PlayerIronSightFOV;
if(class'NiceVeterancyTypes'.static.hasSkill(NicePlayerController(Instigator.Controller), class'NiceSkillSharpshooterHardWork')){
default.ZoomTime *= class'NiceSkillSharpshooterHardWork'.default.zoomSpeedBonus;
PlayerIronSightFOV *= class'NiceSkillSharpshooterHardWork'.default.zoomBonus;
scopePortalFOVHigh *= class'NiceSkillSharpshooterHardWork'.default.zoomBonus;
scopePortalFOV *= class'NiceSkillSharpshooterHardWork'.default.zoomBonus;
PlayerIronSightFOV *= class'NiceSkillSharpshooterHardWork'.default.zoomBonus;
}
super.ZoomOut(bAnimateTransition);
bAimingRifle = False;
if( KFHumanPawn(Instigator)!=none )
KFHumanPawn(Instigator).SetAiming(False);
if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none )
{
if( AimOutSound != none )
{
PlayOwnedSound(AimOutSound, SLOT_Interact,,,,, false);
}
KFPlayerController(Instigator.Controller).TransitionFOV(KFPlayerController(Instigator.Controller).DefaultFOV,0.0);
}
}
simulated function WeaponTick(float dt)
{
super.WeaponTick(dt);
if(bAimingRifle && ForceZoomOutTime > 0 && Level.TimeSeconds - ForceZoomOutTime > 0)
{
ForceZoomOutTime = 0;
ZoomOut(false);
if(Role < ROLE_Authority)
ServerZoomOut(false);
}
}
// Called by the native code when the interpolation of the first person weapon to the zoomed position finishes
simulated event OnZoomInFinished()
{
local name anim;
local float frame, rate;
GetAnimParams(0, anim, frame, rate);
if (ClientState == WS_ReadyToFire)
{
// Play the iron idle anim when we're finished zooming in
if (anim == IdleAnim)
{
PlayIdle();
}
}
if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none &&
KFScopeDetail == KF_TextureScope )
{
KFPlayerController(Instigator.Controller).TransitionFOV(PlayerIronSightFOV,0.0);
}
}
simulated function bool CanZoomNow()
{
Return (!FireMode[0].bIsFiring && !FireMode[1].bIsFiring && Instigator!=none && Instigator.Physics!=PHYS_Falling);
}
simulated event RenderOverlays(Canvas Canvas)
{
local int m;
local PlayerController PC;
if (Instigator == none)
return;
PC = PlayerController(Instigator.Controller);
if(PC == none)
return;
if(!bInitializedScope && PC != none )
{
UpdateScopeMode();
}
Canvas.DrawActor(none, false, true);
for (m = 0; m < NUM_FIRE_MODES; m++)
{
if (FireMode[m] != none)
{
FireMode[m].DrawMuzzleFlash(Canvas);
}
}
SetLocation( Instigator.Location + Instigator.CalcDrawOffset(self) );
SetRotation( Instigator.GetViewRotation() + ZoomRotInterp);
PreDrawFPWeapon();
if(bAimingRifle && PC != none && (KFScopeDetail == KF_ModelScope || KFScopeDetail == KF_ModelScopeHigh)){
if(ShouldDrawPortal()){
if(ScopeScriptedTexture != none){
Skins[LenseMaterialID] = ScopeScriptedShader;
ScopeScriptedTexture.Client = Self;
ScopeScriptedTexture.Revision = (ScopeScriptedTexture.Revision + 1);
}
}
bDrawingFirstPerson = true;
Canvas.DrawBoundActor(self, false, false,DisplayFOV,PC.Rotation,rot(0,0,0),Instigator.CalcZoomedDrawOffset(self));
bDrawingFirstPerson = false;
}
else if(KFScopeDetail == KF_TextureScope && PC.DesiredFOV == PlayerIronSightFOV && bAimingRifle){
Skins[LenseMaterialID] = ScriptedTextureFallback;
SetZoomBlendColor(Canvas);
Canvas.Style = ERenderStyle.STY_Normal;
Canvas.SetPos(0, 0);
Canvas.DrawTile(ZoomMat, (Canvas.SizeX - Canvas.SizeY) / 2, Canvas.SizeY, 0.0, 0.0, 8, 8);
Canvas.SetPos(Canvas.SizeX, 0);
Canvas.DrawTile(ZoomMat, -(Canvas.SizeX - Canvas.SizeY) / 2, Canvas.SizeY, 0.0, 0.0, 8, 8);
Canvas.Style = 255;
Canvas.SetPos((Canvas.SizeX - Canvas.SizeY) / 2,0);
Canvas.DrawTile(ZoomMat, Canvas.SizeY, Canvas.SizeY, 0.0, 0.0, tileSize, tileSize);
Canvas.Font = Canvas.MedFont;
Canvas.SetDrawColor(200,150,0);
Canvas.SetPos(Canvas.SizeX * 0.16, Canvas.SizeY * 0.43);
Canvas.DrawText(" ");
Canvas.SetPos(Canvas.SizeX * 0.16, Canvas.SizeY * 0.47);
}
else{
Skins[LenseMaterialID] = ScriptedTextureFallback;
bDrawingFirstPerson = true;
Canvas.DrawActor(self, false, false, DisplayFOV);
bDrawingFirstPerson = false;
}
}
// Adjust a single FOV based on the current aspect ratio. Adjust FOV is the default NON-aspect ratio adjusted FOV to adjust
simulated function float CalcAspectRatioAdjustedFOV(float AdjustFOV)
{
local KFPlayerController KFPC;
local float ResX, ResY;
local float AspectRatio;
KFPC = KFPlayerController(Level.GetLocalPlayerController());
if( KFPC == none )
{
return AdjustFOV;
}
ResX = float(GUIController(KFPC.Player.GUIController).ResX);
ResY = float(GUIController(KFPC.Player.GUIController).ResY);
AspectRatio = ResX / ResY;
if ( KFPC.bUseTrueWideScreenFOV && AspectRatio >= 1.60 ) //1.6 = 16/10 which is 16:10 ratio and 16:9 comes to 1.77
{
return CalcFOVForAspectRatio(AdjustFOV);
}
else
{
return AdjustFOV;
}
}
// AdjustIngameScope(RO) - Takes the changes to the ScopeDetail variable and
// sets the scope to the new detail mode. Called when the player switches the
// scope setting ingame, or when the scope setting is changed from the menu
simulated function AdjustIngameScope()
{
local PlayerController PC;
if(Instigator == none || PlayerController(Instigator.Controller) == none)
return;
PC = PlayerController(Instigator.Controller);
if(!bHasScope)
return;
switch (KFScopeDetail)
{
case KF_ModelScope:
if(bAimingRifle)
DisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOV);
if (PC.DesiredFOV == PlayerIronSightFOV && bAimingRifle){
if(Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none)
KFPlayerController(Instigator.Controller).TransitionFOV(KFPlayerController(Instigator.Controller).DefaultFOV,0.0);
}
break;
case KF_TextureScope:
if(bAimingRifle)
DisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOV);
if (bAimingRifle && PC.DesiredFOV != PlayerIronSightFOV){
if(Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none)
KFPlayerController(Instigator.Controller).TransitionFOV(PlayerIronSightFOV,0.0);
}
break;
case KF_ModelScopeHigh:
if(bAimingRifle){
if(default.ZoomedDisplayFOVHigh > 0)
DisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOVHigh);
else
DisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOV);
}
if ( bAimingRifle && PC.DesiredFOV == PlayerIronSightFOV )
{
if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none )
{
KFPlayerController(Instigator.Controller).TransitionFOV(KFPlayerController(Instigator.Controller).DefaultFOV,0.0);
}
}
break;
}
// Make any chagned to the scope setup
UpdateScopeMode();
}
simulated event Destroyed()
{
PreTravelCleanUp();
Super.Destroyed();
}
simulated function PreTravelCleanUp()
{
if(ScopeScriptedTexture != none){
ScopeScriptedTexture.Client = none;
Level.ObjectPool.FreeObject(ScopeScriptedTexture);
ScopeScriptedTexture=none;
}
if(ScriptedScopeCombiner != none){
ScriptedScopeCombiner.Material2 = none;
Level.ObjectPool.FreeObject(ScriptedScopeCombiner);
ScriptedScopeCombiner = none;
}
if(ScopeScriptedShader != none){
ScopeScriptedShader.Diffuse = none;
ScopeScriptedShader.SelfIllumination = none;
Level.ObjectPool.FreeObject(ScopeScriptedShader);
ScopeScriptedShader = none;
}
}
defaultproperties
{
tileSize=1024
}

View File

@ -0,0 +1,466 @@
class NiceDualies extends NiceWeapon;
var class<NiceSingle> SingleClass;
var name altFlashBoneName;
var name altTPAnim;
var Actor altThirdPersonActor;
var name altWeaponAttach;
// Track ammo in each gun separately
var int MagAmmoRemLeft, MagAmmoRemLeftClient;
var int MagAmmoRemRight, MagAmmoRemRightClient;
// Variables for managing dual-pistols reload
var const string leftEjectStr, rightEjectStr; // Event names that trigger when magazines ejected
var const string leftInsertStr, rightInsertStr; // Event names that trigger when magazines inserted
var float leftEject, rightEject; // Frame at which magazines ejected
var float leftInsert, rightInsert; // Frame at which magazines inserted
// This weapon is currently switching and soon won't exist
var bool bSwitching;
replication{
reliable if(Role < ROLE_Authority)
ServerUpdateWeaponMag, ServerSetDualMagSize, ServerReduceDualMag, ServerSwitchToSingle, ServerSwitchToGivenSingle;
reliable if(Role == ROLE_Authority)
MagAmmoRemLeft, MagAmmoRemRight, ClientSetDualMagSize;
reliable if(bNetOwner && bNetDirty && (Role == ROLE_Authority))
altThirdPersonActor;
}
simulated function PostBeginPlay(){
super.PostBeginPlay();
SetupDualReloadEvents();
reloadPreEndFrame = FMin(leftEject, rightEject);
reloadEndFrame = FMax(leftInsert, rightInsert);
DemoReplacement = SingleClass;
}
simulated function SetupDualReloadEvents(){
local EventRecord record;
relEvents.Length = 0;
record.eventName = leftEjectStr;
record.eventFrame = leftEject;
relEvents[relEvents.Length] = record;
record.eventName = rightEjectStr;
record.eventFrame = rightEject;
relEvents[relEvents.Length] = record;
record.eventName = leftInsertStr;
record.eventFrame = leftInsert;
relEvents[relEvents.Length] = record;
record.eventName = rightInsertStr;
record.eventFrame = rightInsert;
relEvents[relEvents.Length] = record;
}
// Don't use that one for dualies
simulated function AddReloadedAmmo(){}
// Use this one
simulated function ReloadEvent(string eventName){
local int halfMag;
local int totalAvailableAmmo;
UpdateMagCapacity(Instigator.PlayerReplicationInfo);
halfMag = GetSingleMagCapacity();
totalAvailableAmmo = AmmoAmount(0);
totalAvailableAmmo -= (MagAmmoRemLeftClient + MagAmmoRemRightClient);
// Handle ejection
if(eventName ~= leftEjectStr){
MagAmmoRemLeftClient = 0;
ServerSetDualMagSize(MagAmmoRemLeftClient, MagAmmoRemRightClient, Level.TimeSeconds);
NiceDualies(Instigator.Weapon).GetMagazineAmmo();
return;
}
else if(eventName ~= rightEjectStr){
MagAmmoRemRightClient = 0;
ServerSetDualMagSize(MagAmmoRemLeftClient, MagAmmoRemRightClient, Level.TimeSeconds);
NiceDualies(Instigator.Weapon).GetMagazineAmmo();
return;
}
// Handle reload
if(totalAvailableAmmo < 0)
return;
if(eventName ~= leftInsertStr){
MagAmmoRemLeftClient += totalAvailableAmmo;
MagAmmoRemLeftClient = Min(MagAmmoRemLeftClient, halfMag);
}
else if(eventName ~= rightInsertStr){
MagAmmoRemRightClient += totalAvailableAmmo;
MagAmmoRemRightClient = Min(MagAmmoRemRightClient, halfMag);
}
NiceDualies(Instigator.Weapon).GetMagazineAmmo();
ServerSetDualMagSize(MagAmmoRemLeftClient, MagAmmoRemRightClient, Level.TimeSeconds);
}
simulated function BringUp(optional Weapon PrevWeapon){
super.BringUp(PrevWeapon);
ApplyLaserState();
}
simulated function ApplyLaserState(){
super.ApplyLaserState();
if(NiceAttachment(altThirdPersonActor) != none)
NiceAttachment(altThirdPersonActor).SetLaserType(LaserType);
}
simulated function ZoomIn(bool bAnimateTransition){
super.ZoomIn(bAnimateTransition);
if(bAnimateTransition){
if(bZoomOutInterrupted)
PlayAnim('GOTO_Iron',1.0,0.1);
else
PlayAnim('GOTO_Iron',1.0,0.1);
}
}
simulated function ZoomOut(bool bAnimateTransition){
local float AnimLength, AnimSpeed;
super.ZoomOut(false);
if(bAnimateTransition){
AnimLength = GetAnimDuration('GOTO_Hip', 1.0);
if(ZoomTime > 0 && AnimLength > 0)
AnimSpeed = AnimLength/ZoomTime;
else
AnimSpeed = 1.0;
PlayAnim('GOTO_Hip',AnimSpeed,0.1);
}
}
function AttachToPawn(Pawn P){
local name BoneName;
Super.AttachToPawn(P);
if(altThirdPersonActor == none){
altThirdPersonActor = Spawn(AttachmentClass, Owner);
InventoryAttachment(altThirdPersonActor).InitFor(self);
}
else
altThirdPersonActor.NetUpdateTime = Level.TimeSeconds - 1;
BoneName = P.GetOffhandBoneFor(self);
if(BoneName == ''){
altThirdPersonActor.SetLocation(P.Location);
altThirdPersonActor.SetBase(P);
}
else
P.AttachToBone(altThirdPersonActor, BoneName);
if(altThirdPersonActor != none)
NiceDualiesAttachment(altThirdPersonActor).bIsOffHand = true;
if(altThirdPersonActor != none && ThirdPersonActor != none){
NiceDualiesAttachment(altThirdPersonActor).brother = NiceDualiesAttachment(ThirdPersonActor);
NiceDualiesAttachment(ThirdPersonActor).brother = NiceDualiesAttachment(altThirdPersonActor);
altThirdPersonActor.LinkMesh(NiceDualiesAttachment(ThirdPersonActor).BrotherMesh);
}
}
simulated function DetachFromPawn(Pawn P){
super.DetachFromPawn(P);
if(altThirdPersonActor != none){
altThirdPersonActor.Destroy();
altThirdPersonActor = none;
}
}
simulated function Destroyed(){
super.Destroyed();
if(ThirdPersonActor != none)
ThirdPersonActor.Destroy();
if(altThirdPersonActor != none)
altThirdPersonActor.Destroy();
}
simulated function vector GetEffectStart(){
local Vector RightFlashLoc,LeftFlashLoc;
RightFlashLoc = GetBoneCoords(default.FlashBoneName).Origin;
LeftFlashLoc = GetBoneCoords(default.altFlashBoneName).Origin;
if(Instigator.IsFirstPerson()){
if(WeaponCentered())
return CenteredEffectStart();
if(bAimingRifle){
if(KFFire(GetFireMode(0)).FireAimedAnim != 'FireLeft_Iron')
return RightFlashLoc;
else
return LeftFlashLoc;
}
else{
if(GetFireMode(0).FireAnim != 'FireLeft')
return RightFlashLoc;
else
return LeftFlashLoc;
}
}
else{
return (Instigator.Location + Instigator.EyeHeight * Vect(0, 0, 0.5) + vector(Instigator.Rotation) * 40.0);
}
}
function NicePlainData.Data GetNiceData(){
local NicePlainData.Data transferData;
transferData = super.GetNiceData();
class'NicePlainData'.static.SetInt(transferData, "leftMag", MagAmmoRemLeft);
class'NicePlainData'.static.SetInt(transferData, "rightMag", MagAmmoRemRight);
return transferData;
}
function SetNiceData(NicePlainData.Data transferData, optional NiceHumanPawn newOwner){
local int halfMag;
super.SetNiceData(transferData, newOwner);
if(newOwner != none)
UpdateMagCapacity(newOwner.PlayerReplicationInfo);
halfMag = GetSingleMagCapacity();
MagAmmoRemLeft = class'NicePlainData'.static.GetInt(transferData, "leftMag", halfMag);
MagAmmoRemRight = class'NicePlainData'.static.GetInt(transferData, "rightMag", halfMag);
ClientSetDualMagSize(MagAmmoRemLeft, MagAmmoRemRight);
}
simulated function AltFire(float F){
if(NicePlayerController(Instigator.Controller) != none)
ClientForceInterruptReload(CANCEL_PASSIVESWITCH);
if(!bIsReloading)
ServerSwitchToSingle();
}
simulated function FireGivenGun(bool bFireLeft){
local NiceDualiesFire niceFireMode;
niceFireMode = NiceDualiesFire(FireMode[0]);
if(niceFireMode != none){
if(bFireLeft)
niceFireMode.ModeDoFireLeft();
else
niceFireMode.ModeDoFireRight();
}
}
function NiceSingle ServerSwitchToGivenSingle(bool bSwitchToLeft){
local int m;
local int origAmmo;
local NiceHumanPawn nicePawn;
local NiceSingle singlePistol;
local NicePlainData.Data transferData;
nicePawn = NiceHumanPawn(Instigator);
if(nicePawn == none || SingleClass == none || nicePawn.Health <= 0)
return none;
nicePawn.CurrentWeight -= Weight;
Weight = 0;
bSwitching = true;
origAmmo = AmmoAmount(0);
for(m = 0; m < NUM_FIRE_MODES;m ++)
if(FireMode[m].bIsFiring)
StopFire(m);
DetachFromPawn(nicePawn);
singlePistol = nicePawn.Spawn(SingleClass);
if(singlePistol != none){
singlePistol.Weight = default.Weight;
singlePistol.DemoReplacement = DemoReplacement;
transferData = GetNiceData();
singlePistol.GiveTo(nicePawn);
singlePistol.SetNiceData(transferData, nicePawn);
singlePistol.bIsDual = true;
singlePistol.Weight = default.Weight;
singlePistol.SellValue = SellValue;
if(bSwitchToLeft){
singlePistol.otherMagazine = MagAmmoRemRight;
singlePistol.MagAmmoRemaining = MagAmmoRemLeft;
singlePistol.Ammo[0].AmmoAmount = origAmmo - MagAmmoRemRight;
}
else{
singlePistol.otherMagazine = MagAmmoRemLeft;
singlePistol.MagAmmoRemaining = MagAmmoRemRight;
singlePistol.Ammo[0].AmmoAmount = origAmmo - MagAmmoRemLeft;
}
singlePistol.ClientSetMagSize(singlePistol.MagAmmoRemaining, false);
//nicePawn.ServerChangedWeapon(self, singlePistol);
//nicePawn.ClientChangeWeapon(singlePistol);
}
Destroy();
return singlePistol;
}
function NiceSingle ServerSwitchToSingle(){
return ServerSwitchToGivenSingle(MagAmmoRemLeft > MagAmmoRemRight);
}
function DropFrom(vector StartLocation){
local int m;
local int magKeep, magGive;
local NiceHumanPawn nicePawn;
local KFWeaponPickup weapPickup;
local NiceSingle singlePistol;
local int AmmoThrown, OtherAmmo;
nicePawn = NiceHumanPawn(Instigator);
if(nicePawn == none || !bCanThrow || SingleClass == none)
return;
nicePawn.CurrentWeight -= Weight;
Weight = 0;
bSwitching = true;
if(MagAmmoRemLeft > MagAmmoRemRight){
magKeep = MagAmmoRemLeft;
magGive = MagAmmoRemRight;
}
else{
magKeep = MagAmmoRemRight;
magGive = MagAmmoRemLeft;
}
OtherAmmo = AmmoAmount(0);
ClientWeaponThrown();
for(m = 0; m < NUM_FIRE_MODES;m ++)
if(FireMode[m].bIsFiring)
StopFire(m);
DetachFromPawn(nicePawn);
AmmoThrown = magGive;
OtherAmmo = OtherAmmo - AmmoThrown;
singlePistol = nicePawn.Spawn(SingleClass);
if(singlePistol != none){
singlePistol.DemoReplacement = none;
singlePistol.GiveTo(nicePawn);
singlePistol.Ammo[0].AmmoAmount = OtherAmmo;
singlePistol.MagAmmoRemaining = magKeep;
singlePistol.ClientSetMagSize(singlePistol.MagAmmoRemaining, false);
MagAmmoRemaining = magGive;
//nicePawn.ServerChangedWeapon(self, singlePistol);
//nicePawn.ClientChangeWeapon(singlePistol);
}
weapPickup = KFWeaponPickup(nicePawn.Spawn(SingleClass.default.PickupClass,,, StartLocation));
if(weapPickup != none){
weapPickup.InitDroppedPickupFor(self);
weapPickup.Weight = default.Weight;
weapPickup.Velocity = Velocity;
weapPickup.AmmoAmount[0] = AmmoThrown;
weapPickup.SellValue = SellValue / 2;
singlePistol.SellValue = weapPickup.SellValue;
weapPickup.MagAmmoRemaining = magGive;
if(nicePawn.Health > 0)
weapPickup.bThrown = true;
}
Destroy();
if(KFGameType(Level.Game) != none)
KFGameType(Level.Game).WeaponDestroyed(class);
}
function bool HandlePickupQuery(pickup Item){
if(Item.InventoryType == SingleClass){
if(LastHasGunMsgTime < Level.TimeSeconds && PlayerController(Instigator.Controller) != none){
LastHasGunMsgTime = Level.TimeSeconds + 0.5;
PlayerController(Instigator.Controller).ReceiveLocalizedMessage(Class'KFMainMessages', 1);
}
return true;
}
return super.HandlePickupQuery(Item);
}
// Nice functions
simulated function int GetSingleMagCapacity(){
return int(float(MagCapacity) * 0.5);
}
function UpdateWeaponMag(){
ServerUpdateWeaponMag();
}
function ServerUpdateWeaponMag(){
UpdateMagCapacity(Instigator.PlayerReplicationInfo);
MagAmmoRemLeft = Min(MagAmmoRemLeft, GetSingleMagCapacity());
MagAmmoRemRight = Min(MagAmmoRemRight, GetSingleMagCapacity());
ClientSetDualMagSize(MagAmmoRemLeft, MagAmmoRemRight);
}
simulated function ClientUpdateWeaponMag(){
UpdateMagCapacity(Instigator.PlayerReplicationInfo);
MagAmmoRemLeftClient = Min(MagAmmoRemLeftClient, GetSingleMagCapacity());
MagAmmoRemRightClient = Min(MagAmmoRemRightClient, GetSingleMagCapacity());
ServerSetDualMagSize(MagAmmoRemLeftClient, MagAmmoRemRightClient, Level.TimeSeconds);
}
// Forces update for client's magazine ammo counter
// In case we are using client-side hit-detection, client itself manages remaining ammunition in magazine, but in some cases we want server to dictate current magazine amount
// This function sets client's mag size to a given value
simulated function ClientSetDualMagSize(int newLeftMag, int newRightMag){
MagAmmoRemLeftClient = newLeftMag;
MagAmmoRemRightClient = newRightMag;
MagAmmoRemainingClient = MagAmmoRemLeftClient + MagAmmoRemRightClient;
}
// This function allows clients to change magazine size without altering total ammo amount
// It allows clients to provide time-stamps, so that older change won't override a newer one
function ServerSetDualMagSize(int newLeftMag, int newRightMag, float updateTime){
MagAmmoRemLeft = newLeftMag;
MagAmmoRemRight = newRightMag;
magAmmoRemaining = MagAmmoRemLeft + MagAmmoRemRight;
if(LastMagUpdateFromClient <= updateTime){
LastMagUpdateFromClient = updateTime;
if(magAmmoRemaining > 0)
bServerFiredLastShot = false;
}
}
// This function allows clients to change magazine size along with total ammo amount on the server (to update ammo counter in client-side mode)
// It allows clients to provide time-stamps, so that older change won't override a newer one
// Intended to be used for decreasing ammo count from shooting and cannot increase magazine size
function ServerReduceDualMag(int newLeftMag, int newRightMag, float updateTime, int Mode){
local int delta;
delta = MagAmmoRemLeft - newLeftMag;
delta += MagAmmoRemRight - newRightMag;
// Only update later changes that actually decrease magazine
if(LastMagUpdateFromClient <= updateTime && delta > 0){
LastMagUpdateFromClient = updateTime;
MagAmmoRemLeft = newLeftMag;
MagAmmoRemRight = newRightMag;
ConsumeAmmo(Mode, delta);
MagAmmoRemaining = MagAmmoRemLeft + MagAmmoRemRight;
}
}
simulated function int GetMagazineAmmoLeft(){
if(Role < ROLE_Authority)
return MagAmmoRemLeftClient;
else
return MagAmmoRemLeft;
}
simulated function int GetMagazineAmmoRight(){
if(Role < ROLE_Authority)
return MagAmmoRemRightClient;
else
return MagAmmoRemRight;
}
simulated function bool AllowReload(){
UpdateMagCapacity(Instigator.PlayerReplicationInfo);
if(FireMode[0].IsFiring() ||
bIsReloading || (GetMagazineAmmoLeft() >= GetSingleMagCapacity() && GetMagazineAmmoRight() >= GetSingleMagCapacity()) ||
ClientState == WS_BringUp ||
AmmoAmount(0) <= GetMagazineAmmo())
return false;
return true;
}
simulated function WeaponTick(float dt){
if(Role == Role_AUTHORITY)
MagAmmoRemaining = MagAmmoRemLeft + MagAmmoRemRight;
else
MagAmmoRemainingClient = MagAmmoRemLeftClient + MagAmmoRemRightClient;
super.WeaponTick(dt);
}
// Some functions reloaded to force update of magazine size on client's side
function GiveAmmo(int m, WeaponPickup WP, bool bJustSpawned){
super.GiveAmmo(m, WP, bJustSpawned);
ClientSetDualMagSize(MagAmmoRemLeft, MagAmmoRemRight);
}
defaultproperties
{
SingleClass=Class'NicePack.NiceSingle'
altFlashBoneName="Tip_Left"
altTPAnim="DualiesAttackLeft"
altWeaponAttach="Bone_weapon2"
leftEjectStr="LEFT_EJECT"
rightEjectStr="RIGHT_EJECT"
leftInsertStr="LEFT_INSERT"
rightInsertStr="RIGHT_INSERT"
leftEject=0.130000
rightEject=0.102000
leftInsert=0.444000
rightInsert=0.787000
reloadChargeEndFrame=-1.000000
reloadMagStartFrame=-1.000000
reloadChargeStartFrame=-1.000000
MagazineBone=
bHasChargePhase=False
FirstPersonFlashlightOffset=(X=-15.000000,Z=5.000000)
MagCapacity=30
ReloadRate=3.500000
ReloadAnim="Reload"
ReloadAnimRate=1.000000
FlashBoneName="Tip_Right"
WeaponReloadAnim="Reload_Dual9mm"
Weight=4.000000
bDualWeapon=True
bHasAimingMode=True
IdleAimAnim="Idle_Iron"
StandardDisplayFOV=70.000000
TraderInfoTexture=Texture'KillingFloorHUD.Trader_Weapon_Images.Trader_Dual_9mm'
ZoomInRotation=(Pitch=0,Roll=0)
ZoomedDisplayFOV=65.000000
FireModeClass(0)=Class'NicePack.NiceDualiesFire'
FireModeClass(1)=Class'KFMod.NoFire'
PutDownAnim="PutDown"
AIRating=0.440000
CurrentRating=0.440000
bShowChargingBar=True
Description="A pair of custom 9mm pistols. What they lack in stopping power, they compensate for with a quick refire."
EffectOffset=(X=100.000000,Y=25.000000,Z=-10.000000)
DisplayFOV=70.000000
Priority=65
InventoryGroup=2
GroupOffset=2
PickupClass=Class'NicePack.NiceDualiesPickup'
PlayerViewOffset=(X=20.000000,Z=-7.000000)
BobDamping=7.000000
AttachmentClass=Class'NicePack.NiceDualiesAttachment'
IconCoords=(X1=229,Y1=258,X2=296,Y2=307)
ItemName="!!!Dual something"
DrawScale=0.900000
TransientSoundVolume=1.000000
}

View File

@ -0,0 +1,13 @@
class NiceDualiesAmmo extends NiceAmmo;
#EXEC OBJ LOAD FILE=InterfaceContent.utx
defaultproperties
{
AmmoPickupAmount=30
MaxAmmo=480
InitialAmount=240
PickupClass=Class'NicePack.NiceDualiesAmmoPickup'
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
IconCoords=(X1=413,Y1=82,X2=457,Y2=125)
ItemName="Dualies bullets"
}

View File

@ -0,0 +1,9 @@
class NiceDualiesAmmoPickup extends NiceAmmoPickup;
defaultproperties
{
AmmoAmount=30
InventoryType=Class'NicePack.NiceDualiesAmmo'
PickupMessage="Rounds (9mm)"
StaticMesh=StaticMesh'KillingFloorStatics.DualiesAmmo'
}

View File

@ -0,0 +1,128 @@
class NiceDualiesAttachment extends NiceAttachment;
var bool bIsOffHand, bMyFlashTurn;
var NiceDualiesAttachment brother;
var Mesh BrotherMesh;
replication{
reliable if(Role == ROLE_Authority)
brother;
}
simulated function DoFlashEmitter(){
if(bIsOffHand)
return;
if(bMyFlashTurn)
ActuallyFlash();
else if(brother != none)
brother.ActuallyFlash();
}
simulated function ActuallyFlash(){
super.DoFlashEmitter();
}
simulated event ThirdPersonEffects(){
local NicePlayerController PC;
if((Level.NetMode == NM_DedicatedServer) || (Instigator == none))
return;
PC = NicePlayerController(Level.GetLocalPlayerController());
if(FiringMode == 0){
if(OldSpawnHitCount != SpawnHitCount){
OldSpawnHitCount = SpawnHitCount;
GetHitInfo();
if(((Instigator != none) && (Instigator.Controller == PC)) || (VSize(PC.ViewTarget.Location - mHitLocation) < 4000)){
if(PC != Instigator.Controller){
if(mHitActor != none)
Spawn(class'ROBulletHitEffect',,, mHitLocation, Rotator(-mHitNormal));
CheckForSplash();
SpawnTracer();
}
}
}
}
if(FlashCount > 0){
if(KFPawn(Instigator) != none){
if(bMyFlashTurn)
KFPawn(Instigator).StartFiringX(false, bRapidFire);
else
KFPawn(Instigator).StartFiringX(true, bRapidFire);
}
if(bDoFiringEffects){
if((Level.TimeSeconds - LastRenderTime > 0.2) && (Instigator.Controller != PC))
return;
if(bSpawnLight)
WeaponLight();
DoFlashEmitter();
if(!bIsOffHand){
if(!bMyFlashTurn)
ThirdPersonShellEject();
else if(brother != none)
brother.ThirdPersonShellEject();
}
}
}
else{
GotoState('');
if(KFPawn(Instigator) != none)
KFPawn(Instigator).StopFiring();
}
}
simulated function vector GetTracerStart(){
local Pawn p;
p = Pawn(Owner);
if((p != none) && p.IsFirstPerson() && p.Weapon != none)
return p.Weapon.GetEffectStart();
if(mMuzFlash3rd != none && bMyFlashTurn)
return mMuzFlash3rd.Location;
else if(brother != none && brother.mMuzFlash3rd != none && !bMyFlashTurn)
return brother.mMuzFlash3rd.Location;
}
defaultproperties
{
bMyFlashTurn=True
BrotherMesh=SkeletalMesh'KF_Weapons3rd_Trip.Dual9mm_3rd'
mMuzFlashClass=Class'ROEffects.MuzzleFlash3rdPistol'
mTracerClass=Class'KFMod.KFNewTracer'
mShellCaseEmitterClass=Class'KFMod.KFShellSpewer'
MovementAnims(0)="JogF_Dual9mm"
MovementAnims(1)="JogB_Dual9mm"
MovementAnims(2)="JogL_Dual9mm"
MovementAnims(3)="JogR_Dual9mm"
TurnLeftAnim="TurnL_Dual9mm"
TurnRightAnim="TurnR_Dual9mm"
CrouchAnims(0)="CHwalkF_Dual9mm"
CrouchAnims(1)="CHwalkB_Dual9mm"
CrouchAnims(2)="CHwalkL_Dual9mm"
CrouchAnims(3)="CHwalkR_Dual9mm"
WalkAnims(0)="WalkF_Dual9mm"
WalkAnims(1)="WalkB_Dual9mm"
WalkAnims(2)="WalkL_Dual9mm"
WalkAnims(3)="WalkR_Dual9mm"
CrouchTurnRightAnim="CH_TurnR_Dual9mm"
CrouchTurnLeftAnim="CH_TurnL_Dual9mm"
IdleCrouchAnim="CHIdle_Dual9mm"
IdleWeaponAnim="Idle_Dual9mm"
IdleRestAnim="Idle_Dual9mm"
IdleChatAnim="Idle_Dual9mm"
IdleHeavyAnim="Idle_Dual9mm"
IdleRifleAnim="Idle_Dual9mm"
FireAnims(0)="DualiesAttackRight"
FireAnims(1)="DualiesAttackRight"
FireAnims(2)="DualiesAttackRight"
FireAnims(3)="DualiesAttackRight"
FireAltAnims(0)="DualiesAttackLeft"
FireAltAnims(1)="DualiesAttackLeft"
FireAltAnims(2)="DualiesAttackLeft"
FireAltAnims(3)="DualiesAttackLeft"
FireCrouchAnims(0)="CHDualiesAttackRight"
FireCrouchAnims(1)="CHDualiesAttackRight"
FireCrouchAnims(2)="CHDualiesAttackRight"
FireCrouchAnims(3)="CHDualiesAttackRight"
FireCrouchAltAnims(0)="CHDualiesAttackLeft"
FireCrouchAltAnims(1)="CHDualiesAttackLeft"
FireCrouchAltAnims(2)="CHDualiesAttackLeft"
FireCrouchAltAnims(3)="CHDualiesAttackLeft"
HitAnims(0)="HitF_Dual9mmm"
HitAnims(1)="HitB_Dual9mm"
HitAnims(2)="HitL_Dual9mm"
HitAnims(3)="HitR_Dual9mm"
PostFireBlendStandAnim="Blend_Dual9mm"
PostFireBlendCrouchAnim="CHBlend_Dual9mm"
}

View File

@ -0,0 +1,247 @@
class NiceDualiesFire extends NiceFire;
var bool bWasInZedTime;
var Emitter Flash2Emitter;
var Emitter ShellEject2Emitter;
var name ShellEject2BoneName;
var name FireAnim2, FireAimedAnim2;
var bool bIsLeftShot;
var float leftNextFireTime;
var float rightNextFireTime;
var bool bLastFiredLeft;
simulated function ModeTick(float delta){
local float timeCutScale;
local NicePlayerController nicePlayer;
if(instigator != none)
nicePlayer = NicePlayerController(instigator.controller);
if(nicePlayer != none && nicePlayer.IsZedTimeActive() != bWasInZedTime){
bWasInZedTime = !bWasInZedTime;
timeCutScale = 1.0;
if(bWasInZedTime)
timeCutScale = KFGameType(Level.Game).ZedTimeSlomoScale;
niceNextFireTime = Level.TimeSeconds + (niceNextFireTime - Level.TimeSeconds) * timeCutScale;
nextFireTime = niceNextFireTime;
leftNextFireTime = Level.TimeSeconds + (leftNextFireTime - Level.TimeSeconds) * timeCutScale;
rightNextFireTime = Level.TimeSeconds + (rightNextFireTime - Level.TimeSeconds) * timeCutScale;
}
super.ModeTick(delta);
}
simulated function InitEffects(){
local NiceDualies dualWeapon;
dualWeapon = NiceDualies(Weapon);
if((Level.NetMode == NM_DedicatedServer) || (AIController(Instigator.Controller) != none) || dualWeapon == none)
return;
if((FlashEmitterClass != none) && ((FlashEmitter == none) || FlashEmitter.bDeleteMe)){
FlashEmitter = Weapon.Spawn(FlashEmitterClass);
Weapon.AttachToBone(FlashEmitter, dualWeapon.default.FlashBoneName);
}
if((FlashEmitterClass != none) && ((Flash2Emitter == none) || Flash2Emitter.bDeleteMe)){
Flash2Emitter = Weapon.Spawn(FlashEmitterClass);
Weapon.AttachToBone(Flash2Emitter, dualWeapon.default.altFlashBoneName);
}
if((SmokeEmitterClass != none) && ((SmokeEmitter == none) || SmokeEmitter.bDeleteMe))
SmokeEmitter = Weapon.Spawn(SmokeEmitterClass);
if((ShellEjectClass != none) && ((ShellEjectEmitter == none) || ShellEjectEmitter.bDeleteMe)){
ShellEjectEmitter = Weapon.Spawn(ShellEjectClass);
Weapon.AttachToBone(ShellEjectEmitter, ShellEjectBoneName);
}
if((ShellEjectClass != none) && ((ShellEject2Emitter == none) || ShellEject2Emitter.bDeleteMe)){
ShellEject2Emitter = Weapon.Spawn(ShellEjectClass);
Weapon.AttachToBone(ShellEject2Emitter, ShellEject2BoneName);
}
}
simulated function DestroyEffects(){
super.DestroyEffects();
if(ShellEject2Emitter != none)
ShellEject2Emitter.Destroy();
if(Flash2Emitter != none)
Flash2Emitter.Destroy();
}
function DrawMuzzleFlash(Canvas Canvas){
super.DrawMuzzleFlash(Canvas);
if(ShellEject2Emitter != none)
Canvas.DrawActor( ShellEject2Emitter, false, false, Weapon.DisplayFOV );
}
function FlashMuzzleFlash(){
if(Flash2Emitter == none || FlashEmitter == none)
return;
if(KFWeap.bAimingRifle){
if(FireAimedAnim == 'FireLeft_Iron'){
Flash2Emitter.Trigger(Weapon, Instigator);
if(ShellEjectEmitter != none)
ShellEjectEmitter.Trigger(Weapon, Instigator);
}
else{
FlashEmitter.Trigger(Weapon, Instigator);
if(ShellEject2Emitter != none)
ShellEject2Emitter.Trigger(Weapon, Instigator);
}
}
else{
if(FireAnim == 'FireLeft'){
Flash2Emitter.Trigger(Weapon, Instigator);
if(ShellEjectEmitter != none)
ShellEjectEmitter.Trigger(Weapon, Instigator);
}
else{
FlashEmitter.Trigger(Weapon, Instigator);
if(ShellEject2Emitter != none)
ShellEject2Emitter.Trigger(Weapon, Instigator);
}
}
}
simulated function ModeDoFireLeft(){
local NiceDualies dualWeapon;
local NiceDualiesAttachment dualAttach, dualAttachAlt;
dualWeapon = NiceDualies(Weapon);
dualAttach = NiceDualiesAttachment(dualWeapon.ThirdPersonActor);
dualAttachAlt = NiceDualiesAttachment(dualWeapon.altThirdPersonActor);
if(dualWeapon == none || !AllowLeftFire())
return;
// Set shine turn
if(dualAttach != none)
dualAttach.bMyFlashTurn = false;
if(dualAttachAlt != none)
dualAttachAlt.bMyFlashTurn = true;
// Swap bones and animations
dualWeapon.FlashBoneName = dualWeapon.default.altFlashBoneName;
dualWeapon.altFlashBoneName = dualWeapon.default.FlashBoneName;
FireAnim = default.FireAnim2;
FireAnim2 = default.FireAnim;
FireAimedAnim = default.FireAimedAnim2;
FireAimedAnim2 = default.FireAimedAnim;
// Do left shot
bIsLeftShot = true;
super.ModeDoFire();
leftNextFireTime = UpdateNextFireTimeSingle(leftNextFireTime);
InitEffects();
bLastFiredLeft = true;
}
simulated function ModeDoFireRight(){
local NiceDualies dualWeapon;
local NiceDualiesAttachment dualAttach, dualAttachAlt;
dualWeapon = NiceDualies(Weapon);
dualAttach = NiceDualiesAttachment(dualWeapon.ThirdPersonActor);
dualAttachAlt = NiceDualiesAttachment(dualWeapon.altThirdPersonActor);
if(dualWeapon == none || !AllowRightFire())
return;
// Set shine turn
if(dualAttach != none)
dualAttach.bMyFlashTurn = true;
if(dualAttachAlt != none)
dualAttachAlt.bMyFlashTurn = false;
// Default bones and animations
dualWeapon.FlashBoneName = dualWeapon.default.FlashBoneName;
dualWeapon.altFlashBoneName = dualWeapon.default.altFlashBoneName;
FireAnim = default.FireAnim;
FireAnim2 = default.FireAnim2;
FireAimedAnim = default.FireAimedAnim;
FireAimedAnim2 = default.FireAimedAnim2;
// Do right shot
bIsLeftShot = false;
super.ModeDoFire();
rightNextFireTime = UpdateNextFireTimeSingle(rightNextFireTime);
InitEffects();
bLastFiredLeft = false;
}
simulated function bool AllowLeftFire(){
local NiceDualies niceDualWeap;
niceDualWeap = NiceDualies(currentContext.sourceWeapon);
if(niceDualWeap == none)
return false;
if(niceDualWeap.GetMagazineAmmoLeft() < default.AmmoPerFire && !bCanFireIncomplete)
return false;
return true;
}
simulated function bool AllowRightFire(){
local NiceDualies niceDualWeap;
niceDualWeap = NiceDualies(currentContext.sourceWeapon);
if(niceDualWeap == none)
return false;
if(niceDualWeap.GetMagazineAmmoRight() < default.AmmoPerFire && !bCanFireIncomplete)
return false;
return true;
}
simulated function bool AllowFire(){
return super.AllowFire() && (AllowLeftFire() || AllowRightFire());
}
event ModeDoFire(){
local NiceDualies dualWeap;
dualWeap = NiceDualies(Instigator.Weapon);
if(dualWeap == none || niceNextFireTime > Level.TimeSeconds || !AllowFire())
return;
if(niceNextFireTime + FireRate < Level.TimeSeconds)
bResetRecoil = true;
// Choose correct pistol to fire
if(Level.TimeSeconds > leftNextFireTime && Level.TimeSeconds > rightNextFireTime && AllowLeftFire() && AllowRightFire()){
if(dualWeap.GetMagazineAmmoLeft() > dualWeap.GetMagazineAmmoRight())
ModeDoFireLeft();
else if(dualWeap.GetMagazineAmmoLeft() < dualWeap.GetMagazineAmmoRight())
ModeDoFireRight();
else if(bLastFiredLeft)
ModeDoFireRight();
else
ModeDoFireLeft();
}
else if(Level.TimeSeconds > leftNextFireTime && AllowLeftFire())
ModeDoFireLeft();
else if(Level.TimeSeconds > rightNextFireTime && AllowRightFire())
ModeDoFireRight();
}
simulated function ReduceAmmoClient(){
local NiceDualies dualWeap;
dualWeap = NiceDualies(currentContext.sourceWeapon);
if(dualWeap == none)
return;
if(bIsLeftShot)
dualWeap.MagAmmoRemLeftClient -= Load;
else
dualWeap.MagAmmoRemRightClient -= Load;
if(dualWeap.MagAmmoRemLeftClient < 0)
dualWeap.MagAmmoRemLeftClient = 0;
if(dualWeap.MagAmmoRemRightClient < 0)
dualWeap.MagAmmoRemRightClient = 0;
// Force server's magazine size
dualWeap.ServerReduceDualMag(dualWeap.MagAmmoRemLeftClient, dualWeap.MagAmmoRemRightClient, Level.TimeSeconds, ThisModeNum);
}
simulated function float UpdateNextFireTimeSingle(float fireTimeVar){
FireRate *= 2;
fireTimeVar = UpdateNextFireTime(fireTimeVar);
FireRate = default.FireRate;
return fireTimeVar;
}
defaultproperties
{
ShellEject2BoneName="Shell_eject_right"
FireAnim2="FireLeft"
FireAimedAnim2="FireLeft_Iron"
FireAimedAnim="FireRight_Iron"
RecoilRate=0.070000
maxVerticalRecoilAngle=450
maxHorizontalRecoilAngle=50
ShellEjectClass=Class'ROEffects.KFShellEject9mm'
ShellEjectBoneName="Shell_eject_left"
DamageMin=35
DamageMax=35
Momentum=10500.000000
bPawnRapidFireAnim=True
bWaitForRelease=True
bAttachSmokeEmitter=True
TransientSoundVolume=1.800000
FireAnim="FireRight"
FireLoopAnim=
FireEndAnim=
TweenTime=0.025000
FireForce="AssaultRifleFire"
FireRate=0.087500
AmmoClass=Class'NicePack.NiceSingleAmmo'
ShakeRotMag=(X=75.000000,Y=75.000000,Z=250.000000)
ShakeRotRate=(X=10000.000000,Y=10000.000000,Z=10000.000000)
ShakeRotTime=3.000000
ShakeOffsetMag=(X=6.000000,Y=3.000000,Z=10.000000)
ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000)
ShakeOffsetTime=2.000000
BotRefireRate=0.250000
FlashEmitterClass=Class'ROEffects.MuzzleFlash1stMP'
aimerror=30.000000
}

View File

@ -0,0 +1,38 @@
class NiceDualiesPickup extends NiceWeaponPickup;
var int MagAmmoRemLeft;
var int MagAmmoRemRight;
function ShowDualiesInfo(Canvas C){
C.SetPos((C.SizeX - C.SizeY) / 2,0);
C.DrawTile( Texture'KillingfloorHUD.ClassMenu.Dualies', C.SizeY, C.SizeY, 0.0, 0.0, 256, 256);
}
function InitDroppedPickupFor(Inventory Inv){
local NiceDualies dualW;
super.InitDroppedPickupFor(Inv);
dualW = NiceDualies(Inv);
if(dualW != none){
MagAmmoRemLeft = dualW.MagAmmoRemLeft;
MagAmmoRemRight = dualW.MagAmmoRemRight;
}
}
defaultproperties
{
Weight=1.000000
cost=150
BuyClipSize=30
PowerValue=35
SpeedValue=85
RangeValue=35
Description="A pair of custom 9mm handguns."
ItemName="Dual 9mms"
ItemShortName="Dual 9mms"
AmmoItemName="9mm Rounds"
AmmoMesh=StaticMesh'KillingFloorStatics.DualiesAmmo'
CorrespondingPerkIndex=2
EquipmentCategoryID=1
InventoryType=Class'NicePack.NiceDualies'
PickupMessage="You found another 9mm handgun"
PickupForce="AssaultRiflePickup"
StaticMesh=StaticMesh'KF_pickups_Trip.pistol.double9mm_pickup'
CollisionHeight=5.000000
}

View File

@ -0,0 +1,215 @@
class NiceSingle extends NiceWeapon;
var bool bIsDual;
var int otherMagazine;
var class<NiceDualies> DualClass;
replication{
reliable if(Role < ROLE_Authority)
ServerSwitchToOtherSingle, ServerSwitchToDual;
reliable if(Role == ROLE_Authority)
bIsDual, otherMagazine;
}
function bool HandlePickupQuery(Pickup Item){
local float AddWeight;
if(Item.InventoryType == class){
AddWeight = Weight;
if(DualClass != none)
AddWeight = dualClass.default.Weight - AddWeight;
if(bIsDual || KFHumanPawn(Owner) != none && !KFHumanPawn(Owner).CanCarry(AddWeight)){
PlayerController(Instigator.Controller).ReceiveLocalizedMessage(Class'KFMainMessages', 2);
return true;
}
return false;
}
return super.HandlePickupQuery(Item);
}
simulated function bool AltFireCanForceInterruptReload(){
return true;
}
simulated function Fire(float F){
if(!bIsReloading && GetMagazineAmmo() <= 0 && otherMagazine > 0)
ServerSwitchToOtherSingle();
else
super.Fire(F);
}
simulated function AltFire(float F){
if(bIsDual && NicePlayerController(Instigator.Controller) != none)
ClientForceInterruptReload(CANCEL_PASSIVESWITCH);
if(!bIsReloading && bIsDual)
ServerSwitchToDual();
else
super.AltFire(F);
}
function ServerSwitchToOtherSingle(){
local int swap;
local NiceHumanPawn nicePawn;
nicePawn = NiceHumanPawn(Instigator);
if(!bIsDual || nicePawn == none || nicePawn.Health <= 0)
return;
Ammo[0].AmmoAmount += otherMagazine - MagAmmoRemaining;
swap = MagAmmoRemaining;
MagAmmoRemaining = otherMagazine;
otherMagazine = swap;
ClientSetMagSize(MagAmmoRemaining, bRoundInChamber);
//nicePawn.ClientChangeWeapon(self);
}
function ServerSwitchToDual(){
local int m;
local int origAmmo;
local NiceHumanPawn nicePawn;
local NiceDualies dualPistols;
local NicePlainData.Data transferData;
nicePawn = NiceHumanPawn(Instigator);
if(!bIsDual || DualClass == none || nicePawn == none || nicePawn.Health <= 0)
return;
nicePawn.CurrentWeight -= Weight;
Weight = 0;
origAmmo = AmmoAmount(0);
for(m = 0; m < NUM_FIRE_MODES;m ++)
if(FireMode[m].bIsFiring)
StopFire(m);
DetachFromPawn(nicePawn);
dualPistols = nicePawn.Spawn(DualClass);
if(dualPistols != none){
dualPistols.DemoReplacement = class;
transferData = GetNiceData();
dualPistols.GiveTo(nicePawn);
dualPistols.SetNiceData(transferData, nicePawn);
dualPistols.MagAmmoRemRight = MagAmmoRemaining;
dualPistols.MagAmmoRemLeft = otherMagazine;
dualPistols.MagAmmoRemaining = dualPistols.MagAmmoRemLeft + dualPistols.MagAmmoRemRight;
dualPistols.SellValue = SellValue;
dualPistols.Ammo[0].AmmoAmount = origAmmo + otherMagazine;
dualPistols.ClientSetDualMagSize(dualPistols.MagAmmoRemLeft, dualPistols.MagAmmoRemRight);
//nicePawn.ClientChangeWeapon(dualPistols);
//nicePawn.ServerChangedWeapon(self, dualPistols);
}
Destroy();
}
function DropFrom(vector StartLocation){
local int m;
local int magKeep, magGive;
local KFWeaponPickup weapPickup;
local int weightBeforeThrow;
local int AmmoThrown, OtherAmmo;
local NiceHumanPawn nicePawn;
nicePawn = NiceHumanPawn(Instigator);
if(nicePawn == none)
return;
if(!bIsDual){
super.DropFrom(StartLocation);
return;
}
weightBeforeThrow = nicePawn.CurrentWeight;
magKeep = otherMagazine;
magGive = MagAmmoRemaining;
OtherAmmo = AmmoAmount(0) - magKeep;
ClientWeaponThrown();
for(m = 0; m < NUM_FIRE_MODES;m ++)
if(FireMode[m].bIsFiring)
StopFire(m);
if(nicePawn != none)
DetachFromPawn(nicePawn);
AmmoThrown = OtherAmmo / 2;
OtherAmmo = OtherAmmo - AmmoThrown;
Ammo[0].AmmoAmount = OtherAmmo + magKeep;
MagAmmoRemaining = magKeep;
ClientSetMagSize(MagAmmoRemaining, bRoundInChamber);
weapPickup = KFWeaponPickup(nicePawn.Spawn(default.PickupClass,,, StartLocation));
if(weapPickup != none){
weapPickup.InitDroppedPickupFor(self);
weapPickup.Velocity = Velocity;
weapPickup.AmmoAmount[0] = AmmoThrown + magGive;
weapPickup.SellValue = SellValue * 0.5;
SellValue *= 0.5;
weapPickup.MagAmmoRemaining = magGive;
if(nicePawn.Health > 0)
weapPickup.bThrown = true;
nicePawn.ClientChangeWeapon(self);
}
RemoveDual(weightBeforeThrow);
}
function RemoveDual(int pawnWeight){
local NiceHumanPawn nicePawn;
nicePawn = NiceHumanPawn(Instigator);
if(!bIsDual || nicePawn == none)
return;
bIsDual = false;
DemoReplacement = none;
nicePawn.CurrentWeight = pawnWeight - (Weight - default.Weight);
Weight = default.Weight;
otherMagazine = 0;
}
//SellValue
function GiveTo(Pawn other, optional Pickup Pickup){
local int m;
local int initAmmo, initMag;
local bool bDestroy;
local NiceSingle nicePistol;
local NiceDualies niceDual;
if(other != none){
nicePistol = NiceSingle(other.FindInventoryType(class));
niceDual = NiceDualies(other.FindInventoryType(DualClass));
}
bDestroy = false;
if(nicePistol == none || (niceDual != none && niceDual.bSwitching))
super.GiveTo(other, Pickup);
else if((nicePistol != none && nicePistol.bIsDual) || niceDual != none)
bDestroy = true;
else{
nicePistol.UpdateMagCapacity(other.PlayerReplicationInfo);
initAmmo = nicePistol.FireMode[0].AmmoClass.default.InitialAmount;
initMag = nicePistol.MagCapacity;
initMag = Min(initMag, initAmmo);
initAmmo -= initMag;
if(nicePistol.Ammo[0] != none){
nicePistol.Ammo[0].AmmoAmount += initAmmo;
nicePistol.Ammo[0].AmmoAmount = Min(nicePistol.Ammo[0].AmmoAmount, nicePistol.Ammo[0].MaxAmmo);
}
nicePistol.bIsDual = true;
nicePistol.otherMagazine = initMag;
nicePistol.SellValue = 2 * min(SellValue, nicePistol.SellValue);
nicePistol.ServerSwitchToDual();
bDestroy = true;
}
if(bDestroy){
for(m = 0; m < NUM_FIRE_MODES;m ++)
Ammo[m] = none;
Destroy();
}
}
defaultproperties
{
DualClass=Class'NicePack.NiceDualies'
bHasChargePhase=False
FirstPersonFlashlightOffset=(X=-20.000000,Y=-22.000000,Z=8.000000)
MagCapacity=15
ReloadRate=2.000000
ReloadAnim="Reload"
ReloadAnimRate=1.000000
WeaponReloadAnim="Reload_Single9mm"
ModeSwitchAnim="LightOn"
Weight=0.000000
bHasAimingMode=True
IdleAimAnim="Idle_Iron"
StandardDisplayFOV=70.000000
TraderInfoTexture=Texture'KillingFloorHUD.Trader_Weapon_Images.Trader_9mm'
ZoomedDisplayFOV=65.000000
FireModeClass(0)=Class'NicePack.NiceSingleFire'
FireModeClass(1)=Class'KFMod.NoFire'
PutDownAnim="PutDown"
AIRating=0.250000
CurrentRating=0.250000
bShowChargingBar=True
Description="A 9mm Pistol"
DisplayFOV=70.000000
Priority=60
InventoryGroup=2
GroupOffset=1
PickupClass=Class'NicePack.NiceSinglePickup'
PlayerViewOffset=(X=20.000000,Y=25.000000,Z=-10.000000)
BobDamping=6.000000
AttachmentClass=Class'NicePack.NiceSingleAttachment'
IconCoords=(X1=434,Y1=253,X2=506,Y2=292)
ItemName="Just a single pistol"
}

View File

@ -0,0 +1,13 @@
class NiceSingleAmmo extends NiceAmmo;
#EXEC OBJ LOAD FILE=InterfaceContent.utx
defaultproperties
{
AmmoPickupAmount=30
MaxAmmo=240
InitialAmount=120
PickupClass=Class'KFMod.SingleAmmoPickup'
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
IconCoords=(X1=413,Y1=82,X2=457,Y2=125)
ItemName="9mm bullets"
}

View File

@ -0,0 +1,10 @@
class NiceSingleAmmoPickup extends NiceAmmoPickup;
defaultproperties
{
AmmoAmount=20
InventoryType=Class'NicePack.NiceSingleAmmo'
RespawnTime=0.000000
PickupMessage="Rounds (9mm)"
StaticMesh=StaticMesh'KillingFloorStatics.DualiesAmmo'
}

View File

@ -0,0 +1,52 @@
class NiceSingleAttachment extends NiceAttachment;
defaultproperties
{
mMuzFlashClass=Class'ROEffects.MuzzleFlash3rdPistol'
mTracerClass=Class'KFMod.KFNewTracer'
mShellCaseEmitterClass=Class'KFMod.KFShellSpewer'
MovementAnims(0)="JogF_Single9mm"
MovementAnims(1)="JogB_Single9mm"
MovementAnims(2)="JogL_Single9mm"
MovementAnims(3)="JogR_Single9mm"
TurnLeftAnim="TurnL_Single9mm"
TurnRightAnim="TurnR_Single9mm"
CrouchAnims(0)="CHwalkF_Single9mm"
CrouchAnims(1)="CHwalkB_Single9mm"
CrouchAnims(2)="CHwalkL_Single9mm"
CrouchAnims(3)="CHwalkR_Single9mm"
CrouchTurnRightAnim="CH_TurnR_Single9mm"
CrouchTurnLeftAnim="CH_TurnL_Single9mm"
IdleCrouchAnim="CHIdle_Single9mm"
IdleWeaponAnim="Idle_Single9mm"
IdleRestAnim="Idle_Single9mm"
IdleChatAnim="Idle_Single9mm"
IdleHeavyAnim="Idle_Single9mm"
IdleRifleAnim="Idle_Single9mm"
FireAnims(0)="Fire_Single9mm"
FireAnims(1)="Fire_Single9mm"
FireAnims(2)="Fire_Single9mm"
FireAnims(3)="Fire_Single9mm"
FireAltAnims(0)="Fire_Single9mm"
FireAltAnims(1)="Fire_Single9mm"
FireAltAnims(2)="Fire_Single9mm"
FireAltAnims(3)="Fire_Single9mm"
FireCrouchAnims(0)="CHFire_Single9mm"
FireCrouchAnims(1)="CHFire_Single9mm"
FireCrouchAnims(2)="CHFire_Single9mm"
FireCrouchAnims(3)="CHFire_Single9mm"
FireCrouchAltAnims(0)="CHFire_Single9mm"
FireCrouchAltAnims(1)="CHFire_Single9mm"
FireCrouchAltAnims(2)="CHFire_Single9mm"
FireCrouchAltAnims(3)="CHFire_Single9mm"
HitAnims(0)="HitF_Single9mm"
HitAnims(1)="HitB_Single9mm"
HitAnims(2)="HitL_Single9mm"
HitAnims(3)="HitR_Single9mm"
PostFireBlendStandAnim="Blend_Single9mm"
PostFireBlendCrouchAnim="CHBlend_Single9mm"
SplashEffect=Class'ROEffects.BulletSplashEmitter'
LightType=LT_Pulse
LightRadius=0.000000
CullDistance=5000.000000
}

View File

@ -0,0 +1,46 @@
class NiceSingleFire extends NiceFire;
var bool bWasInZedTime;
simulated function ModeTick(float delta){
local NicePlayerController nicePlayer;
if(instigator != none)
nicePlayer = NicePlayerController(instigator.controller);
if(nicePlayer != none && nicePlayer.IsZedTimeActive() != bWasInZedTime){
bWasInZedTime = !bWasInZedTime;
if(bWasInZedTime)
niceNextFireTime = Level.TimeSeconds + (niceNextFireTime - Level.TimeSeconds) * KFGameType(Level.Game).ZedTimeSlomoScale;
nextFireTime = niceNextFireTime;
}
super.ModeTick(delta);
}
defaultproperties
{
FireAimedAnim="Fire_Iron"
RecoilRate=0.070000
maxVerticalRecoilAngle=300
maxHorizontalRecoilAngle=50
ShellEjectClass=Class'ROEffects.KFShellEject9mm'
ShellEjectBoneName="Shell_eject"
bRandomPitchFireSound=False
DamageMin=35
DamageMax=35
Momentum=10000.000000
bPawnRapidFireAnim=True
bWaitForRelease=True
bAttachSmokeEmitter=True
TransientSoundVolume=1.800000
FireAnimRate=1.500000
TweenTime=0.025000
FireForce="AssaultRifleFire"
FireRate=0.175000
AmmoClass=Class'NicePack.NiceSingleAmmo'
ShakeRotMag=(X=75.000000,Y=75.000000,Z=250.000000)
ShakeRotRate=(X=10000.000000,Y=10000.000000,Z=10000.000000)
ShakeRotTime=3.000000
ShakeOffsetMag=(X=6.000000,Y=3.000000,Z=10.000000)
ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000)
ShakeOffsetTime=2.000000
BotRefireRate=0.350000
FlashEmitterClass=Class'ROEffects.MuzzleFlash1stMP'
aimerror=30.000000
}

View File

@ -0,0 +1,83 @@
class NiceSinglePickup extends NiceWeaponPickup;
function Inventory SpawnCopy(Pawn other){
local Inventory CurInv;
local NiceWeapon PistolInInventory;
for(CurInv = other.Inventory;CurInv != none;CurInv = CurInv.Inventory){
PistolInInventory = NiceWeapon(CurInv);
if(PistolInInventory != none && PistolInInventory.class == default.InventoryType){
// Make dualies to cost twice of lowest value in case of PERKED+UNPERKED pistols
SellValue = 2 * min(SellValue, PistolInInventory.SellValue);
AmmoAmount[0] += PistolInInventory.AmmoAmount(0);
class'NicePlainData'.static.SetInt(weaponData, "leftMag", MagAmmoRemaining);
class'NicePlainData'.static.SetInt(weaponData, "rightMag", PistolInInventory.MagAmmoRemaining);
// destroy the inventory to force parent SpawnCopy() to make a new instance of class
// we specified below
if(Inventory != none)
Inventory.Destroy();
// spawn dual guns instead of another instance of single
if(class<NiceSingle>(default.InventoryType) != none)
InventoryType = class<NiceSingle>(default.InventoryType).default.DualClass;
if(CurInv != none){
CurInv.Destroyed();
CurInv.Destroy();
}
return super(KFWeaponPickup).SpawnCopy(other);
}
}
InventoryType = default.InventoryType;
return super(KFWeaponPickup).SpawnCopy(other);
}
function bool CheckCanCarry(KFHumanPawn Hm){
local Inventory CurInv;
local class<NiceWeapon> dualClass;
local float AddWeight;
AddWeight = class<KFWeapon>(default.InventoryType).default.Weight;
if(class<NiceWeapon>(default.InventoryType) != none)
dualClass = class<NiceSingle>(default.InventoryType).default.dualClass;
for(CurInv = Hm.Inventory; CurInv != none; CurInv = CurInv.Inventory){
if(CurInv.class == dualClass) {
// Already have duals, can't carry a single
if(LastCantCarryTime < Level.TimeSeconds && PlayerController(Hm.Controller) != none){
LastCantCarryTime = Level.TimeSeconds + 0.5;
PlayerController(Hm.Controller).ReceiveLocalizedMessage(Class'KFMainMessages', 2);
}
return false;
}
else if(CurInv.class == default.InventoryType && dualClass != none){
AddWeight = dualClass.default.Weight - AddWeight;
break;
}
}
if(!Hm.CanCarry(AddWeight)){
if(LastCantCarryTime < Level.TimeSeconds && PlayerController(Hm.Controller) != none){
LastCantCarryTime = Level.TimeSeconds + 0.5;
PlayerController(Hm.Controller).ReceiveLocalizedMessage(Class'KFMainMessages', 2);
}
return false;
}
return true;
}
defaultproperties
{
Weight=0.000000
cost=150
AmmoCost=10
BuyClipSize=30
PowerValue=20
SpeedValue=50
RangeValue=35
Description="A 9mm handgun."
ItemName="!!!"
ItemShortName="!!!"
AmmoItemName="9mm Rounds"
AmmoMesh=StaticMesh'KillingFloorStatics.DualiesAmmo'
CorrespondingPerkIndex=2
EquipmentCategoryID=1
InventoryType=Class'NicePack.NiceSingle'
PickupMessage="You got the 9mm handgun"
PickupSound=Sound'KF_9MMSnd.9mm_Pickup'
PickupForce="AssaultRiflePickup"
StaticMesh=StaticMesh'KF_pickups_Trip.pistol.9mm_Pickup'
CollisionHeight=5.000000
}

View File

@ -0,0 +1,5 @@
class NiceDamTypeNadeNail extends NiceDamTypeNailGun
abstract;
defaultproperties
{ stunMultiplier=10.000000
}

View File

@ -0,0 +1,5 @@
class NiceDamTypeSmallNail extends NiceDamTypeNailGun
abstract;
defaultproperties
{ headSizeModifier=2.000000 HeadShotDamageMult=1.000000
}

View File

@ -0,0 +1,61 @@
class NiceDelayedNade extends NiceNailNade;
var float EarlyExplodeTimer;
simulated function Tick(float DeltaTime){
if(EarlyExplodeTimer >= 0 && Physics == PHYS_None)
EarlyExplodeTimer -= DeltaTime;
Super.Tick(DeltaTime);
if(!bHasExploded && !bDisintegrated && EarlyExplodeTimer < 0)
Explode(Location, vect(0,0,1));
if(LifeSpan < 0.1){
ReleaseNails(true);
Disintegrate(Location, vect(0,0,1));
}
}
simulated function bool TooClose(){
local Vector Diff;
local float distance;
if(Instigator == none)
return false;
Diff = Location - Instigator.Location;
distance = Sqrt(Diff Dot Diff);
return (distance < DamageRadius);
}
// Overloaded to implement nade skills
simulated function Explode(vector HitLocation, vector HitNormal){
local PlayerController LocalPlayer;
// Variables for skill-detection
local NiceHumanPawn nicePawn;
local class<NiceVeterancyTypes> niceVet;
// Do we need to blow up?
if(!TooClose()){
bHasExploded = true;
nicePawn = NiceHumanPawn(Instigator);
if(nicePawn != none)
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(nicePawn.PlayerReplicationInfo);
BlowUp(HitLocation);
// null reference fix
if(ExplodeSounds.length > 0)
PlaySound(ExplodeSounds[rand(ExplodeSounds.length)],,2.0);
// Real shrapnel
ReleaseNails();
if(EffectIsRelevant(Location,false)){
Spawn(Class'KFmod.KFNadeExplosion',,, HitLocation, rotator(vect(0,0,1)));
Spawn(ExplosionDecal, self,, HitLocation, rotator(-HitNormal));
}
// Shake nearby players screens
LocalPlayer = Level.GetLocalPlayerController();
if((LocalPlayer != none) && (VSize(Location - LocalPlayer.ViewTarget.Location) < (DamageRadius * 1.5)))
LocalPlayer.ShakeView(RotMag, RotRate, RotTime, OffsetMag, OffsetRate, OffsetTime);
Destroy();
}
}
defaultproperties
{
EarlyExplodeTimer=2.000000
ExplodeTimer=5.000000
LifeSpan=5.100000
}

View File

@ -0,0 +1,72 @@
class NiceNailNade extends NiceNade;
var int numberOfShards;
var NiceFire.ShotType shotParams;
var NiceFire.FireModeContext fireContext;
simulated function ReleaseNails(optional bool bServerOnly){
local byte i;
local NicePack niceMut;
fireContext.continiousBonus = 1.0;
fireContext.burstLength = 1;
fireContext.instigator = NiceHumanPawn(instigator);
shotParams.bShouldBounce = true;
shotParams.damage = 52;
shotParams.projSpeed = 3500.0;
shotParams.momentum = 50000;
shotParams.shotDamageType = class'NicePack.NiceDamTypeNailGun';
shotParams.bulletClass = class'NicePack.NiceNail';
shotParams.bCausePain = true;
if(fireContext.instigator != none)
niceMut = class'NicePack'.static.Myself(fireContext.Instigator.Level);
if(bServerOnly){
if(niceMut == none)
return;
for(i = 0;i < niceMut.playersList.Length;i ++)
niceMut.playersList[i].ClientNailsExplosion(numberOfShards, location, shotParams, fireContext,
niceMut.playersList[i] != fireContext.Instigator.Controller);
}
else if(Role < Role_AUTHORITY)
for(i = 0;i < numberOfShards;i ++)
class'NiceProjectileSpawner'.static.MakeProjectile(location, RotRand(true), shotParams, fireContext);
}
// Overloaded to implement nade skills
simulated function Explode(vector HitLocation, vector HitNormal){
local PlayerController LocalPlayer;
// Variables for skill-detection
local NiceHumanPawn nicePawn;
local class<NiceVeterancyTypes> niceVet;
nicePawn = NiceHumanPawn(Instigator);
if(nicePawn != none)
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(nicePawn.PlayerReplicationInfo);
bHasExploded = true;
BlowUp(HitLocation);
// null reference fix
if(ExplodeSounds.length > 0)
PlaySound(ExplodeSounds[rand(ExplodeSounds.length)],,2.0);
// Real shrapnel
ReleaseNails();
if(EffectIsRelevant(Location,false)){
Spawn(Class'KFmod.KFNadeExplosion',,, HitLocation, rotator(vect(0,0,1)));
Spawn(ExplosionDecal, self,, HitLocation, rotator(-HitNormal));
}
// Shake nearby players screens
LocalPlayer = Level.GetLocalPlayerController();
if((LocalPlayer != none) && (VSize(Location - LocalPlayer.ViewTarget.Location) < (DamageRadius * 1.5)))
LocalPlayer.ShakeView(RotMag, RotRate, RotTime, OffsetMag, OffsetRate, OffsetTime);
Destroy();
}
function TakeDamage(int Damage, Pawn InstigatedBy, Vector HitLocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex){
if(Monster(instigatedBy) != none || instigatedBy == Instigator){
if(DamageType == class'SirenScreamDamage'){
ReleaseNails(true);
Disintegrate(HitLocation, vect(0,0,1));
}
else
Explode(HitLocation, vect(0,0,1));
}
}
defaultproperties
{
numberOfShards=50
Damage=50.000000
}

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +1,39 @@
//============================================================================== //======================================================================================================================
// NicePack / NiceBulletAdapter // NicePack / NiceBulletAdapter
//============================================================================== //======================================================================================================================
// Temporary stand-in for future functionality. // Temporary stand-in for future functionality.
//============================================================================== //======================================================================================================================
// Class hierarchy: Object > NiceBulletAdapter
//==============================================================================
// 'Nice pack' source // 'Nice pack' source
// Do whatever the fuck you want with it // Do whatever the fuck you want with it
// Author: dkanus // Author: dkanus
// 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, Vector hitLocation){
/*local NiceReplicationInfo niceRI;
niceRI = bullet.niceRI;
if(!bullet.bGhost){ if(!bullet.bGhost){
niceRI.ServerExplode(bullet.fireType.explosion.damage, bullet.fireType.explosion.radius, bullet.fireType.explosion.exponent, niceRI.ServerExplode(bullet.charExplosionDamage, bullet.charExplosionRadius, bullet.charExplosionExponent,
bullet.fireType.explosion.damageType, bullet.fireType.explosion.momentum, hitLocation, bullet.instigator, true, bullet.charExplosionDamageType, bullet.charExplosionMomentum, hitLocation, bullet.instigator, true,
Vector(bullet.Rotation)); explosionTarget, Vector(bullet.Rotation));
if(KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead) if(KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead)
niceRI.ServerDealDamage(KFMonster(bullet.base), bullet.fireType.explosion.damage, bullet.instigator, hitLocation, niceRI.ServerDealDamage(KFMonster(bullet.base), bullet.charExplosionDamage, bullet.instigator, hitLocation,
bullet.fireType.explosion.momentum * vect(0,0,-1), bullet.fireType.explosion.damageType, 1.0); bullet.charExplosionMomentum * vect(0,0,-1), bullet.charExplosionDamageType, 1.0);
}*/ }
} }
static function HandleCalibration
/*static function HitWall(NiceBullet bullet, Actor targetWall, (
bool isHeadshot,
NiceHumanPawn nicePawn,
NiceMonster targetZed
){
if(nicePawn == none) return;
if(nicePawn.currentCalibrationState != CALSTATE_ACTIVE) return;
nicePawn.ServerUpdateCalibration(isHeadshot, targetZed);
}
static function HitWall(NiceBullet bullet, NiceReplicationInfo niceRI, Actor targetWall,
Vector hitLocation, Vector hitNormal){ Vector hitLocation, Vector hitNormal){
local NicePlayerController nicePlayer; local NicePlayerController nicePlayer;
local NiceReplicationInfo niceRI;
niceRI = bullet.niceRI;
nicePlayer = NicePlayerController(bullet.Instigator.Controller); nicePlayer = NicePlayerController(bullet.Instigator.Controller);
if(nicePlayer == none) if(nicePlayer == none)
return; return;
@ -43,135 +44,97 @@ static function Explode(NiceBullet bullet, Vector hitLocation){
bullet.charMomentumTransfer * hitNormal, bullet.charDamageType); bullet.charMomentumTransfer * hitNormal, bullet.charDamageType);
nicePlayer.wallHitsLeft --; nicePlayer.wallHitsLeft --;
} }
}*/
static function HitWall//Actor
(
NiceBullet bullet,
Actor targetWall,
Vector hitLocation,
Vector hitNormal
)
{
local NicePlayerController nicePlayer;
local NiceReplicationInfo niceRI;
if(bullet == none || bullet.instigator == none)
return;
niceRI = bullet.niceRI;
nicePlayer = NicePlayerController(bullet.instigator.controller);
if(nicePlayer == none)
return;
// No need to deal damage to geometry or static actors
if(targetWall.bStatic || targetWall.bWorldGeometry)
return;
// If target is a projectile - we must send message about damage,
// otherwise it's probably a wall. And if we hit our limits of reporting
// about wall damages - avoid sending too many replication messages
// about damage.
// NICETODO: should probably find another way to solve the
// `ServerDealDamage` spam issue, this is bullshit.
if(Projectile(targetWall) == none && nicePlayer.wallHitsLeft <= 0)
return;
niceRI.ServerDealDamage(targetWall, bullet.fireType.bullet.damage, bullet.instigator, hitLocation,
bullet.fireType.bullet.momentum * hitNormal, bullet.fireType.bullet.shotDamageType);
// We've sent a reliable message about hitting a wall
nicePlayer.wallHitsLeft --;
} }
static function HandleScream(NiceBullet bullet, NiceReplicationInfo niceRI, Vector location, Vector entryDirection){
static function HandleScream(NiceBullet bullet, Vector location, Vector entryDirection){ bullet.charIsDud = true;
bullet.bIsDud = true;
} }
static function HitPawn(NiceBullet bullet, NiceReplicationInfo niceRI, KFPawn targetPawn, Vector hitLocation,
static function HitPawn(NiceBullet bullet, KFPawn targetPawn, Vector hitLocation, Vector hitNormal, array<int> hitPoints){
Vector hitNormal){ local NiceMedicProjectile niceDart;
// local NiceMedicProjectile niceDart; niceDart = NiceMedicProjectile(bullet);
local NiceReplicationInfo niceRI;
niceRI = bullet.niceRI;
/*niceDart = NiceMedicProjectile(bullet);
if(niceDart == none) if(niceDart == none)
niceRI.ServerDealDamage(targetPawn, bullet.damage, bullet.instigator, HitLocation, niceRI.ServerDealDamage(targetPawn, bullet.charDamage, bullet.instigator, HitLocation,
hitNormal * bullet.fireType.bullet.momentum, bullet.fireType.bullet.shotDamageType); hitNormal * bullet.charMomentumTransfer, bullet.charDamageType);
else*/ //MEANTODO else
//niceRI.ServerHealTarget(targetPawn, bullet.damage, bullet.instigator); niceRI.ServerHealTarget(NiceHumanPawn(targetPawn), bullet.charDamage, bullet.instigator);
} }
static function HitZed(NiceBullet bullet, NiceReplicationInfo niceRI, KFMonster kfZed, Vector hitLocation,
static function HitZed(NiceBullet bullet, NiceMonster niceZed, Vector hitLocation,
Vector hitNormal, float headshotLevel){ Vector hitNormal, float headshotLevel){
local bool bIsHeadshot; local bool bIsHeadshot, bIsPreciseHeadshot;
local float actualDamage; local float actualDamage;
local int lockonTicks; local int lockonTicks;
local float lockOnTickRate;
local float angle; local float angle;
local NiceHumanPawn nicePawn;
local NicePlayerController nicePlayer; local NicePlayerController nicePlayer;
local class<NiceVeterancyTypes> niceVet; local class<NiceVeterancyTypes> niceVet;
local NiceReplicationInfo niceRI;
niceRI = bullet.niceRI;
bIsHeadshot = (headshotLevel > 0.0); bIsHeadshot = (headshotLevel > 0.0);
/* if(bIsHeadshot && bullet.fireState.base.sourceWeapon != none){ bIsPreciseHeadshot = (headshotLevel > bullet.charDamageType.default.prReqPrecise);
if(bullet.level.TimeSeconds - bullet.fireState.base.sourceWeapon.lastHeadshotTime <= if(!bullet.bAlreadyHitZed || bIsHeadshot)
class'NiceSkillGunslingerPlayful'.default.quickWindow) HandleCalibration(bIsHeadshot, NiceHumanPawn(bullet.Instigator), NiceMonster(kfZed));
bullet.fireState.base.sourceWeapon.quickHeadshots ++; if(bIsHeadshot && bullet.sourceWeapon != none)
bullet.fireState.base.sourceWeapon.lastHeadshotTime = bullet.Level.TimeSeconds; bullet.sourceWeapon.lastHeadshotTime = bullet.Level.TimeSeconds;
}*/
// Try to get necessary variables and bail in case they're unaccessible // Try to get necessary variables and bail in case they're unaccessible
nicePlayer = NicePlayerController(bullet.Instigator.Controller); nicePlayer = NicePlayerController(bullet.Instigator.Controller);
if(nicePlayer == none) if(nicePlayer == none)
return; return;
nicePawn = NiceHumanPawn(bullet.instigator);
if( !bIsHeadshot
&& nicePawn != none
&& nicePlayer.abilityManager != none
&& nicePlayer.abilityManager.IsAbilityActive(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.fireType.bullet.bCausePain) if(bullet.charCausePain)
actualDamage = bullet.fireType.bullet.damage; actualDamage = bullet.charOrigDamage;
else else
actualDamage = bullet.damage; actualDamage = bullet.charDamage;
if(niceZed == bullet.fireState.lockon.target && bullet.fireState.lockon.time > 0.5 if(headshotLevel > 0)
&& niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterKillConfirmed')){ actualDamage *= bullet.charContiniousBonus;
lockonTicks = Ceil(2 * bullet.fireState.lockon.time) - 1; if(bullet.bGrazing)
//actualDamage *= 1.0 + actualDamage *= class'NiceSkillSupportGraze'.default.grazeDamageMult;
// 0.5 * lockonTicks * (lockonTicks + 1) * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus; bullet.bGrazing = false;
//damageMod *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus; if(kfZed == bullet.lockonZed && bullet.lockonTime > bullet.sourceWeapon.stdFireRate
actualDamage *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus; && niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterKillConfirmed')){
}/* lockOnTickRate =class'NiceSkillSharpshooterKillConfirmed'.default.stackDelay;
if(niceVet == class'NiceVetGunslinger' && !bullet.bAlreadyHitZed) lockonTicks = Ceil(bullet.lockonTime / lockOnTickRate) - 1;
niceRI.ServerGunslingerConfirm(niceZed, actualDamage, bullet.instigator, hitLocation, lockonTicks = Min(class'NiceSkillSharpshooterKillConfirmed'.default.maxStacks, lockonTicks);
bullet.fireType.bullet.momentum * hitNormal, bullet.fireType.bullet.shotDamageType, headshotLevel, bullet.fireState.lockon.time);*/ //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) if(!bullet.bGhost)
niceRI.ServerDealDamage(niceZed, actualDamage, bullet.instigator, hitLocation, niceRI.ServerDealDamage(kfZed, actualDamage, bullet.instigator, hitLocation,
bullet.fireType.bullet.momentum * hitNormal, bullet.fireType.bullet.shotDamageType, headshotLevel, bullet.fireState.lockon.time); bullet.charMomentumTransfer * hitNormal, bullet.charDamageType, headshotLevel, bullet.lockonTime);
//// Handle angled shots //// Handle angled shots
angle = asin(hitNormal.Z); angle = asin(hitNormal.Z);
// Gunslinger skill check
/*bGunslingerAngleShot = class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillGunslingerCloseAndPersonal');
if(bGunslingerAngleShot)
bGunslingerAngleShot =
VSizeSquared(bullet.instigator.location - niceZed.location) <=
class'NiceSkillGunslingerCloseAndPersonal'.default.closeDistance ** 2;*/
// Apply angled shots // Apply angled shots
if((angle > 0.8 || angle < -0.45) && bullet.bCanAngleDamage && niceZed != 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.damage, bullet, niceZed, headshotLevel)) if(ZedPenetration(bullet.charDamage, bullet, kfZed, bIsHeadshot, bIsPreciseHeadshot))
HitZed(bullet, niceZed, 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 != none && nicePlayer.IsZedTimeActive() && bullet.insideBouncesLeft > 0
&& niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBore')){ && 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.damage, bullet, niceZed, 0.0); ZedPenetration(bullet.charDamage, bullet, kfZed, false, false);
HitZed(bullet, niceZed, 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, NiceMonster niceZed, float headshotLevel){ local float reductionMod;
local float penReduction; local NiceMonster niceZed;
local bool bIsHeadshot, bIsPreciseHeadshot;
local NicePlayerController nicePlayer; local NicePlayerController nicePlayer;
local int actualMaxPenetrations; local int actualMaxPenetrations;
local class<NiceVeterancyTypes> niceVet; local class<NiceVeterancyTypes> niceVet;
@ -179,47 +142,51 @@ static function bool ZedPenetration(out float Damage, NiceBullet bullet, NiceMon
// 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);
nicePlayer = NicePlayerController(bullet.Instigator.Controller); nicePlayer = NicePlayerController(bullet.Instigator.Controller);
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo)); niceVet = none;
niceDmgType = bullet.fireType.bullet.shotDamageType; if(nicePlayer != none)
bIsHeadshot = (headshotLevel > 0.0); niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
bIsPreciseHeadshot = (headshotLevel > bullet.fireType.bullet.shotDamageType.default.prReqPrecise); niceDmgType = bullet.charDamageType;
bEasyHeadPenetration = bIsHeadshot && !niceDmgType.default.bPenetrationHSOnly; bEasyHeadPenetration = bIsHeadshot && !niceDmgType.default.bPenetrationHSOnly;
reductionMod = 1.0f;
penReduction = niceDmgType.default.PenDmgReduction;
// 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)
penReduction *= niceDmgType.default.BigZedPenDmgReduction; reductionMod *= niceDmgType.default.BigZedPenDmgReduction;
else if(niceZed.default.Health >= default.MediumZedMinHealth && !bEasyHeadPenetration) else if(niceZed.default.Health >= default.MediumZedMinHealth && !bEasyHeadPenetration)
penReduction *= niceDmgType.default.MediumZedPenDmgReduction; reductionMod *= niceDmgType.default.MediumZedPenDmgReduction;
} }
else else
penReduction *= niceDmgType.default.BigZedPenDmgReduction; reductionMod *= niceDmgType.default.BigZedPenDmgReduction;
if(niceVet != none) if(niceVet != none)
penReduction = niceVet.static.GetPenetrationDamageMulti(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo), penReduction, niceDmgType); reductionMod = niceVet.static.GetPenetrationDamageMulti(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo), reductionMod, niceDmgType);
if(niceVet != none && nicePlayer.pawn.bIsCrouched && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterSurgical') && bIsHeadshot) actualMaxPenetrations = niceDmgType.default.maxPenetrations;
penReduction = FMax(penReduction, class'NiceSkillSharpshooterSurgical'.default.penDmgReduction); 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 *= penReduction; Damage *= reductionMod * niceDmgType.default.PenDmgReduction;
actualMaxPenetrations = niceDmgType.default.maxPenetrations; bullet.decapMod *= reductionMod * niceDmgType.default.PenDecapReduction;
if(actualMaxPenetrations >= 0) bullet.incapMod *= reductionMod * niceDmgType.default.PenIncapReduction;
actualMaxPenetrations += if(niceVet != none && actualMaxPenetrations >= 0)
niceVet.static.GetAdditionalPenetrationAmount(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo)); actualMaxPenetrations +=
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.fireType.bullet.damage < (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
} }

View File

@ -1,218 +0,0 @@
//==============================================================================
// NicePack / NiceBulletSpawner
//==============================================================================
// Class that is supposed to handle bullet spawning.
// It's main purpose is to allow spawning of large amounts of bullets with
// minimal replication between server and clients, which is supposed to be
// achieved via commands that can spawn multiple bullets at once,
// while 'syncing' any randomness by replicating seeds to it's own RNG.
// Functionality:
// - 'Xorshift' RNG implementation
// - Ability to spawn both single bullets and groups of them
// via single replication call
//==============================================================================
// Class hierarchy: Object > Actor > NiceBulletSpawner
//==============================================================================
// 'Nice pack' source
// Do whatever the fuck you want with it
// Author: dkanus
// E-mail: dkanus@gmail.com
//==============================================================================
class NiceBulletSpawner extends Actor
dependson(NiceFire);
//==============================================================================
//==============================================================================
// > Random number generation
// Variables and structures related to generating pseudo-random numbers, but
// completly determined by a random state object ('NiceRandomState').
// For that task we use xorshift algorithm, described here:
// https://en.wikipedia.org/wiki/Xorshift
// (page version as of 21 September 2016)
//
// This class doesn't bother with replicating random states, and all the work
// for their syncronization must be done via some other means.
//==============================================================================
// >> State of the psudo-random number generator
// This structure contains four integer values used in our version of xorshift
struct NiceRandomState{
var int x, y, z, w;
};
//==============================================================================
//==============================================================================
// > RNG-related functions
// Generates new random state (seed).
// This must be called on one machine only (server or client) and then
// replicated to other meachines that are required to generate the same
// sequence of random numbers.
// Separetely calling it on different machines will produce different seeds
// and different random sequences.
static function NiceRandomState GenerateRandomState(){
local NiceRandomState newState;
newState.x = Rand(MaxInt);
newState.y = Rand(MaxInt);
newState.z = Rand(MaxInt);
newState.w = Rand(MaxInt);
return newState;
}
// Generates new random float between 0 and 'maxValue'
// and modifies the used state as a result.
// In case 'maxValue' is less than 1, - it'll be treated as 1.
static function int GetRandomInt( out NiceRandomState randomState,
int maxValue){
local int t;
local int randomValue;
// This part was taken from:
// https://en.wikipedia.org/wiki/Xorshift
// (page version as of 21 September 2016)
t = randomState.x;
t = t ^ (t << 11);
t = t ^ (t >> 8);
randomState.x = randomState.y;
randomState.y = randomState.z;
randomState.z = randomState.w;
randomState.w = randomState.w ^ (randomState.w >> 19);
randomState.w = randomState.w ^ t;
// This is the supposed output random value,
// but since it can be negative...
randomValue = randomState.w;
// ...we will force it to be positive;
// (the case when 'randomValue' turns out to be the minimal possible value
// won't compromise anything for us)
if(randomValue < 0)
randomValue = -randomValue;
// Now quit if the value generated is indeed lower than 'maxValue'...
maxValue = Max(maxValue, 1);
if(randomState.w <= maxValue)
return randomState.w;
// ...because this will mess things up when 'maxValue' == 'MaxInt'
return (randomState.w % (maxValue + 1)) / maxValue;
}
// Generates new random float between 0 and 1
// and modifies the used state as a result.
static function float GetRandomFloat(out NiceRandomState randomState){
return GetRandomInt(randomState, MaxInt) / MaxInt;
}
//==============================================================================
//==============================================================================
// > Bullet spawning-related functions
// When called on a server -
// replicates to all players a message about spawned bullets
// (to cause them to spawn their ghost versions);
//
// 'bSkipOwner' flag allows to skip replicating this information
// to the owner (instigator) of the bullets,
// which is useful when used in 'DoNiceFireEffect' in 'NiceFire' class that's
// called on both client and server.
//
// When called on a client - instantly terminates itself
static function ReplicateBullets( int amount,
Vector start,
Rotator dir,
float spread,
NiceFire.NWFireType fireType,
NiceFire.NWCFireState fireState,
bool bSkipOwner){
local int i;
local NicePack niceMut;
local NicePlayerController bulletOwner;
if(fireState.base.instigator == none) return;
if(fireState.base.instigator.role < ROLE_Authority) return;
niceMut = class'NicePack'.static.Myself(fireState.base.instigator.level);
bulletOwner = fireState.base.instigatorCtrl;
for(i = 0;i < niceMut.playersList.length;i ++){
if(niceMut.playersList[i] == bulletOwner && bSkipOwner)
continue;
niceMut.playersList[i].ClientSpawnGhosts(amount, start,
dir.pitch, dir.yaw, dir.roll,
spread, fireType, fireState);
}
}
// Spawns a single bullet with no spread, exactly in the specified direction
static function SpawnSingleBullet( Vector start,
Rotator dir,
NiceFire.NWFireType fireType,
NiceFire.NWCFireState fireState){
local Actor other;
local NiceBullet niceBullet;
local Vector hitLocation, hitNormal, traceDir;
if(fireType.movement.bulletClass == none) return;
if(fireState.base.instigator == none) return;
// Try to spawn
niceBullet = fireState.base.instigator.
Spawn(fireType.movement.bulletClass,,, start, dir);
// If the first projectile spawn failed it's probably because we're trying
// to spawn inside the collision bounds of an object with properties that
// ignore zero extent traces.
// We need to do a non-zero extent trace so
// we can find a safe spawn loc for our projectile
if(niceBullet == none){
traceDir = fireState.base.instigator.location +
fireState.base.instigator.EyePosition();
other = fireState.base.instigator.Trace(hitLocation, hitNormal, start,
traceDir, false, Vect(0,0,1));
if(other != none)
start = hitLocation;
niceBullet = fireState.base.instigator.
Spawn( fireType.movement.bulletClass,,, start, dir);
}
// Give up if failed after these two attempts
if(niceBullet == none)
return;
// Initialize bullet's data
niceBullet.fireType = fireType;
niceBullet.fireState = fireState;
niceBullet.InitBullet();
}
// Spawns a several bullets at once from the same location, but possibly
// spreads them in different directions (if 'spread' is greater than zero)
// by at most 'spread' angle (given in rotator units).
static function SpawnBullets( int amount,
Vector start,
Rotator dir,
float spread,
NiceFire.NWFireType fireType,
NiceFire.NWCFireState fireState){
local int i;
local Vector dirVector;
local Rotator randomRot;
dirVector = Vector(dir);
for(i = 0;i < amount;i ++){
if(spread > 0.0){
randomRot.yaw = spread * (FRand() - 0.5); // NICETODO: replace with proper fucking RNG, after adding syncronization of seeds
randomRot.pitch = spread * (FRand() - 0.5);
}
SpawnSingleBullet( start, Rotator(dirVector >> randomRot),
fireType, fireState);
}
}
// A usability function;
// it calls 'SpawnBullets' on client (instigator) and
// 'ReplicateBullets' on server, without duplicating shots on the client.
//
// Just a shortcut to use to fire bullets from 'NiceFire' class
static function FireBullets(int amount,
Vector start,
Rotator dir,
float spread,
NiceFire.NWFireType fireType,
NiceFire.NWCFireState fireState){
if(fireState.base.instigator == none) return;
if(fireState.base.instigator.role == ROLE_Authority)
ReplicateBullets(amount, start, dir, spread, fireType, fireState, true);
else
SpawnBullets(amount, start, dir, spread, fireType, fireState);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,167 @@
class NiceProjectileSpawner extends Actor
dependson(NiceBullet);
// NICETODO: use flags correctly
static function MakeProjectile(Vector start, Rotator dir, NiceFire.ShotType shotParams, NiceFire.FireModeContext fireContext, optional bool bForceComplexTraj,
optional bool bDuplReal, optional bool bSkipGhosts){
local int i;
local NicePack niceMut;
niceMut = class'NicePack'.static.Myself(fireContext.Instigator.Level);
if(niceMut == none)
return;
if(fireContext.Instigator.Role < ROLE_Authority || bDuplReal)
SpawnProjectile(Start, Dir, shotParams, fireContext, false, bForceComplexTraj);
if(fireContext.Instigator.Role == ROLE_Authority && niceMut != none && !bSkipGhosts){
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){
local int i;
local NicePack niceMut;
niceMut = class'NicePack'.static.Myself(expData.Instigator.Level);
if(niceMut == none)
return;
niceMut.stuckCounter ++;
if(expData.Instigator.Role < ROLE_Authority)
SpawnStuckProjectile(instigator, base, bone, shift, direction, 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){
local Actor other;
local NiceBullet niceProj;
local Vector HitLocation, HitNormal;
local NicePlayerController nicePlayer;
local class<NiceVeterancyTypes> niceVet;
// No class - no projectile
if(shotParams.bulletClass == none)
return none;
// Try to spawn
if(fireContext.Instigator != none)
niceProj = fireContext.Instigator.Spawn(shotParams.bulletClass,,, Start, Dir);
// Try harder
if(niceProj == none && fireContext.Instigator != none){
other = fireContext.Instigator.Trace(HitLocation, HitNormal, 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
if(niceProj == none)
return none;
niceProj.Renew();
// Initialize projectile
if(fireContext.Instigator != none)
nicePlayer = NicePlayerController(fireContext.Instigator.Controller);
if(nicePlayer != none)
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(nicePlayer.PlayerReplicationInfo);
niceProj.bGhost = bIsGhost;
// Fill-up data about what damage should projectile deal
niceProj.charDamage = shotParams.damage;
if(niceVet != none && fireContext.bIsBursting && niceVet.static.hasSkill(nicePlayer, class'NiceSkillCommandoExplosivePower'))
niceProj.charDamage *= class'NiceSkillCommandoExplosivePower'.default.dmgMod;
if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBulletStorm') && nicePlayer.IsZedTimeActive())
niceProj.charDamage = shotParams.damage * class'NiceSkillSupportZEDBulletStorm'.default.damageCut;
niceProj.charOrigDamage = niceProj.charDamage;
niceProj.charDamageType = shotParams.shotDamageType;
niceProj.charExplosionDamageType = shotParams.explosionDamageType;
niceProj.charExplosionDamage = shotParams.explosionDamage;
niceProj.charExplosionRadius = shotParams.explosionRadius;
niceProj.charExplosionExponent = shotParams.explosionExponent;
niceProj.charExplosionMomentum = shotParams.explosionMomentum;
niceProj.charFuseTime = shotParams.fuseTime;
niceProj.charExplodeOnFuse = shotParams.explodeOnFuse;
niceProj.charExplodeOnPawnHit = shotParams.explodeOnPawnHit;
niceProj.charExplodeOnWallHit = shotParams.explodeOnWallHit;
niceProj.charMomentumTransfer = shotParams.momentum;
niceProj.charWasHipFired = fireContext.bHipfire;
niceProj.charCausePain = shotParams.bCausePain;
niceProj.lockonTime = fireContext.lockonTime;
niceProj.lockonZed = fireContext.lockonZed;
niceProj.instigator = fireContext.instigator;
niceProj.sourceWeapon = fireContext.sourceWeapon;
niceProj.charContiniousBonus = fireContext.continiousBonus;
// Fill-up data about at what speed should projectile travel
niceProj.movementSpeed = shotParams.projSpeed;
if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoOnperk'))
niceProj.movementSpeed *= class'NiceSkillDemoOnperk'.default.speedBonus;
niceProj.movementDirection = Vector(niceProj.rotation);
niceProj.charAffectedByScream = shotParams.projAffectedByScream;
niceProj.charIsSticky = shotParams.bShouldStick;
niceProj.nicePlayer = nicePlayer;
if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoVolatile')){
niceProj.charExplosionRadius *= class'NiceSkillDemoVolatile'.default.explRangeMult;
niceProj.charExplosionExponent *= class'NiceSkillDemoVolatile'.default.falloffMult;
niceProj.charMinExplosionDist *= class'NiceSkillDemoVolatile'.default.safeDistanceMult;
}
if(niceVet != none && 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;
// And some leftovers
//niceProj.bShouldBounce = shotParams.bShouldBounce;
niceProj.bInitFinished = true;
return niceProj;
}
static function SpawnStuckProjectile(KFHumanPawn instigator, Actor base, name bone, Vector shift, 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);
if(base == none || nicePlayer == none)
return;
justPawn = Pawn(base);
fireContext.instigator = NiceHumanPawn(instigator);
fireContext.sourceWeapon = expData.sourceWeapon;
shotParams.bulletClass = expData.bulletClass;
shotParams.explosionDamageType = expData.explosionDamageType;
shotParams.explosionDamage = expData.explosionDamage;
shotParams.explosionRadius = expData.explosionRadius;
shotParams.explosionExponent = expData.explosionExponent;
shotParams.explosionMomentum = expData.explosionMomentum;
shotParams.fuseTime = expData.fuseTime;
shotParams.explodeOnFuse = expData.explodeOnFuse;
shotParams.projAffectedByScream = expData.affectedByScream;
spawnedBullet = SpawnProjectile(base.location, direction, shotParams, fireContext, bIsGhost);
if(spawnedBullet == none)
return;
spawnedBullet.stuckID = stuckID;
spawnedBullet.bStuck = true;
nicePlayer.RegisterStuckBullet(spawnedBullet);
if(justPawn != none){
spawnedBullet.bStuckToHead = expData.stuckToHead;
spawnedBullet.SetBase(base);
justPawn.AttachToBone(spawnedBullet, bone);
spawnedBullet.SetRelativeLocation(shift);
spawnedBullet.SetRelativeRotation(Rotator(Vector(direction) << justPawn.GetBoneRotation(bone, 0)));
spawnedBullet.bUseBone = true;
spawnedBullet.stuckBone = bone;
}
else{
spawnedBullet.SetBase(base);
spawnedBullet.SetRelativeLocation(shift);
}
}
defaultproperties
{
bHidden=True
RemoteRole=ROLE_SimulatedProxy
LifeSpan=1.000000
}

File diff suppressed because it is too large Load Diff

View File

@ -15,15 +15,19 @@ simulated function SetNiceData(NicePlainData.Data newData){
simulated function InitDroppedPickupFor(Inventory Inv){ simulated function InitDroppedPickupFor(Inventory Inv){
local NiceWeapon niceWeap; local NiceWeapon niceWeap;
niceWeap = NiceWeapon(Inv); niceWeap = NiceWeapon(Inv);
if(niceWeap != none) SetNiceData(niceWeap.GetNiceData()); if(niceWeap != none)
SetNiceData(niceWeap.GetNiceData());
// Do as usual // Do as usual
if(Role == ROLE_Authority) super.InitDroppedPickupFor(Inv); if(Role == ROLE_Authority)
super.InitDroppedPickupFor(Inv);
} }
function Destroyed(){ function Destroyed(){
if(bDropped && Inventory != none && class<Weapon>(Inventory.Class) != none && KFGameType(Level.Game) != none) KFGameType(Level.Game).WeaponDestroyed(class<Weapon>(Inventory.Class)); if(bDropped && Inventory != none && class<Weapon>(Inventory.Class) != none && KFGameType(Level.Game) != none)
KFGameType(Level.Game).WeaponDestroyed(class<Weapon>(Inventory.Class));
super(WeaponPickup).Destroyed(); super(WeaponPickup).Destroyed();
} }
defaultproperties defaultproperties
{ {
cost=1000 cost=1000
} }

View File

@ -0,0 +1,5 @@
class NiceAK12Ammo extends NiceAmmo;
#EXEC OBJ LOAD FILE=KillingFloorHUD.utx
defaultproperties
{ WeaponPickupClass=Class'NicePack.NiceAK12Pickup' AmmoPickupAmount=30 MaxAmmo=270 InitialAmount=60 PickupClass=Class'NicePack.NiceAK12AmmoPickup' IconMaterial=Texture'KillingFloorHUD.Generic.HUD' IconCoords=(X1=336,Y1=82,X2=382,Y2=125) ItemName="5.45x39mm"
}

View File

@ -0,0 +1,4 @@
class NiceAK12AmmoPickup extends NiceAmmoPickup;
defaultproperties
{ AmmoAmount=30 InventoryType=Class'NicePack.NiceAK12Ammo' PickupMessage="Rounds 5.45x39mm" StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'
}

View File

@ -0,0 +1,4 @@
class NiceAK12AssaultRifle extends NiceAssaultRifle;
defaultproperties
{ bSemiAutoFireEnabled=False bBurstFireEnabled=True reloadPreEndFrame=0.158000 reloadEndFrame=0.521000 reloadChargeEndFrame=0.726000 reloadMagStartFrame=0.363000 reloadChargeStartFrame=0.726000 MagazineBone="Bone_Magazine" MagCapacity=30 ReloadRate=3.000000 ReloadAnim="Reload" ReloadAnimRate=1.000000 WeaponReloadAnim="Reload_AK47" Weight=6.000000 bHasAimingMode=True IdleAimAnim="Idle_Iron" StandardDisplayFOV=55.000000 SleeveNum=8 TraderInfoTexture=Texture'ScrnWeaponPack_T.AK12.AK12_trader' bIsTier3Weapon=True MeshRef="ScrnWeaponPack_A.AK12_mesh" SkinRefs(0)="ScrnWeaponPack_T.AK12.AK12_tex_1_cmb" SkinRefs(1)="ScrnWeaponPack_T.AK12.AK12_tex_2_cmb" SkinRefs(2)="ScrnWeaponPack_T.AK12.AK12_tex_3_cmb" SkinRefs(3)="ScrnWeaponPack_T.AK12.AK12_tex_4_cmb" SkinRefs(4)="ScrnWeaponPack_T.AK12.AK12_tex_5_cmb" SkinRefs(5)="ScrnWeaponPack_T.AK12.AK12_tex_6_cmb" SkinRefs(6)="ScrnWeaponPack_T.AK12.AK12_tex_7_cmb" SkinRefs(7)="ScrnWeaponPack_T.AK12.AK12_aimpoint_sh" SkinRefs(8)="KF_Weapons_Trip_T.hands.hands_1stP_military_cmb" SelectSoundRef="ScrnWeaponPack_SND.AK12.AK12_select" HudImageRef="ScrnWeaponPack_T.AK12.AK12_Unselect" SelectedHudImageRef="ScrnWeaponPack_T.AK12.AK12_select" PlayerIronSightFOV=65.000000 ZoomedDisplayFOV=20.000000 FireModeClass(0)=Class'NicePack.NiceAK12Fire' FireModeClass(1)=Class'KFMod.NoFire' PutDownAnim="PutDown" SelectAnimRate=1.300000 SelectForce="SwitchToAssaultRifle" AIRating=0.550000 CurrentRating=0.550000 bShowChargingBar=True Description="The Kalashnikov AK-12 (formerly AK-200) is the newest derivative of the Soviet/Russian AK-47 series of assault rifles and was proposed for possible general issue to the Russian Army. This version uses the 5.45x39mm ammo (the same as AK-74)" EffectOffset=(X=100.000000,Y=25.000000,Z=-10.000000) DisplayFOV=55.000000 Priority=145 CustomCrosshair=11 CustomCrossHairTextureName="Crosshairs.HUD.Crosshair_Cross5" InventoryGroup=4 GroupOffset=7 PickupClass=Class'NicePack.NiceAK12Pickup' PlayerViewOffset=(X=-0.500000,Y=20.000000,Z=-3.000000) BobDamping=6.000000 AttachmentClass=Class'NicePack.NiceAK12Attachment' IconCoords=(X1=245,Y1=39,X2=329,Y2=79) ItemName="AK12" TransientSoundVolume=1.250000
}

View File

@ -0,0 +1,5 @@
class NiceAK12Attachment extends NiceAttachment;
simulated function WeaponLight();
defaultproperties
{ bSpawnLight=False mMuzFlashClass=Class'ScrnWeaponPack.MuzzleFlashAK12AR' mTracerClass=Class'KFMod.KFNewTracer' mShellCaseEmitterClass=Class'KFMod.KFShellSpewer' MovementAnims(0)="JogF_AK47" MovementAnims(1)="JogB_AK47" MovementAnims(2)="JogL_AK47" MovementAnims(3)="JogR_AK47" TurnLeftAnim="TurnL_AK47" TurnRightAnim="TurnR_AK47" CrouchAnims(0)="CHWalkF_AK47" CrouchAnims(1)="CHWalkB_AK47" CrouchAnims(2)="CHWalkL_AK47" CrouchAnims(3)="CHWalkR_AK47" WalkAnims(0)="WalkF_AK47" WalkAnims(1)="WalkB_AK47" WalkAnims(2)="WalkL_AK47" WalkAnims(3)="WalkR_AK47" CrouchTurnRightAnim="CH_TurnR_AK47" CrouchTurnLeftAnim="CH_TurnL_AK47" IdleCrouchAnim="CHIdle_AK47" IdleWeaponAnim="Idle_AK47" IdleRestAnim="Idle_AK47" IdleChatAnim="Idle_AK47" IdleHeavyAnim="Idle_AK47" IdleRifleAnim="Idle_AK47" FireAnims(0)="Fire_AK47" FireAnims(1)="Fire_AK47" FireAnims(2)="Fire_AK47" FireAnims(3)="Fire_AK47" FireAltAnims(0)="IS_Fire_AK47" FireAltAnims(1)="IS_Fire_AK47" FireAltAnims(2)="IS_Fire_AK47" FireAltAnims(3)="IS_Fire_AK47" FireCrouchAnims(0)="CHFire_AK47" FireCrouchAnims(1)="CHFire_AK47" FireCrouchAnims(2)="CHFire_AK47" FireCrouchAnims(3)="CHFire_AK47" FireCrouchAltAnims(0)="CHFire_AK47" FireCrouchAltAnims(1)="CHFire_AK47" FireCrouchAltAnims(2)="CHFire_AK47" FireCrouchAltAnims(3)="CHFire_AK47" HitAnims(0)="HitF_AK47" HitAnims(1)="HitB_AK47" HitAnims(2)="HitL_AK47" HitAnims(3)="HitR_AK47" PostFireBlendStandAnim="Blend_AK47" PostFireBlendCrouchAnim="CHBlend_AK47" MeshRef="ScrnWeaponPack_A.AK12_3rd" bHeavy=True SplashEffect=Class'ROEffects.BulletSplashEmitter' CullDistance=5000.000000
}

View File

@ -0,0 +1,4 @@
class NiceAK12Fire extends NiceFire;
defaultproperties
{ zedTimeFireSpeedUp=2.500000 ProjectileSpeed=44000.000000 FireAimedAnim="Fire_Iron" RecoilRate=0.040000 maxVerticalRecoilAngle=240 maxHorizontalRecoilAngle=120 ShellEjectClass=Class'ScrnWeaponPack.KFShellEjectAK12AR' ShellEjectBoneName="Shell_eject" bAccuracyBonusForSemiAuto=True bRandomPitchFireSound=False FireSoundRef="ScrnWeaponPack_SND.AK12.AK12_shot" StereoFireSoundRef="ScrnWeaponPack_SND.AK12.AK12_shot" NoAmmoSoundRef="ScrnWeaponPack_SND.AK12.AK12_empty" DamageType=Class'NicePack.NiceDamTypeAK12AssaultRifle' DamageMax=68 Momentum=18500.000000 bPawnRapidFireAnim=True TransientSoundVolume=3.800000 FireLoopAnim="Fire" TweenTime=0.025000 FireForce="AssaultRifleFire" FireRate=0.095000 AmmoClass=Class'NicePack.NiceAK12Ammo' ShakeRotMag=(X=50.000000,Y=50.000000,Z=350.000000) ShakeRotRate=(X=5000.000000,Y=5000.000000,Z=5000.000000) ShakeRotTime=0.750000 ShakeOffsetMag=(X=6.000000,Y=3.000000,Z=7.500000) ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000) ShakeOffsetTime=1.250000 BotRefireRate=0.990000 FlashEmitterClass=Class'ScrnWeaponPack.MuzzleFlashAK12AR' aimerror=42.000000
}

View File

@ -0,0 +1,4 @@
class NiceAK12Pickup extends NiceWeaponPickup;
defaultproperties
{ Weight=6.000000 cost=750 BuyClipSize=30 PowerValue=55 SpeedValue=80 RangeValue=30 Description="The Kalashnikov AK-12 (formerly AK-200) is the newest derivative of the Soviet/Russian AK-47 series of assault rifles and was proposed for possible general issue to the Russian Army. This version uses the 5.45x39mm ammo (the same as AK-74)" ItemName="AK12" ItemShortName="AK12" AmmoItemName="5.45x39mm" AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo' CorrespondingPerkIndex=3 EquipmentCategoryID=2 InventoryType=Class'NicePack.NiceAK12AssaultRifle' PickupMessage="You got the AK-12" PickupSound=Sound'ScrnWeaponPack_SND.AK12.AK12_select' PickupForce="AssaultRiflePickup" StaticMesh=StaticMesh'ScrnWeaponPack_SM.AK12_st' DrawScale=1.100000 CollisionRadius=25.000000 CollisionHeight=5.000000
}

View File

@ -0,0 +1,5 @@
class NiceDamTypeAK12AssaultRifle extends NiceDamageTypeVetCommando
abstract;
defaultproperties
{ bPenetrationHSOnly=True MaxPenetrations=3 HeadShotDamageMult=1.300000 WeaponClass=Class'NicePack.NiceAK12AssaultRifle' DeathString="%k killed %o (AK12)." FemaleSuicide="%o shot herself in the foot." MaleSuicide="%o shot himself in the foot." bRagdollBullet=True KDeathVel=400.000000 KDeathUpKick=120.000000
}

View File

@ -0,0 +1,5 @@
class NiceAK47Ammo extends NiceAmmo;
#EXEC OBJ LOAD FILE=KillingFloorHUD.utx
defaultproperties
{ WeaponPickupClass=Class'NicePack.NiceAK47Pickup' AmmoPickupAmount=30 MaxAmmo=270 InitialAmount=90 PickupClass=Class'NicePack.NiceAK47AmmoPickup' IconMaterial=Texture'KillingFloorHUD.Generic.HUD' IconCoords=(X1=336,Y1=82,X2=382,Y2=125) ItemName="AK47 bullets"
}

View File

@ -0,0 +1,4 @@
class NiceAK47AmmoPickup extends NiceAmmoPickup;
defaultproperties
{ AmmoAmount=30 InventoryType=Class'NicePack.NiceAK47Ammo' PickupMessage="Rounds 7.62mm" StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'
}

View File

@ -0,0 +1,7 @@
class NiceAK47AssaultRifle extends NiceAssaultRifle;
#exec OBJ LOAD FILE=KillingFloorWeapons.utx
#exec OBJ LOAD FILE=KillingFloorHUD.utx
#exec OBJ LOAD FILE=Inf_Weapons_Foley.uax
defaultproperties
{ bSemiAutoFireEnabled=False bBurstFireEnabled=True reloadPreEndFrame=0.167000 reloadEndFrame=0.578000 reloadChargeEndFrame=0.800000 reloadMagStartFrame=0.433000 reloadChargeStartFrame=0.711000 MagazineBone="MagazineAK" MagCapacity=30 ReloadRate=3.000000 ReloadAnim="Reload" ReloadAnimRate=1.000000 WeaponReloadAnim="Reload_AK47" Weight=6.000000 bHasAimingMode=True IdleAimAnim="Idle_Iron" StandardDisplayFOV=60.000000 TraderInfoTexture=Texture'KillingFloor2HUD.Trader_Weapon_Icons.Trader_AK_47' bIsTier2Weapon=True MeshRef="KF_Weapons2_Trip.AK47_Trip" SkinRefs(0)="KF_Weapons2_Trip_T.Rifles.AK47_cmb" SelectSoundRef="KF_AK47Snd.AK47_Select" HudImageRef="KillingFloor2HUD.WeaponSelect.Ak_47_unselected" SelectedHudImageRef="KillingFloor2HUD.WeaponSelect.Ak_47" PlayerIronSightFOV=65.000000 ZoomedDisplayFOV=32.000000 FireModeClass(0)=Class'NicePack.NiceAK47Fire' FireModeClass(1)=Class'KFMod.NoFire' PutDownAnim="PutDown" SelectForce="SwitchToAssaultRifle" AIRating=0.550000 CurrentRating=0.550000 bShowChargingBar=True Description="A classic Russian assault rifle. Can be fired in semi or full auto with nice knock down power but not great accuracy." EffectOffset=(X=100.000000,Y=25.000000,Z=-10.000000) DisplayFOV=60.000000 Priority=95 CustomCrosshair=11 CustomCrossHairTextureName="Crosshairs.HUD.Crosshair_Cross5" InventoryGroup=3 GroupOffset=7 PickupClass=Class'NicePack.NiceAK47Pickup' PlayerViewOffset=(X=18.000000,Y=22.000000,Z=-6.000000) BobDamping=6.000000 AttachmentClass=Class'NicePack.NiceAK47Attachment' IconCoords=(X1=245,Y1=39,X2=329,Y2=79) ItemName="AK47" TransientSoundVolume=1.250000
}

View File

@ -0,0 +1,4 @@
class NiceAK47Attachment extends NiceAttachment;
defaultproperties
{ mMuzFlashClass=Class'ROEffects.MuzzleFlash3rdMP' mTracerClass=Class'KFMod.KFNewTracer' mShellCaseEmitterClass=Class'KFMod.KFShellSpewer' MovementAnims(0)="JogF_AK47" MovementAnims(1)="JogB_AK47" MovementAnims(2)="JogL_AK47" MovementAnims(3)="JogR_AK47" TurnLeftAnim="TurnL_AK47" TurnRightAnim="TurnR_AK47" CrouchAnims(0)="CHWalkF_AK47" CrouchAnims(1)="CHWalkB_AK47" CrouchAnims(2)="CHWalkL_AK47" CrouchAnims(3)="CHWalkR_AK47" WalkAnims(0)="WalkF_AK47" WalkAnims(1)="WalkB_AK47" WalkAnims(2)="WalkL_AK47" WalkAnims(3)="WalkR_AK47" CrouchTurnRightAnim="CH_TurnR_AK47" CrouchTurnLeftAnim="CH_TurnL_AK47" IdleCrouchAnim="CHIdle_AK47" IdleWeaponAnim="Idle_AK47" IdleRestAnim="Idle_AK47" IdleChatAnim="Idle_AK47" IdleHeavyAnim="Idle_AK47" IdleRifleAnim="Idle_AK47" FireAnims(0)="Fire_AK47" FireAnims(1)="Fire_AK47" FireAnims(2)="Fire_AK47" FireAnims(3)="Fire_AK47" FireAltAnims(0)="Fire_AK47" FireAltAnims(1)="Fire_AK47" FireAltAnims(2)="Fire_AK47" FireAltAnims(3)="Fire_AK47" FireCrouchAnims(0)="CHFire_AK47" FireCrouchAnims(1)="CHFire_AK47" FireCrouchAnims(2)="CHFire_AK47" FireCrouchAnims(3)="CHFire_AK47" FireCrouchAltAnims(0)="CHFire_AK47" FireCrouchAltAnims(1)="CHFire_AK47" FireCrouchAltAnims(2)="CHFire_AK47" FireCrouchAltAnims(3)="CHFire_AK47" HitAnims(0)="HitF_AK47" HitAnims(1)="HitB_AK47" HitAnims(2)="HitL_AK47" HitAnims(3)="HitR_AK47" PostFireBlendStandAnim="Blend_AK47" PostFireBlendCrouchAnim="CHBlend_AK47" MeshRef="KF_Weapons3rd_Trip.AK47_3rd" bRapidFire=True bAltRapidFire=True SplashEffect=Class'ROEffects.BulletSplashEmitter' CullDistance=5000.000000
}

View File

@ -0,0 +1,4 @@
class NiceAK47Fire extends NiceFire;
defaultproperties
{ zedTimeFireSpeedUp=2.500000 ProjectileSpeed=35750.000000 FireAimedAnim="Fire_Iron" RecoilRate=0.070000 maxVerticalRecoilAngle=210 maxHorizontalRecoilAngle=105 ShellEjectClass=Class'ROEffects.KFShellEjectAK' ShellEjectBoneName="Shell_eject" bAccuracyBonusForSemiAuto=True bRandomPitchFireSound=False FireSoundRef="KF_AK47Snd.AK47_Fire" StereoFireSoundRef="KF_AK47Snd.AK47_FireST" NoAmmoSoundRef="KF_AK47Snd.AK47_DryFire" DamageType=Class'NicePack.NiceDamTypeAK47AssaultRifle' DamageMin=60 DamageMax=60 Momentum=8500.000000 bPawnRapidFireAnim=True TransientSoundVolume=1.800000 FireLoopAnim="Fire" TweenTime=0.025000 FireForce="AssaultRifleFire" FireRate=0.109000 AmmoClass=Class'NicePack.NiceAK47Ammo' ShakeRotMag=(X=50.000000,Y=50.000000,Z=350.000000) ShakeRotRate=(X=5000.000000,Y=5000.000000,Z=5000.000000) ShakeRotTime=0.750000 ShakeOffsetMag=(X=6.000000,Y=3.000000,Z=7.500000) ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000) ShakeOffsetTime=1.250000 BotRefireRate=0.990000 FlashEmitterClass=Class'ROEffects.MuzzleFlash1stSTG' aimerror=42.000000
}

View File

@ -0,0 +1,4 @@
class NiceAK47Pickup extends NiceWeaponPickup;
defaultproperties
{ Weight=6.000000 cost=750 AmmoCost=30 BuyClipSize=30 PowerValue=40 SpeedValue=80 RangeValue=50 Description="Standard issue military rifle. Equipped with an integrated 2X scope." ItemName="AK47" ItemShortName="AK47" AmmoItemName="7.62mm Ammo" AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo' CorrespondingPerkIndex=3 EquipmentCategoryID=2 VariantClasses(0)=Class'KFMod.GoldenAK47pickup' VariantClasses(1)=Class'KFMod.NeonAK47Pickup' InventoryType=Class'NicePack.NiceAK47AssaultRifle' PickupMessage="You got the AK47" PickupSound=Sound'KF_AK47Snd.AK47_Pickup' PickupForce="AssaultRiflePickup" StaticMesh=StaticMesh'KF_pickups_Trip.Rifle.AK47_Pickup' CollisionRadius=25.000000 CollisionHeight=5.000000
}

View File

@ -0,0 +1,5 @@
class NiceDamTypeAK47AssaultRifle extends NiceDamageTypeVetCommando
abstract;
defaultproperties
{ MaxPenetrations=1 HeadShotDamageMult=2.000000 WeaponClass=Class'NicePack.NiceAK47AssaultRifle' DeathString="%k killed %o (AK47)." FemaleSuicide="%o shot herself in the foot." MaleSuicide="%o shot himself in the foot." bRagdollBullet=True KDamageImpulse=5500.000000 KDeathVel=175.000000 KDeathUpKick=15.000000
}

View File

@ -0,0 +1,5 @@
class NiceDamTypeVALDT extends NiceDamageTypeVetCommando
abstract;
defaultproperties
{ HeadShotDamageMult=1.500000 WeaponClass=Class'NicePack.NiceVALDTAssaultRifle' DeathString="%k killed %o (AS 'VAL')." FemaleSuicide="%o shot herself in the foot." MaleSuicide="%o shot himself in the foot." bRagdollBullet=True KDamageImpulse=1500.000000 KDeathVel=110.000000 KDeathUpKick=2.000000
}

View File

@ -0,0 +1,5 @@
class NiceVALDTAmmo extends NiceAmmo;
#EXEC OBJ LOAD FILE=KillingFloorHUD.utx
defaultproperties
{ WeaponPickupClass=Class'NicePack.NiceVALDTPickup' AmmoPickupAmount=20 MaxAmmo=300 InitialAmount=75 PickupClass=Class'NicePack.NiceVALDTAmmoPickup' IconMaterial=Texture'KillingFloorHUD.Generic.HUD' IconCoords=(X1=336,Y1=82,X2=382,Y2=125) ItemName="9x39mm"
}

View File

@ -0,0 +1,4 @@
class NiceVALDTAmmoPickup extends NiceAmmoPickup;
defaultproperties
{ AmmoAmount=20 InventoryType=Class'NicePack.NiceVALDTAmmo' PickupMessage="9x39mm" StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'
}

View File

@ -0,0 +1,4 @@
class NiceVALDTAssaultRifle extends NiceAssaultRifle;
defaultproperties
{ reloadPreEndFrame=0.121000 reloadEndFrame=0.477000 reloadChargeEndFrame=0.748000 reloadMagStartFrame=0.299000 reloadChargeStartFrame=0.598000 MagazineBone="clip" MagCapacity=20 ReloadRate=3.500000 ReloadAnim="Reload" ReloadAnimRate=1.100000 WeaponReloadAnim="Reload_AK47" Weight=5.000000 bHasAimingMode=True IdleAimAnim="Iron_Idle" StandardDisplayFOV=65.000000 SleeveNum=3 TraderInfoTexture=Texture'ScrnWeaponPack_T.Val.ValDT_Trader' bIsTier2Weapon=True MeshRef="ScrnWeaponPack_A.ValDTmesh" SkinRefs(0)="ScrnWeaponPack_T.VAL.wpn_vss" SkinRefs(1)="ScrnWeaponPack_T.VAL.newvss" SkinRefs(2)="ScrnWeaponPack_T.VAL.wpn_bullet1_545" SkinRefs(3)="KF_Weapons2_Trip_T.hands.BritishPara_Hands_1st_P" SelectSoundRef="KF_PumpSGSnd.SG_Select" HudImageRef="ScrnWeaponPack_T.VAL.ValDT_unselected" SelectedHudImageRef="ScrnWeaponPack_T.VAL.ValDT_selected" PlayerIronSightFOV=65.000000 ZoomedDisplayFOV=32.000000 FireModeClass(0)=Class'NicePack.NiceVALDTFire' FireModeClass(1)=Class'NicePack.NiceVALDTFire' PutDownAnim="PutDown" SelectForce="SwitchToAssaultRifle" AIRating=0.550000 CurrentRating=0.550000 bShowChargingBar=True Description="The AS VAL (Avtomat Specialnyj Val or Special Automatic Rifle, code name: 'Shaft') is a Soviet designed assault rifle featuring an integrated suppressor. It was developed during the late 1980s by TsNIITochMash (Central Institute for Precision Machine Building) and is used by Russian Spetsnaz special forces and the MVD, FSB and select units of the Russian Army." EffectOffset=(X=100.000000,Y=25.000000,Z=-10.000000) DisplayFOV=65.000000 Priority=135 CustomCrosshair=11 CustomCrossHairTextureName="Crosshairs.HUD.Crosshair_Cross5" InventoryGroup=3 GroupOffset=7 PickupClass=Class'NicePack.NiceVALDTPickup' PlayerViewOffset=(X=10.000000,Y=10.000000,Z=-5.000000) BobDamping=5.000000 AttachmentClass=Class'ScrnWeaponPack.VALDTAttachment' IconCoords=(X1=245,Y1=39,X2=329,Y2=79) ItemName="AS 'VAL'" TransientSoundVolume=1.250000
}

View File

@ -0,0 +1,4 @@
class NiceVALDTFire extends NiceFire;
defaultproperties
{ FireAimedAnim="Fire" RecoilRate=0.070000 maxVerticalRecoilAngle=315 maxHorizontalRecoilAngle=158 ShellEjectClass=Class'ROEffects.KFShellEjectMac' ShellEjectBoneName="Shell_eject" bAccuracyBonusForSemiAuto=True bRandomPitchFireSound=False FireSoundRef="ScrnWeaponPack_SND.VSS.VSS_Fire" StereoFireSoundRef="ScrnWeaponPack_SND.VSS.VSS_Fire" NoAmmoSoundRef="KF_AK47Snd.AK47_DryFire" DamageType=Class'NicePack.NiceDamTypeVALDT' DamageMin=40 DamageMax=40 Momentum=18500.000000 bPawnRapidFireAnim=True TransientSoundVolume=2.800000 FireLoopAnim="Fire" TweenTime=0.025000 FireForce="AssaultRifleFire" FireRate=0.089000 AmmoClass=Class'NicePack.NiceVALDTAmmo' ShakeRotMag=(X=50.000000,Y=50.000000,Z=350.000000) ShakeRotRate=(X=5000.000000,Y=5000.000000,Z=5000.000000) ShakeRotTime=0.750000 ShakeOffsetMag=(X=6.000000,Y=3.000000,Z=7.500000) ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000) ShakeOffsetTime=1.250000 BotRefireRate=0.990000 FlashEmitterClass=Class'ScrnWeaponPack.MuzzleFlash3rdVALDT' aimerror=42.000000
}

View File

@ -0,0 +1,4 @@
class NiceVALDTPickup extends NiceWeaponPickup;
defaultproperties
{ Weight=5.000000 AmmoCost=10 BuyClipSize=30 PowerValue=50 SpeedValue=95 RangeValue=50 Description="The AS VAL (Avtomat Specialnyj Val or Special Automatic Rifle, code name: 'Shaft') is a Soviet designed assault rifle featuring an integrated suppressor. It was developed during the late 1980s by TsNIITochMash (Central Institute for Precision Machine Building) and is used by Russian Spetsnaz special forces and the MVD, FSB and select units of the Russian Army." ItemName="AS 'VAL'" ItemShortName="VAL" AmmoItemName="9x39mm" AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo' CorrespondingPerkIndex=3 EquipmentCategoryID=2 InventoryType=Class'NicePack.NiceVALDTAssaultRifle' PickupMessage="You've got a AS 'VAL'" PickupSound=Sound'KF_AK47Snd.AK47_Pickup' PickupForce="AssaultRiflePickup" StaticMesh=StaticMesh'ScrnWeaponPack_SM.ValDT_sm' DrawScale=1.300000 CollisionRadius=25.000000 CollisionHeight=5.000000
}

View File

@ -0,0 +1,7 @@
class NiceBullpup extends NiceAssaultRifle;
#exec OBJ LOAD FILE=KillingFloorWeapons.utx
#exec OBJ LOAD FILE=KillingFloorHUD.utx
#exec OBJ LOAD FILE=Inf_Weapons_Foley.uax
defaultproperties
{ reloadPreEndFrame=0.333000 reloadEndFrame=0.783000 reloadChargeEndFrame=-1.000000 reloadMagStartFrame=0.483000 reloadChargeStartFrame=-1.000000 MagCapacity=30 ReloadRate=1.966667 ReloadAnim="Reload" ReloadAnimRate=1.000000 WeaponReloadAnim="Reload_BullPup" Weight=5.000000 bHasAimingMode=True IdleAimAnim="Idle_Iron" StandardDisplayFOV=70.000000 SleeveNum=2 TraderInfoTexture=Texture'KillingFloorHUD.Trader_Weapon_Images.Trader_Bullpup' MeshRef="KF_Weapons_Trip.Bullpup_Trip" SkinRefs(0)="KF_Weapons_Trip_T.Rifles.bullpup_cmb" SkinRefs(1)="KF_Weapons_Trip_T.Rifles.reflex_sight_A_unlit" SelectSoundRef="KF_BullpupSnd.Bullpup_Select" HudImageRef="KillingFloorHUD.WeaponSelect.Bullpup_unselected" SelectedHudImageRef="KillingFloorHUD.WeaponSelect.Bullpup" PlayerIronSightFOV=65.000000 ZoomedDisplayFOV=40.000000 FireModeClass(0)=Class'NicePack.NiceBullpupFire' FireModeClass(1)=Class'KFMod.NoFire' PutDownAnim="PutDown" SelectForce="SwitchToAssaultRifle" AIRating=0.550000 CurrentRating=0.550000 bShowChargingBar=True Description="A military grade automatic rifle. Can be fired in semi-auto or full auto firemodes and comes equipped with a scope for increased accuracy." EffectOffset=(X=100.000000,Y=25.000000,Z=-10.000000) DisplayFOV=70.000000 Priority=70 CustomCrosshair=11 CustomCrossHairTextureName="Crosshairs.HUD.Crosshair_Cross5" InventoryGroup=3 GroupOffset=1 PickupClass=Class'NicePack.NiceBullpupPickup' PlayerViewOffset=(X=20.000000,Y=21.500000,Z=-9.000000) BobDamping=6.000000 AttachmentClass=Class'NicePack.NiceBullpupAttachment' IconCoords=(X1=245,Y1=39,X2=329,Y2=79) ItemName="Bullpup" TransientSoundVolume=1.250000
}

View File

@ -0,0 +1,5 @@
class NiceBullpupAmmo extends NiceAmmo;
#EXEC OBJ LOAD FILE=KillingFloorHUD.utx
defaultproperties
{ WeaponPickupClass=Class'NicePack.NiceBullpupPickup' AmmoPickupAmount=30 MaxAmmo=240 InitialAmount=45 PickupClass=Class'NicePack.NiceBullpupAmmoPickup' IconMaterial=Texture'KillingFloorHUD.Generic.HUD' IconCoords=(X1=336,Y1=82,X2=382,Y2=125) ItemName="Bullpup bullets"
}

View File

@ -0,0 +1,4 @@
class NiceBullpupAmmoPickup extends NiceAmmoPickup;
defaultproperties
{ AmmoAmount=30 InventoryType=Class'NicePack.NiceBullpupAmmo' PickupMessage="Rounds (5.56 NATO)" StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'
}

View File

@ -0,0 +1,4 @@
class NiceBullpupAttachment extends NiceAttachment;
defaultproperties
{ mMuzFlashClass=Class'ROEffects.MuzzleFlash3rdMP' mTracerClass=Class'KFMod.KFNewTracer' mShellCaseEmitterClass=Class'KFMod.KFShellSpewer' TurnLeftAnim="TurnL_Bullpup" TurnRightAnim="TurnR_Bullpup" WalkAnims(0)="WalkF_Bullpup" WalkAnims(1)="WalkB_Bullpup" WalkAnims(2)="WalkL_Bullpup" WalkAnims(3)="WalkR_Bullpup" CrouchTurnRightAnim="CH_TurnR_Bullpup" CrouchTurnLeftAnim="CH_TurnL_Bullpup" MeshRef="KF_Weapons3rd_Trip.BullPup_3rd" bRapidFire=True bAltRapidFire=True SplashEffect=Class'ROEffects.BulletSplashEmitter' CullDistance=5000.000000
}

View File

@ -0,0 +1,4 @@
class NiceBullpupFire extends NiceFire;
defaultproperties
{ zedTimeFireSpeedUp=5.000000 ProjectileSpeed=45500.000000 FireAimedAnim="Fire_Iron" RecoilRate=0.070000 maxVerticalRecoilAngle=210 maxHorizontalRecoilAngle=105 ShellEjectClass=Class'ROEffects.KFShellEjectBullpup' ShellEjectBoneName="Bullpup" bAccuracyBonusForSemiAuto=True FireSoundRef="KF_BullpupSnd.Bullpup_Fire" StereoFireSoundRef="KF_BullpupSnd.Bullpup_FireST" NoAmmoSoundRef="KF_9MMSnd.9mm_DryFire" DamageType=Class'NicePack.NiceDamTypeBullpup' DamageMin=48 DamageMax=48 Momentum=8500.000000 bPawnRapidFireAnim=True TransientSoundVolume=1.800000 FireLoopAnim="Fire" TweenTime=0.025000 FireForce="AssaultRifleFire" FireRate=0.100000 AmmoClass=Class'NicePack.NiceBullpupAmmo' ShakeRotMag=(X=75.000000,Y=75.000000,Z=250.000000) ShakeRotRate=(X=10000.000000,Y=10000.000000,Z=10000.000000) ShakeRotTime=0.500000 ShakeOffsetMag=(X=6.000000,Y=3.000000,Z=10.000000) ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000) ShakeOffsetTime=1.000000 BotRefireRate=0.990000 FlashEmitterClass=Class'ROEffects.MuzzleFlash1stSTG' aimerror=42.000000
}

View File

@ -0,0 +1,4 @@
class NiceBullpupPickup extends NiceWeaponPickup;
defaultproperties
{ bBackupWeapon=True Weight=5.000000 cost=200 BuyClipSize=30 PowerValue=24 SpeedValue=90 RangeValue=60 Description="Standard issue military rifle. Equipped with an integrated 2X scope." ItemName="Bullpup" ItemShortName="Bullpup" AmmoItemName="5.56 NATO Ammo" AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo' CorrespondingPerkIndex=3 EquipmentCategoryID=2 InventoryType=Class'NicePack.NiceBullpup' PickupMessage="You got the Bullpup" PickupForce="AssaultRiflePickup" StaticMesh=StaticMesh'KF_pickups_Trip.Rifle.Bullpup_Pickup' CollisionRadius=25.000000 CollisionHeight=5.000000
}

View File

@ -0,0 +1,5 @@
class NiceDamTypeBullpup extends NiceDamageTypeVetCommando
abstract;
defaultproperties
{ HeadShotDamageMult=1.500000 WeaponClass=Class'NicePack.NiceBullpup' DeathString="%k killed %o (Bullpup)." FemaleSuicide="%o shot herself in the foot." MaleSuicide="%o shot himself in the foot." bRagdollBullet=True KDamageImpulse=1500.000000 KDeathVel=110.000000 KDeathUpKick=2.000000
}

View File

@ -0,0 +1,4 @@
class NiceCZ805M extends CZ805M;
defaultproperties
{ FireModeClass(0)=Class'NicePack.NiceCZ805MFire' FireModeClass(1)=Class'NicePack.NiceCZ805MAltFire' PickupClass=Class'NicePack.NiceCZ805MPickup' ItemName="CZ-805M Medic/Assault Rifle NW"
}

View File

@ -0,0 +1,4 @@
class NiceCZ805MAltFire extends CZ805MAltFire;
defaultproperties
{ ProjectileClass=Class'NicePack.NiceCZ805MHealingProjectile'
}

View File

@ -0,0 +1,4 @@
class NiceCZ805MAmmo extends CZ805MAmmo;
defaultproperties
{ MaxAmmo=300 InitialAmount=150 PickupClass=Class'NicePack.NiceCZ805MAmmoPickup'
}

View File

@ -0,0 +1,4 @@
class NiceCZ805MAmmoPickup extends CZ805MAmmoPickup;
defaultproperties
{ InventoryType=Class'NicePack.NiceCZ805MAmmo'
}

View File

@ -0,0 +1,4 @@
class NiceCZ805MFire extends CZ805MFire;
defaultproperties
{ maxVerticalRecoilAngle=270 maxHorizontalRecoilAngle=135 DamageType=Class'NicePack.NiceDamTypeCZ805M' DamageMax=40 AmmoClass=Class'NicePack.NiceCZ805MAmmo'
}

View File

@ -0,0 +1,4 @@
class NiceCZ805MHealingProjectile extends CZ805MHealingProjectile;
defaultproperties
{ HealBoostAmount=20
}

View File

@ -0,0 +1,4 @@
class NiceCZ805MPickup extends CZ805MPickup;
defaultproperties
{ cost=2500 BuyClipSize=30 Description="Horzine's modification of CZ-805 BREN rifle with attached healing dart launcher. Useful for both Medic and Commando perks." ItemName="CZ-805M NW" ItemShortName="CZ-805M NW" InventoryType=Class'NicePack.NiceCZ805M' PickupMessage="You got the CZ-805M NW"
}

View File

@ -0,0 +1,5 @@
class NiceDamTypeCZ805M extends NiceDamageTypeVetCommando
abstract;
defaultproperties
{ HeadShotDamageMult=1.500000 WeaponClass=Class'NicePack.NiceCZ805M' DeathString="%k killed %o (CZ 805)." FemaleSuicide="%o shot herself in the foot." MaleSuicide="%o shot himself in the foot." bRagdollBullet=True KDamageImpulse=5500.000000 KDeathVel=175.000000 KDeathUpKick=20.000000
}

View File

@ -0,0 +1,5 @@
class NiceDamTypeFNFALAssaultRifle extends NiceDamageTypeVetCommando
abstract;
defaultproperties
{ MaxPenetrations=3 HeadShotDamageMult=2.250000 WeaponClass=Class'NicePack.NiceFNFAL_ACOG_AssaultRifle' DeathString="%k killed %o (FNFAL ACOG)." FemaleSuicide="%o shot herself in the foot." MaleSuicide="%o shot himself in the foot." bRagdollBullet=True KDamageImpulse=6500.000000 KDeathVel=175.000000 KDeathUpKick=20.000000
}

View File

@ -0,0 +1,5 @@
class NiceFNFALAmmo extends NiceAmmo;
#EXEC OBJ LOAD FILE=KillingFloorHUD.utx
defaultproperties
{ WeaponPickupClass=Class'NicePack.NiceFNFAL_ACOG_Pickup' AmmoPickupAmount=20 MaxAmmo=180 InitialAmount=45 PickupClass=Class'NicePack.NiceFNFALAmmoPickup' IconMaterial=Texture'KillingFloorHUD.Generic.HUD' IconCoords=(X1=336,Y1=82,X2=382,Y2=125) ItemName="FNFAL bullets"
}

View File

@ -0,0 +1,4 @@
class NiceFNFALAmmoPickup extends NiceAmmoPickup;
defaultproperties
{ AmmoAmount=20 InventoryType=Class'NicePack.NiceFNFALAmmo' PickupMessage="Rounds 7.62x51mm" StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'
}

View File

@ -0,0 +1,4 @@
class NiceFNFALFire extends NiceFire;
defaultproperties
{ zedTimeFireSpeedUp=2.500000 ProjectileSpeed=41150.000000 FireAimedAnim="Fire_Iron" FireEndAimedAnim="Fire_Iron_End" FireLoopAimedAnim="Fire_Iron_Loop" RecoilRate=0.080000 maxVerticalRecoilAngle=200 maxHorizontalRecoilAngle=100 ShellEjectClass=Class'KFMod.KFShellEjectFAL' ShellEjectBoneName="Shell_eject" bAccuracyBonusForSemiAuto=True bRandomPitchFireSound=False FireSoundRef="KF_FNFALSnd.FNFAL_Fire_Single_M" StereoFireSoundRef="KF_FNFALSnd.FNFAL_Fire_Single_S" NoAmmoSoundRef="KF_SCARSnd.SCAR_DryFire" DamageType=Class'NicePack.NiceDamTypeFNFALAssaultRifle' DamageMin=66 DamageMax=66 Momentum=8500.000000 bPawnRapidFireAnim=True TransientSoundVolume=1.800000 FireLoopAnim="Fire_Loop" FireEndAnim="Fire_End" TweenTime=0.025000 FireForce="AssaultRifleFire" FireRate=0.100000 AmmoClass=Class'NicePack.NiceFNFALAmmo' ShakeRotMag=(X=80.000000,Y=80.000000,Z=450.000000) ShakeRotRate=(X=7500.000000,Y=7500.000000,Z=7500.000000) ShakeRotTime=0.650000 ShakeOffsetMag=(X=6.000000,Y=3.000000,Z=8.500000) ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000) ShakeOffsetTime=1.150000 BotRefireRate=0.990000 FlashEmitterClass=Class'ROEffects.MuzzleFlash1stSTG' aimerror=42.000000
}

View File

@ -0,0 +1,4 @@
class NiceFNFAL_ACOG_AssaultRifle extends NiceAssaultRifle;
defaultproperties
{ reloadPreEndFrame=0.178000 reloadEndFrame=0.626000 reloadChargeEndFrame=0.882000 reloadMagStartFrame=0.411000 reloadChargeStartFrame=0.710000 MagCapacity=20 ReloadRate=3.600000 ReloadAnim="Reload" ReloadAnimRate=1.000000 WeaponReloadAnim="Reload_Fal_Acog" Weight=8.000000 bHasAimingMode=True IdleAimAnim="Idle_Iron" StandardDisplayFOV=55.000000 SleeveNum=2 TraderInfoTexture=Texture'KillingFloor2HUD.Trader_Weapon_Icons.Trader_FNFAL' bIsTier3Weapon=True MeshRef="KF_Wep_Fal_Acog.FAL_ACOG" SkinRefs(0)="KF_Weapons5_Trip_T.Weapons.FAL_cmb" SkinRefs(1)="KF_Weapons5_Scopes_Trip_T.FNFAL.AcogShader" SelectSoundRef="KF_FNFALSnd.FNFAL_Select" HudImageRef="KillingFloor2HUD.WeaponSelect.FNFAL_unselected" SelectedHudImageRef="KillingFloor2HUD.WeaponSelect.FNFAL" PlayerIronSightFOV=55.000000 ZoomedDisplayFOV=15.000000 FireModeClass(0)=Class'NicePack.NiceFNFALFire' FireModeClass(1)=Class'KFMod.NoFire' PutDownAnim="PutDown" SelectForce="SwitchToAssaultRifle" AIRating=0.550000 CurrentRating=0.550000 bShowChargingBar=True Description="Classic NATO battle rifle. Has a high rate of fire and decent accuracy, with good power." EffectOffset=(X=100.000000,Y=25.000000,Z=-10.000000) DisplayFOV=55.000000 Priority=180 CustomCrosshair=11 CustomCrossHairTextureName="Crosshairs.HUD.Crosshair_Cross5" InventoryGroup=4 GroupOffset=12 PickupClass=Class'NicePack.NiceFNFAL_ACOG_Pickup' PlayerViewOffset=(X=3.000000,Y=15.000000,Z=-6.000000) BobDamping=6.000000 AttachmentClass=Class'NicePack.NiceFNFAL_ACOG_Attachment' IconCoords=(X1=245,Y1=39,X2=329,Y2=79) ItemName="FNFAL" TransientSoundVolume=1.250000
}

View File

@ -0,0 +1,4 @@
class NiceFNFAL_ACOG_Attachment extends NiceAttachment;
defaultproperties
{ mMuzFlashClass=Class'ROEffects.MuzzleFlash3rdMP' mTracerClass=Class'KFMod.KFNewTracer' mShellCaseEmitterClass=Class'KFMod.KFShellSpewer' MovementAnims(0)="JogF_AA12" MovementAnims(1)="JogB_AA12" MovementAnims(2)="JogL_AA12" MovementAnims(3)="JogR_AA12" TurnLeftAnim="TurnL_AA12" TurnRightAnim="TurnR_AA12" CrouchAnims(0)="CHWalkF_AA12" CrouchAnims(1)="CHWalkB_AA12" CrouchAnims(2)="CHWalkL_AA12" CrouchAnims(3)="CHWalkR_AA12" WalkAnims(0)="WalkF_AA12" WalkAnims(1)="WalkB_AA12" WalkAnims(2)="WalkL_AA12" WalkAnims(3)="WalkR_AA12" CrouchTurnRightAnim="CH_TurnR_AA12" CrouchTurnLeftAnim="CH_TurnL_AA12" IdleCrouchAnim="CHIdle_AA12" IdleWeaponAnim="Idle_AA12" IdleRestAnim="Idle_AA12" IdleChatAnim="Idle_AA12" IdleHeavyAnim="Idle_AA12" IdleRifleAnim="Idle_AA12" FireAnims(0)="Fire_AA12" FireAnims(1)="Fire_AA12" FireAnims(2)="Fire_AA12" FireAnims(3)="Fire_AA12" FireAltAnims(0)="Fire_AA12" FireAltAnims(1)="Fire_AA12" FireAltAnims(2)="Fire_AA12" FireAltAnims(3)="Fire_AA12" FireCrouchAnims(0)="CHFire_AA12" FireCrouchAnims(1)="CHFire_AA12" FireCrouchAnims(2)="CHFire_AA12" FireCrouchAnims(3)="CHFire_AA12" FireCrouchAltAnims(0)="CHFire_AA12" FireCrouchAltAnims(1)="CHFire_AA12" FireCrouchAltAnims(2)="CHFire_AA12" FireCrouchAltAnims(3)="CHFire_AA12" HitAnims(0)="HitF_AA12" HitAnims(1)="HitB_AA12" HitAnims(2)="HitL_AA12" HitAnims(3)="HitR_AA12" PostFireBlendStandAnim="Blend_AA12" PostFireBlendCrouchAnim="CHBlend_AA12" MeshRef="KF_Weapons3rd4_Trip.Fal_Acog_3rd" WeaponAmbientScale=2.000000 bRapidFire=True bAltRapidFire=True SplashEffect=Class'ROEffects.BulletSplashEmitter' CullDistance=5000.000000
}

View File

@ -0,0 +1,4 @@
class NiceFNFAL_ACOG_Pickup extends NiceWeaponPickup;
defaultproperties
{ Weight=8.000000 cost=1250 AmmoCost=40 BuyClipSize=20 PowerValue=45 SpeedValue=90 RangeValue=70 Description="Classic NATO battle rifle. Has a high rate of fire and decent accuracy, with good power." ItemName="FNFAL" ItemShortName="FNFAL" AmmoItemName="7.62x51mm Ammo" AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo' CorrespondingPerkIndex=3 EquipmentCategoryID=3 InventoryType=Class'NicePack.NiceFNFAL_ACOG_AssaultRifle' PickupMessage="You got the FN FAL with ACOG Sight" PickupSound=Sound'KF_FNFALSnd.FNFAL_Pickup' PickupForce="AssaultRiflePickup" StaticMesh=StaticMesh'KF_pickups4_Trip.Rifles.Fal_Acog_Pickup' CollisionRadius=25.000000 CollisionHeight=5.000000
}

View File

@ -0,0 +1,4 @@
class NiceDamTypeHK417AR extends NiceDamageTypeVetCommando;
defaultproperties
{ MaxPenetrations=2 HeadShotDamageMult=2.000000 WeaponClass=Class'NicePack.NiceHK417AR' DeathString="%k killed %o (HK-417)." FemaleSuicide="%o shot herself in the foot." MaleSuicide="%o shot himself in the foot." bRagdollBullet=True KDamageImpulse=1500.000000 KDeathVel=110.000000 KDeathUpKick=2.000000
}

View File

@ -0,0 +1,4 @@
class NiceHK417AR extends NiceScopedWeapon;
defaultproperties
{ lenseMaterialID=8 scopePortalFOVHigh=40.000000 scopePortalFOV=40.000000 ZoomMatRef="ScrnWeaponPack_T.HK417AR.HK417Scope_FB" ScriptedTextureFallbackRef="KF_Weapons_Trip_T.Rifles.CBLens_cmb" CrosshairTexRef="ScrnWeaponPack_T.HK417AR.HK417Scope" reloadPreEndFrame=0.158000 reloadEndFrame=0.653000 reloadChargeEndFrame=-1.000000 reloadMagStartFrame=0.284000 reloadChargeStartFrame=-1.000000 MagazineBone="clip" bHasScope=True ZoomedDisplayFOVHigh=60.000000 MagCapacity=20 ReloadRate=3.150000 ReloadAnim="Reload" ReloadAnimRate=1.000000 WeaponReloadAnim="Reload_M4" Weight=6.000000 bHasAimingMode=True IdleAimAnim="Iron_Idle" StandardDisplayFOV=65.000000 SleeveNum=0 TraderInfoTexture=Texture'ScrnWeaponPack_T.HK417AR.HK417_Trader' MeshRef="ScrnWeaponPack_A.HK417_mesh" SkinRefs(0)="KF_Weapons3_Trip_T.hands.Priest_Hands_1st_P" SkinRefs(1)="ScrnWeaponPack_T.HK417AR.hk417_sk1_d2" SkinRefs(2)="ScrnWeaponPack_T.HK417AR.mueller" SkinRefs(3)="ScrnWeaponPack_T.HK417AR.body" SkinRefs(4)="ScrnWeaponPack_T.HK417AR.body2" SkinRefs(5)="ScrnWeaponPack_T.HK417AR.hk416_5" SkinRefs(6)="ScrnWeaponPack_T.HK417AR.clip_hk417" SkinRefs(7)="ScrnWeaponPack_T.HK417AR.hk416_8" SkinRefs(8)="KF_Weapons_Trip_T.Rifles.CBLens_cmb" SelectSoundRef="ScrnWeaponPack_SND.HK417AR.HK417_select" HudImageRef="ScrnWeaponPack_T.HK417AR.HK417_Unselected" SelectedHudImageRef="ScrnWeaponPack_T.HK417AR.HK417_selected" PlayerIronSightFOV=32.000000 ZoomedDisplayFOV=60.000000 FireModeClass(0)=Class'NicePack.NiceHK417Fire' FireModeClass(1)=Class'KFMod.NoFire' PutDownAnim="PutDown" SelectAnimRate=2.000000 BringUpTime=0.500000 SelectForce="SwitchToAssaultRifle" AIRating=0.650000 CurrentRating=0.650000 Description="The Heckler & Koch HK417 is a gas-operated, selective fire rifle with a rotating bolt and is essentially an enlarged HK416 assault rifle. Chambered for the full power 7.62x51mm NATO round, instead of a less powerful intermediate cartridge, the HK417 is intended for use as a designated marksman rifle, and in other roles where the greater penetrative power and range of the 7.62x51mm NATO round are required." DisplayFOV=65.000000 Priority=100 CustomCrosshair=11 CustomCrossHairTextureName="Crosshairs.HUD.Crosshair_Cross5" InventoryGroup=4 GroupOffset=3 PickupClass=Class'NicePack.NiceHK417Pickup' PlayerViewOffset=(X=14.000000,Y=7.000000,Z=-4.000000) BobDamping=6.000000 AttachmentClass=Class'NicePack.NiceHK417Attachment' IconCoords=(X1=253,Y1=146,X2=333,Y2=181) ItemName="HK-417"
}

View File

@ -0,0 +1,5 @@
class NiceHK417Ammo extends NiceAmmo;
#EXEC OBJ LOAD FILE=InterfaceContent.utx
defaultproperties
{ WeaponPickupClass=Class'NicePack.NiceHK417Pickup' AmmoPickupAmount=20 MaxAmmo=180 InitialAmount=45 PickupClass=Class'ScrnWeaponPack.HK417AmmoPickup' IconMaterial=Texture'KillingFloorHUD.Generic.HUD' IconCoords=(X1=338,Y1=40,X2=393,Y2=79) ItemName="7.62x51mm NATO"
}

View File

@ -0,0 +1,4 @@
class NiceHK417AmmoPickup extends NiceAmmoPickup;
defaultproperties
{ AmmoAmount=20 InventoryType=Class'NicePack.NiceHK417Ammo' PickupMessage="7.62x51mm NATO"
}

View File

@ -0,0 +1,4 @@
class NiceHK417Attachment extends NiceAttachment;
defaultproperties
{ mMuzFlashClass=Class'ROEffects.MuzzleFlash3rdMP' mTracerClass=Class'KFMod.KFNewTracer' mShellCaseEmitterClass=Class'KFMod.KFShellSpewer' ShellEjectBoneName="Shell_eject" MovementAnims(0)="JogF_SCAR" MovementAnims(1)="JogB_SCAR" MovementAnims(2)="JogL_SCAR" MovementAnims(3)="JogR_SCAR" TurnLeftAnim="TurnL_SCAR" TurnRightAnim="TurnR_SCAR" CrouchAnims(0)="CHWalkF_SCAR" CrouchAnims(1)="CHWalkB_SCAR" CrouchAnims(2)="CHWalkL_SCAR" CrouchAnims(3)="CHWalkR_SCAR" WalkAnims(0)="WalkF_SCAR" WalkAnims(1)="WalkB_SCAR" WalkAnims(2)="WalkL_SCAR" WalkAnims(3)="WalkR_SCAR" CrouchTurnRightAnim="CH_TurnR_SCAR" CrouchTurnLeftAnim="CH_TurnL_SCAR" IdleCrouchAnim="CHIdle_SCAR" IdleWeaponAnim="Idle_SCAR" IdleRestAnim="Idle_SCAR" IdleChatAnim="Idle_SCAR" IdleHeavyAnim="Idle_SCAR" IdleRifleAnim="Idle_SCAR" FireAnims(0)="Fire_SCAR" FireAnims(1)="Fire_SCAR" FireAnims(2)="Fire_SCAR" FireAnims(3)="Fire_SCAR" FireAltAnims(0)="Fire_SCAR" FireAltAnims(1)="Fire_SCAR" FireAltAnims(2)="Fire_SCAR" FireAltAnims(3)="Fire_SCAR" FireCrouchAnims(0)="CHFire_SCAR" FireCrouchAnims(1)="CHFire_SCAR" FireCrouchAnims(2)="CHFire_SCAR" FireCrouchAnims(3)="CHFire_SCAR" FireCrouchAltAnims(0)="CHFire_SCAR" FireCrouchAltAnims(1)="CHFire_SCAR" FireCrouchAltAnims(2)="CHFire_SCAR" FireCrouchAltAnims(3)="CHFire_SCAR" HitAnims(0)="HitF_SCAR" HitAnims(1)="HitB_SCAR" HitAnims(2)="HitL_SCAR" HitAnims(3)="HitR_SCAR" PostFireBlendStandAnim="Blend_SCAR" PostFireBlendCrouchAnim="CHBlend_SCAR" MeshRef="ScrnWeaponPack_A.HK417_3rd" WeaponAmbientScale=2.000000 bRapidFire=True bAltRapidFire=True SplashEffect=Class'ROEffects.BulletSplashEmitter' DrawScale=0.600000
}

View File

@ -0,0 +1,4 @@
class NiceHK417Fire extends NiceFire;
defaultproperties
{ ProjectileSpeed=40850.000000 FireAimedAnim="Iron_Idle" RecoilRate=0.070000 maxVerticalRecoilAngle=500 maxHorizontalRecoilAngle=250 ShellEjectClass=Class'ROEffects.KFShellEjectAK' ShellEjectBoneName="Shell_eject" FireSoundRef="ScrnWeaponPack_SND.HK417AR.HK417_shot" StereoFireSoundRef="ScrnWeaponPack_SND.HK417AR.HK417_shot" NoAmmoSoundRef="ScrnWeaponPack_SND.HK417AR.HK417_empty" DamageType=Class'NicePack.NiceDamTypeHK417AR' DamageMin=75 DamageMax=75 Momentum=20000.000000 bPawnRapidFireAnim=True bWaitForRelease=True TransientSoundVolume=1.800000 FireLoopAnim="Fire" TweenTime=0.025000 FireForce="AssaultRifleFire" FireRate=0.230000 AmmoClass=Class'NicePack.NiceHK417Ammo' ShakeRotMag=(X=50.000000,Y=50.000000,Z=300.000000) ShakeRotRate=(X=9500.000000,Y=9500.000000,Z=9500.000000) ShakeRotTime=0.650000 ShakeOffsetMag=(X=3.000000,Y=3.000000,Z=3.000000) ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000) ShakeOffsetTime=1.250000 BotRefireRate=0.990000 FlashEmitterClass=Class'ROEffects.MuzzleFlash1stSTG' aimerror=60.000000
}

View File

@ -0,0 +1,4 @@
class NiceHK417Pickup extends NiceWeaponPickup;
defaultproperties
{ Weight=6.000000 AmmoCost=40 BuyClipSize=10 PowerValue=60 SpeedValue=30 RangeValue=95 Description="The Heckler & Koch HK417 is a gas-operated, selective fire rifle with a rotating bolt and is essentially an enlarged HK416 assault rifle. Chambered for the full power 7.62x51mm NATO round, instead of a less powerful intermediate cartridge, the HK417 is intended for use as a designated marksman rifle, and in other roles where the greater penetrative power and range of the 7.62x51mm NATO round are required." ItemName="HK-417" ItemShortName="HK-417" AmmoItemName="7.62x51mm NATO" CorrespondingPerkIndex=3 EquipmentCategoryID=2 InventoryType=Class'NicePack.NiceHK417AR' PickupMessage="You've got a HK-417" PickupSound=Sound'ScrnWeaponPack_SND.HK417AR.HK417_pickup' PickupForce="AssaultRiflePickup" StaticMesh=StaticMesh'ScrnWeaponPack_SM.HK417_st' DrawScale=0.800000 CollisionRadius=30.000000 CollisionHeight=5.000000
}

Some files were not shown because too many files have changed in this diff Show More