Class Ext_PerkRhythmPerkBase extends Ext_PerkBase; var byte HeadShotComboCount,MaxRhythmCombo,MissComboCount; var float RhythmComboDmg; var private const float HeadShotCountdownIntervall; simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCauser, optional KFPawn_Monster MyKFPM, optional KFPlayerController DamageInstigator, optional class DamageType, optional int HitZoneIdx ) { Super.ModifyDamageGiven(InDamage,DamageCauser,MyKFPM,DamageInstigator,DamageType,HitZoneIdx); if( RhythmComboDmg>0 && BasePerk==None || (DamageType!=None && DamageType.Default.ModifierPerkList.Find(BasePerk)>=0) || IsWeaponOnPerk(KFWeapon(DamageCauser)) ) InDamage *= (1.f+RhythmComboDmg); } final function SetMaxRhythm( byte MaxCombo ) { MaxRhythmCombo = MaxCombo; } final function ResetRhythm() { MaxRhythmCombo = 0; HeadShotComboCount = 0; RhythmComboDmg = 0; MissComboCount = 0; HeadShotMessage(0,true,1); } function SubstractHeadShotCombo() { if( HeadShotComboCount > 0 ) { --HeadShotComboCount; HeadShotMessage( HeadShotComboCount, true, MaxRhythmCombo ); } else if( HeadShotComboCount <= 0 ) { ClearTimer( nameOf( SubstractHeadShotCombo ) ); } } final function UpdateDmgScale( bool bUp ) { if( bUp ) { MissComboCount = 0; if (HeadShotComboCount < MaxRhythmCombo) HeadShotComboCount = Min(HeadShotComboCount+1,255); HeadShotMessage(HeadShotComboCount,false,MaxRhythmCombo); SetTimer( HeadShotCountdownIntervall, true, nameOf( SubstractHeadShotCombo ) ); } else if( HeadShotComboCount>0 && ++MissComboCount==3 ) { --HeadShotComboCount; HeadShotMessage(HeadShotComboCount,true,MaxRhythmCombo); MissComboCount = 0; } else return; RhythmComboDmg = FMin(HeadShotComboCount,MaxRhythmCombo)*0.075; } function UpdatePerkHeadShots( ImpactInfo Impact, class DamageType, int NumHit ) { local int HitZoneIdx; local KFPawn_Monster KFPM; // `log("RACKEMUP" @ GetScriptTrace()); if( MaxRhythmCombo<=0 ) return; KFPM = KFPawn_Monster(Impact.HitActor); if( KFPM==none || KFPM.GetTeamNum()==0 ) { if( NumHit < 1 && HeadShotComboCount>0 ) UpdateDmgScale(false); return; } HitZoneIdx = KFPM.HitZones.Find('ZoneName', Impact.HitInfo.BoneName); if( HitZoneIdx == HZI_Head && KFPM.IsAliveAndWell() ) { if( class(DamageType)!=None && (class(DamageType).Default.ModifierPerkList.Find(BasePerk)>=0 || DamageType == class'ExtDT_Ballistic_9mm' || DamageType == class'ExtDT_Ballistic_Pistol_Medic' || DamageType == class'KFDT_Ballistic_9mm' || DamageType == class'KFDT_Ballistic_Pistol_Medic')) UpdateDmgScale(true); else if( HeadShotComboCount>0 ) UpdateDmgScale(false); } else if( NumHit < 1 && HeadShotComboCount>0 ) UpdateDmgScale(false); } reliable client function HeadShotMessage( byte HeadShotNum, bool bMissed, byte MaxHits ) { local AkEvent TempAkEvent; local KFPlayerController PC; PC = KFPlayerController(PlayerOwner); if( PC==none || PC.MyGFxHUD==none ) { return; } PC.MyGFxHUD.RhythmCounterWidget.SetInt("count", HeadShotNum); PC.MyGFxHUD.RhythmCounterWidget.SetBonusPercentage(float(HeadShotNum) / float(MaxHits)); if( HeadshotNum==0 ) TempAkEvent = AkEvent'WW_UI_PlayerCharacter.Play_R_Method_Reset'; else if( HeadShotNum