class NiceSyringeFire extends NiceMeleeFire; var float LastHealAttempt; var float HealAttemptDelay; var float LastHealMessageTime; var float HealMessageDelay; var localized string NoHealTargetMessage; var KFHumanPawn CachedHealee; var transient float PendingHealTime; simulated function DestroyEffects() { super.DestroyEffects(); if (CachedHealee != None) CachedHealee = none; } simulated function bool AllowFire() { local KFHumanPawn Healtarget; local string healeeName; if (!super.AllowFire()) { return false; } if (CanFindHealee()) { if( CachedHealee.PlayerReplicationInfo != none && CachedHealee.PlayerReplicationInfo.PlayerName != "") { HealeeName = CachedHealee.PlayerReplicationInfo.PlayerName; } else { HealeeName = CachedHealee.MenuName; } NiceSyringe(Weapon).ClientSuccessfulHeal(HealeeName); // Give the messages if we missed our heal, can't find a target, etc if ( KFPlayerController(Instigator.Controller) != none ) { if ( LastHealAttempt + HealAttemptDelay < Level.TimeSeconds) { PlayerController(Instigator.controller).ClientMessage(NoHealTargetMessage, 'CriticalEvent'); LastHealAttempt = Level.TimeSeconds; } if ( Level.TimeSeconds - LastHealMessageTime > HealMessageDelay ) { // if there's a Player within 2 meters who needs healing, say that we're trying to heal them foreach Instigator.VisibleCollidingActors(class'KFHumanPawn', Healtarget, 100) { if ( Healtarget != Instigator && Healtarget.Health < Healtarget.HealthMax ) { PlayerController(Instigator.Controller).Speech('AUTO', 5, ""); LastHealMessageTime = Level.TimeSeconds; break; } } } } return true; } return false; } function Timer() { local KFPlayerReplicationInfo PRI; local int MedicReward; local KFHumanPawn Healed; local float HealSum, HealPotency; // for modifying based on perks PRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo); Healed = CachedHealee; HealPotency = 1.0; CachedHealee = none; if ( Healed != none && Healed.Health > 0 && Healed != Instigator ) { Load = 1; ReduceAmmoClient(); if ( PRI != none && PRI.ClientVeteranSkill != none ) HealPotency = PRI.ClientVeteranSkill.Static.GetHealPotency(PRI); HealSum = NiceSyringe(Weapon).HealBoostAmount; HealSum *= HealPotency; MedicReward = HealSum; if ( (Healed.Health + Healed.healthToGive + MedicReward) > Healed.HealthMax ) { MedicReward = Healed.HealthMax - (Healed.Health + Healed.healthToGive); if ( MedicReward < 0 ) { MedicReward = 0; } } if ( NiceHumanPawn(Healed) != none ) NiceHumanPawn(Healed).TakeHealing(NiceHumanPawn(Instigator), HealSum, HealPotency, KFWeapon(Instigator.Weapon)); else Healed.GiveHealth(HealSum, Healed.HealthMax); // Tell them we're healing them PlayerController(Instigator.Controller).Speech('AUTO', 5, ""); LastHealMessageTime = Level.TimeSeconds; if ( PRI != None ) { if ( MedicReward > 0 && KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements) != none ) { KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements).AddDamageHealed(MedicReward); } // Give the medic reward money as a percentage of how much of the person's health they healed MedicReward = int((FMin(float(MedicReward),Healed.HealthMax)/Healed.HealthMax) * 60); // Increased to 80 in Balance Round 6, reduced to 60 in Round 7 if ( class'ScrnBalance'.default.Mut.bMedicRewardFromTeam && Healed.PlayerReplicationInfo != none && Healed.PlayerReplicationInfo.Team != none ) { // give money from team wallet if ( Healed.PlayerReplicationInfo.Team.Score >= MedicReward ) { Healed.PlayerReplicationInfo.Team.Score -= MedicReward; PRI.Score += MedicReward; } } else PRI.Score += MedicReward; if ( KFHumanPawn(Instigator) != none ) { KFHumanPawn(Instigator).AlphaAmount = 255; } } } } function KFHumanPawn GetHealee() { local KFHumanPawn KFHP, BestKFHP; local vector Dir; local float TempDot, BestDot; Dir = vector(Instigator.GetViewRotation()); foreach Instigator.VisibleCollidingActors(class'KFHumanPawn', KFHP, 80.0) { if ( KFHP.Health < KFHP.HealthMax && KFHP.Health > 0 ) { TempDot = Dir dot (KFHP.Location - Instigator.Location); if ( TempDot > 0.7 && TempDot > BestDot ) { BestKFHP = KFHP; BestDot = TempDot; } } } return BestKFHP; } // Can we find someone to heal function bool CanFindHealee() { local KFHumanPawn Healtarget; Healtarget = GetHealee(); CachedHealee = Healtarget; // Can't use syringe if we can't find a target if ( Healtarget == none ) { if ( KFPlayerController(Instigator.Controller) != none ) { KFPlayerController(Instigator.Controller).CheckForHint(53); } return false; } // Can't use syringe if our target is already being healed to full health. if ( (Healtarget.Health == Healtarget.Healthmax) || ((Healtarget.healthToGive + Healtarget.Health) >= Healtarget.Healthmax) ) { return false; } return true; } function float GetFireSpeed() { if ( KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo) != none && KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill != none ) { return KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill.Static.GetFireSpeedMod(KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo), Weapon); } return 1; } defaultproperties { AmmoClass=class'NiceSyringeAmmo' ammoPerFire=1 FireAnims(0)="Fire" FireRate=2.800000 damageDelay=0.36 HealAttemptDelay=0.5 HealMessageDelay=10.0 NoHealTargetMessage="You must be near another player to heal them!" bWaitForRelease=true }