• Уважаемые гости и новички, приветствуем Вас на нашем форуме
    Здесь вы можете найти ответы практически на все свои вопросы о серии игр «Готика» (в том числе различных модах на нее), «Ведьмак», «Ризен», «Древние свитки», «Эра дракона» и о многих других играх. Можете также узнать свежие новости о разработке новых проектов, восхититься творчеством наших форумчан, либо самим показать, что вы умеете. Ну и наконец, можете обсудить общие увлечения или просто весело пообщаться с посетителями «Таверны».

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!

Не стесняюсь спросить....

Лебедев

Участник форума
Регистрация
3 Сен 2005
Сообщения
595
Благодарности
77
Баллы
225
ОМГ! Ты тут с завидной периодичностью сетуешь, что тебе ТО не объяснили, ЭТО не расписали в туториалах. А между тем, получив ответ на вопрос, ты даже не пытаешься вникнуть в его смысл. *facepalm*

Ну точно. Даже в твоём варианте мне нужно сделать:

576/24 - случайное число от 0 до 24

А генератор готики будет в 75-80 случаев из 100 чисел выдавать случайные числа 0 1 2 3

Т.е. ответ так и не был получен.

Мне нужно, чтобы было в среднем 10 случаев (выпадение постоянное к примеру: сейчас числа 5, второй запуск числа 9, третий запуск числа 15, четвёртый запуск число 7 и т.д.) из 100 возможного выпадения любого числа от 0 до 24 (при каждом запуске генератора)

В сталкере генератор нормально работает и при смешивании 14 тактик (которые являются заполненными массивами случайных чисел + другие параметры) = получаю вариант - не могу предсказать где и когда, кого или чего ждать.
 
Последнее редактирование:

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.860
Благодарности
6.740
Баллы
1.625
Т.е. ответ так и не был получен.
А генератор готики будет в 75-80 случаев из 100 чисел выдавать случайные числа 0 1 2 3
Сам задал вопрос, сам на него ответил.
Если ты все это протестировал и увидел, что генератор работает только таким образом и ни как иначе, к чему ты задаешь этот вопрос?
Поразглагольствовать? можно в спец разделах.
 

Лебедев

Участник форума
Регистрация
3 Сен 2005
Сообщения
595
Благодарности
77
Баллы
225
Сам задал вопрос, сам на него ответил.
Если ты все это протестировал и увидел, что генератор работает только таким образом и ни как иначе, к чему ты задаешь этот вопрос?
Поразглагольствовать? можно в спец разделах.

Мною спросилось у Вас "Спецов"- может есть вариант прикрутить другой генератор. (Раз встроенный генератор в заданных параметрах не может отработать как нужно)

Кто чаще меня ломаланием/мододеланием готики занимался?

Нет. Тоже ответ. Придётся запасным вариантом пользоваться.
Спасибо за помощь.
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.860
Благодарности
6.740
Баллы
1.625
Мною спросилось у Вас "Спецов"- может есть вариант прикрутить другой генератор. (Раз встроенный генератор в заданных параметрах не может отработать как нужно)

Кто чаще меня ломаланием/мододеланием готики занимался?

Нет. Тоже ответ. Придётся запасным вариантом пользоваться.
Спасибо за помощь.
видимо я не правильно понял тебя.
Нет. на сколько я помню - это единственный генератор. А так даже не представляется как можно по другому случайные числа выдавать.
так что придется запасным вариантом пользоваться.
А вот если ты используешь расширения, типа аста или икаруса, то не знаю. Может они что-то умеют..
 

cool_er

Участник форума
Регистрация
23 Мар 2015
Сообщения
118
Благодарности
42
Баллы
190
Ну если движок использует "srand(time(NULL)); int x = rand() % МАКС_ЗНАЧЕНИЕ;", то все ясно. Данный подход делает появление меньших чисел вероятнее. В принципе что можно ожидать от псевдо-рандома? Везде рандом зависит от чего-либо (время, ввод пользователя, и т.д.). Скриптами не слишком многого можно в этом плане добиться. Насчет Икаруса не знаю, но вполне можно в АСТ создать свой алгоритм использую в качестве "сида" время выполнения игры, или что-либо еще. Если хочется настоящего рандома, то придется самому спроектировать квантовый механизм и распространять его вместе с модом, хотя нет, ведь из скриптов его не используешь. *trollface*
P.S: если Готика использует time(NULL), то рандому в ней придет конец в 2038 году (кто знает тот поймет) :D
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
если Готика использует time(NULL), то рандому в ней придет конец в 2038 году (кто знает тот поймет) :D
Думаю что как и в случае с "линолиумом" что нибудь придумают.. ::)
 

