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:
parent
3c46801714
commit
12d95e387e
757 changed files with 10788 additions and 4046 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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."
|
||||
}
|
||||
6
sources/Weapons/BaseWeaponClasses/Heavy/NiceHeavyFire.uc
Normal file
6
sources/Weapons/BaseWeaponClasses/Heavy/NiceHeavyFire.uc
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
class NiceHeavyFire extends NiceFire;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
maxBonusContLenght=3
|
||||
}
|
||||
5
sources/Weapons/BaseWeaponClasses/Heavy/NiceHeavyGun.uc
Normal file
5
sources/Weapons/BaseWeaponClasses/Heavy/NiceHeavyGun.uc
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class NiceHeavyGun extends NiceWeapon;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
57
sources/Weapons/BaseWeaponClasses/Medic/NiceMedicDartFire.uc
Normal file
57
sources/Weapons/BaseWeaponClasses/Medic/NiceMedicDartFire.uc
Normal 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
|
||||
}
|
||||
91
sources/Weapons/BaseWeaponClasses/Medic/NiceMedicGun.uc
Normal file
91
sources/Weapons/BaseWeaponClasses/Medic/NiceMedicGun.uc
Normal 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
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
class NiceMeleeAttachment extends NiceAttachment;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bDoFiringEffects=False
|
||||
}
|
||||
290
sources/Weapons/BaseWeaponClasses/Melee/NiceMeleeFire.uc
Normal file
290
sources/Weapons/BaseWeaponClasses/Melee/NiceMeleeFire.uc
Normal 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
|
||||
}
|
||||
42
sources/Weapons/BaseWeaponClasses/Melee/NiceMeleeWeapon.uc
Normal file
42
sources/Weapons/BaseWeaponClasses/Melee/NiceMeleeWeapon.uc
Normal 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
|
||||
}
|
||||
123
sources/Weapons/BaseWeaponClasses/NiceHighROFFire.uc
Normal file
123
sources/Weapons/BaseWeaponClasses/NiceHighROFFire.uc
Normal 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
|
||||
}
|
||||
441
sources/Weapons/BaseWeaponClasses/NiceScopedWeapon.uc
Normal file
441
sources/Weapons/BaseWeaponClasses/NiceScopedWeapon.uc
Normal 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
|
||||
}
|
||||
466
sources/Weapons/BaseWeaponClasses/Pistols/NiceDualies.uc
Normal file
466
sources/Weapons/BaseWeaponClasses/Pistols/NiceDualies.uc
Normal 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
|
||||
}
|
||||
13
sources/Weapons/BaseWeaponClasses/Pistols/NiceDualiesAmmo.uc
Normal file
13
sources/Weapons/BaseWeaponClasses/Pistols/NiceDualiesAmmo.uc
Normal 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"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
class NiceDualiesAmmoPickup extends NiceAmmoPickup;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
AmmoAmount=30
|
||||
InventoryType=Class'NicePack.NiceDualiesAmmo'
|
||||
PickupMessage="Rounds (9mm)"
|
||||
StaticMesh=StaticMesh'KillingFloorStatics.DualiesAmmo'
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
247
sources/Weapons/BaseWeaponClasses/Pistols/NiceDualiesFire.uc
Normal file
247
sources/Weapons/BaseWeaponClasses/Pistols/NiceDualiesFire.uc
Normal 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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
215
sources/Weapons/BaseWeaponClasses/Pistols/NiceSingle.uc
Normal file
215
sources/Weapons/BaseWeaponClasses/Pistols/NiceSingle.uc
Normal 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"
|
||||
}
|
||||
13
sources/Weapons/BaseWeaponClasses/Pistols/NiceSingleAmmo.uc
Normal file
13
sources/Weapons/BaseWeaponClasses/Pistols/NiceSingleAmmo.uc
Normal 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"
|
||||
}
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
46
sources/Weapons/BaseWeaponClasses/Pistols/NiceSingleFire.uc
Normal file
46
sources/Weapons/BaseWeaponClasses/Pistols/NiceSingleFire.uc
Normal 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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue