Модератор форума: Kris†a™  
Форум » TES V: Skyrim » Мастерская » Вопросы по скриптам Papyrus (О скриптах Papyrus (Skyrim). Скриптеры не проходите мимо!)

Вопросы по скриптам Papyrus
sansuli  Offline  Сообщение №1 написано: 31 августа 2012, 13:29 | Отредактировано: Multigone - 23 апреля 2020, 14:24


The Red Sun


193
Уроки по скриптованию на языке Papyrus
Прежде чем задать вопрос просмотрите вышеуказанные уроки.
ok


Тема регламентирована.


• Прежде, чем задать вопрос, пожалуйста, убедитесь, что такой вопрос не задавался раньше. Старайтесь описать суть вопроса как можно подробней.
• Прежде, чем опубликовать ответ на вопрос, пожалуйста, убедитесь, что обладаете необходимыми для этого знаниями. Старайтесь cформулировать суть ответа как можно лаконичней.
• При желании ответить в приватном порядке, пожалуйста, воспользуйтесь ЛС.
• При желании поблагодарить ответившего, пожалуйста, воспользуйтесь кнопкой "
+" полезного сообщения.

Сообщения, не относящиеся к вопросам по скриптам Papyrus, ответам на них или уточнениям, являются оффтопом и могут быть удалены.

Красное солнце
Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
Dsion  Offline  Сообщение №2881 написано: 17 апреля 2020, 15:12



Myprism, я только об одном плюсе слышал: возможность сразу обнаружить то, что ты забыл поставить второй "=" в операторе "==". Но все-равно так очень мало кто делает.

А за переодевание... Если охота будет, то можно сделать его совместимым с любыми модами. Надо только подумать, как.
Ну, например, невидимую ауру вокруг игрока, которая будет накладывать на всех магический эффект со скриптом. Или не на всех, а только на teammate. Неоправданная трата ресурсов, да?
Я когда-то делал мод, чтоб спутники не вступали в бой и игнорирвали врагов, пока игрок в режиме скрытности. Тоже был нужен способ засовывать спутника в алиас, не зависимо от установленных модов. Да еще чтоб на Серану работало. Я тогда забил и просто добавил в диалог опцию "Пожалуйста, не выдавай наше присутствие.".

emelya8307  Offline  Сообщение №2882 написано: 18 апреля 2020, 19:08 | Отредактировано: Multigone - 21 апреля 2020, 18:54



22
Цитата yakor77

Емеля, если Вы в Яндексе погуглите "Скайрим Курица", то в первой же статье прочтёте вот такое примечание.


Нет, просто у курицы, оказывается, стоит флаг "Simple Actor", а это значт в том числе, что "Also disables the Story Manager's Death and Assault events".

То есть убийство курицы, как я понял, отключено в ивентах Story Manager, а у меня как раз этот квест построен на событии OnStoryKillActor, Стори Менеджер просто его не фиксирует. А как фиксировать я не знаю, я всего лишь третью неделю изучаю скрипты и квесты.

Myprism  Offline  Сообщение №2883 написано: 22 апреля 2020, 15:09


Физик


Multigone, буквально нашёл в коде мода, с которым сейчас разбираюсь вот такие штуки (именно то, о чём ты говорил):
Код
    String n = ((self as ReferenceAlias) As TweakSettings).originalName    
    if (n == "Erik")
  invCode=10
    elseif (n == "Iona")
  invCode=1
    elseif (n == "Calder")
  invCode=1
..............................

И если переводчик пытался эти строки переводить, то, естественно, получал неработающий код.
Иногда этот код поражает меня своим объёмом и аккуратностью, но иногда натыкаюсь вот на такую фигню...

Добавлено (26 Апреля 2020, 07:59)
---------------------------------------------
Как скриптом изменить Outfit? Нет, не заменить у персонажа один Outfit на другой, а именно изменить имеющийся или создать новый.
Outfit является расширением Form.
Из описания следует, что это специальная разновидность FormList, которая принимает только объекты Armor.
Есть команда getoutfit(),
в SKSE есть команды: getnumparts() и GetNthPart(Int n),
т.е. получить этот список легко, можно получить и его компоненты. Но как решить обратную задачу, т.е. закинуть туда свой объект?
Приведение FormList, Form[], Armor[] к(as) Outfit не работает, сообщается о несовместимости типов.

Добавлено (26 Апреля 2020, 13:11)
---------------------------------------------
Нет ли способа принудительно по ID (как по указателю в других языках) подсунуть туда данные, не объявляя типа в явном виде?


Multigone  Offline  Сообщение №2884 написано: 26 апреля 2020, 10:52



815
Цитата Myprism

Приведение FormList, Form[], Armor[] к(as) Outfit не работает, сообщается о несовместимости типов.


А что бы это дало?

Код
Outfit Property MyOTFT Auto
FormList Property MyFLST Auto

FUNCTION MyFun()
   MyOTFT = MyFLST AS Outfit
   ; Даже если бы это работало, это было бы простое присвоение переменной MyOTFT, ранее заполненной /
   / твоим комплектом, нового значения в виде MyFLST AS Outfit. Над базовой формой твоего комплекта при этом не совешится /
   / никаких действий, для этого нужна к.-л. функция (типа MyOTFT.SetSomePart(n)).


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

Dsion  Offline  Сообщение №2885 написано: 26 апреля 2020, 12:35



Я в свое время способа не нашел.
Разве что действительно создавать специальные аутфиты из LeveledItem. Там есть функции AddForm() и Revert().
Либо, как это делали большинство модов, устанавливать НИПам пустой аутфит и надевать на них все вещи вручную. Только после отключения мода они могут и голыми остаться т.к. оригинальный аутфит не вернется.

Myprism  Offline  Сообщение №2886 написано: 26 апреля 2020, 13:30


Физик


Dsion, вот в том то и дело, что мне хочется, чтобы отпущенный на волю персонаж оставался с новым оутфитом, который создал для него игрок.
Цитата Dsion

Разве что действительно создавать специальные аутфиты из LeveledItem. Там есть функции AddForm() и Revert().


А вот это мне нравится! Ведь тогда я могу менять не аутфит, а левельный список который в нём лежит! Только надо продумать, как это сделать не для всех персонажей, а только для тех, кого игрок захочет переодевать в первую очередь. Или сделать пару десятков таких аутфитов и выдавать их последним нанятым и освобождённым спутникам и когда запас подготовленных аутфитов закончится, освобождать их с конца. Надо думать.
Multigone, похоже, надо просто заменять аутфит у отпущенного персонажа на тот, что содержит только один левельный список.

Dsion  Offline  Сообщение №2887 написано: 26 апреля 2020, 13:40



Если установить НИП "голый" аутфит, а потом надеть вещи функцией equipitem() с флагом preventunequip, то они, вроде, эти вещи больше и не снимают. Даже если отключить мод.
Я бы потестил оба варианта.

Myprism  Offline  Сообщение №2888 написано: 26 апреля 2020, 15:50


Физик


Dsion, Буду всё пробовать. Сейчас игра ставит стандартный аутфит при смене интеллектуального пакета. Но если в обработчик события смены пакета поставить добавление персонажу некоторой шмотки (лук спутника, например) и тут же отобрать её обратно, то на время действия пакета игра ставит персонажу наилучший комплект из имеющихся у персонажа шмоток, вместо стандартного аутфита. Это я уже проверил. :)

emelya8307  Offline  Сообщение №2889 написано: 27 апреля 2020, 22:46



22
Уважаемые скриптеры. Хочу сделать, чтобы в сообщениях квеста отображалось количество убитых определенных персонажей. В игровых квестах это делается через тег <Global=MyGlobal>, тег заменяется значением из глобальной переменной MyGlobal . Но у меня всегда цифра 0.
В Quest Data в окне Text Display Globals я эту переменную вписал.
При убийстве определенные персонажи вносятся в эту глобальную переменную. Другие скрипты её значение нормально видят и работают с ней правильно. А в тексте сообщения, выводимого квестом всегда "убито 0". Пишу так: "Убито <Global=MyGlobal>"
Смотрел в игровых квестах, например, про виноград джазби - точно так же сделано. Но там нормально выводится значение.
Вносить значение в переменную пробовал разными командами, например:
MyGlobal.SetValue(MyGlobal.GetValue() +1)
или
ModObjectiveGlobal(1, MyGlobal)
или
MyGlobal.Value +=1
и еще другими способами.
У меня совсем нет опыта, многое делаю наугад или по аналогии с другими скриптами.

Myprism  Offline  Сообщение №2890 написано: 28 апреля 2020, 08:37


Физик


emelya8307, присоединяюсь к вопросу. Я попробовал сделать это позавчера и так же не получилось. Только у меня это не первоочередная задача, поэтому я отложил её. Что-то мы одно и то же пропускаем сделать.

Multigone  Offline  Сообщение №2891 написано: 28 апреля 2020, 10:14



815
emelya8307, возможно, не заполнено Property MyGlobal. Проверь ее значение консолью.

Для изменения значения (неважно, глобальная в форме Int или Float) всегда достаточно этого:
Код
float Function Mod(float afHowMuch)

Dsion  Offline  Сообщение №2892 написано: 28 апреля 2020, 11:10



emelya8307, Myprism, там в первом табе настроек квеста был какой-то список, в который нужно вносить все глобалы, используемые для замены текста в квесте... Видели, да?

emelya8307  Offline  Сообщение №2893 написано: 28 апреля 2020, 13:30 | Отредактировано: emelya8307 - 28 апреля 2020, 13:31



22
Dsion, Myprism, Multigone, спасибо за отклик. Заставил-таки отображаться значение переменной в сообщениях. Оно отбражается при условии, что значение переменной было изменено в этом же квесте.
А у меня при событии убийства заносилось значение в переменную, затем стартовал другой квест, из которого я пытался выцепить это значение переменной. Но оно почему-то из другого квеста не читается. Хотя квесты связаны, и в пропертях ее обьявил, и в первой вкладке квеста прописал.

Myprism  Offline  Сообщение №2894 написано: 28 апреля 2020, 13:55


Физик


Dsion, точно! Именно это я и пропустил.

Multigone  Offline  Сообщение №2895 написано: 28 апреля 2020, 16:22



815
emelya8307, если ты разбирал квест с джазби, то, наверное, видел, что там используется UpdateCurrentInstanceGlobal() для обновления кэшированного значения глобальной (квест не читает значение напрямую?).

emelya8307  Offline  Сообщение №2896 написано: 28 апреля 2020, 16:38



22
Multigone, да, я использовал UpdateCurrentInstanceGlobal(), но это ничего не давало. Квест читает только переменные, которые сам изменяет. Не знаю, как сделать по другому. Ну хотя бы так.

Myprism  Offline  Сообщение №2897 написано: 30 апреля 2020, 06:10


Физик


Как определить, каких случаях передаются данные, а в каких указатель на них. Так у меня есть скрипт:

Код
FormList    Property  TweakInv3 Auto
FormList    Property  TweakInv4 Auto

Function InventorySnapshot()
............................
    TweakInv4 = TweakInv3
...........................
endFunction

В игре обнаруживается, что любые изменения в TweakInv3 приводят к таким же изменениям TweakInv4. Т.е. в данном случае передался указатель на формлист. Как копировать именно содержимое, а самое главное: как различать, когда копируются данные, а когда только указатель?

Dsion  Offline  Сообщение №2898 написано: 30 апреля 2020, 08:13



Myprism, да, вроде, копируются только простые типы: int, float, bool, string. А всё, что наследует Form, - указатели.
Только в Oblivion и только в OBSE была функция что-то типа CloneForm, которая позволяла создать временный клон формы и изменять его. Но этот клон даже не сохранялся в сейве.

Добавлено (30 Апреля 2020, 11:20)
---------------------------------------------
Вместо формлистов, есть еще массивы в скриптах. Их можно копировать и изменять. Там только ограничение на 128 элементов.


Myprism  Offline  Сообщение №2899 написано: 2 мая 2020, 15:19


Физик


Цитата Dsion

Вместо формлистов, есть еще массивы в скриптах.


И у них есть преимущество: в них можно записывать одинаковые объекты, в то время, как в формлист только разные.

В скрипте, с которым я сейчас разбираюсь, объявлено довольно много переменных вот таким образом:
Код
Form  Property    lastLeftWeapon    Auto
Form  property    lastRightWeapon    Auto  
int   property  lastLeftCharge  Auto
int  property    lastRightCharge    Auto

Т.е. предусмотрено заполнение их как свойств извне. Но извне они никак не заполняются. Таким образом, автор скрипта использует их как обычные переменные скрипта. Одновременно, в скрипте нет других обычных переменных не объявленных свойствами. Правильно ли это? В чём сермяжная правда - объявлять все переменные свойствами, даже те, что в моде не заполняются?

Multigone  Offline  Сообщение №2900 написано: 3 мая 2020, 16:30



815
Myprism, можно оперировать Property переменными из др. скриптов, не используя напрямую ту форму, к которой прицеплен этот скрипт (т.е. не определяется через Use Info). Что-нибудь такое:
Код

Event OnTriggerEnter(ObjectReference akActionRef)
   IF akActionRef AS Actor
      MyActorScriptName xRandomName = (akActionRef AS Actor) AS MyActorScriptName
      IF xRandomName
          Int iRandomName = xRandomName.lastLeftCharge
          ...
EndEvent


Myprism  Offline  Сообщение №2901 написано: 4 мая 2020, 10:13 | Отредактировано: Myprism - 4 мая 2020, 10:14


Физик


Multigone, т.е. единственное оправдание - возможность менять переменную из другого скрипта?
Dsion, сейчас есть временный клон формы TempClone(), например:
Код
Actor npc0 = npc.TempClone() as Actor

вроде работает.

Добавлено (06 Мая 2020, 11:15)
---------------------------------------------
Попал в очередную засаду. Вот фрагмент кода:

Код
............
Outfit SleepOutfit = npc.GetActorBase().GetOutfit( true )
CN = 0
Debug.MessageBox( "Stop" )
;Utility.wait( 10.3 )
Armor TItem = SleepOutfit.getNthPart( CN ) as Armor
;Debug.MessageBox( "Stop" )
............

Весь код очень большой, поэтому я вычленил только значимый фрагмент. Дело в том, что если я размещаю в коде отладочное сообщение Debug.MessageBox( "Stop" ) вот в том месте, где оно стоит сейчас, то всё работает так, как мне нужно (это ещё не значит, что правильно :) ) Если это сообщение закоментарить, нужной мне работы не будет. Это же сообщение поставленное там, где оно сейчас закоментарено (ниже по коду), нужной мне работы не даёт (не действует).
1. Почему код с отладочным сообщением работает иначе, чем без него? Понятно, что это сообщение вызывает остановку (задержку) выполнения кода. Но когда я вместо него ставлю просто заведомо большую задержку (она сейчас закоментарена), то это не помогает.
2. Почему отладочное сообщение поставленное до строки Armor TItem = SleepOutfit.getNthPart( CN ) as Armor действует иначе, чем после неё. Переменная TItem только обозначена, заполнена, но больше нигде не используется (для поиска разгадки я всё остальное отрубил).

Dsion  Offline  Сообщение №2902 написано: 6 мая 2020, 09:22



Myprism, а индексы вещей в аутфите вообще с 0 начинаются или с 1?

Myprism  Offline  Сообщение №2903 написано: 6 мая 2020, 10:48


Физик


Dsion, да вроде в Скайриме всё с 0 начинается... Вот пример:
Код
Actor property Ralof Auto
int NumPart

Function Outfit()
    NumPart = Ralof.GetActorBase().getoutfit().getnumparts()
    while NumPart
  Numpart -= 1
  Form Clothing = Ralof.GetActorBase().GetOutfit().getNthPart(NumPart)
  If (Clothing.IsCuirass()) ;Checks for the Cuirass Keyword.
   Debug.Trace("Index " + NumPart + " is a Cuirass.")
  EndIf
    EndWhile
EndFunction