kraw


Модостроитель
Регистрация
11 Окт 2005
Сообщения
2.095
Благодарности
871
Баллы
295
Если нужен свой генератор псевдослучайных чисел, открываем "Искусство программирования на ЭВМ" (не помню, который том), выбираем оттуда алгоритм и реализуем его. Я имею в виду тех, кого не устраивает стандартная функция движка.

Пираньи писали игру (и модифицировали движок) исключительно для нужд своего проекта. А не для нужд сочинителей "суперпродвинутых" модов. Так, что пользуйтесь тем, что вам дали. Бесплатно. Не устраивает? не можете написать сценарий, который можно реализовать этими средствами? Переходите на другой движок. Нравится движок сталкера? Так чего же не пишете на нем?
 

cool_er

Участник форума
Регистрация
23 Мар 2015
Сообщения
118
Благодарности
42
Баллы
190
Думаю что как и в случае с "линолиумом" что нибудь придумают.. ::)
Ну дак уже придумали :D. На х64 системах возвращаемое значение которое возвращает ф-ция time длиною в 64 бита (если и приложение х64)и вроде если в имплементации используется unsigned значение, то это не только продлит жизнь, но и при ресете изначальное значение будет 0, а это не должно вызвать таких проблем. А в новом с++ есть chrono (говорят он 500 лет проживёт), но не знаю если можно его использовать для srand. *right* Единственное но это то что Готика - это х86 приложение и использует имплементацию в которой time_t - это тип signed int. :)
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Ну точно. Даже в твоём варианте мне нужно сделать:

576/24 - случайное число от 0 до 24
Давай уже не будем свою криворукость сваливать на движок, хреновых советчиков и прочая, прочая, прочая...

В спойлере функция, генерирующая случайные числа от 0 до 11 (больше поленился расписывать). Вызов её запихнул в циклическую функцию.
Код:
func void TestFunc()
{
   var int random;
   var int Hour_0;
   var int Hour_1;
   var int Hour_2;
   var int Hour_3;
   var int Hour_4;
   var int Hour_5;
   var int Hour_6;
   var int Hour_7;
   var int Hour_8;
   var int Hour_9;
   var int Hour_10;
   var int Hour_11;
   var int Hour_All;
  
   random = Hlp_Random(1000)%12;
   if(random == 0)
   {
     Hour_0 += 1;
   }
   else if(random == 1)
   {
     Hour_1 += 1;
   }
   else if(random == 2)
   {
     Hour_2 += 1;
   }
   else if(random == 3)
   {
     Hour_3 += 1;
   }
   else if(random == 4)
   {
     Hour_4 += 1;
   }
   else if(random == 5)
   {
     Hour_5 += 1;
   }
   else if(random == 6)
   {
     Hour_6 += 1;
   }
   else if(random == 7)
   {
     Hour_7 += 1;
   }
   else if(random == 8)
   {
     Hour_8 += 1;
   }
   else if(random == 9)
   {
     Hour_9 += 1;
   }
   else if(random == 10)
   {
     Hour_10 += 1;
   }
   else if(random == 11)
   {
     Hour_11 += 1;
   };
  
   Hour_All += 1;
  
   PrintScreen("0  - ",5,5,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_0),9,5,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_0*100)/Hour_All),15,5,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("1  - ",5,8,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_1),9,8,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_1*100)/Hour_All),15,8,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("2  - ",5,11,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_2),9,11,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_2*100)/Hour_All),15,11,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("3  - ",5,14,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_3),9,14,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_3*100)/Hour_All),15,14,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("4  - ",5,17,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_4),9,17,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_4*100)/Hour_All),15,17,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("5  - ",5,20,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_5),9,20,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_5*100)/Hour_All),15,20,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("6  - ",5,23,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_6),9,23,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_6*100)/Hour_All),15,23,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("7  - ",5,26,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_7),9,26,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_7*100)/Hour_All),15,26,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("8  - ",5,29,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_8),9,29,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_8*100)/Hour_All),15,29,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("9  - ",5,32,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_9),9,32,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_9*100)/Hour_All),15,32,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("10 - ",5,35,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_10),9,35,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_10*100)/Hour_All),15,35,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("11 - ",5,38,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_11),9,38,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_11*100)/Hour_All),15,38,"FONT_OLD_10_WHITE.TGA",1);
  
   PrintScreen("All - ",5,41,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_All),9,41,"FONT_OLD_10_WHITE.TGA",1);
};

А это результат её работы:
TestRandoniser.jpg

Левый столбец - случайное число, средний - количество попаданий, правый столбец - процент с учётом округления до целого.
 

Лебедев

