MonsterDiffBuilder

Тема в разделе "Общего назначения", создана пользователем Dr_Killjoy, 31 июл 2014.

  1. Dr_Killjoy

    Dr_Killjoy Заблокированные

    Monster Diff Builder

    Представляю вашему вниманию мутатор, который настраивает параметры монстров, появляющихся на сервере. Знаю, многие недовольны той настройкой хп мобов, и остальных параметров, которые имеют монстры по умолчанию. Этот мутатор позволит настроить хп монстров, а так же его рост в зависимости от количества игроков, скорость, урон и другие параметры. Так же, вы можете самостоятельно настроить модификаторы хп, урона, скорости для каждой сложности, создав тем самым свою сложность. Таких функций не было в том же HarderMutator, а теперь вы можете поставить на свой сервер голосование за сложность, и настроить каждую сложность под себя.

    Автор: Dr. Killjoy (Steklo)

    Код для загрузки мутатора в .bat-файле или MutLoader:

    MonsterDiffBuilder.MonsterDiffBuilder
    Конфиг:

    [MonsterDiffBuilder.MonsterDiffBuilder]
    UpdateMaxHealthFrequency=1.00

    Время, через которое выставляется правильное значение максимального хп монстров на клиентах. Лучше этот параметр не трогать.

    Теперь на примере скрейка рассмотрим какие параметры можно настроить у конкретного моба.

    [ScrakeSettings MonsterSettings]
    Первое слово это название настройки. Само название не играет роль, но оно не должно повторяться, и начинаться с цифры.
    MonsterClass="KFChar.ZombieScrake_STANDARD"
    Класс монстра, для которого работает данная настройка.
    bMonsterClassIsChild=false
    Применять ли настройку к монстрам, чей класс наследует класс данного монстра.
    Health=1000
    Здоровье тела.
    PerPlayerHealth=(Health=500,MinPlayers=2,MaxPlayers=8)
    PerPlayerHealth=(Health=250,MinPlayers=9,MaxPlayers=16)
    Количество хп, выдаваемое за каждого следующего игрока. Соотвественно MinPlayers и MaxPlayers это границы, в рамках которых будет даваться хп. Как видите PerPlayerHealth это массив, в данном примере он делает так что начиная с 2 игроков до 8, за каждого игрока добавляется скрейку 500 хп, а начиная с 9 до 16, - добавляется только 250. После 16 игроков хп скрейка уже не растёт. Если не хотите заморачиваться, оставьте одну строчку с PerPlayerHealth и поставьте увеличение с 2 до 100 игроков.
    HeadHealth=650
    Здоровье головы.
    PerPlayerHeadHealth=(Health=195,MinPlayers=2,MaxPlayers=8)
    PerPlayerHeadHealth=(Health=98,MinPlayers=9,MaxPlayers=16)
    То же самое что и PerPlayerHealth, только работает для здоровья головы.
    Speed=85.00
    Скорость движения монстра.
    Damage=20
    Урон в ближнем бою монстра.
    ScreamDamage=0
    Урон криком (используется для таких мобов как сирена, баньши).
    Mass=500.0
    Масса. Влияет на отображение моба в KillMessage, а так же на то как он будет отлетать от различного физического воздействия. Именно изза маленькой массы сирены так летают от взрывчатки.
    BombDanger=3.00
    Уровень реакции мин на этого моба. Если он равен 1 или больше, мина взрывается.
    ZapThreshold=1.25
    Насколько быстро монстр поддаётся влиянию Zedgun'ов.
    ZappedDamageMod=1.25
    Дополнительный урон, который получает монстр будучи обработанным Zedgun'ом.
    ScoringValue=75
    Деньги, выдаваемые за монстра.
    DifficultyUsed=(Min=0.00,Max=100.00)
    Минимальное и максимальное значение сложности, при котором данная настройка сработает. Если мы просто настраиваем параметры конкретного моба, то желательно чтобы диапазон охватывал все возможные сложности. В KF обычно используются сложности от 1 до 7, но при настройках моба я на всякий случай поставил 100, вдруг кому ударит в голову поставить сложность больше 7. Вы всё ещё задаётесь вопросом, а зачем тогда вообще этот параметр в конфиге? Ниже я приведу пример другой настройки, которая позволит настроить параметры моба при определённой сложности.

    [SuicidalSettings MonsterSettings]
    MonsterClass="KFMod.KFMonster"
    bMonsterClassIsChild=true
    KFMonster - базовый класс всех монстров в KF. Если мы поставим переменную bMonsterClassIsChild=true, то настройка заработает на всех монстров, наследующих данный класс, в нашем случае это все монстры в KF.
    HealthMod=1.55
    На это число умножается хп тела монстра
    HeadHealthMod=1.55
    На это число умножается хп головы монстра
    SpeedMod=1.22
    На это число умножается скорость движения монстра
    DamageMod=1.50
    На это число умножается урон монстра в ближнем бою
    ScreamDamageMod=1.50
    На это число умножается урон монстра от крика
    DifficultyUsed=(Min=5.00,Max=6.999)
    Здесь мы задали сложность, на какой настройка будет работать. Получается начиная с 5 и до 6.999. Если вместо 6.999 поставить 7, то настройки сложности ад на земле перемножатся с настройками суицида, и монстры сделают вам очень больно.

    Важно: для каждого используемого на вашем сервере моба должна быть прописана настройка в этом мутаторе. Если вы хотите чтобы у монстра росло хп в зависимости от количества человек, задайте это в его настройке, само по себе оно расти не будет.

    Пример содержимого .ini файла:

    Код:
    [MonsterDiffBuilder.MonsterDiffBuilder]
    UpdateMaxHealthFrequency=1.00
    
    [ClotSettings MonsterSettings]
    MonsterClass="KFChar.ZombieClot_STANDARD"
    bMonsterClassIsChild=false
    Health=130
    HeadHealth=25
    Speed=105.00
    Damage=6
    ScreamDamage=0
    Mass=100.0
    BombDanger=0.34
    ZapThreshold=0.25
    ZappedDamageMod=2.00
    ScoringValue=7
    DifficultyUsed=(Min=0.00,Max=100.00)
    
    [GorefastSettings MonsterSettings]
    MonsterClass="KFChar.ZombieGorefast_STANDARD"
    bMonsterClassIsChild=false
    Health=250
    PerPlayerHealth=(Health=37,MinPlayers=2,MaxPlayers=8)
    PerPlayerHealth=(Health=19,MinPlayers=9,MaxPlayers=16)
    HeadHealth=25
    Speed=120.00
    Damage=15
    ScreamDamage=0
    Mass=350.0
    BombDanger=0.50
    ZapThreshold=0.25
    ZappedDamageMod=2.00
    ScoringValue=12
    DifficultyUsed=(Min=0.00,Max=100.00)
    
    [BloatSettings MonsterSettings]
    MonsterClass="KFChar.ZombieBloat_STANDARD"
    bMonsterClassIsChild=false
    Health=525
    PerPlayerHealth=(Health=131,MinPlayers=2,MaxPlayers=8)
    PerPlayerHealth=(Health=66,MinPlayers=9,MaxPlayers=16)
    HeadHealth=25
    Speed=75.00
    Damage=15
    ScreamDamage=0
    Mass=400.0
    BombDanger=1.00
    ZapThreshold=0.50
    ZappedDamageMod=1.50
    ScoringValue=17
    DifficultyUsed=(Min=0.00,Max=100.00)
    
    [StalkerSettings MonsterSettings]
    MonsterClass="KFChar.ZombieStalker_STANDARD"
    bMonsterClassIsChild=false
    Health=100
    HeadHealth=25
    Speed=200.00
    Damage=9
    ScreamDamage=0
    Mass=100.0
    BombDanger=0.25
    ZapThreshold=0.25
    ZappedDamageMod=2.00
    ScoringValue=15
    DifficultyUsed=(Min=0.00,Max=100.00)
    
    [CrawlerSettings MonsterSettings]
    MonsterClass="KFChar.ZombieCrawler_STANDARD"
    bMonsterClassIsChild=false
    Health=70
    HeadHealth=25
    Speed=140.00
    Damage=6
    ScreamDamage=0
    Mass=100.0
    BombDanger=0.34
    ZapThreshold=0.25
    ZappedDamageMod=2.00
    ScoringValue=10
    DifficultyUsed=(Min=0.00,Max=100.00)
    
    [HuskSettings MonsterSettings]
    MonsterClass="KFChar.ZombieHusk_STANDARD"
    bMonsterClassIsChild=false
    Health=600
    PerPlayerHealth=(Health=60,MinPlayers=2,MaxPlayers=8)
    PerPlayerHealth=(Health=30,MinPlayers=9,MaxPlayers=16)
    HeadHealth=200
    PerPlayerHeadHealth=(Health=10,MinPlayers=2,MaxPlayers=8)
    PerPlayerHeadHealth=(Health=5,MinPlayers=9,MaxPlayers=16)
    Speed=115.00
    Damage=15
    ScreamDamage=0
    Mass=400.0
    BombDanger=1.00
    ZapThreshold=0.75
    ZappedDamageMod=2.00
    ScoringValue=17
    DifficultyUsed=(Min=0.00,Max=100.00)
    
    [SirenSettings MonsterSettings]
    MonsterClass="KFChar.ZombieSiren_STANDARD"
    bMonsterClassIsChild=false
    Health=300
    PerPlayerHealth=(Health=30,MinPlayers=2,MaxPlayers=8)
    PerPlayerHealth=(Health=15,MinPlayers=9,MaxPlayers=16)
    HeadHealth=200
    PerPlayerHeadHealth=(Health=10,MinPlayers=2,MaxPlayers=8)
    PerPlayerHeadHealth=(Health=5,MinPlayers=9,MaxPlayers=16)
    Speed=100.00
    Damage=13
    ScreamDamage=8
    Mass=100.0
    BombDanger=1.00
    ZapThreshold=0.50
    ZappedDamageMod=1.50
    ScoringValue=25
    DifficultyUsed=(Min=0.00,Max=100.00)
    
    [ScrakeSettings MonsterSettings]
    MonsterClass="KFChar.ZombieScrake_STANDARD"
    bMonsterClassIsChild=false
    Health=1000
    PerPlayerHealth=(Health=500,MinPlayers=2,MaxPlayers=8)
    PerPlayerHealth=(Health=250,MinPlayers=9,MaxPlayers=16)
    HeadHealth=650
    PerPlayerHeadHealth=(Health=195,MinPlayers=2,MaxPlayers=8)
    PerPlayerHeadHealth=(Health=98,MinPlayers=9,MaxPlayers=16)
    Speed=85.00
    Damage=20
    ScreamDamage=0
    Mass=500.0
    BombDanger=3.00
    ZapThreshold=1.25
    ZappedDamageMod=1.25
    ScoringValue=75
    DifficultyUsed=(Min=0.00,Max=100.00)
    
    [FleshpoundSettings MonsterSettings]
    MonsterClass="KFChar.ZombieFleshpound_STANDARD"
    bMonsterClassIsChild=false
    Health=1500
    PerPlayerHealth=(Health=375,MinPlayers=2,MaxPlayers=8)
    PerPlayerHealth=(Health=187,MinPlayers=9,MaxPlayers=16)
    HeadHealth=700
    PerPlayerHeadHealth=(Health=210,MinPlayers=2,MaxPlayers=8)
    PerPlayerHeadHealth=(Health=105,MinPlayers=9,MaxPlayers=16)
    Speed=130.00
    Damage=35
    ScreamDamage=0
    Mass=500.0
    BombDanger=5.00
    ZapThreshold=1.75
    ZappedDamageMod=1.25
    ScoringValue=200
    DifficultyUsed=(Min=0.00,Max=100.00)
    
    [BossSettings MonsterSettings]
    MonsterClass="KFChar.ZombieBoss_STANDARD"
    bMonsterClassIsChild=false
    Health=4000
    PerPlayerHealth=(Health=3000,MinPlayers=2,MaxPlayers=100)
    Speed=130.00
    Damage=75
    ScreamDamage=0
    Mass=1000.0
    BombDanger=10.00
    ZapThreshold=5.00
    ZappedDamageMod=1.25
    ScoringValue=500
    DifficultyUsed=(Min=0.00,Max=100.00)
    
    [EasySettings MonsterSettings]
    MonsterClass="KFMod.KFMonster"
    bMonsterClassIsChild=true
    HealthMod=0.50
    HeadHealthMod=0.50
    SpeedMod=0.95
    DamageMod=0.30
    ScreamDamageMod=0.30
    DifficultyUsed=(Min=0.00,Max=1.999)
    
    [NormalSettings MonsterSettings]
    MonsterClass="KFMod.KFMonster"
    bMonsterClassIsChild=true
    HealthMod=1.00
    HeadHealthMod=1.00
    SpeedMod=1.00
    DamageMod=1.00
    ScreamDamageMod=1.00
    DifficultyUsed=(Min=2.00,Max=3.999)
    
    [HardSettings MonsterSettings]
    MonsterClass="KFMod.KFMonster"
    bMonsterClassIsChild=true
    HealthMod=1.35
    HeadHealthMod=1.35
    SpeedMod=1.15
    DamageMod=1.25
    ScreamDamageMod=1.25
    DifficultyUsed=(Min=4.00,Max=4.999)
    
    [SuicidalSettings MonsterSettings]
    MonsterClass="KFMod.KFMonster"
    bMonsterClassIsChild=true
    HealthMod=1.55
    HeadHealthMod=1.55
    SpeedMod=1.22
    DamageMod=1.50
    ScreamDamageMod=1.50
    DifficultyUsed=(Min=5.00,Max=6.999)
    
    [HellOnEarthSettings MonsterSettings]
    MonsterClass="KFMod.KFMonster"
    bMonsterClassIsChild=true
    HealthMod=1.75
    HeadHealthMod=1.75
    SpeedMod=1.30
    DamageMod=1.75
    ScreamDamageMod=1.75
    DifficultyUsed=(Min=7.00,Max=100.0)

    Распаковать архив в папку с игрой.

    Скачать
    Зеркало

    Исходник:

    Код:
    //====== Author: Dr. Killjoy (Steklo)
    
    class MonsterDiffBuilder extends Mutator
        config(MonsterDiffBuilder);
        
    var    config    float    UpdateMaxHealthFrequency;
    var            float    UpdateMaxHealthTime;
        
    var    array<KFMonster>    PendingMonsters;
    
    var    array<MonsterSettings>    MonsterRules;
        
    function PostBeginPlay()
    {
        local int i,n;
        //local MDBGameRules GR;
        local class<KFMonster> KFMClass;
        local array<string> Names;
        
        Super.PostBeginPlay();
        /*GR = spawn(class'MDBGameRules');
        GR.MutatorOwner = Self;
        if ( Level.Game.GameRulesModifiers == None ) Level.Game.GameRulesModifiers = GR;
        else Level.Game.GameRulesModifiers.AddGameRules(GR);*/
        // Изза того что резист, вводимый с помощью GameRules, работает только на урон не в голову, я решил отказаться от настройки резиста в этом мутаторе
        Names = class'MonsterSettings'.Static.GetPerObjectNames("MonsterDiffBuilder");
        n = Names.Length;
        for(i=0; i<n; i++)
        {
            MonsterRules[i] = new (None,Names[i]) class'MonsterSettings';
        }
        n = MonsterRules.Length;
        for(i=0; i<n; i++)
        {
            KFMClass = class<KFMonster>(DynamicLoadObject(MonsterRules[i].MonsterClass,class'class'));
            if ( KFMClass != none )
                MonsterRules[i].LoadedMonsterClass = KFMClass;
        }
    }
    
    function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
    {
        if ( KFMonster(Other) != none )
        {
            PendingMonsters.Insert(0,1);
            PendingMonsters[0] = KFMonster(Other);
            SetTimer(0.1,false);
        }
        return Super.CheckReplacement(Other,bSuperRelevant);
    }
    
    simulated function Timer()
    {
        local int i,n;
        
        n = PendingMonsters.Length;
        for(i=0; i<n; i++)
        {
            if ( PendingMonsters[i] != none && PendingMonsters[i].Health > 0 && !PendingMonsters[i].bDeleteMe )
                InitMonster(PendingMonsters[i]);
        }
        PendingMonsters.Remove(0,n);
    }
    
    function InitMonster(KFMonster KFM)
    {
        local int i,n,j,m,NumPlayers,AddPlayers;
        local float CurrentDiff;
        local float Speed,AddHealth,AddHeadHealth,HealthMod,HeadHealthMod,SpeedMod,DamageMod,ScreamDamageMod;
        local bool bLoadedHealth;
        
        //log("InitMonster entry. KFM = " $ KFM $ ", KFM.Class = " $ KFM.Class);
        CurrentDiff = Level.Game.GameDifficulty;
        //log("CurrentDiff = " $ CurrentDiff);
        NumPlayers = GetNumPlayers();
        //log("NumPlayers = " $ NumPlayers);
        HealthMod = 1.00;
        HeadHealthMod = 1.00;
        SpeedMod = 1.00;
        DamageMod = 1.00;
        ScreamDamageMod = 1.00;
        n = MonsterRules.Length;
        //log("for i = 0 to n = " $ n);
        for(i=0; i<n; i++)
        {
            //log("i = " $ i);
            //log("MonsterRules[" $ i $ "].Name = " $ MonsterRules[i].Name);
            //log("LoadedMonsterClass = " $ MonsterRules[i].LoadedMonsterClass);
            //log("MonsterRules[i].bMonsterClassIsChild = " $ MonsterRules[i].bMonsterClassIsChild);
            //log("KFM.Class != MonsterRules[i].LoadedMonsterClass = " $ string(KFM.Class != MonsterRules[i].LoadedMonsterClass));
            //log("!ClassIsChildOf(KFM.Class,MonsterRules[i].LoadedMonsterClass) = " $ string(!ClassIsChildOf(KFM.Class,MonsterRules[i].LoadedMonsterClass)));
            //if ( MonsterRules[i].DifficultyUsed.Min > 0 )
                //log("MinDiff = " $ MonsterRules[i].DifficultyUsed.Min);
            //if ( MonsterRules[i].DifficultyUsed.Max > 0 )
                //log("MaxDiff = " $ MonsterRules[i].DifficultyUsed.Max);
            //log("CurrentDiff < MonsterRules[i].DifficultyUsed.Min = " $ string(CurrentDiff < MonsterRules[i].DifficultyUsed.Min));
            //log("CurrentDiff > MonsterRules[i].DifficultyUsed.Max = " $ string(CurrentDiff > MonsterRules[i].DifficultyUsed.Max));
            if ( KFM.Class != MonsterRules[i].LoadedMonsterClass && !MonsterRules[i].bMonsterClassIsChild
                || !ClassIsChildOf(KFM.Class,MonsterRules[i].LoadedMonsterClass) && MonsterRules[i].bMonsterClassIsChild
                || CurrentDiff < MonsterRules[i].DifficultyUsed.Min || CurrentDiff > MonsterRules[i].DifficultyUsed.Max )
            continue;
            //log("KFM.Health = " $ KFM.Health);
            //log("KFM.HeadHealth = " $ KFM.HeadHealth);
            if ( !bLoadedHealth )
            {
                //log("Loaded Health");
                bLoadedHealth = true;
                KFM.Health = KFM.default.Health;
                KFM.HealthMax = KFM.default.HealthMax;
                KFM.HeadHealth = KFM.default.HeadHealth;
            }
            //log("KFM.Health = " $ KFM.Health);
            //log("KFM.HeadHealth = " $ KFM.HeadHealth);
            if ( MonsterRules[i].Health > 0 )
                KFM.Health = MonsterRules[i].Health;
            if ( MonsterRules[i].HeadHealth > 0 )
                KFM.HeadHealth = MonsterRules[i].HeadHealth;
            if ( MonsterRules[i].StunDamage > 0 )
                KFM.default.Health = MonsterRules[i].StunDamage * 1.5;
            if ( MonsterRules[i].Speed > 0 )
                Speed = MonsterRules[i].Speed;
            if ( MonsterRules[i].Damage > 0 )
                KFM.MeleeDamage = MonsterRules[i].Damage;
            if ( MonsterRules[i].ScreamDamage > 0 )
                KFM.ScreamDamage = MonsterRules[i].ScreamDamage;
            if ( MonsterRules[i].HealthMod > 0 )
                HealthMod *= MonsterRules[i].HealthMod;
            if ( MonsterRules[i].HeadHealthMod > 0 )
                HeadHealthMod *= MonsterRules[i].HeadHealthMod;
            if ( MonsterRules[i].SpeedMod > 0 )
                SpeedMod *= MonsterRules[i].SpeedMod;
            if ( MonsterRules[i].DamageMod > 0 )
                DamageMod *= MonsterRules[i].DamageMod;
            if ( MonsterRules[i].ScreamDamageMod > 0 )
                ScreamDamageMod *= MonsterRules[i].ScreamDamageMod;
            if ( MonsterRules[i].Mass > 0 )
                KFM.Mass = MonsterRules[i].Mass;
            if ( MonsterRules[i].ZapThreshold > 0 )
                KFM.ZapThreshold = MonsterRules[i].ZapThreshold;
            if ( MonsterRules[i].ZappedDamageMod > 0 )
                KFM.ZappedDamageMod = MonsterRules[i].ZappedDamageMod;
            if ( MonsterRules[i].BombDanger > 0 )
                KFM.MotionDetectorThreat = MonsterRules[i].BombDanger;
            if ( MonsterRules[i].ScoringValue > 0 )
                KFM.ScoringValue = MonsterRules[i].ScoringValue;
            m = MonsterRules[i].PerPlayerHealth.Length;
            for(j=0; j<m; j++)
            {
                if ( NumPlayers >= MonsterRules[i].PerPlayerHealth[j].MinPlayers )
                {
                    AddPlayers = Min(NumPlayers-MonsterRules[i].PerPlayerHealth[j].MinPlayers+1,MonsterRules[i].PerPlayerHealth[j].MaxPlayers-MonsterRules[i].PerPlayerHealth[j].MinPlayers+1);
                    AddHealth += MonsterRules[i].PerPlayerHealth[j].Health * AddPlayers;
                }
            }
            m = MonsterRules[i].PerPlayerHeadHealth.Length;
            for(j=0; j<m; j++)
            {
                if ( NumPlayers >= MonsterRules[i].PerPlayerHeadHealth[j].MinPlayers )
                {
                    AddPlayers = Min(NumPlayers-MonsterRules[i].PerPlayerHeadHealth[j].MinPlayers+1,MonsterRules[i].PerPlayerHeadHealth[j].MaxPlayers-MonsterRules[i].PerPlayerHeadHealth[j].MinPlayers+1);
                    AddHeadHealth += MonsterRules[i].PerPlayerHeadHealth[j].Health * AddPlayers;
                }
            }
            //log("HealthMod = " $ HealthMod);
            //log("HeadHealthMod = " $ HeadHealthMod);
        }
        //log("End interation");
        KFM.Health += AddHealth;
        KFM.HeadHealth += AddHeadHealth;
        KFM.Health = float(KFM.Health) * HealthMod;
        KFM.HeadHealth = KFM.HeadHealth * HeadHealthMod;
        KFM.MeleeDamage = float(KFM.MeleeDamage) * DamageMod;
        KFM.ScreamDamage = float(KFM.ScreamDamage) * ScreamDamageMod;
        Speed *= SpeedMod;
        KFM.OriginalGroundSpeed = Speed;
        KFM.GroundSpeed = Speed;
        KFM.WaterSpeed = Speed;
        KFM.AirSpeed = Speed;
        KFM.HealthMax = KFM.Health;
        //log("KFM.Health = " $ KFM.Health);
        //log("KFM.HeadHealth = " $ KFM.HeadHealth);
    }
    
    function int ModifyMonsterDamage(int Damage, KFMonster Injured, pawn instigatedBy, vector HitLocation, out vector Momentum, class<DamageType> DamageType)
    {/*
        local int i,n,j,m;
        local float Modifer;
        local float CurrentDiff;
        local class<DamageType> ModDamageType;
        
        Modifer = 1.00;
        CurrentDiff = Level.Game.GameDifficulty;
        n = MonsterRules.Length;
        for(i=0; i<n; i++)
        {
            if ( Injured.Class != MonsterRules[i].LoadedMonsterClass && !MonsterRules[i].bMonsterClassIsChild
                || !ClassIsChildOf(Injured.Class,MonsterRules[i].LoadedMonsterClass) && MonsterRules[i].bMonsterClassIsChild
                || CurrentDiff < MonsterRules[i].DifficultyUsed.Min || CurrentDiff > MonsterRules[i].DifficultyUsed.Max )
            continue;
            m = MonsterRules[i].DamageModifer.Length;
            for(j=0; j<m; j++)
            {
                ModDamageType = class<DamageType>(DynamicLoadObject(MonsterRules[i].DamageModifer[j].DamageType,class'class'));
                if ( ModDamageType != DamageType && !MonsterRules[i].DamageModifer[j].bIsChild
                    || !ClassIsChildOf(ModDamageType,DamageType) && MonsterRules[i].DamageModifer[j].bIsChild
                    || CurrentDiff < MonsterRules[i].DamageModifer[j].DifficultyUsed.Min || CurrentDiff > MonsterRules[i].DamageModifer[j].DifficultyUsed.Max )
                continue;
                Modifer = MonsterRules[i].DamageModifer[j].Modifer;
            }
        }
        Damage = float(Damage) * Modifer;*/
        return Damage;
    }
    
    function int GetNumPlayers()
    {
        local int Ret;
        local Controller C;
        
        For( C=Level.ControllerList; C!=None; C=C.NextController )
        {
            if( C.bIsPlayer && C.Pawn!=None && C.Pawn.Health > 0 && KFHumanPawn(C.Pawn) != none )
            {
                Ret++;
            }
        }
        return Ret;
    }
    
    simulated function Tick(float DT)
    {
        local KFMonster KFM;
        
        Super.Tick(DT);
        if ( Level.NetMode == NM_DedicatedServer )
            return;
        if ( UpdateMaxHealthTime < Level.TimeSeconds )
        {
            UpdateMaxHealthTime = Level.TimeSeconds + UpdateMaxHealthFrequency;
            foreach DynamicActors(class'KFMonster',KFM)
            {
                if ( KFM.Health > KFM.HealthMax )
                    KFM.HealthMax = KFM.Health;
            }
        }
    }
    
    defaultproperties
    {
        UpdateMaxHealthFrequency=1.00
        
        bAddToServerPackages=true
        bAlwaysRelevant=true
        RemoteRole=ROLE_SimulatedProxy
        GroupName="KF-MonsterDiffBuilder"
        FriendlyName="MonsterDiffBuilder"
        Description="Set difficulty of monsters using different settings."
    }
    Код:
    class MonsterSettings extends Object
        config(MonsterDiffBuilder)
        PerObjectConfig;
        
    struct FloatRangeRecord
    {
        var    float Min,Max;
    };
        
    struct PerPlayerHealthRecord
    {
        var int    Health,MinPlayers,MaxPlayers;
    };
    /*
    struct ResistRecord
    {
        var    string    DamageType;
        var    bool        bIsChild;
        var    float        Modifer;
        var    FloatRangeRecord    DifficultyUsed;
    };*/
        
    var    config    string    MonsterClass;
    var    config    bool        bMonsterClassIsChild;
    var    config    int        Health,HeadHealth,StunDamage,Damage,ScreamDamage,ScoringValue;
    var    config    float        Speed,Mass,BombDanger,ZapThreshold,ZappedDamageMod;
    var    config    float        HealthMod,HeadHealthMod,SpeedMod,DamageMod,ScreamDamageMod;
    
    var    config    array<PerPlayerHealthRecord>    PerPlayerHealth,PerPlayerHeadHealth;
    //var    config    array<ResistRecord>            DamageModifer;
    var    config    FloatRangeRecord            DifficultyUsed;
    
    var class<KFMonster>    LoadedMonsterClass;
        
    defaultproperties
    {
    }

    Распространение по другим сайтам только с разрешения автора.
     
    Denkul999, Stein, Dave_Scream и 6 другим нравится это.
  2. kok-s

    kok-s Консильери

    За идею конечно :plus:.

    P.S. Жду MonsterConfigv2 :whistling:
     
  3. Proton

    Proton Игровой администратор

    Краткое описание настроек в ini есть?
     
  4. Nytte-maere

    Nytte-maere Guest

    Завтра-послезавтра потестим)
     
  5. DARK-MEN

    DARK-MEN Солдат

    Те классы,чьи настройки не хочешь менять,можно удалить из .ini файла?И есть ли ограничение на кол-во классов?
     
  6. Dr_Killjoy

    Dr_Killjoy Заблокированные

    Там выставлены стандартные параметры мобов, кроме того что после 8 человек хп растёт медленнее, так что ничего удалять не надо. И да, надо прописать настройки для каждого моба, который стоит на сервере. Некоторые настройки для конкретного моба можно опустить, просто не указывая их. Однако обязательно надо указать хп, растущее от количества человек, если вам нужно чтобы у этого моба оно росло.

    Количество настроек ограничено размером массива в движке. Не помню точно какое там ограничение, но минимум 255 настроек для мобов можно сделать.

    Скажем так, в этом мутаторе часть функционала MonsterConfig, а именно настройка параметров мобов. Это скажем так шаг на пути к реализации MonsterConfig независимого от GameType.
     
  7. Flame

    Flame -Заслуженый кодер форума-

    Код хорошенький)

    То что под спойлером уже устарело)
    Единственно не очень понятно, что будет со скоростью нерелевантных для всех зомбиков. Она же должна быть повышенная вроде. Как раз на момент таймера 0.1.
    А тут будет из инишника. Может дольше будет игра из-за этого.

    Upd. А хотя нормалёк. Тик же выполняется.
    Код:
    		else if ( Level.NetMode == NM_DedicatedServer )
    		{
    			if ( Level.TimeSeconds - LastReplicateTime > 0.5 )
    			{
    				SetGroundSpeed(default.GroundSpeed * (300.0 / default.GroundSpeed));
    			}
    			else
    			{
    				LastSeenOrRelevantTime = Level.TimeSeconds;
    				SetGroundSpeed(GetOriginalGroundSpeed());
    			}
    		}
    
    И вроде должно быть всё нормально. И OriginalGroundSpeed ты заменил. Вроде нормалёк

    С Health тоже сходу не соображу. Не будет ли на клиентах такой фигни, что полосочка жизни вылазит за свои границы. HealthMax же не меняется тут, а надо бы )

    Постараюсь потестить

    Upd. А. Вижу. Меняется HealthMax и как раз на клиенте меняется))
    Тогда красота )
     
  8. kok-s

    kok-s Консильери

    Отлично)))
     
  9. Dr_Killjoy

    Dr_Killjoy Заблокированные

    Товарищи, кто-нибудь уже протестил мутатор?
     
  10. Dr_Killjoy

    Dr_Killjoy Заблокированные

    Ап темы. Обновил первый пост, мутатор был протестирован и теперь рабочий. Добавил описание как работает мутатор и как заполнять конфиг.
     
  11. AitherKill

    AitherKill Солдат

    class MonsterSettings extends Object
    config(MonsterDiffBuilder)
    PerObjectConfig;

    struct FloatRangeRecord
    {
    var float Min,Max;
    };

    struct PerPlayerHealthRecord
    {
    var int Health,MinPlayers,MaxPlayers;
    };
    /*
    struct ResistRecord
    {
    var string DamageType;
    var bool bIsChild;
    var float Modifer;
    var FloatRangeRecord DifficultyUsed;
    };*/

    var config string MonsterClass;
    var config bool bMonsterClassIsChild;
    var config int Health,HeadHealth,StunDamage,Damage,ScreamDamage,ScoringValue;
    var config float Speed,Mass,BombDanger,ZapThreshold,ZappedDamageMod;
    var config float HealthMod,HeadHealthMod,SpeedMod,DamageMod,ScreamDamageMod;

    var config array<PerPlayerHealthRecord> PerPlayerHealth,PerPlayerHeadHealth;
    //var config array<ResistRecord> DamageModifer;
    var config FloatRangeRecord DifficultyUsed;

    var class<KFMonster> LoadedMonsterClass;

    defaultproperties
    {
    }
    //var config array<ResistRecord> DamageModifer;
    /*
    struct ResistRecord
    {
    var string DamageType;
    var bool bIsChild;
    var float Modifer;
    var FloatRangeRecord DifficultyUsed;
    };*/

    - я так понял была задумка еще резисты мобам прикручивать?
     
  12. Dr_Killjoy

    Dr_Killjoy Заблокированные

    Да, хотел как в монстр конфиге задавать резисты, но выяснилось, что резист, задаваемый через GameRules не будет работать против хедшотного урона (урон в тело понизится, урон в голову нет). Поэтому я убрал весь код связанный с резистами.

    П.С. Как вариант могу сделать настройку резистов, однако вам придётся переписать необходимых мобов, добавив в takedamage обращение к мутатору. То есть кто разбирается, сможет себе прикрутить резисты. Но это попозже.
     
  13. AitherKill

    AitherKill Солдат

    Будет полезно.
    А исходник от MDBGameRules остался?
     
  14. Proton

    Proton Игровой администратор

    Вопрос:
    PerPlayerHealth=(Health=195,MinPlayers=2,MaxPlayers=8)
    и
    PerPlayerHeadHealth=(Health=195,MinPlayers=2,MaxPlayers=8)

    Есть данные о том, насколько по стандарту растет Количество хп, выдаваемое за каждого следующего игрока у каждого из стандартных мобов,
    или по какой формуле?
    Чтобы вообще знать, какой должен быть порядок цифр, какой размер выставлять себе на сервер для каждого моба?
     
  15. Dr_Killjoy

    Dr_Killjoy Заблокированные

    Там как раз стандартные значения в инишнике и стоят. Ну те которые до 8 игроков.
     
  16. Proton

    Proton Игровой администратор

    У Клота и Сталкера и Краулера - нет вообще таких строчек.
    У Горефаста и Блота и Босса - нет строчек на Голову.
    Т.е. у них это вообще не будет расти, так?
     
  17. Dr_Killjoy

    Dr_Killjoy Заблокированные

    Так по стандарту и есть. Если хочется, можно сделать чтобы росло.
     
  18. Proton

    Proton Игровой администратор

    Ясно.

    Вот, например, настроили мы Скрейка для суицидальной сложности:

    [ScrakeSettings MonsterSettings]
    MonsterClass="KFChar.ZombieScrake_STANDARD"
    bMonsterClassIsChild=false
    Health=1000
    PerPlayerHealth=(Health=500,MinPlayers=2,MaxPlayers=8)
    PerPlayerHealth=(Health=250,MinPlayers=9,MaxPlayers=16)
    HeadHealth=650
    PerPlayerHeadHealth=(Health=195,MinPlayers=2,MaxPlayers=8)
    PerPlayerHeadHealth=(Health=98,MinPlayers=9,MaxPlayers=16)
    Speed=85.00
    Damage=20
    ScreamDamage=0
    Mass=500.0
    BombDanger=3.00
    ZapThreshold=1.25
    ZappedDamageMod=1.25
    ScoringValue=75
    DifficultyUsed=(Min=5.00,Max=6.999)

    Теперь хотим настроить Скрейка но уже для сложности Ад На Земле на том же сервере(предполагается, что на сервере будет голосование за сложность ), что мы должны сделать? написать ещё раз всю эту настройку, изменив только первое слово названия настройки и параметр DifficultyUsed=(Min=7.00,Max=7.00)
    Так?
     
  19. Dr_Killjoy

    Dr_Killjoy Заблокированные

    Вот эти настройки отвечают за сложность:

    [EasySettings MonsterSettings]
    MonsterClass="KFMod.KFMonster"
    bMonsterClassIsChild=true
    HealthMod=0.50
    HeadHealthMod=0.50
    SpeedMod=0.95
    DamageMod=0.30
    ScreamDamageMod=0.30
    DifficultyUsed=(Min=0.00,Max=1.999)

    [NormalSettings MonsterSettings]
    MonsterClass="KFMod.KFMonster"
    bMonsterClassIsChild=true
    HealthMod=1.00
    HeadHealthMod=1.00
    SpeedMod=1.00
    DamageMod=1.00
    ScreamDamageMod=1.00
    DifficultyUsed=(Min=2.00,Max=3.999)

    [HardSettings MonsterSettings]
    MonsterClass="KFMod.KFMonster"
    bMonsterClassIsChild=true
    HealthMod=1.35
    HeadHealthMod=1.35
    SpeedMod=1.15
    DamageMod=1.25
    ScreamDamageMod=1.25
    DifficultyUsed=(Min=4.00,Max=4.999)

    [SuicidalSettings MonsterSettings]
    MonsterClass="KFMod.KFMonster"
    bMonsterClassIsChild=true
    HealthMod=1.55
    HeadHealthMod=1.55
    SpeedMod=1.22
    DamageMod=1.50
    ScreamDamageMod=1.50
    DifficultyUsed=(Min=5.00,Max=6.999)

    [HellOnEarthSettings MonsterSettings]
    MonsterClass="KFMod.KFMonster"
    bMonsterClassIsChild=true
    HealthMod=1.75
    HeadHealthMod=1.75
    SpeedMod=1.30
    DamageMod=1.75
    ScreamDamageMod=1.75
    DifficultyUsed=(Min=7.00,Max=100.0)

    В принципе их обычно хватает. Но если надо скрейка как-то по особенному поменять, то да, две разных настройки, одна для сложности 5-6.9, другая для 7.
     
  20. Stein

    Stein Солдат

    совместим ли мут с Custom Game Type?