Цикл выполняется пока NumPart на его входе больше 0. Т.е. от общего числа уменьшается до 1,
которая тут же уменьшается до 0. Т.е. младшим членом является нулевой.

Dsion  Offline  Сообщение №2904 написано: 6 мая 2020, 11:09



А, сорян, это в LUA с 1 (я на нем аддоны для WOW писал). Везде с нуля, а вот LUA почему-то решили пооригинальничать.
Не, без понятия, почему не работает скрипт.

xCYNICx  Offline  Сообщение №2905 написано: 31 мая 2020, 07:13 | Отредактировано: xCYNICx - 31 мая 2020, 09:22



6
Здрасти всем. Если тут еще кто-то есть, можете помочь? Я тут создал несколько paired animations, и при помощи FNISS зарегистрировал соответствующие Anim Events. Теперь CK видит мои анимации. Я создал заклинание с магическим эффектом со скриптом, что бы проигрывать эти анимации. Все работает, но есть проблема. Эти анимации не Killmovesб после их проигрывания не предусматривается убийство NPC. И тут оказывается что если вызвать анимации во время боя, после проигрывания непись перестает сражаться и вообще что-либо делать, он тупо бегает вокруг игрока и ничего не делает)) Есть ли возможность как то это исправить, что бы после проигрывания парной анимации непись возвращался в прежнее состояние? Вообще я новичок в скриптах, прошу тапками не закидывать.

Idle Property pa_01 Auto

Event OnEffectStart(Actor akTarget, Actor akCaster)
akCaster.PlayIdleWithTarget(pa_01, akTarget)

Endevent

[b]Добавлено[/b] (31 Мая 2020, 12:09)
---------------------------------------------
Дополню. Путем многочисленных проб я обнаружил, что если в мое заклинание, инициирующее проигрывание анимации, добавить ванильный магический эффект - calm, который понижает агрессию NPC и выставить его длительность больше, чем длительность парной анимации, то после проигрывания анимации во время боя, непись снова продолжает бой, а не бегает вокруг. Видимо это как то связано с behaviors NPC во время боя, ведь парные анимации это по сути айдлы, которые должны работать в спокойном состоянии, а я пытаюсь их впихнуть во время боя. Есть ли возможность добиться такого же эффекта в самом скрипте без дополнительного эффекта calm в моем заклинании.

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

Multigone  Offline  Сообщение №2906 написано: 31 мая 2020, 09:54



815
xCYNICx, попробуй после того, как актер застрял, такое:
Код
Actor.PlayIdle(IdleStop_Loose)

Попробуй ре-экипировать оружие скриптом (UnequipItem / EquipItem).

xCYNICx  Offline  Сообщение №2907 написано: 31 мая 2020, 12:26 | Отредактировано: Multigone - 31 мая 2020, 14:22



6
Цитата Multigone

Попробуй ре-экипировать оружие скриптом (UnequipItem / EquipItem).


Спасибо за совет. Я пока только учусь папирусу, поэтому не знаю как снять конкретное оружие с NPC, но я использовал команду aktarget.unequipall(), а затем после проигрывания IdleStop_Loose анимации - akTarget.DrawWeapon().

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

Код
Event OnEffectFinish(Actor akTarget, Actor akCaster)
    NPCWeapon = akTarget.GetEquippedWeapon()
    akTarget.unEquipAll()
    akTarget.PlayIdle(IdleStop_Loose)
    akTarget.DrawWeapon()
Endevent

Multigone  Offline  Сообщение №2908 написано: 31 мая 2020, 14:21



815
xCYNICx, все функции есть в исходниках (Data/Scripts/Source). Смотри, что расширяет скрипт, который ты пишешь (Например, заголовок "Script MyScript Extends Actor"), ищи в исходниках .psc с таким именем (Actor.psc), в нем будут все допустимые функции для этого типа форм с комментами. Больше инфо о любой функции можно получить здесь, набрав в поиске ее название. Также смотри, что расширяет Actor.psc (ObjectReference), ищи ObjectReference.psc и смотри все функции, многие из них могут применяться в том числе к Actor. И так далее. Большинство скрипт-объектов имеют иерархию.