Участник форума
Регистрация
3 Сен 2005
Сообщения
595
Благодарности
77
Баллы
225
Давай уже не будем свою криворукость сваливать на движок, хреновых советчиков и прочая, прочая, прочая...

В спойлере функция, генерирующая случайные числа от 0 до 11 (больше поленился расписывать). Вызов её запихнул в циклическую функцию.
Код:
func void TestFunc()
{
   var int random;
   var int Hour_0;
   var int Hour_1;
   var int Hour_2;
   var int Hour_3;
   var int Hour_4;
   var int Hour_5;
   var int Hour_6;
   var int Hour_7;
   var int Hour_8;
   var int Hour_9;
   var int Hour_10;
   var int Hour_11;
   var int Hour_All;

   random = Hlp_Random(1000)%12;
   if(random == 0)
   {
     Hour_0 += 1;
   }
   else if(random == 1)
   {
     Hour_1 += 1;
   }
   else if(random == 2)
   {
     Hour_2 += 1;
   }
   else if(random == 3)
   {
     Hour_3 += 1;
   }
   else if(random == 4)
   {
     Hour_4 += 1;
   }
   else if(random == 5)
   {
     Hour_5 += 1;
   }
   else if(random == 6)
   {
     Hour_6 += 1;
   }
   else if(random == 7)
   {
     Hour_7 += 1;
   }
   else if(random == 8)
   {
     Hour_8 += 1;
   }
   else if(random == 9)
   {
     Hour_9 += 1;
   }
   else if(random == 10)
   {
     Hour_10 += 1;
   }
   else if(random == 11)
   {
     Hour_11 += 1;
   };

   Hour_All += 1;

   PrintScreen("0  - ",5,5,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_0),9,5,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_0*100)/Hour_All),15,5,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("1  - ",5,8,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_1),9,8,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_1*100)/Hour_All),15,8,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("2  - ",5,11,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_2),9,11,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_2*100)/Hour_All),15,11,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("3  - ",5,14,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_3),9,14,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_3*100)/Hour_All),15,14,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("4  - ",5,17,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_4),9,17,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_4*100)/Hour_All),15,17,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("5  - ",5,20,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_5),9,20,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_5*100)/Hour_All),15,20,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("6  - ",5,23,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_6),9,23,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_6*100)/Hour_All),15,23,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("7  - ",5,26,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_7),9,26,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_7*100)/Hour_All),15,26,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("8  - ",5,29,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_8),9,29,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_8*100)/Hour_All),15,29,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("9  - ",5,32,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_9),9,32,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_9*100)/Hour_All),15,32,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("10 - ",5,35,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_10),9,35,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_10*100)/Hour_All),15,35,"FONT_OLD_10_WHITE.TGA",1);
   PrintScreen("11 - ",5,38,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_11),9,38,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString((Hour_11*100)/Hour_All),15,38,"FONT_OLD_10_WHITE.TGA",1);

   PrintScreen("All - ",5,41,"FONT_OLD_10_WHITE.TGA",1); PrintScreen(IntToString(Hour_All),9,41,"FONT_OLD_10_WHITE.TGA",1);
};

А это результат её работы:
Посмотреть вложение 46010

Левый столбец - случайное число, средний - количество попаданий, правый столбец - процент с учётом округления до целого.

Хорошо сделано, но проверка от 1 до 11. (проверка была проведена 1000 срабатываний при 11 числах т.е. 1000/11 = 90,9) (на изображении видим часто выпадают числа 1,3,9,10 т.к. их число выше или равно 90,9)
Если проверить от 1 до 24 при 1000 заданий случайного числа картина выйдет какая? (т.е. 1000/24 = 41,666) - больше диапазон срабатывания генератора и соответственно более чистая проверка генератора.

А нужно при проверке от 1 до 24 при 1000 заданий случайного числа, чтобы только 1 число имело частоту выпадения не выше 41-49. (если имеем 2 и больше чисел которые имеют число выпадения 41 или выше - генератор работает вне заданных параметров)

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

Аналогичного и хочу добиться от Готики. Иначе смысла нету от матриц, выбора чисел из матриц (если они часто будут одинаковыми заполняться)

Если нужен свой генератор псевдослучайных чисел, открываем "Искусство программирования на ЭВМ" (не помню, который том), выбираем оттуда алгоритм и реализуем его. Я имею в виду тех, кого не устраивает стандартная функция движка.

Пираньи писали игру (и модифицировали движок) исключительно для нужд своего проекта. А не для нужд сочинителей "суперпродвинутых" модов. Так, что пользуйтесь тем, что вам дали. Бесплатно. Не устраивает? не можете написать сценарий, который можно реализовать этими средствами? Переходите на другой движок. Нравится движок сталкера? Так чего же не пишете на нем?

