Christmas Patriarch

Exp Multiplier. Множитель прокачки

Множитель может быть любым. Хоть 1000 (я на 1000 и проверял, чтобы точно быть уверенным, что не забыл про какой-нибудь параметр какого-нибудь перка) )
Можно даж 0 или отрицательный поставить. Для многих параметров будет работать )

Только я так подумал
Я вижу 2 способа использования данного мутатора
1. В праздники делать всем подарок в виде повышенного кача
2. Вип лист игроков (часто эти игроки платят деньги) и для них повышенный кач

Первый способ мне вполне нравится, а вот второй нет
Поэтому те кто желают вип список - вот ссылка или приделывайте список сами

class MultipliedExpMut extends Mutator config(MultipliedExpMut);
var config int nExp;
var MeXGameRules RulesMod;
function PostBeginPlay()
{
    if( RulesMod==None )
        RulesMod = Spawn(Class'MeXGameRules');
    RulesMod.nExp=nExp;

    if(KFGameType(Level.Game)==None) Destroyed();
    class'KFMod.Welder'.default.FireModeClass[0]=Class'MultipliedExpMut.newWeldFire';
    class'KFMod.Welder'.default.FireModeClass[1]=Class'MultipliedExpMut.newUnWeldFire';
    class'KFMod.Syringe'.default.FireModeClass[0]=Class'MultipliedExpMut.newSyringeFire';
    class'KFMod.KrissMAltFire'.default.ProjectileClass=Class'MultipliedExpMut.newKrissMHealingProjectile';
    class'KFMod.M7A3MAltFire'.default.ProjectileClass=Class'MultipliedExpMut.newM7A3MHealinglProjectile';
    class'KFMod.MP5MAltFire'.default.ProjectileClass=Class'MultipliedExpMut.newMP5MHealinglProjectile';
    class'KFMod.MP7MAltFire'.default.ProjectileClass=Class'MultipliedExpMut.newMP7MHealinglProjectile';
    class'MultipliedExpMut.newWeldFire'.default.nExp=nExp;
    class'MultipliedExpMut.newSyringeFire'.default.nExp=nExp;
    Class'MultipliedExpMut.newKrissMHealingProjectile'.default.nExp=nExp;
    Class'MultipliedExpMut.newM7A3MHealinglProjectile'.default.nExp=nExp;
    Class'MultipliedExpMut.newMP5MHealinglProjectile'.default.nExp=nExp;
    Class'MultipliedExpMut.newMP7MHealinglProjectile'.default.nExp=nExp;
    Class'MultipliedExpMut.newMedicNade'.default.nExp=nExp;
    Super.PostBeginPlay();
}
defaultproperties
{
    nExp=2
    bAddToServerPackages=True
    GroupName="KF-Exp"
    FriendlyName="MultipliedExpMut"
    Description="Multiplies experience of all players"
}
class MeXGameRules extends GameRules;
var array<KFMonster> DecapitatedMonsters;
var int nExp;
function PostBeginPlay()
{
    if( Level.Game.GameRulesModifiers==None )
        Level.Game.GameRulesModifiers = Self;
    else Level.Game.GameRulesModifiers.AddGameRules(Self);
}
function AddGameRules(GameRules GR)
{
    if ( GR!=Self )
        Super.AddGameRules(GR);
}
function bool PreventDeath(Pawn Killed, Controller Killer, class<DamageType> damageType, vector HitLocation)
{
    local KFSteamStatsAndAchievements KFStatsAndAchievements;
    local PlayerController PC;
    local int i;
    //Чистим список обезглавленых от уже мёртвых
    CleanDecapitatedList();
    if(damageType==None || Killer==None || Killed==None)
    {
        if ( NextGameRules != None)
            return NextGameRules.PreventDeath(Killed,Killer,damageType,HitLocation);
        return false;
    }
    PC=PlayerController(Killer);
    if(PC!=None)
        KFStatsAndAchievements = KFSteamStatsAndAchievements(PC.SteamStatsAndAchievements);
    if( PC==None || KFStatsAndAchievements==None )
    {
        if ( NextGameRules != None)
            return NextGameRules.PreventDeath(Killed,Killer,damageType,HitLocation);
        return false;
    }
    // Commando
    if    (
            DamageType.Name == 'DamTypeBullpup'                    ||
            DamageType.Name == 'DamTypeAK47AssaultRifle'        ||
            DamageType.Name == 'DamTypeFNFALAssaultRifle'        ||
            DamageType.Name == 'DamTypeSCARMK17AssaultRifle'    ||
            DamageType.Name == 'DamTypeM4AssaultRifle'            ||
            DamageType.Name == 'DamTypeThompson'                ||
            DamageType.Name == 'DamTypeMKb42AssaultRifle'
        )
    {
        if( Killed.IsA('ZombieStalker') )
        {
            for(i=0;i<nExp-1;i++)
                KFStatsAndAchievements.AddStalkerKill();
        }
    }
    if ( NextGameRules != None)
        return NextGameRules.PreventDeath(Killed,Killer, damageType,HitLocation);
    return false;
}
function int NetDamage( int OriginalDamage, int Damage, Pawn Injured, Pawn InstigatedBy, vector HitLocation, out vector Momentum, class<DamageType> DamageType )
{
    local KFSteamStatsAndAchievements KFStatsAndAchievements;
    local PlayerController PC;
    local int i;
    if(Injured==None || InstigatedBy==None)
    {
        if ( NextGameRules != None)
            return NextGameRules.NetDamage(OriginalDamage, Damage, injured, instigatedBy, HitLocation, Momentum, DamageType);
        return Damage;
    }
    if    (
            Injured.IsA('KFMonster')                        &&
            InstigatedBy.IsA('KFHumanPawn')                    &&
            InstigatedBy.Controller.IsA('PlayerController')    &&
            Damage>0
        )
    {
        PC=PlayerController(InstigatedBy.Controller);
        if(PC!=None)
            KFStatsAndAchievements = KFSteamStatsAndAchievements(PC.SteamStatsAndAchievements);
        if( PC==None || KFStatsAndAchievements==None )
        {
            if ( NextGameRules != None)
                return NextGameRules.NetDamage(OriginalDamage, Damage, injured, instigatedBy, HitLocation, Momentum, DamageType);
            return Damage;
        }
        // SupportSpec
        if    (
                class<KFWeaponDamageType>(DamageType)!=none    &&
                class<KFWeaponDamageType>(DamageType).default.bIsPowerWeapon
            )
            KFStatsAndAchievements.AddShotgunDamage((nExp-1) * Min(Damage,Injured.Health));
        // Berserker
        else if    (
                    class<KFWeaponDamageType>(DamageType) != none &&
                    class<KFWeaponDamageType>(DamageType).default.bIsMeleeDamage
                )
            KFStatsAndAchievements.AddMeleeDamage((nExp-1) * Min(Damage,Injured.Health));
        // Commando
        else if    (
                    DamageType.Name == 'DamTypeBullpup'                    ||
                    DamageType.Name == 'DamTypeAK47AssaultRifle'        ||
                    DamageType.Name == 'DamTypeFNFALAssaultRifle'        ||
                    DamageType.Name == 'DamTypeSCARMK17AssaultRifle'    ||
                    DamageType.Name == 'DamTypeM4AssaultRifle'            ||
                    DamageType.Name == 'DamTypeThompson'                ||
                    DamageType.Name == 'DamTypeMKb42AssaultRifle'
                )
            KFStatsAndAchievements.AddBullpupDamage((nExp-1) * Min(Damage,Injured.Health));
        // Firebug
        else if    (
                    class<KFWeaponDamageType>(DamageType)!=None &&
                    class<KFWeaponDamageType>(DamageType).default.bDealBurningDamage
                )
            KFStatsAndAchievements.AddFlameThrowerDamage((nExp-1) * Min(Damage,Injured.Health));
        // Sharpshooter
        else if    (
                    class<KFWeaponDamageType>(DamageType)!=None &&
                    class<KFWeaponDamageType>(DamageType).default.bSniperWeapon
                )
        {
            if(KFMonster(Injured).bDecapitated && !InDecapitatedList(KFMonster(Injured)))
            {
                DecapitatedMonsters[DecapitatedMonsters.Length]=KFMonster(Injured);
                for(i=0;i<nExp-1;i++)
                    KFStatsAndAchievements.AddHeadshotKill(false);
            }
        }
        // Demolitions
        else if    (
                    class<KFWeaponDamageType>(DamageType)!=none &&
                    class<KFWeaponDamageType>(DamageType).default.bIsExplosive
                )
            KFStatsAndAchievements.AddExplosivesDamage((nExp-1) * Min(Damage,Injured.Health));
    }
    if ( NextGameRules != None )
        return NextGameRules.NetDamage( OriginalDamage, Damage,injured,instigatedBy,HitLocation,Momentum,DamageType );
    return Damage;
}
function bool InDecapitatedList(KFMonster M)
{
    local int i;
    for(i=0;i<DecapitatedMonsters.Length;i++)
        if(DecapitatedMonsters[i]==M) return true;
    return false;
}
function CleanDecapitatedList()
{
    local int i;
    for (i=0; i<DecapitatedMonsters.Length; i++)
    {
        if (DecapitatedMonsters[i]==none)
        {
            DecapitatedMonsters.Remove(i,1);
            i--;
        }
    }
}

Для медика и в случае сварки - я заменяю либо Fire классы, либо Projectile
Потом может выложу версию, которая это обходит
Но в принципе и так неплохо

В данном мутаторе учтено только классическое оружие - остальное прописывайте
по-аналогии
Хотя в общем то это касается оружия коммандоса, оружия медика и новых сварок
Всё остальное будет работать и так скорее всего.
Чтобы использовать мед. гранату - надо в ServerPerksP.SRVetFieldMedic прописать

static function class<Grenade> GetNadeType(KFPlayerReplicationInfo KFPRI)
{
    local class<Grenade> gClass;
    gClass = class<Grenade>(DynamicLoadObject("MultipliedExpMut.newMedicNade", class'Class'));
    if(gClass!=none)
        return gClass;
    return Super.GetNadeType(KFPRI);
}

Скачать скомпилированную версию: ссылка, зеркало

Добавлять мутатор в виде MultipliedExpMut.MultipliedExpMut

Множитель nExp задаётся в ini файле

Автор: Flame