484 lines
18 KiB
Ucode
484 lines
18 KiB
Ucode
class NiceDualies extends NiceWeapon;
|
|
var bool startedWithFullPistol;
|
|
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;
|
|
}
|
|
exec simulated function ClientReloadMeNow(){
|
|
startedWithFullPistol = false;
|
|
if ( MagAmmoRemLeftClient >= GetSingleMagCapacity()
|
|
|| MagAmmoRemRightClient >= GetSingleMagCapacity()) {
|
|
startedWithFullPistol = true;
|
|
}
|
|
super.ClientReloadMeNow();
|
|
}
|
|
simulated function float GetCurrentReloadMult(){
|
|
local float normalMultiplier;
|
|
normalMultiplier = super.GetCurrentReloadMult();
|
|
if (startedWithFullPistol) {
|
|
return normalMultiplier * 2;
|
|
}
|
|
return normalMultiplier;
|
|
}
|
|
// 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'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'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'NiceDualiesPickup'
|
|
PlayerViewOffset=(X=20.000000,Z=-7.000000)
|
|
BobDamping=7.000000
|
|
AttachmentClass=class'NiceDualiesAttachment'
|
|
IconCoords=(X1=229,Y1=258,X2=296,Y2=307)
|
|
ItemName="!!!Dual something"
|
|
DrawScale=0.900000
|
|
TransientSoundVolume=1.000000
|
|
}
|