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

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

  1. Essence

    Essence Moderator Команда форума

    Кто-нить пытался отрисовывать текстурки с помощью DrawTileStretched снизу вверх и реально ли эт вообще? Или можно ток справа налево и сверху вниз растягивать текстуру?

    UPD. Как я думал, DrawTileStretched растягивает текстуру только справа налево и сверху вниз.
     
    Последнее редактирование: 10 фев 2019
  2. STaJIKeR

    STaJIKeR Капо

    Доброе время суток, есть ли возможность выдавать группу SPRI.bIsVIP (bool)?
    Какие есть способы выдачи такой группы?
     
  3. Essence

    Essence Moderator Команда форума

    В файл моба. Куда пихнуть вызов этой функции думаю сам решишь.
    Код:
    function AttachedActorsDebugLog()
    {
        local int i;
        for(i=0; i<Attached.Length; i++) Log("Num"@i@"Name"@Attached[i].Class.Name);
    }
     
  4. Mikizverb

    Mikizverb Новенький

    Добрый день, подскажите как изменить у этого оружия (THR40) обычный выстрел на дробь !
     
  5. sindzi

    sindzi Соучастник

    всем привет!

    подскажите реально ли как-то узнать какую версию игры (конкретно язык) использует игрок?
    не важно serverperks или какой-либо другой мутатор.
     
  6. Essence

    Essence Moderator Команда форума

    Если ток через костыли, русский/английский.
    Код:
    var string LangStringRus; // Нельзя писать на кириллице в коде. Только в defaultproperties. Если хотим написать что-то по-русски, то объявляем переменную.
    
    // Функция для удобства статическая
    static function string GetUserLanguage()
    {
        if(Class'KFGameType'.Default.SandboxGroup~=Default.LangStringRus) Return "RUS";
        Return "ENG";
    }
    
    defaultproperties
    {
        LangStringRus="Песочница" // Строка для сравнения
    }
     
    Flame нравится это.
  7. Arthur88

    Arthur88 Соучастник

    Доброго времени суток, друзья. Появилась необходимость передавать в функцию таймера индекс последней проверенной переменной. Не могу придумать как это сделать. Отметил проблемный участок комментарием в функции Timer, может кто сообразит:
    Код:
    function CheckRestrictZone()
    {
        local PlayerController PC;
        local SRPlayerReplicationInfo SRPRI;
        PC = PlayerOwner();
        SRPRI = SRPlayerReplicationInfo(PC.PlayerReplicationInfo);
        if(SRPRI.bShowWarning && ... && ...) {
            ShowWarning();
            ...
        }
        else if(...) {
            ...
        }
    }
    
    function ShowWarning()
    {
        local PlayerController PC;
        local int i;
        local string WarnLine[8];
        PC = PlayerOwner();
    
        if(...) {
            WarnLine[0] = class'FillWarnLine'.static.WarnLine[0];
            WarnLine[1] = class'FillWarnLine'.static.WarnLine[1];
            WarnLine[2] = class'FillWarnLine'.static.WarnLine[2];
            WarnLine[3] = class'FillWarnLine'.static.WarnLine[3];
            WarnLine[4] = class'FillWarnLine'.static.WarnLine[4];
            WarnLine[5] = class'FillWarnLine'.static.WarnLine[5];
            WarnLine[6] = class'FillWarnLine'.static.WarnLine[6];
            WarnLine[7] = class'FillWarnLine'.static.WarnLine[7];
        }
    
        for(i = 0; i < 8; i++) {
            if(WarnLine[i] != "") {
                PC.ClientMessage("WARNING!"@WarnLine[i]);
                ViolationCheck();
                SetTimer(15, false);  // задержка в 15 секунд между сообщениями
                return;
            }
        }
    }
    
    function ViolationCheck()
    {
        if(...) {
            ...
            SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo)bForgiven = true;
        }
        else
            SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo)bForgiven = false;
    }
    
    function Timer()
    {
        if(SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo)bForgiven)
            return;
    
        // Здесь в функцию ShowWarning нужно как-то передать
        // индекс (i) последней проверенной "WarnLine",
        // чтобы не начинать с i = 0.
        // Вернее на +1 больше последней проверенной "WarnLine", т.к. она уже проверена и тоже нам не нужна.
        // Как это сделать?
        ShowWarning();
    }
     
  8. Flame

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

    Код:
    WarnLine[3] = class'FillWarnLine'.static.WarnLine[3];
    эээ
    Может не static, а default?
    Или WarnLine(3), если это функция, а не переменная?

    Ну а по сути вопроса
    ShowWarning зовёт таймер, а Таймер зовёт ShowWarning

    Напиши нормальным языком чего тут вообще происходит (цель всего этого)
    Ибо это точно неадекватная реализация чего бы то ни было)

    Ну или может Эссенс тебя сможет понять)
     
  9. Arthur88

    Arthur88 Соучастник

    Да, WarnLine - не статик, а дефолт, верно подметил. Но не суть. По идее WarnLine будут наполняться текстом по условиям отдельной функции, а не тупо заданы в дефолтсах. В общем-то мне и таймер не нужен, просто не знаю как по-другому сделать интервал в 15 секунд между сообщениями, при том, что сообщения не должны печататься, если игроком выполнены условия (то есть он перестал нарушать, к примеру). Грубо говоря останавливаем вывод сообщений, если всё хорошо. Либо продолжаем выводить сообщения с последнего, которое уже было отправлено клиенту, если нарушение с его стороны продолжается (значит надо как-то запоминать номер последнего отпечатанного сообщения). То, как это сейчас работает - обычный цикл, таймер вызывает ShowWarning и сообщения начинают выводиться с самого первого, что не есть хорошо)
     
  10. Flame

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

    Так
    Уже понятнее, но уточню:

    Есть какой-то массив с сообщениями и если в SRPlayerReplicationInfo игрока переменная bForgiven==false мы печатаем сообщения из этого массива по одному с паузой в 15 секунд. Правильно я понял?

    После того, как последнее сообщение в массиве отправлено мы прекращаем отправлять или заново начинаем с 1 сообщения?
     
  11. Arthur88

    Arthur88 Соучастник

    Совершенно верно. К примеру пусть пока будет просто массив из 8 строк.

    Проверяем bForgiven, если false, то продолжаем отправлять сообщения, но не с первого, а с того, которое было отправлено последним. Вот этот момент отловить и регулировать не получается. К примеру последним было сообщение из WarnLine[3], значит нужно продолжать с WarnLine[4], но цикл этого не позволяет.
     
  12. Flame

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

    Чегот я запутался
    Индекс то как меняется? Каждые 15 секунд вызывается сообщение со следующим индексом или каждые 15 секунд вызывается сообщение с текущим индексом (который меняется где-то ещё)?

    То есть
    Сообщение[0] -> пауза 15 секунд -> Сообщение[1] -> пауза 15 секунд -> Сообщение[2]...
    или
    Сообщение[0] -> пауза 15 секунд -> Сообщение[0] -> пауза 15 секунд (+ мы где-то поменяли индекс) -> Сообщение[1]...
     
  13. Arthur88

    Arthur88 Соучастник

    Нет, всё правильно поняли. Проходит 15 секунд, вызывается сообщение со следующим индексом (i++). Но только, если bForgiven за эти 15 сек. НЕ станет true. Поэтому и нужно как-то запоминать индекс последнего сообщения, которое было выведено пока bForgiven был false. Знаю, слишком сумбурно излагаю желаемое. Вообще, если бы была нормальная пауза в unreal script'е, то и цикл был бы в данном случае не нужен, наверное
     
  14. Flame

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

    Тогда ещё уточню. Если мы дошли до последнего сообщения, то дальше его и продолжаем воспроизводить?
    То есть первые n-1 сообщений по одному разу с паузой 15 секунд, а последнее до победного?)

    Ну а вообще лично я бы сделал через Item в Inventory (тут можно глянуть пример)
    И просто бы в Item'е хранил бы индекс в глобальной переменной
    То же самое можно реализовать и в SRPlayerReplicationInfo

    Если делать серверный мутатор, то тогда можно хранить в массиве структуру ID+Индекс
    Если делать клиентский мутатор, как представлено выше, то надо проверять что там с глобальной переменной происходит. Возможно там надо будет помучиться со свойствами актёра (мутатора), чтобы не было вызовов чужой версии мутатора.

    Я накидаю пару реализаций. Днём в воскресенье. Через клиентский мутатор (ибо самому интересно, возможны ли там косяки) и через Item (ибо я так бы и делал) )
     
    Arthur88 и Essence нравится это.
  15. Arthur88

    Arthur88 Соучастник

    Вот здесь я протупил) Последнее сообщение нужно вывести тоже всего 1 раз, а после завершить функцию ShowWarning и не возвращаться к ней. Предполагается, что после последнего (восьмого) сообщения, игрок кикается.
     
  16. Flame

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

    Ну вот и неспеша наступает воскресенье))
    Я глянул чуток - сделал чисто клиентский мутатор
    Код:
    class SendMessageMut extends Mutator;
    
    var array<string> Message;
    var int i;
    
    simulated function PostBeginPlay()
    {
        SetTimer(15.0,true);
    }
    
    simulated function Timer()
    {
        local PlayerController PC;
        PC = Level.GetLocalPlayerController();
        if(PC==none)
            return;
        PC.ClientMessage(Message[i]);
        i++;
        if(i==Message.Length)
            SetTimer(0,false);
    }
    
    defaultproperties
    {
        bAddToServerPackages=True
        bAlwaysRelevant=true
        RemoteRole=ROLE_SimulatedProxy
    
        Message(0)="Message1"
        Message(1)="Message2"
        Message(2)="Message3"
        Message(3)="Message4"
        Message(4)="Message5"
    
        GroupName="KF-SendMessageMut"
        FriendlyName="SendMessageMut"
        Description="SendMessageMut"
    }
    

    Сюда можно добавить проверку на bForgiven и сообщения будут идти только когда bForgiven==false
    У каждого клиента свой экземпляр мутатора, поэтому индекс можно делать просто как глобальная переменная
    А на сервере мутатор не выполняется, потому что там Level.GetLocalPlayerController() всегда none

    Ссылка

    Но вообще мне такая реализация не нравится
    Практика показывает, что мододелам очень сложно работать с клиентскими мутаторами
    Нужна серверная реализация. Сделаю серверную версию через Item с нормальным функционалом
     
    Arthur88 нравится это.
  17. Arthur88

    Arthur88 Соучастник

    Благодарю, работает как и требовалось) Честно говоря я не догадался в самой функции таймера делать инкременет индекса, всё ломал голову как передать последний известный индекс в таймер. Пока оставлю так, но подожду серверный вариант, если это более правильно
     
  18. Arthur88

    Arthur88 Соучастник

    Поместил мутатор в состав пакета ServerPerksMut, пытался вывести bool переменную в конфиг ServerPerks.ini, чтобы регулировать включение/отключение, не выключая сам мутатор. В итоге у меня получилось только в теле таймера сделать проверку переменной из конфига через реплецирование в классе SRPlayerReplicationInfo. Но это неоптимально, потому что переменная будет проверяться с каждым вызовом таймера. Не знаю как сделать проверку переменной в функции PostBeginPlay. В таймере сделал так:
    Код:
    simulated function Timer()
    {
        local PlayerController PC;
        local SRPlayerReplicationInfo SRPRI;
        PC = Level.GetLocalPlayerController();
        SRPRI = SRPlayerReplicationInfo(PC.PlayerReplicationInfo);
        if(PC==none)
            return;
        // если bCheck из конфига ServerPerks.ini равен True
        // естественно работает только когда на сервере есть игрок
        if(SRPRI.bCheck) {
           PC.ClientMessage(Message[i]);
           i++;
        }
        if(i==Message.Length)
            SetTimer(0,false);
    }
    По уму нужно сделать так:
    Код:
    simulated function PostBeginPlay()
    {
        // вопрос в том как проверить эту переменную из ServerPerks.ini, если мутатор не является одним из штатных классов СП, а представляет собой самостоятельный мутатор в составе пакета СП
        if(bCheck)
           SetTimer(15.0,true);
    }
    Также не совсем понимаю можно ли в принципе напрямую читать конфиг ServerPerks.ini из SendMessageMut, если он (мутатор) чисто клиентский, учитывая модификатор simulated в том же PostBeginPlay и свойство RemoteRole=ROLE_SimulatedProxy
     
    Последнее редактирование: 12 сен 2019
  19. Flame

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

    Вот поэтому я и писал))
    "Практика показывает, что мододелам очень сложно работать с клиентскими мутаторами"

    Серверный вариант нужен для нормальной работы)