360 lines
12 KiB
Ucode
360 lines
12 KiB
Ucode
class ScrnChainsaw extends Chainsaw;
|
|
|
|
var float IdleFuelConsumeTime; // time between fuel consumption on idle
|
|
|
|
var sound EngineStartSound, EngineStopSound;
|
|
var string EngineStartSoundRef, EngineStopSoundRef;
|
|
|
|
struct SoundList {
|
|
var string SoundRef;
|
|
var sound Sound;
|
|
var float Duration;
|
|
};
|
|
var array<SoundList> ReloadSounds;
|
|
var float TotalReloadSoundDuration; // total duration of all reload sounds
|
|
var transient float TimeToNextReloadSound;
|
|
var transient int NextReloadSoundIndex;
|
|
var transient bool bBlownUpThisReload;
|
|
|
|
var transient int OldMagAmmoRemaining;
|
|
var ScrnFakedProjectile FakedGasCan; //adds a faked gas can during reload
|
|
|
|
replication
|
|
{
|
|
reliable if(Role == ROLE_Authority)
|
|
HideGasCan;
|
|
}
|
|
|
|
simulated function PostNetReceive()
|
|
{
|
|
super.PostNetReceive();
|
|
|
|
if ( Role < ROLE_Authority ) {
|
|
if ( OldMagAmmoRemaining != MagAmmoRemaining ) {
|
|
if ( MagAmmoRemaining == 0 ) {
|
|
if ( ThirdPersonActor != none )
|
|
ThirdPersonActor.AmbientSound = none;
|
|
TexPanner(Skins[1]).PanRate = 0; // stop saw cycling
|
|
PlaySound(EngineStopSound);
|
|
}
|
|
else if ( OldMagAmmoRemaining < MagAmmoRemaining && MagAmmoRemaining > 0 ) {
|
|
//just reloaded
|
|
if ( IsInState('Reloading') )
|
|
GotoState('');
|
|
if ( ThirdPersonActor != none )
|
|
ThirdPersonActor.AmbientSound = ThirdPersonActor.default.AmbientSound;
|
|
TexPanner(Skins[1]).PanRate = 3; // start saw cycling
|
|
PlaySound(EngineStartSound);
|
|
if ( !IsAnimating() )
|
|
PlayIdle();
|
|
}
|
|
OldMagAmmoRemaining = MagAmmoRemaining;
|
|
}
|
|
}
|
|
}
|
|
|
|
static function PreloadAssets(Inventory Inv, optional bool bSkipRefCount)
|
|
{
|
|
local int i;
|
|
local ScrnChainsaw W;
|
|
|
|
super.PreloadAssets(Inv, bSkipRefCount);
|
|
|
|
W = ScrnChainsaw(Inv);
|
|
|
|
default.EngineStartSound = sound(DynamicLoadObject(default.EngineStartSoundRef, class'sound'));
|
|
default.EngineStopSound = sound(DynamicLoadObject(default.EngineStopSoundRef, class'sound'));
|
|
|
|
for ( i = 0; i < default.ReloadSounds.Length; ++i ) {
|
|
default.ReloadSounds[i].Sound = sound(DynamicLoadObject(default.ReloadSounds[i].SoundRef, class'sound'));
|
|
if ( W != none ) {
|
|
W.ReloadSounds[i].Sound = default.ReloadSounds[i].Sound;
|
|
}
|
|
}
|
|
|
|
if ( W != none ) {
|
|
W.EngineStartSound = default.EngineStartSound;
|
|
W.EngineStopSound = default.EngineStopSound;
|
|
|
|
W.CalcReloadSoundDuration();
|
|
default.TotalReloadSoundDuration = W.TotalReloadSoundDuration;
|
|
}
|
|
}
|
|
static function bool UnloadAssets()
|
|
{
|
|
local int i;
|
|
|
|
default.EngineStartSound = none;
|
|
default.EngineStopSound = none;
|
|
|
|
default.TotalReloadSoundDuration = 0;
|
|
for ( i = 0; i < default.ReloadSounds.Length; ++i ) {
|
|
default.ReloadSounds[i].Sound = none;
|
|
}
|
|
|
|
return super.UnloadAssets();
|
|
}
|
|
|
|
|
|
simulated function PostBeginPlay()
|
|
{
|
|
super.PostBeginPlay();
|
|
AttachGasCan();
|
|
|
|
CalcReloadSoundDuration();
|
|
}
|
|
|
|
simulated function AttachGasCan() {
|
|
if ( Level.NetMode != NM_DedicatedServer )
|
|
{
|
|
if ( FakedGasCan == none ) //only spawn FakedGasCan once
|
|
FakedGasCan = spawn(class'ScrnFakedGasCan',self);
|
|
if ( FakedGasCan != none )
|
|
{
|
|
AttachToBone(FakedGasCan, 'Chainsaw'); //attach faked shell to chainsaw
|
|
FakedGasCan.SetDrawScale(0.01);
|
|
FakedGasCan.SetRelativeLocation(vect(-3, 2, 3)); //x y z
|
|
FakedGasCan.SetRelativeRotation(rot(-4000, 38000, 12000)); //pitch yaw roll
|
|
}
|
|
}
|
|
}
|
|
|
|
simulated function CalcReloadSoundDuration()
|
|
{
|
|
local int i;
|
|
|
|
TotalReloadSoundDuration = 0;
|
|
for ( i = 0; i < default.ReloadSounds.Length; ++i ) {
|
|
ReloadSounds[i].Duration = GetSoundDuration(ReloadSounds[i].Sound);
|
|
TotalReloadSoundDuration += ReloadSounds[i].Duration;
|
|
}
|
|
}
|
|
|
|
simulated function bool ConsumeAmmo( int Mode, float Load, optional bool bAmountNeededIsMax )
|
|
{
|
|
local Inventory Inv;
|
|
local bool bOutOfAmmo;
|
|
local KFWeapon KFWeap;
|
|
|
|
if ( Super(Weapon).ConsumeAmmo(Mode, Load, bAmountNeededIsMax) )
|
|
{
|
|
if ( Load > 0 && (Mode == 0 || bReduceMagAmmoOnSecondaryFire) ) {
|
|
MagAmmoRemaining -= Load; // Changed from "MagAmmoRemaining--" -- PooSH
|
|
if ( MagAmmoRemaining < 0 )
|
|
MagAmmoRemaining = 0;
|
|
if ( MagAmmoRemaining == 0 ) {
|
|
ThirdPersonActor.AmbientSound = none;
|
|
TexPanner(Skins[1]).PanRate = 0; // stop saw cycling
|
|
PlaySound(EngineStopSound);
|
|
}
|
|
}
|
|
OldMagAmmoRemaining = MagAmmoRemaining;
|
|
|
|
NetUpdateTime = Level.TimeSeconds - 1;
|
|
|
|
if ( FireMode[Mode].AmmoPerFire > 0 && InventoryGroup > 0 && !bMeleeWeapon && bConsumesPhysicalAmmo &&
|
|
(Ammo[0] == none || FireMode[0] == none || FireMode[0].AmmoPerFire <= 0 || Ammo[0].AmmoAmount < FireMode[0].AmmoPerFire) &&
|
|
(Ammo[1] == none || FireMode[1] == none || FireMode[1].AmmoPerFire <= 0 || Ammo[1].AmmoAmount < FireMode[1].AmmoPerFire) )
|
|
{
|
|
bOutOfAmmo = true;
|
|
|
|
for ( Inv = Instigator.Inventory; Inv != none; Inv = Inv.Inventory )
|
|
{
|
|
KFWeap = KFWeapon(Inv);
|
|
|
|
if ( Inv.InventoryGroup > 0 && KFWeap != none && !KFWeap.bMeleeWeapon && KFWeap.bConsumesPhysicalAmmo &&
|
|
((KFWeap.Ammo[0] != none && KFWeap.FireMode[0] != none && KFWeap.FireMode[0].AmmoPerFire > 0 &&KFWeap.Ammo[0].AmmoAmount >= KFWeap.FireMode[0].AmmoPerFire) ||
|
|
(KFWeap.Ammo[1] != none && KFWeap.FireMode[1] != none && KFWeap.FireMode[1].AmmoPerFire > 0 && KFWeap.Ammo[1].AmmoAmount >= KFWeap.FireMode[1].AmmoPerFire)) )
|
|
{
|
|
bOutOfAmmo = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( bOutOfAmmo )
|
|
{
|
|
PlayerController(Instigator.Controller).Speech('AUTO', 3, "");
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
simulated function ClientReload()
|
|
{
|
|
super.ClientReload();
|
|
if (FakedGasCan != none)
|
|
FakedGasCan.SetDrawScale(2); //test
|
|
// if MagAmmoRemaining == 0, chaisaw is already stopped
|
|
if ( MagAmmoRemaining > 0 )
|
|
PlaySound(EngineStopSound);
|
|
ThirdPersonActor.AmbientSound = none;
|
|
|
|
GotoState('Reloading');
|
|
}
|
|
|
|
|
|
simulated function ActuallyFinishReloading()
|
|
{
|
|
super.ActuallyFinishReloading();
|
|
|
|
IdleFuelConsumeTime = default.IdleFuelConsumeTime;
|
|
GotoState('');
|
|
if ( MagAmmoRemaining > 0) {
|
|
PlaySound(EngineStartSound);
|
|
ThirdPersonActor.AmbientSound = ThirdPersonActor.default.AmbientSound;
|
|
TexPanner(Skins[1]).PanRate = 3; // start saw cycling
|
|
PlayIdle();
|
|
}
|
|
}
|
|
|
|
simulated function ClientFinishReloading()
|
|
{
|
|
super.ClientFinishReloading();
|
|
if ( Level.NetMode != NM_DedicatedServer )
|
|
{
|
|
if (FakedGasCan != none)
|
|
FakedGasCan.SetDrawScale(0.01); //hide gas can after reload
|
|
}
|
|
}
|
|
|
|
simulated function WeaponTick(float dt)
|
|
{
|
|
super.WeaponTick(dt);
|
|
|
|
if ( Role == Role_Authority ) {
|
|
if ( !bIsReloading ) {
|
|
if ( MagAmmoRemaining <= 0) {
|
|
ThirdPersonActor.AmbientSound = none;
|
|
TexPanner(Skins[1]).PanRate = 0; // stop saw cycling
|
|
}
|
|
else {
|
|
if ( Level.TimeSeconds - FireMode[0].NextFireTime > 1.0 && Level.TimeSeconds - FireMode[1].NextFireTime > 1.0 ) {
|
|
//consume ammo on idle
|
|
IdleFuelConsumeTime -= dt;
|
|
if ( IdleFuelConsumeTime <= 0 ) {
|
|
ConsumeAmmo(0, 1);
|
|
IdleFuelConsumeTime = default.IdleFuelConsumeTime;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// there is no reload animation for Chainsaw, so play slow put down animation
|
|
// taking sounds from flamethrower reload
|
|
simulated state Reloading
|
|
{
|
|
simulated function BeginState()
|
|
{
|
|
NextReloadSoundIndex = 0;
|
|
TimeToNextReloadSound = ReloadRate * 0.2;
|
|
bBlownUpThisReload = false;
|
|
}
|
|
|
|
simulated function WeaponTick(float dt)
|
|
{
|
|
super.WeaponTick(dt);
|
|
|
|
if ( NextReloadSoundIndex < ReloadSounds.length ) {
|
|
// if ( NextReloadSoundIndex < ReloadSounds.length - 2 )
|
|
// ThirdPersonActor.AmbientSound = none;
|
|
TimeToNextReloadSound -= dt;
|
|
if ( TimeToNextReloadSound <= 0 ) {
|
|
PlaySound(ReloadSounds[NextReloadSoundIndex].Sound);
|
|
TimeToNextReloadSound += 0.8*ReloadRate * ReloadSounds[NextReloadSoundIndex].Duration/TotalReloadSoundDuration;
|
|
NextReloadSoundIndex++;
|
|
}
|
|
}
|
|
}
|
|
|
|
function TakeDamage(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional int HitIndex)
|
|
{
|
|
local ScrnFlameNade nade;
|
|
local int FuelInTank;
|
|
|
|
//blow the fuel inside a tank on fire damage received (excluding DoT)
|
|
if ( bBlownUpThisReload || DamageType == none || Damage < 5 || DamageType == class'DamTypeFlamethrower' )
|
|
return;
|
|
|
|
if ( Level.TimeSeconds > ReloadTimer + ReloadRate*0.9 ) //almost finished reloading, don't blow up
|
|
return;
|
|
|
|
if ( DamageType.default.bFlaming || (class<KFWeaponDamageType>(DamageType) != none && class<KFWeaponDamageType>(DamageType).default.bDealBurningDamage) ) {
|
|
bBlownUpThisReload = true;
|
|
FuelInTank = MagAmmoRemaining + (MagCapacity - MagAmmoRemaining) * (Level.TimeSeconds - ReloadTimer) / ReloadRate;
|
|
if ( FuelInTank > AmmoAmount(0) )
|
|
FuelInTank = AmmoAmount(0);
|
|
if ( FuelInTank < 1 )
|
|
return;
|
|
nade = spawn(class'ScrnBalanceSrv.ScrnFlameNade');
|
|
HideGasCan();
|
|
AttachToBone(nade, 'Chainsaw'); //attempt to move explosion onto chainsaw to make it obvious that the gas can caused the explosion
|
|
nade.SetRelativeLocation(vect(-3, 2, 3)); //move nade to exact gas can location
|
|
nade.SetTimer(0, false); // it will be blown up manualy
|
|
nade.Instigator = Instigator;
|
|
// the more fuel in tank, the higher is explosion
|
|
nade.Damage = FuelInTank;
|
|
AddAmmo(-FuelInTank, 0);
|
|
nade.Explode(Location, vect(0,0,1));
|
|
}
|
|
}
|
|
}
|
|
|
|
simulated function HideGasCan()
|
|
{
|
|
if ( Level.NetMode != NM_DedicatedServer )
|
|
{
|
|
FakedGasCan.SetDrawScale(0.01); //hide gas can after reload
|
|
}
|
|
}
|
|
|
|
//destroy gas can on destroy
|
|
simulated function Destroyed()
|
|
{
|
|
if ( FakedGasCan != none && !FakedGasCan.bDeleteMe )
|
|
FakedGasCan.Destroy();
|
|
|
|
super.Destroyed();
|
|
}
|
|
|
|
simulated function PlayIdle()
|
|
{
|
|
if ( MagAmmoRemaining > 0 )
|
|
super.PlayIdle();
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
IdleFuelConsumeTime=5.000000
|
|
EngineStartSoundRef="KF_ChainsawSnd.Chainsaw_FalseStart4"
|
|
EngineStopSoundRef="KF_ChainsawSnd.Chainsaw_Deselect1"
|
|
ReloadSounds(0)=(SoundRef="KF_FlamethrowerSnd.FT_Reload1")
|
|
ReloadSounds(1)=(SoundRef="KF_FlamethrowerSnd.FT_Reload2")
|
|
ReloadSounds(2)=(SoundRef="KF_FlamethrowerSnd.FT_Reload3")
|
|
ReloadSounds(3)=(SoundRef="KF_FlamethrowerSnd.FT_Reload4")
|
|
ReloadSounds(4)=(SoundRef="KF_FlamethrowerSnd.FT_Reload5")
|
|
ReloadSounds(5)=(SoundRef="KF_FlamethrowerSnd.FT_Reload5b")
|
|
ReloadSounds(6)=(SoundRef="KF_FlamethrowerSnd.FT_Reload6")
|
|
ReloadSounds(7)=(SoundRef="KF_ChainsawSnd.Chainsaw_FalseStart1")
|
|
ReloadSounds(8)=(SoundRef="KF_ChainsawSnd.Chainsaw_FalseStart2")
|
|
MagCapacity=105
|
|
ReloadRate=2.666667
|
|
ReloadAnim="PutDown"
|
|
ReloadAnimRate=0.250000
|
|
WeaponReloadAnim="Reload_Flamethrower"
|
|
bAmmoHUDAsBar=True
|
|
FireModeClass(0)=Class'ScrnBalanceSrv.ScrnChainsawFire'
|
|
FireModeClass(1)=Class'ScrnBalanceSrv.ScrnChainsawAltFire'
|
|
bMeleeWeapon=False
|
|
bShowChargingBar=True
|
|
Description="This legendary chainsaw is used through the centuries to fight evil forces"
|
|
PickupClass=Class'ScrnBalanceSrv.ScrnChainsawPickup'
|
|
ItemName="Ash's Chainsaw"
|
|
}
|