219 lines
5.7 KiB
Ucode
219 lines
5.7 KiB
Ucode
class SyringeFire extends SyringeAltFire;
|
|
|
|
var float LastHealAttempt;
|
|
var float HealAttemptDelay;
|
|
var float LastHealMessageTime;
|
|
var float HealMessageDelay;
|
|
var localized string NoHealTargetMessage;
|
|
var KFHumanPawn CachedHealee;
|
|
|
|
simulated function DestroyEffects()
|
|
{
|
|
super.DestroyEffects();
|
|
|
|
if (CachedHealee != None)
|
|
CachedHealee = none;
|
|
}
|
|
|
|
function AttemptHeal()
|
|
{
|
|
local KFHumanPawn Healtarget;
|
|
local string HealeeName;
|
|
|
|
CachedHealee = none;
|
|
|
|
if( AllowFire() && CanFindHealee() )
|
|
{
|
|
super.ModeDoFire();
|
|
|
|
if(CachedHealee.PlayerReplicationInfo != none &&
|
|
CachedHealee.PlayerReplicationInfo.PlayerName != "")
|
|
{
|
|
HealeeName = CachedHealee.PlayerReplicationInfo.PlayerName;
|
|
}
|
|
else /* We're healing someone without a PRI. Grab the menu name of their pawn */
|
|
{
|
|
HealeeName = CachedHealee.MenuName;
|
|
}
|
|
|
|
Syringe(Weapon).ClientSuccessfulHeal(HealeeName);
|
|
}
|
|
else
|
|
{
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// do the animations, etc
|
|
simulated function SuccessfulHeal()
|
|
{
|
|
if( Weapon.Role < Role_Authority )
|
|
{
|
|
super.ModeDoFire();
|
|
}
|
|
}
|
|
|
|
Function Timer()
|
|
{
|
|
local KFPlayerReplicationInfo PRI;
|
|
local int MedicReward;
|
|
local KFHumanPawn Healed;
|
|
local float HealSum; // for modifying based on perks
|
|
|
|
Healed = CachedHealee;
|
|
CachedHealee = none;
|
|
|
|
if ( Healed != none && Healed.Health > 0 && Healed != Instigator )
|
|
{
|
|
Weapon.ConsumeAmmo(ThisModeNum, AmmoPerFire);
|
|
|
|
MedicReward = Syringe(Weapon).HealBoostAmount;
|
|
|
|
if ( KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo) != none && KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill != none )
|
|
{
|
|
MedicReward *= KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill.Static.GetHealPotency(KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo));
|
|
}
|
|
|
|
HealSum = MedicReward;
|
|
|
|
if ( (Healed.Health + Healed.healthToGive + MedicReward) > Healed.HealthMax )
|
|
{
|
|
MedicReward = Healed.HealthMax - (Healed.Health + Healed.healthToGive);
|
|
if ( MedicReward < 0 )
|
|
{
|
|
MedicReward = 0;
|
|
}
|
|
}
|
|
|
|
Healed.GiveHealth(HealSum, Healed.HealthMax);
|
|
|
|
// Tell them we're healing them
|
|
PlayerController(Instigator.Controller).Speech('AUTO', 5, "");
|
|
LastHealMessageTime = Level.TimeSeconds;
|
|
|
|
PRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
|
|
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
|
|
|
|
PRI.ReceiveRewardForHealing( MedicReward, Healed );
|
|
|
|
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.bCanBeHealed )
|
|
continue;
|
|
|
|
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;
|
|
}
|
|
|
|
function bool AllowFire()
|
|
{
|
|
return Weapon.AmmoAmount(ThisModeNum) >= AmmoPerFire;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
event ModeDoFire()
|
|
{
|
|
// Try and heal on the server
|
|
if( Weapon.Instigator.IsLocallyControlled() )
|
|
{
|
|
Syringe(Weapon).ServerAttemptHeal();
|
|
}
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
FireAnim=Fire
|
|
FireRate=2.800000
|
|
AmmoPerFire=250
|
|
InjectDelay=0.36//0.4
|
|
|
|
HealAttemptDelay=0.5
|
|
HealMessageDelay=10.0
|
|
NoHealTargetMessage="You must be near another player to heal them!"
|
|
bWaitForRelease=true
|
|
}
|