Точно, что не пишу - только мод свой на движке сталкера имею. Новую версию с правкой DLL и т.д. вместе с модом для готики буду выпускать. (Лишних людей нету = надо всё разом выпускать)
 
Последнее редактирование:

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Если проверить от 1 до 24 при 1000 заданий случайного числа картина выйдет какая?
А самому проверить? ;)

если имеем 2 и больше чисел которые имеют число выпадения 41 или выше - генератор работает вне заданных параметров
Номер ГОСТа не подскажешь, где эти параметры заданы? Рандом, он на то и рандом, чтобы числа были случайными, а значит, с определённой вероятностью более частого появления каких-то значений. Если хочешь равномерности, перебирай по кольцу значения из одномерного массива.
 

cool_er

Участник форума
Регистрация
23 Мар 2015
Сообщения
118
Благодарности
42
Баллы
190
Аналогичного и хочу добиться от Готики. Иначе смысла нету от матриц, выбора чисел из матриц (если они часто будут одинаковыми заполняться)
Матрицы можно через массив реализовать (размер = число рядов * число столбцов) а элементы получать через формулу: индекс = ряд * число столбцов + столбец. Если ты имел ввиду что нету смысла от матриц в готе, то да, если вообще, то это фейспалм.
 

DoomDreams

Участник форума
Регистрация
16 Янв 2011
Сообщения
21
Благодарности
0
Баллы
150
Жи есть! С все таки прикрутил визуал святого болта палов к копью спящего, кто только догадался присобачить от телекинеза, в гробнице Инубиса движок готики от таких спецэффектов просто умирает. Еще бы поудалять свечение диммеловских шляп, только как они в скриптах зовутся непонятно.
 

Вложения

  • 111.jpg
    111.jpg
    1,9 MB · Просмотры: 143

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.301
Благодарности
4.636
Баллы
625
в аст работают. объект имеет *параметр жизней* и при отрицательном показателе объект ломается, где проигрывается визуал дестроя. например поломка сундука, из которого впоследствии выпадает все содержимое.

это не смотрел, пока нету желания, однако предположу. где-то в твоих постах непись перетаскивал стулья. вот из этой оперы скорее всего
 

Gor

Участник форума
Регистрация
26 Дек 2009
Сообщения
977
Благодарности
547
Баллы
245
Есть ли в движке, хоть какая-нибудь информация о параметрах moveable и takeable у обьектов класса oCMob ? Почему эти параметры не работают нормально, и что послужило причиной, предпосылкой для их отключения?
А что именно не работает нормально и что отключено можно поподробнее?
moveable
1) При использовании телекинеза проверяется сей параметр. Если oCMob может быть перемещен, то телекинез его видит.
2) Когда НПС смотрит на oCMob, то он его видит, только если он (moveable || takeable).
takeable
1) При проверке моба на интерактивность проверяется этот параметр.
2) Также при попытке воздействия на oCMob, если он в фокусе НПС.
3) пункт 2 в moveable.
 
Последнее редактирование:

Phantom95

Участник форума
Регистрация
31 Июл 2014
Сообщения
2.227
Благодарности
1.910
Баллы
370
в аст работают. объект имеет *параметр жизней* и при отрицательном показателе объект ломается, где проигрывается визуал дестроя. например поломка сундука, из которого впоследствии выпадает все содержимое.


это не смотрел, пока нету желания, однако предположу. где-то в твоих постах непись перетаскивал стулья. вот из этой оперы скорее всего
Спасибо за ответ, планируете ли в будущем адаптировать AST под г1?
А что именно не работает нормально и что отключено можно поподробнее?
Не работает, например, возможность взять мобси обьект в руки как это показано на этом скрине (предположительно из этого режима можно было переключаться на бросок моба, в скриптах это оформлено, частично.. есть хвосты.)
Goth07.jpg
К тому же я не уверен, что мобы с параметром moveable можно переместить/сдвинуть хоть немного... Увидеть бы это все на практике, если конечно возможно.
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.301
Благодарности
4.636
Баллы
625
Спасибо за ответ, планируете ли в будущем адаптировать AST под г1?
возможно

К тому же я не уверен, что мобы с параметром moveable можно переместить/сдвинуть хоть немного... Увидеть бы это все на практике, если конечно возможно.
да что там смотреть то? кода на 2 строки. получаешь моб в фокусе и конектишь его к слоту перса. вот и вся магия.
далее подключаешь воображалку и пилишь косметику типа оверлеев анимаций с переносом груза, реакции на внешние факторы и тд.

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