В твоем случае нужно определить, что именно влияет на исправление - экипирование, проигрывание IdleStop_Loose или мб что-то другое. Ре-экипировать оружие можно так:

Если есть SKSE:
Код
Form ActorObject = akTarget.GetEquippedObject(0)
IF ActorObject
    akTarget.UnequipItem(ActorObject)
    Utility.Wait(0.01)
    akTarget.EquipItem(ActorObject)
ELSE
    ActorObject = akTarget.GetEquippedObject(1)
    IF ActorObject
        akTarget.UnequipItem(ActorObject)
        Utility.Wait(0.01)
        akTarget.EquipItem(ActorObject)
    ELSE
        Debug.Notification("У актера нет ничего.")
    ENDIF
ENDIF

Если нет SKSE:
Код
Weapon ActorWeaponRight = akTarget.GetEquippedWeapon()
Weapon ActorWeaponLeft = akTarget.GetEquippedWeapon(true)
Armor ActorShield = akTarget.GetEquippedShield()
Spell ActorSpellRight = akTarget.GetEquippedSpell(1)
Spell ActorSpellLeft = akTarget.GetEquippedSpell(0)

Form ActorObject

IF ActorWeaponRight
    ActorObject = ActorWeaponRight
ELSEIF ActorWeaponLeft
    ActorObject = ActorWeaponLeft
ELSEIF ActorShield
    ActorObject = ActorShield
ELSEIF ActorSpellRight
    ActorObject = ActorSpellRight
ELSEIF ActorSpellLeft
    ActorObject = ActorSpellLeft
ENDIF
IF ActorObject
    akTarget.UnequipItem(ActorObject)
    Utility.Wait(0.01)
    akTarget.EquipItem(ActorObject)
ELSE
    Debug.Notification("У актера нет ничего.")
ENDIF

Можно попробовать просто убрать / достать оружие:
Код
akTarget.SheatheWeapon()
Utility.Wait(0.01)
akTarget.DrawWeapon()

xCYNICx  Offline  Сообщение №2909 написано: 31 мая 2020, 16:38 | Отредактировано: Multigone - 2 июня 2020, 18:16



6
Цитата Multigone

xCYNICx, все функции есть в исходниках (Data/Scripts/Source). Смотри, что расширяет скрипт, который ты пишешь (Например, заголовок "Script MyScript Extends Actor"), ищи в исходниках .psc с таким именем (Actor.psc), в нем будут все допустимые функции для этого типа форм с комментами. Больше инфо о любой функции можно получить здесь, набрав в поиске ее название. Также смотри, что расширяет Actor.psc (ObjectReference), ищи ObjectReference.psc и смотри все функции, многие из них могут применяться в том числе к Actor. И так далее. Большинство скрипт-объектов имеют иерархию.


Спасибо за подсказку. Теперь буду знать где искать полезные функции. Попробую все предложенные тобой варианты. Надеюсь все заработает)

У меня возник еще один вопрос. Как можно определить под каким углом стоит НПС по отношению к игроку. Например я хочу чтобы событие (анимация) произошло когда НПС стоит спиной или лицом к персонажу. Я вписал в скрипт такой код. Но работает он как то не правильно, как будто рандомно. Видимо я использую не ту функцию:
Код
Event OnEffectStart(Actor akTarget, Actor akCaster)
    if AkTarget.GetAngleZ() > 90 && AkTarget.GetAngleZ() < 270
        akCaster.PlayIdleWithTarget(pa_01, akTarget)
        Debug.MessageBox("Back")
    Else
        akCaster.PlayIdleWithTarget(pa_02, akTarget)
        Debug.MessageBox("Front")
    Endif
Endevent

Dsion  Offline  Сообщение №2910 написано: 31 мая 2020, 17:23 | Отредактировано: Dsion - 31 мая 2020, 17:27



xCYNICx, посмотри функцию GetHeadingAngle(). Скорее всего, это то, что нужно.

Форум » TES V: Skyrim » Мастерская » Вопросы по скриптам Papyrus (О скриптах Papyrus (Skyrim). Скриптеры не проходите мимо!)
Поиск:





Ответ на жалобу смотрите в разделе жалоб