class NiceRules extends GameRules; var ScrnGameRules ScrnRules; function PostBeginPlay(){ if(Level.Game.GameRulesModifiers == none) Level.Game.GameRulesModifiers = Self; else{ // We need to be the ones giving achievements first Self.AddGameRules(Level.Game.GameRulesModifiers); Level.Game.GameRulesModifiers = Self; } if(NicePack(Owner) != none) ScrnRules = NicePack(Owner).ScrnMut.GameRules; else{ Log("Wrong owner! Owner must be NicePack!"); Destroy(); } } function bool CheckEndGame(PlayerReplicationInfo Winner, string Reason){ local bool bWin; local string MapName; if(Level.Game.IsInState('PendingMatch')) return false; if(Level.Game.bGameEnded) return true; if(NextGameRules != none && !NextGameRules.CheckEndGame(Winner,Reason)) return false; if(ScrnRules.Mut.bStoryMode) bWin = Reason ~= "WinAction"; else{ bWin = KFGameReplicationInfo(Level.GRI) != none && KFGameReplicationInfo(Level.GRI).EndGameType == 2; } if(bWin){ // Map achievements MapName = ScrnRules.Mut.KF.GetCurrentMapName(Level); ScrnRules.CheckMapAlias(MapName); GiveMapAchievements(MapName); } return true; } // We would never get ScrN Sui and Hoe achievs with our new zeds, so let's add them ourselves. For different reasons. function GiveMapAchievements(optional String MapName){ local bool bCustomMap, bGiveHardAch, bGiveSuiAch, bGiveHoeAch, bNewAch; local ScrnPlayerInfo SPI; local ClientPerkRepLink PerkLink; local TeamInfo WinnerTeam; WinnerTeam = TeamInfo(Level.Game.GameReplicationInfo.Winner); if(ScrnRules.Mut.bStoryMode){ bGiveHardAch = Level.Game.GameDifficulty >= 4; bGiveSuiAch = Level.Game.GameDifficulty >= 5; bGiveHoeAch = Level.Game.GameDifficulty >= 7; } else{ bGiveHardAch = ScrnRules.HardcoreLevel >= 5; bGiveSuiAch = ScrnRules.HardcoreLevel >= 10; bGiveHoeAch = ScrnRules.HardcoreLevel >= 15; } for (SPI = ScrnRules.PlayerInfo;SPI != none;SPI = SPI.NextPlayerInfo){ if (SPI.PlayerOwner == none || SPI.PlayerOwner.PlayerReplicationInfo == none) continue; PerkLink = SPI.GetRep(); if(PerkLink == none) continue; if(WinnerTeam != none && SPI.PlayerOwner.PlayerReplicationInfo.Team != WinnerTeam) continue; // no candies for loosers // additional achievements that are granted only when surviving the game if(ScrnPlayerController(SPI.PlayerOwner) != none && !ScrnPlayerController(SPI.PlayerOwner).bChangedPerkDuringGame) SPI.ProgressAchievement('PerkFavorite', 1); //unlock "Normal" achievement and see if the map is found bCustomMap = ScrnRules.MapAchClass.static.UnlockMapAchievement(PerkLink, MapName, 0) == -2; bNewAch = false; if(bCustomMap){ //map not found - progress custom map achievements if(bGiveHardAch) ScrnRules.AchClass.static.ProgressAchievementByID(PerkLink, 'WinCustomMapsHard', 1); if(bGiveSuiAch) ScrnRules.AchClass.static.ProgressAchievementByID(PerkLink, 'WinCustomMapsSui', 1); if(bGiveHoeAch) ScrnRules.AchClass.static.ProgressAchievementByID(PerkLink, 'WinCustomMapsHoE', 1); ScrnRules.AchClass.static.ProgressAchievementByID(PerkLink, 'WinCustomMapsNormal', 1); ScrnRules.AchClass.static.ProgressAchievementByID(PerkLink, 'WinCustomMaps', 1); } else{ //map found - give related achievements if(bGiveHardAch) ScrnRules.MapAchClass.static.UnlockMapAchievement(PerkLink, MapName, 1); if(bGiveSuiAch) ScrnRules.MapAchClass.static.UnlockMapAchievement(PerkLink, MapName, 2); if(bGiveHoeAch) ScrnRules.MapAchClass.static.UnlockMapAchievement(PerkLink, MapName, 3); } } } function int NetDamage(int OriginalDamage, int Damage, pawn injured, pawn instigatedBy, vector HitLocation, out vector Momentum, class DamageType){ local TeamGame TG; TG = TeamGame(Level.Game); if(KFPawn(injured) != none && TG != none && Damage > 0 && class(DamageType) == none){ if((KFPawn(instigatedBy) != none || FakePlayerPawn(instigatedBy) != none) && (instigatedBy.PlayerReplicationInfo == none || instigatedBy.PlayerReplicationInfo.bOnlySpectator)){ Momentum = vect(0,0,0); if(NoFF(injured, TG.FriendlyFireScale)) return 0; else if(OriginalDamage == Damage) return Damage * TG.FriendlyFireScale; } else if(instigatedBy == none && !DamageType.default.bCausedByWorld){ Momentum = vect(0,0,0); if(NoFF(injured, TG.FriendlyFireScale)) return 0; else if(OriginalDamage == Damage) return Damage * TG.FriendlyFireScale; } } return super.NetDamage(OriginalDamage, Damage, injured, instigatedBy, HitLocation, Momentum, DamageType); } function bool NoFF(Pawn injured, float FF){ return (FF == 0.0 || (Vehicle(injured) != none && Vehicle(injured).bNoFriendlyFire)); } function bool PreventDeath(Pawn Killed, Controller Killer, class damageType, vector HitLocation){ local NiceHumanPawn nicePawn; local NicePlayerController nicePlayer; nicePlayer = NicePlayerController(Killed.controller); nicePawn = NiceHumanPawn(Killed); if(nicePawn != none && (!nicePawn.bReactiveArmorUsed) && class'NiceVeterancyTypes'.static.HasSkill(nicePlayer, class'NiceSkillDemoReactiveArmor')){ nicePawn.bReactiveArmorUsed = true; nicePlayer.niceRI.ServerExplode(class'NiceSkillDemoReactiveArmor'.default.baseDamage, class'NiceSkillDemoReactiveArmor'.default.explRadius, class'NiceSkillDemoReactiveArmor'.default.explExponent, class'NiceDamTypeDemoSafeExplosion', class'NiceSkillDemoReactiveArmor'.default.explMomentum, killed.location, killed ); return true; } if(NextGameRules != none) return NextGameRules.PreventDeath(Killed, Killer, damageType, HitLocation); return false; } defaultproperties { }