Вопросы к кодерам и мододелам

Тема в разделе "Игровое редактирование", создана пользователем Фрэгл, 20 ноя 2011.

  1. Flame

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

    Я сам отпишусь минут через 50))
    Туплю сижу с бумажкой. И то верно и то верно. И вроде не идентичные выражения
    Зря я коньяка выпил))
     
  2. Flame

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

    Не. Мой вариант плох.
    Почему плох? А дело именно в этой функции, где на вход подаются куча пушек.
    Так то я всё правильно расписал, но тут же в чём фишка - мы решение принимаем по каждой конкретной пушке, а не только по этой (BinachiPickup). Этож получается если пушка любая другая, то сразу возвращаем false. А эт фигня
    Так что должна работать версия где вначале идёт проверка на пушку и уже для неё идут отрицания
    Вроде так должно быть правильно:
    Код:
    if    (
                Pickup.Name=='BinachiPickup'
                &&
                (
                    SRPRI.KilledPats<25
                    ||    SRPRI.SuppDam<25000000
                    ||    KFPRI.ClientVeteranSkill.Name!='SRVetSupportSpec'
                )
        )
    {
        return false;
    }
    
     
    Essence нравится это.
  3. Flame

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

    Так. Разобрался вроде
    Условие изначальное у нас такое:
    Код:
    if    (
            Pickup.Name!='BinachiPickup'
            ||
            Pickup.Name=='BinachiPickup'
            &&    SRPRI.KilledPats>=25
            &&    SRPRI.SuppDam>=25000000
            &&    KFPRI.ClientVeteranSkill.Name=='SRVetSupportSpec'
        )
    {
        Проходим дальше()
    }
    
    А его отрицание
    Код:
    if    (
            Pickup.Name=='BinachiPickup'
            &&
            (
                Pickup.Name!='BinachiPickup'
                ||    SRPRI.KilledPats<25
                ||    SRPRI.SuppDam<25000000
                ||    KFPRI.ClientVeteranSkill.Name!='SRVetSupportSpec'
            )
        )
    {
        НеРазрешаем();
    }
    
    Но если Pickup.Name=='BinachiPickup' выполнено, то Pickup.Name!='BinachiPickup' не выполнено, а так как у нас там "или", то 0 оттуда можно тупо убрать. Ибо "или" это максимум из значений.
    Если Pickup.Name=='BinachiPickup' не выполнено, то у нас выражение (0 && что-то), что будет в любом случае 0 и мы проходим дальше.

    Итоговый вариант получается
    Код:
    if    (
            Pickup.Name=='BinachiPickup'
            &&
            (
                SRPRI.KilledPats<25
                ||    SRPRI.SuppDam<25000000
                ||    KFPRI.ClientVeteranSkill.Name!='SRVetSupportSpec'
            )
        )
    {
        НеРазрешаем();
    }
    
    Вот. Теперь я доволен)
     
    Последнее редактирование: 26 окт 2016
    Essence нравится это.
  4. Essence

    Essence Бандит

    В общем, запутал я себя и тебя зря тревожил)
    Как всегда моя невнимательность
    Всё у меня изначально было правильно
    Просто статистику менял, наверное, когда сервер был включен, вот изменения и не сохранились. Поэтому всё оружие было заблокировано.
    Всё равно спасибо, что разжевал, раньше я как-то поверхностно понимал эти условия. Сейчас стал лучше разбираться, что к чему. Да и другим форумчанам будет полезно.
     
  5. Flame

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

    Главное я сам разобрался)
     
  6. Essence

    Essence Бандит

    Потестил. Себя игрок вылечить может. Товарища почему-то нет.
    Придётся всё ж в СП вмешиваться?
    Ты в этом вопросе не копался ещё?
     
  7. Flame

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

    ну фигово сделал значит) должен мочь
    либо ищи ошибку, либо кидай свой код
     
  8. Essence

    Essence Бандит

    newSyringeAltFire:
    Код:
    class newSyringeAltFire extends InstantFire;
    
    var float InjectDelay;
    var float HealeeRange;
    
    function DoFireEffect()
    {
        SetTimer(InjectDelay, False);
    
        if ( Level.NetMode != NM_StandAlone && Level.Game.NumPlayers > 1 && KFPlayerController(Instigator.Controller) != none &&
             KFSteamStatsAndAchievements(KFPlayerController(Instigator.Controller).SteamStatsAndAchievements) != none )
        {
            KFSteamStatsAndAchievements(KFPlayerController(Instigator.Controller).SteamStatsAndAchievements).AddSelfHeal();
        }
    }
    
    function DoTrace(Vector Start, Rotator Dir)
    {
    }
    
    Function Timer()
    {
        local float HealSum;
    
        HealSum = Syringe(Weapon).HealBoostAmount;
    
        if ( KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo) != none && KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill != none )
        {
            HealSum *= KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill.Static.GetHealPotency(KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo));
        }
    
        Weapon.ConsumeAmmo(ThisModeNum, AmmoPerFire);
        Instigator.GiveHealth(HealSum, 100);
    }
    
    function bool AllowFire()
    {
        if (Instigator.Health >= Instigator.HealthMax)
         return false;
    
            return Weapon.AmmoAmount(ThisModeNum) >= AmmoPerFire;
    }
    
    event ModeDoFire()
    {
        Load = 0;
        Super.ModeDoFire(); // We don't consume the ammo just yet.   
    }
    
    function PlayFiring()
    {
        if ( Weapon.Mesh != None )
        {
            if ( FireCount > 0 )
            {
                if ( Weapon.HasAnim(FireLoopAnim) )
                {
                    Weapon.PlayAnim(FireLoopAnim, FireLoopAnimRate, 0.0);
                }
                else
                {
                    Weapon.PlayAnim(FireAnim, FireAnimRate, 0.0);
                }
            }
            else
            {
                Weapon.PlayAnim(FireAnim, FireAnimRate, 0.0);
            }
        }
        Weapon.PlayOwnedSound(FireSound,SLOT_Interact,TransientSoundVolume,,TransientSoundRadius,Default.FireAnimRate/FireAnimRate,false);
        ClientPlayForceFeedback(FireForce);  // jdf
    
        FireCount++;
    }
    
    function float MaxRange()
    {
        return 5000;
    }
    
    defaultproperties
    {
         InjectDelay=0.100000
         HealeeRange=70.000000
         TransientSoundVolume=1.800000
         FireAnim="AltFire"
         FireRate=3.600000
         AmmoPerFire=500
    }
    newSyringeFire:
    Код:
    class newSyringeFire extends newSyringeAltFire;
    
    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
    {
         HealAttemptDelay=0.500000
         HealMessageDelay=10.000000
         NoHealTargetMessage="You must be near another player to heal them!"
         InjectDelay=0.360000
         bWaitForRelease=True
         FireAnim="Fire"
         FireRate=2.800000
         AmmoPerFire=250
         DamageMin=1.000000
         DamageMax=1.000000
         DamageType=Class'lhPerksMut.DamTypeHeal'
    }
    Пустой или нет DoTrace - роли не играет.
    Я так полагаю, всё из-за ModeDoFire и замены FireMode класса.
    Там ведь в Syringe:
    Код:
    // Try to heal a player on the server
    function ServerAttemptHeal()
    {
        SyringeFire(FireMode[0]).AttemptHeal();
    }
    
    // The server lets the client know they successfully healed someone
    simulated function ClientSuccessfulHeal(String HealedName)
    {
        SyringeFire(FireMode[0]).SuccessfulHeal();
        if( PlayerController(Instigator.Controller) != none )
        {
            PlayerController(Instigator.controller).ClientMessage(SuccessfulHealMessage$HealedName, 'CriticalEvent');
        }
    }
    Хотя может всё и окей тут.
     
  9. Flame

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

    Сейчас некогда особо вглядываться, то если идёт вызов на Syringe и он тебя не устраивает - не делай вызов на Syringe)
    Возьми и замени SyringeFire(FireMode[0]).AttemptHeal(); тем же кодом, но в фаер классе
     
  10. Essence

    Essence Бандит

    В общем, выдрал шприц, поменял наследуемый фаер класс. Всё окей.
    Видимо, не нравится ему замена подобного типа:
    Код:
        class'KFMod.Syringe'.default.FireModeClass[0] = Class'lhPerksMut.newSyringeFire';
    Или что-то другое. Главное, что рабочий вариант я нашёл.

    Upd. Другое. Надо было ещё создать класс, наследующий Syringe и эти 2 функции поправить следующим образом:
    Код:
    // Try to heal a player on the server
    function ServerAttemptHeal()
    {
        newSyringeFire(FireMode[0]).AttemptHeal(); // Используем новый Fire класс
    }
    
    // The server lets the client know they successfully healed someone
    simulated function ClientSuccessfulHeal(String HealedName)
    {
        newSyringeFire(FireMode[0]).SuccessfulHeal(); // Используем новый Fire класс
        if( PlayerController(Instigator.Controller) != none )
        {
            PlayerController(Instigator.controller).ClientMessage(SuccessfulHealMessage$HealedName, 'CriticalEvent');
        }
    }
    Ну и тут же Fire классы можно заменить. А новый шприц выдавать, закоментив соответствующую строчку в SRHumanPawn и прописав его выдачу в SRVet* классах.
     
    Последнее редактирование: 30 окт 2016
  11. Essence

    Essence Бандит

    По поводу PatDamageStoreMut.
    Статистика обнуляется после смены карты.
    Я так полагаю, надо в SRPRI в PostBeginPlay добавить примерно такой код:
    Код:
    simulated function PostBeginPlay()
    {
        local int PatDamage;
        local PlayerController PC;
        local PlayerReplicationInfo PRI;
        PC=PlayerController(Controller);
        PRI=PC.PlayerReplicationInfo;
        if(Role<Role_Authority)
        {
            PatDamage=int(PRI.GetPropertyText("PatDamage"));
            PRI.SetPropertyText("PatDamage",string(tmpDamage+Damage));
            PatDamage=PatDamage; // Стоило дать другое название переменной в SRPRI
        }
        Super.PostBeginPlay();
    }
    И как, кстати, быть, если уже используется такое (код из Часы в ScoreBoard):
    Код:
    simulated event PostBeginPlay()
    {
        SetTimer(1.0,true);
        Super.PostBeginPlay();
    }
    Лучше тогда Тик использовать для часиков? Или можно в event код впихать, разницы не будет?

    UPD. Код в PostBeginPlay не помог.
    В логах нашёл такую строчку, которая появляется перед сменой карты:
    Warning: PatDamageStoreMut KF-Arcade-Horzinemall-FIN.PatDamageStoreMut (Function lhPerksMut.PatDamageStoreMut.SaveStats:0166) Accessed None 'PRI'

    UPD №2. Вроде как добавление "if(ActiveStats.PRI!=None)" помогло.
     
    Последнее редактирование: 7 ноя 2016
    Фрэгл нравится это.
  12. Essence

    Essence Бандит

    Итак, добавил я урон всему мед. оружию.
    Отслеживаю вылеченных игроков так:
    Код:
    function int NetDamage( int OriginalDamage, int Damage, Pawn Injured, Pawn InstigatedBy, vector HitLocation, out vector Momentum, class<DamageType> DamageType )
    {
        local SRPlayerReplicationInfo SRPRI;
        local PlayerController PC;
        local int HealedPlayersStat;
        if(Injured==None || InstigatedBy==None)
        {
            if ( NextGameRules != None)
                return NextGameRules.NetDamage(OriginalDamage, Damage, Injured, InstigatedBy, HitLocation, Momentum, DamageType);
            return Damage;
        }
        if(Injured.IsA('KFHumanPawn') && InstigatedBy.IsA('KFHumanPawn') && InstigatedBy!=None
                     && InstigatedBy.Controller.IsA('PlayerController') && Damage>0)
        {
            PC = PlayerController(InstigatedBy.Controller);
            if(PC!=None)
                SRPRI = SRPlayerReplicationInfo(PC.PlayerReplicationInfo);
    
            if(PC==None || SRPRI==None)
            {
                if(NextGameRules != None)  
                    return NextGameRules.NetDamage(OriginalDamage, Damage, Injured, InstigatedBy, HitLocation, Momentum, DamageType);
                return Damage;
            }
            // Field Medic
            if(DamageType.Name == 'DamTypeHeal' && KFGameType(InstigatedBy.Level.Game).bWaveBossInProgress)
            {
                HealedPlayersStat=int(InstigatedBy.PlayerReplicationInfo.GetPropertyText("HealedPlayers"));
                InstigatedBy.PlayerReplicationInfo.SetPropertyText("HealedPlayers",string(HealedPlayersStat+1));
            }
        }
        if(NextGameRules != None)
            return NextGameRules.NetDamage(OriginalDamage, Damage, Injured, InstigatedBy, HitLocation, Momentum, DamageType);
        return Damage;
    }
    Но засчитывать игроков он не хочет. Что я делаю не так?

    UPD. Понял, в чём моя ошибка. За дамаг нужно считать MedicReward.
     
    Последнее редактирование: 10 ноя 2016
    Flame нравится это.
  13. Фрэгл

    Фрэгл Administrator

    Ну вот,по чуть-чуть, мозгами начинаем ДУМАТЬ.Уже плюс.
     
    Последнее редактирование: 12 ноя 2016
  14. yjas0105

    yjas0105 Новенький

    Всем привет, Ребята где взять Мутатор WTF чтоб работал с СП 7.50 ? Где не пытаюсь скачать везде файлы удалены. И второй вопрос, как мне запустить 2 сервера одновременно ?
     
  15. STaJIKeR

    STaJIKeR Солдат

    по поводу второго читай форум, тут полно ответов.
     
  16. w.a.l

    w.a.l Консильери

    По поводу первого, нигде
     
  17. yjas0105

    yjas0105 Новенький

    Понял, спасибо за исчерпывающие ответы:)
     
  18. yjas0105

    yjas0105 Новенький

    Ребят, по поводу второго может кинете ссылочку на тему ? блин уже глаза на лоб лезут найти не могу:confused:
     
  19. WipeMaster

    WipeMaster Соучастник

    Не поленился бы искать.. WTF! v2.0
     
  20. w.a.l

    w.a.l Консильери

    а кто его делал под 7.5 ? Никто ! Так что ответ выше