Crafty
28 February 2015 | 14:24
QUOTE |
@Crafty: у тебя есть какой-нибудь генеральный план твоих изменений? |
Не, плана нет ;) Был todo файлик, но сейчас он уже пустой (только что ещё добавил в код с FreeWeight изменение цвета текста на красный при перегрузке).
Fakeman
28 February 2015 | 14:52
Crafty почему у тебя все комментарии в файлах в dos кодировке?
Crafty
28 February 2015 | 15:11
QUOTE |
Crafty почему у тебя все комментарии в файлах в dos кодировке? |
В Far'е всё делаю, какую он определил в той и пишу , даже не обратил внимание :-p
Поменял на win.
Phobos
1 March 2015 | 07:16
Посмотрел твой код. Блин, что принципиально мешало соблюдать стиль существующего исходного кода? Это же базовые вещи, когда дописываешь в чужой код не нужно все ломать.
1) Вместо табуляций один пробел, в итоге код нечитаем.
2) Я так понял ты добавил все в один файл Inventory.cpp? Даже вещи не связанные с инвентарем?
3) Комментарии на русском языке, проект англоязычный, придется их переводить.
4) Пишешь на асме то что можно (и нужно) писать на С++, например вызовы функций, определенных в sfall.
5) Ты проверял свои новые хуки на конфликты с уже существующими? (достаточно сделать поиск смещения на которое ты делаешь HookCall в исходниках всего проекта). Если есть конфликт поздравляю, ты сломал какуюто другую фичу.
6) В ChangeArmorFid идет проверка конкретных PID, это неверно (суть sfall в том чтобы "расхардкодить" как можно больше), нужно смотреть прототип предмета и в нем FID.
7) Стиль кода. Если ставить пробелы до/после операторов (присваивания, сложения и т.п.), читаемость сразу возрастет. Хотя Timeslip писала в точно таком же стиле, он все равно ужасен :)
Если пойдешь на встречу и попробуешь исправить часть моментов, будет вообще отлично, можно будет твои наработки включать в официальную версию (тогда больше людей сможет насладиться плодами твоих трудов). Если же тебе это не интересно, чтож очень жаль. Одно дело скопировать готовый код с небольшими правками, другое полностью написать с нуля используя другой код как "пример", нужно намного больше времени на тестирование и т.п.
Fakeman
1 March 2015 | 17:48
QUOTE |
3) Комментарии на русском языке, проект англоязычный, придется их переводить. |
пусть учат русский)))
QUOTE |
одна из проблем это невозможность сделать полноценный "модальный" режим и блокировать клик на карту если игрок кликнул на окне |
Как бы и без Sfall'a модальность окон частично решается скриптово.
CODE |
game_ui_disable; MouseShape("mouse.pcx", 0, 0);
|
Теоретически с помощью имеющихся команд AddRegion и AddRegionProc сделать скрипт и использовать reg_anim_clear(dude_obj) то выходит оно никуда не побежит. хз не проверял надобности не было
Phobos
1 March 2015 | 19:23
QUOTE |
Как бы и без Sfall'a модальность окон частично решается скриптово. |
В том то и дело что "частично". Про решение с reg_anim_clear я в курсе, оно во всех модах и используется, но заставляет героя "дернутся" повернувшись в сторону курсора. Было бы неплохо вообще заблокировать нажатие на сетку.
А что дает отключение интерфейса и курсора?
Добавил в sfall параметр SkipSizeCheck (в секцию Debugging), последний билд:
https://yadi.sk/d/mTRKFKsMexSa2Если интересно, прошу проверить будет ли работать с модами меняющими ЕХЕшник. Нужно будет еще добавить CRC измененного файла в ExtraCRC.
Fakeman
1 March 2015 | 19:45
QUOTE |
А что дает отключение интерфейса и курсора? |
курсор не выключатся а наоборот включатся) что и дает возможность как раз таки с заблокированным интерфейсом игры и кликами по карте, управлять пользовательскими окнами. т.е. получается пока не закроешь окно игрок управлять игрой не сможет. я бы даже тут слово "частично" исключил. :)
QUOTE |
Добавил в sfall параметр SkipSizeCheck (в секцию Debugging) Нужно будет еще добавить CRC измененного файла в ExtraCRC. |
я так понял надо дописать в ini SkipSizeCheck=1 ?
тогда правильнее было бы сразу и crc отрубать, если стоит SkipSizeCheck=1
Проверил все работает.
jordan
1 March 2015 | 20:51
Кошерные изменения, хорошо бы интегрировать в стандартный билд.:)
Иначе усилия распыляются, каждый пилит свой небоскрёб, при чём несовместимый.
Phobos
1 March 2015 | 21:59
Добавил перезарядку по хоткею в официалку, но мне пришлось делать это полностью с нуля, с другим подходом.
QUOTE |
курсор не выключатся а наоборот включатся) что и дает возможность как раз таки с заблокированным интерфейсом игры и кликами по карте, управлять пользовательскими окнами. т.е. получается пока не закроешь окно игрок управлять игрой не сможет. я бы даже тут слово "частично" исключил. :)
|
О, ну это круто тогда.. Но только для модальных окон которые как бы блочат весь интерфейс. Для панелек типа как в некоторых модах это не проканает же? (они всегда доступны, когда доступна обычная панель) Плюс насколько знаю game_ui_disable Отрубает клавиатуру, то есть ты не сможешь закрыть свое окно клавишей Escape или прикрутить к нему другие клавиши.
QUOTE |
тогда правильнее было бы сразу и crc отрубать, если стоит SkipSizeCheck=1 |
CRC все равно нужен. На случай если игрок заменит ЕХЕшнит каким-нибудь несовместимым. То есть моддер (или игрок) должен убедится что ЕХЕшник совместим и сознательно вбить его CRC. Так мы избегаем непонятных баг репортов о вылетах на форумах модов...
Fakeman
1 March 2015 | 23:54
QUOTE |
Для панелек типа как в некоторых модах это не проканает же? (они всегда доступны, когда доступна обычная панель) Плюс насколько знаю game_ui_disable Отрубает клавиатуру, то есть ты не сможешь закрыть свое окно клавишей Escape или прикрутить к нему другие клавиши. |
Ну ды, тут только химичить с AddRegion с "дерганным" героем.
Пойду попробую скриптану с использованием этой связки, скажу потом о результате.
QUOTE |
CRC все равно нужен. ... То есть моддер (или игрок) должен убедится что ЕХЕшник совместим и сознательно вбить его CRC. |
а ну да. все правильно)
Отправлено: 2 мар 15 01:46
Phobos
В общем с AddRegion в связке с game_ui_disable и MouseShape решается вся проблема и нет никакого "дерганья" героя. Так что решение полностью рабочее, даже работает если регион пересекается с кнопкой окна т.е. срабатывает и событие кнопки, правда не совсем разобрался как правильно размер региона задавать оно там как то по хитрому сделано. ладно суть скрипта получается такая(подумаю поймешь)
AddRegionProc("window_reg", none, none, game_ui_disable, game_ui_enable)
а MouseShape нужен для того чтобы вовремя нажатия по окну не пропадал указатель мыши.
Phobos
2 March 2015 | 17:39
Попросил Джима попробовать твой вариант (в его моде как раз это нужно), в общем неполное это решение. Если зажать мышкой по кнопке и увести не срабатывает событие unpress, UI залипает, приходится кликать еще раз по кнопке.
Он какой-то костыль замутил через hs_moveblocking (не дает ГГ двигаться или поворачивать) работает надежнее, но это все равно костыль...
Придется ждать новый движок... :D
Fakeman
2 March 2015 | 18:47
QUOTE |
Если зажать мышкой по кнопке и увести не срабатывает событие unpress, UI залипает, приходится кликать еще раз по кнопке. |
во косяк...
тогда в событие on(off) региона (и для надежности кнопки тоже) прописывается процедура с game_ui_enable, косяк с залипанием остается, но автоматически отлипает при наведении мыши на окно или кнопки без нажатия.
еще придется конкретно усложнять скрип чтобы выключенный интерфейс из другого скрипта не включался при наведении на окно. в общем полная фигня)
Кстати ты не в курсе как он задавал размеры региона, я вчера сидел тыкал-мыкал так и не смог правильно создать регион по размеру окна.
AddRegion reg_name {x, y, x, y, x, y, ...} вот и как тут понимать какие x/y куда относятся.
QUOTE |
Придется ждать новый движок... :D |
да ну юзаем reg_anim_clear и чихать что оно дергается)
Phobos
2 March 2015 | 20:11
Ну хак через хук скрипт лучше работает :)
По поводу регионов, вот комментарий из исходников sslc:
CODE |
// // regions are defined as: // // region "name", { x, y, x, y, x, y, x, y }; // // meaning if the mouse is clicked in the region defined by the // list of points, procedureName is called. // // Regions are related to the currently selected window.
|
Судя по коду компилятор принимает любое количество пар координат, т.е. сколько угодно точек. Видимо многоугольник.
Fakeman
2 March 2015 | 21:49
QUOTE |
Ну хак через хук скрипт лучше работает :) |
хук в официалке будет?
QUOTE |
region "name", { x, y, x, y, x, y, x, y }; Судя по коду компилятор принимает любое количество пар координат, т.е. сколько угодно точек. Видимо многоугольник. |
спс разобрался.
Phobos
3 March 2015 | 11:12
QUOTE |
хук в официалке будет? |
Он там давно уже был, старая фича. Если очень интересно, можно выпросить код у Джима.
Вышла 3.6 официалка.
Fakeman
3 March 2015 | 13:24
QUOTE |
Он там давно уже был, старая фича. Если очень интересно, можно выпросить код у Джима. |
Аа... я подумал он специально для своего мода что-то там соорудил)
Ну так-то если можно давайте код, ибо я не совсем понимаю как с это реализовать через hs_hexmoveblocking.
или скажи название его мода гляну сам как скрип реализован.
Phobos
3 March 2015 | 13:36
Вот
тут он описал, смотри раздел про UI.
Crafty
8 March 2015 | 10:18
Добавил отключение абуза отрицательных эффектов (от наркотиков/радиации/etc) при чтении книг поесть наркотиков, дождаться побочных эффектов и под ними читать книги, а за счёт динамического расчёта статов получать больше очков к скиллу.
Метод абуза подробно описан
здесь. Перки не трогал (вообще-то трогал, но закомментил код, потому что там нужен более серьёзный подход).
Довёл до ума "пропадание" неиспользованного перка при получении следующего перкового уровня как оказалось в sfall уже было это исправление, но сделано (как и мой первый вариант) на скорую руку (открыть экран персонажа -> взять перк -> "положительно" закрыть экран персонажа -> открыть -> взять перк -> "положительно" закрыть и т.д.), сейчас нормально (открыть -> взять перк -> взять перк -> ... -> "положительно" закрыть).
Fakeman
10 March 2015 | 17:07
Еше раз немножко Оффтопну
QUOTE |
Вышла 3.6 официалка. |
то Phobos: в sfall есть небольшой баг тянется наверное еще с древних версий 2х, в общем суть такая если сменить разрешение в игре(hires) без перезапуска и начать игру то sfall не правильно определяет разрешение т.е. функции get_screen_width(), get_screen_height() возвращают не правильные размеры экрана. во такие дела)
Crafty
17 March 2015 | 23:46
Долгое время я знал о дополнительных кнопках прокрутки списка квестов в пипбое (если включить их в ddraw.ini через
UseScrollingQuestsList=1), но не мог понять как это работает и считал что эта возможность просто сломана. Начав играть в Неваду я наконец-то обратил внимание на те малюсенькие кнопки, да и то только потому что они перекрывали надпись "Задания" ("Статус" в оригинальном F2) в пипбое. Решил заменить их на что-то поприличнее :-p
В конечном итоге я почти полностью переработал и расширил функционал кнопок прокрутки квестов в пипбое: больше размер (кнопки прокрутки из инвентаря), новая позиция (лучше видно), неактивность кнопок когда нечего прокручивать (если открыта последняя страница квестов, то кнопка перехода на следующую становится неактивной), навигация такая же как при просмотре голодисков (кнопка вверх|
PgUp и кнопка вниз|
PgDn переход по страницам, кнопка вверх|
PgUp на первой странице возврат в окно со списком зон|голодисков), также кнопки теперь можно использовать и при просмотре голодисков.
Добавил горячие клавиши для кнопок управления пипбоя '
1' для "Статус", '
3' для "Карты", '
4' для "Архивы". На '
2' повесил будильник. Не стал вешать на '
5' закрытие пипбоя для этого и так хватает горячих клавиш (
p|
P|
Esc|
Enter).
Исправил два бага движка в пипбое они не шибко критичны и проявляются в определённых ситуациях. Суть первого (скриншот
здесь) если открыть окно "Статус" и нажать
Page Up или
Page Down когда курсор мыши находится в левой части (там где 1), то теперь нельзя будет кликнуть по голодискам из части 3, а клик по голодиску из части 2 будет открывать список квестов из части 1 (клик по "Военная база уровень 1" откроет список квестов в Дыре).
Суть второго если открыть пипбой в зоне где спать нельзя, затем открыть любое окно с кликабельным списком ("Статус", "Карты" или "Архивы") и после этого вызвать будильник, то после закрытия окошка с сообщением о невозможности спать клик по зоне будет вызывать сон из будильника.
Поэтому в первом случае клавиши "заморожены", а во втором вызов будильника в "бодрой" зоне автоматом открывает окно "Статус".
Баги исправляются только при UseScrollingQuestsList=1 лень выносить их отдельно.
Ещё поднял выше окно выбора перков на экране персонажа и раскомментил код для перков при отключении абуза эффектов наркоты.
Drobovik
18 March 2015 | 21:00
Crafty,
А можешь перекомпилить sfall c твоими изменениями и новыми сорсами 3.6?
Спасибо
Crafty
19 March 2015 | 18:46
QUOTE |
А можешь перекомпилить sfall c твоими изменениями и новыми сорсами 3.6? |
Готово ;) Это "релизная" версия dll, но в ней оставлены SkipSizeCheck и ExtraCRC из секции [Debugging].
И теперь баги кликабельности в пипбое исправляются независимо от значения переменной UseScrollingQuestsList.
Само собой ReloadWeaponHotKey удалена.
Update: Поправил оригинальный подсчёт квестов на страницу, к примеру 21 квест раньше показывался на первой странице 1-10, на второй 10-19, на третьей 19-21. Сейчас 1-10, 11-20, 21.
Fakeman
21 March 2015 | 13:55
QUOTE |
Решил заменить их на что-то поприличнее :-p В конечном итоге я почти полностью переработал и расширил функционал кнопок прокрутки квестов в пипбое: больше размер (кнопки прокрутки из инвентаря), новая позиция (лучше видно), |
Что-то не очень удачная позиция кнопок...
Такое предложение -вывести настройки x,y для положения кнопок в ini-файл сфала, чтобы можно было настроить под любой мод с измененной картинкой pip-boy.
Crafty
21 March 2015 | 17:56
QUOTE |
Что-то не очень удачная позиция кнопок... |
Почему? Для оригинала отлично, и даже в Неваду вписались. Для Олимпа согласен не подходит, ну так там кнопки и не нужны если судить по настройкам ini-файла. А какие ещё есть моды со своей картинкой пипбоя?
Были варианты поместить кнопки в
4 и 5 части.
QUOTE |
Такое предложение -вывести настройки x,y для положения кнопок в ini-файл сфала |
Честно лень ;)
Fakeman
21 March 2015 | 21:01
QUOTE |
Были варианты поместить кнопки в 4 и 5 части. |
вот место 4 так и просится на кнопки, но что-то как-то высоковато
Покачанушке)
а если их немного сместить влево чтобы на сетке были, а не на "бордюре" пипбоя.
CODE |
Для Олимпа согласен не подходит, ну так там кнопки и не нужны |
это пока не нужны.
так что давай не ленись)
Crafty
21 March 2015 | 23:53
QUOTE |
а если их немного сместить влево чтобы на сетке были, а не на "бордюре" пипбоя. |
Не вписывается в концепт зачем на сетке кнопки прокрутки :-p И для Невады будет неочень.
Если судить по обсуждениям на форуме Олимпа, то "Олимп 2" будет на новом движке.
И будем честными вероятность появления нового серьёзного проекта на движке F2 стремится к нулю...
QUOTE |
так что давай не ленись) |
Организационные вопросы мучают как назвать переменные для ini-файла (QuestsScrollButtons[X|Y]?), какой угол брать за стартовую точку (нижний левый?). А ведь можно вообще каждую кнопку отдельно размещать. Дуристика это :-p
Fakeman
22 March 2015 | 02:26
QUOTE |
Не вписывается в концепт зачем на сетке кнопки прокрутки :-p И для Невады будет неочень. |
а что на бордюре экрана вписывается в концепт? :D
ну если ты мерил по невадскому пипбою тогда ладно...
QUOTE |
какой угол брать за стартовую точку (нижний левый?) |
не знаю как у вас там в параллельном мире, но у нас тут принято считать от верхнего левого. :)
QUOTE |
Организационные вопросы мучают как назвать переменные для ini-файла (QuestsScrollButtons[X|Y]?)
|
вот сам же и ответил на вопрос QuestsScrollButtonsXY=123,346
QUOTE |
И будем честными вероятность появления нового серьёзного проекта на движке F2 стремится к нулю... |
Не спорю. Но как говориться "надо вася..."
Crafty
22 March 2015 | 04:20
QUOTE |
а что на бордюре экрана вписывается в концепт? :D |
Конечно, провода же вписываются :-p
QUOTE |
вот сам же и ответил на вопрос QuestsScrollButtonsXY=123,346 |
Хлопотно, строку разбирать :)
Две переменных QuestsScrollButtonsX и QuestsScrollButtonsY, с границами 0-618 для X и 0-434 для Y. Всё равно размер окна пипбоя (640x480) зашит в движке.
Перенёс обработку горячих клавиш для кнопок управления пипбоя (1-4) в другое место, а то ранее работали только при UseScrollingQuestsList=1.
Crafty
24 March 2015 | 20:29
Вообще убрал ограничение на максимальное количество квестов (10) на странице сколько на экране пипбоя помещается, столько и показывается.
Crafty
1 April 2015 | 04:19
Наконец-то дошли руки допилить отображение свободного веса в окне обмена (что включается через FreeWeight). Теперь свободный вес показывается и при обмене с предметами (ящики/багажник/etc) и во время воровства или торговли (свободный вес не показывается для торгаша, посколько ему можно продавать вещи даже загоняя в минус по весу).
Однако при обмене с предметами используется размер/объём, а не вес. И размер как правило не равен весу размер пустой снайперской винтовки равен 5, а весит она 8.
Формат "свободный вес/максимальный вес" для персонажей и "свободный объём/максимальный объём" для предметов.
Значение FreeWeight игнорируется (равно 0) если переменная CritterInvSizeLimitMode не равна 0. Конечно надо было бы это дело совместить, но желания пока нет ;-p
А ещё в пипбое при просмотре списка квестов если больше одной страницы, то наверху показывается номер страницы ("1 из 2") аналогиично как при просмотре многостраничных голодисков.
Fakeman
2 April 2015 | 23:25
QUOTE |
Теперь свободный вес показывается и при обмене с предметами (ящики/багажник/etc) |
Так что-то мне опять не нравится :)
а нельзя ли сделать цвет шрифта веса зеленым а не белым?
и расположить веса не в слотах для предметов, а под картинками чюза и объекта, по мне такое расположение выглядело бы логичнее)
QUOTE |
Это "релизная" версия dll, но в ней оставлены SkipSizeCheck и ExtraCRC из секции [Debugging]) |
А можно еще оставить и возможность DebugMode ?
Crafty
3 April 2015 | 01:02
QUOTE |
а нельзя ли сделать цвет шрифта веса зеленым а не белым? |
Можно, но всё равно нечётко в окне торговли/обмена с сопартийцем.
QUOTE |
и расположить веса не в слотах для предметов, а под картинками чюза и объекта, по мне такое расположение выглядело бы логичнее) |
Не, нельзя место под картинкой объекта используется для кнопок прокрутки по объектам если их несколько (трупы в одном месте).
QUOTE |
А можно еще оставить и возможность DebugMode ? |
Нет смысла, проще сразу отладочную версию собрать кинул в архив в \debugging.
Fakeman
3 April 2015 | 13:49
QUOTE |
Не, нельзя место под картинкой объекта используется для кнопок прокрутки по объектам если их несколько (трупы в одном месте). |
QUOTE |
отладочную версию собрать кинул в архив в \debugging. |
Спасибо то что мне нужно!
Ну а цвет веса при бартере можно было оставить и белым ибо с зеленый шрифт не сочетается с доской.
Crafty
3 April 2015 | 15:13
QUOTE |
не, ты не понял я имел ввиду вот так |
Просто ты проверяешь на маленьком шкафе, а ведь есть и более крупные (навскидку сразу могу сделать скрин как раз из Невады Солт-Лейк, завод ядер-колы, здание с верстаком напротив офиса, полки во второй комнате) и там текст накладывается точно на картинку, а не серый фон. Ещё и придётся дописывать свою процедуру перерисовки части экрана. И опять же следуя стилю нужно и при торговле/обмене с сопартийцем выводить свободный вес не на доске, а под картинками персонажей.
QUOTE |
Ну а цвет веса при бартере можно было оставить и белым ибо с зеленый шрифт не сочетается с доской. |
Общая процедура для вывода текста свободного веса, потому цвет меняется везде.
Белый тоже сливается, всегда напрягало. В каком-то старом варианте я менял на чёрный (ну не совсем), выглядело намного лучше.
Fakeman
3 April 2015 | 16:46
QUOTE |
а ведь есть и более крупные и там текст накладывается точно на картинку |
да в курсе...
Я вот вообще не вижу никакого смысла показывать этот вес(размер) для контейнеров. Можно этот размер к багажнику машины прикрутить, а для остальных вырубить, вот такое мое мнение :)
Crafty
3 April 2015 | 23:49
QUOTE |
Я вот вообще не вижу никакого смысла показывать этот вес(размер) для контейнеров. Можно этот размер к багажнику машины прикрутить, а для остальных вырубить, вот такое мое мнение :) |
Кушать не просит, почему бы и не показывать :-p
В F2 в качестве временных хранилищ я использовал шкаф в доме Гришэма в Модоке, шкафчик во второй комнате мастерской дочери Вика в Городе Убежище и ещё кучу подобных мест, особенно до появления машины.
Crafty
5 April 2015 | 15:42
Люблю масштабные битвы так чтобы куча врагов и добра после них. Потом всё добро собрать и разрядить. Да вот беда если оружие одинаковое, но патроны в нём разные, то после разрядки будет не один, а два стака оружия каждый для своего типа патронов. Жутко неудобно. Поправил ;)
Если оружие без патронов воруется, перекладывается в/из объект[а], подбирается с земли и конечно же разряжается руками, то тип используемых патронов меняется на патроны "по умолчанию" для этого оружия. При торговле или обмене не меняется.
На форуме Олимпа затронули вопрос оптического прицела и связанного с ним штрафа дистанции, я там
отписался и думаю стоит добавить решение в sfall. Глупо считать что если оружие с оптическим прицелом, то стрелять можно только глядя в оптику.
Crafty
8 April 2015 | 02:08
Добавил фикс для "Too Many Items Bug" ("если неожиданно становится невозможно зайти на какую-либо карту из-за того, что игра виснет на черном экране") предотвращает создание битых .SAV с картами из-за которых баг и проявляется. Но если уже есть битый сейв, то утилита
TooManyItemsBug в помощь.
PS. Если действительно интересно расскажу в чём суть бага.
Update: Добавил ещё одну проверку.
The Master
8 April 2015 | 10:22
Ну где-то описывалось, читал даже, но освежить и донести до тех, кто не знает, не помешает. Пиши :)
Crafty
10 April 2015 | 10:25
QUOTE |
Ну где-то описывалось, читал даже, но освежить и донести до тех, кто не знает, не помешает. Пиши :) |
Мой рассказ таков, что без бутылки и не понять ;)
В общем, с каждой картой связано 5 типов скриптов (s_system, s_spatial, s_time, s_item, s_critter).
Для активной в данный момент карты каждый тип скриптов хранится в памяти в таком виде:
CODE |
Пример ┌──────────┐ ┌───────┐ │FirstBlock│ = │Block_1│ │LastBlock │ = │Block_3│ │BlockNums │ = │3 │ │Id │ = │неважн.│ └──────────┘ └───────┘ |
FirstBlock указатель на первый блок, а LastBlock на последний блок скриптов этого типа.
BlockNums количество блоков скриптов этого типа.
Если BlockNums = 0, то FirstBlock и LastBlock равны 0 и скриптов этого типа нет. Если BlockNums = 1, то LastBlock равен FirstBlock.
В свою очередь каждый блок скриптов (Block_1...Block_3) хранится в памяти в таком виде:
CODE |
Block_1 Block_2 Block_3 ╔═╤═════════╤═══════╗ ╔═╤═════════╤═══════╗ ╔═╤═════════╤═══════╗ ║+│скрипт_1 │ ║ ┌─>─╢+│скрипт_17│ ║ ┌─>─╢+│скрипт_33│ ║ ║+│скрипт_2 │ ║ │ ║+│скрипт_18│ ║ │ ║ │ │ ║ ║+│скрипт_3 │ ║ │ ║+│скрипт_19│ ║ │ ║ │ │ ║ ║+│скрипт_4 │ ║ │ ║+│скрипт_20│ ║ │ ║ │ │ ║ ║+│скрипт_5 │ ║ │ ║+│скрипт_21│ ║ │ ║ │ │ ║ ║+│скрипт_6 │ ║ │ ║+│скрипт_22│ ║ │ ║ │ │ ║ ║+│скрипт_7 │ ║ │ ║+│скрипт_23│ ║ │ ║ │ │ ║ ║+│скрипт_8 │ ║ │ ║+│скрипт_24│ ║ │ ║ │ │ ║ ║+│скрипт_9 │ ║ │ ║+│скрипт_25│ ║ │ ║ │ │ ║ ║+│скрипт_10│ ║ │ ║+│скрипт_26│ ║ │ ║ │ │ ║ ║+│скрипт_11│ ║ │ ║+│скрипт_27│ ║ │ ║ │ │ ║ ║+│скрипт_12│ ║ │ ║+│скрипт_28│ ║ │ ║ │ │ ║ ║-│скрипт_13│ ║ │ ║+│скрипт_29│ ║ │ ║ │ │ ║ ║-│скрипт_14│ ║ │ ║+│скрипт_30│ ║ │ ║ │ │ ║ ║-│скрипт_15│ ║ │ ║+│скрипт_31│ ║ │ ║ │ │ ║ ║-│скрипт_16│ ║ │ ║+│скрипт_32│ ║ │ ║ │ │ ║ ╟─┴─────────┼───────╢ │ ╟─┴─────────┼───────╢ │ ╟─┴─────────┼───────╢ ║Количество │16 ║ │ ║Количество │16 ║ │ ║Количество │1 ║ ╟───────────┼───────╢ │ ╟───────────┼───────╢ │ ╟───────────┼───────╢ ║Указатель │Block_2╟─>─┘ ║Указатель │Block_3╟─>─┘ ║Указатель │0x0 ║ ╚═══════════╧═══════╝ ╚═══════════╧═══════╝ ╚═══════════╧═══════╝ |
Когда в игре для карты добавляется новый скрипт, то добавляется он в конец последнего блока (увеличивая количество скриптов в этом блоке) или если количество скриптов равно 16 в этом блоке, то создаётся новый блок и скрипт добавляется в него.
При смене карты её состояние записывается в имя_карты.sav, который потом будет использоваться при записи игры (для текущей карты файл этой карты перезаписывается в момент записи игры). Важно то, что записываются все скрипты (каждого типа скриптов) связанные с картой, но сначала блоки чистятся от "неактивных" скриптов (я не стал разбирать структуру скриптов и точно не знаю почему некоторые скрипты не записываются, поэтому называю их "неактивными" они связаны с игроком) с помощью обмена содержимого "неактивного" скрипта с первым доступным "активным" скриптом из конца списка. Само собой подсчитывается количество записываемых "активных" скриптов, но не трогается содержимое остальных блоков скриптов количество скриптов в блоках и указатели на следующий блок (указатели после записи карты будут нужны для освобождения памяти).
После чистки наступает очередь записи сначала записывается подсчитанное количество "активных" скриптов, а потом содержимое блоков, включая значения количества скриптов в блоке и указатель на следующий блок (при загрузке карты значение указателя игнорируется).
Однако при этом движок вместо того чтобы использовать подсчитанное количество записываемых "активных" скриптов пользуется данными из блоков и это провал.
Лучше на примере есть 3 блока скриптов, в 1 и 2 по 16 скриптов, в 3 один скрипт. Всего 33 скрипта, которые после чистки 4 "неактивных" скриптов станут 29. Движок должен записать первый блок, изменить количество скриптов во втором блоке и затем записать его.
В действительности, поскольку не был изменён указатель на последний блок, движок записывает два блока, затем обнаруживает что в третьем блоке "неактивный" скрипт и нигде не изменяя количество скриптов завершает обработку скриптов этого типа.
Что приводит к некритической ошибке (с поправкой на то, что в действительности представляют из себя "неактивные" скрипты). Если проверить любой из своих сейвов, то с большой вероятностью найдётся несколько некритических результатов этого бага (но карта будет рабочая). Если воспользоваться утилитой TooManyItemsBug:
CODE |
Number of script's descriptors in 3'th sequence = 29 In 0'th block, 16 scripts were used. In 0'th block, 4 unknown bytes = 26002544. In 1'th block, 16 scripts were used. In 1'th block, 4 unknown bytes = 240554040. In last block 4 unknown bytes = 240554040. |
Ошибка становится критической когда количество "неактивных" скриптов сдвигает список на один или более блоков и до чистки блоков было больше двух. Для нашего примера пусть будет 20 "неактивных" скриптов должен быть записан только первый блок с 13 скриптами, но движок запишет ещё второй блок (ведь указатель на последний блок не поменялся), который и будет являться причиной зависания при загрузке этой карты. Для TooManyItemsBug:
CODE |
Number of script's descriptors in 3'th sequence = 13 In 0'th block, 16 scripts were used. In 0'th block, 4 unknown bytes = 26002544. In last block 4 unknown bytes = 26002544. Unused block detected. In unused block, 16 scripts were used. In unused block, 4 unknown bytes = 1. |
Update: "Неактивные" скрипты это скрипты связанные с игроком (ну там скриптовые вещи в инвентаре).
А вот описание бага на английском:
QUOTE |
The too many items bug I don't know exactly how it works technically, but what happens is that late in the game, if you have too many (different) items in one location, this will eventually corrupt maps. The number of items in question includes what you and your NPCs are carrying, the items on critters and in containers on the map (including shops), plus the stuff in your car no matter if it's present or not. The bug triggers upon leaving an area, and means that next time you try to enter that map, your computer will lock up completely. Many people have reported this behaviour; you'll notice how the "orbiting rocket" mouse pointer shows up on the screen, but doesn't animate. The hard drive might buzz for a while then fall silent. Depending on your system you may have to turn your computer off entirely. If you reload the game the same thing will happen again eventually, or right away if the save includes the broken state of the map you're trying to enter (but since a map goes bad only when you leave it, the current map of each save will never be corrupted, thankfully). Maps will become corrupted more frequently as you continue to play and amass items, making the game nearly (or literally) unplayable towards the end.
The simplest way to prevent this from happening is to avoid carrying around quest items which you have no further use of. If you want to keep them, don't store them in your trunk but in some accessible container on a map where there are no shops, or where there are not too many items anyway. If you want to be doubly safe, avoid selling too many different items in one place. If you're not in the habit of hoarding items, this will probably not be an issue. |
© Per Jorner, The Nearly Ultimate Fallout 2 Guide v1.2
Crafty
14 April 2015 | 16:04
Исправил два бага при использовании инвентаря игрока (вызов через 'I'). У них общая причина возникновения связанная с обратным порядком хранения предметов инвентаря в памяти первый предмет в инвентаре (самый верхний в списке) хранится в памяти последним, и наоборот последний предмет в инвентаре (самый нижний в списке) хранится в памяти первым. Поэтому движок должен менять порядок когда использует данные о предметах инвентаря. В инвентаре игрока движок об этом "забывает", что приводит к двум ошибкам.
Ошибка первая визуальная при взятии предмета мышкой если предмет был в единственном экземпляре, то место откуда предмет взят становится пустым (стирается), если там несколько предметов, то место остаётся прежним (картинка предмета не стирается), но уменьшается счётчик количества предметов. В инвентаре игрока это сломано.
Пример: в инвентаре лежит 4 предмета пистолет, автомат, винтовка и 3 стимулятора. Если взять мышкой пистолет, то движок использует данные о количестве стимуляторов и не сотрёт картинку места откуда взят пистолет. Если взять автомат, то картинка будет стёрта используются данные винтовки. Взятие винтовки тоже сотрёт картинку используются данные автомата. Взятие же стимулятора вместо того чтобы оставить картинку и уменьшить количество предметов на месте сотрёт её используются данные пистолета.
Ошибка вторая техническая вряд ли кто знает, что для зарядки оружия/складывания предметов в сумку помимо способа "взять оружие в руку, а затем перетащить патроны из инвентаря в руку с оружием" существует и другой способ "перетащить патроны из инвентаря в оружие в инвентаре". В движке такая возможность есть, но правильно она не работает (это когда работает).
Пример: в инвентаре лежит 3 предмета снайперская винтовка, патроны 0.223 и охотничье ружьё. Если перетащить патроны на винтовку, то зарядится ружьё. И наоборот :-p
Уже после исправления я обнаружил что установленный High Resolution Patch (который F2_RES) может дополнительно сломать уже сломанное ;) Если переменная IFACE_BAR_MODE из f2_res.ini равна 1, то сбивается порядковый номер слота (добавляется 1) куда перетаскивается предмет. Пример приводить не буду ;)
Fakeman
16 April 2015 | 19:46
QUOTE |
Ошибка первая визуальная Ошибка вторая техническая |
вот не поверишь, никогда не замечал таких ошибок... *убежал проверять так ли это на самом деле* :))
Crafty
17 April 2015 | 19:48
Бывает в бою нужно подлечиться открываю инвентарь, использую стимпаки и "чтобы два раза не бегать" © заряжаю оружие перетаскивая патроны в руку с оружием. И тут вылазит это навязчивое окошко с предложением указать количество коробок патронов... Капут окошку ;)
Теперь клавиша перезарядки (ReloadWeaponKey) кроме собственно перезарядки оружия дополнительно функционирует как "Использовать" для не оружия.
Изменил минимальное и максимальное значение возраста игрока с 16-35 (возрастная аудитория?) на 8-60 :-p
Включённый DrugExploitFix дополнительно не позволит абузить повышение скиллов под отрицательным эффектом (101% в Легкое оружие поесть баффаутов, дождаться отрицательного эффекта и качать скилл за 1 поинт вместо 2).
А при получении перков игнорируются и отрицательные эффекты (ранее только положительные). При 10 ловкости в списке перков не будет "Добавить ловкости", но под отрицательным эффектом появится.
Fakeman
18 April 2015 | 13:55
QUOTE |
И тут вылазит это навязчивое окошко с предложением указать количество коробок патронов... Капут окошку... |
Не совсем понял что-ты сделала с окошком... ты что его убил :'(
Crafty
18 April 2015 | 18:05
QUOTE |
ты что его убил :'( |
Вроде того :-p
Окошко вызывается когда количество коробок патронов больше 1 и возвращает введённое количество в диапазоне 1-макс.количество коробок. Вместо вызова окошка сразу возвращается макс.количество коробок.
Естественно это только при перетаскивании патронов в оружие в остальных случаях (сумка, багажник или торговля) окошко вызываться будет.
Исправил ещё один хитрый баг при зарядке оружия в инвентаре если оружие в единственном экземпляре и находится перед патронами, то используется только одна коробка патронов даже если указать макс.количество коробок.
Fakeman
19 April 2015 | 00:10
Это ты зря!!!
Ты не подумал о ситуации когда у игрока допустим есть 3 пачки патронов, 2 из них он захочет зарядить в пулемет(магазин 3 пачки), а одну оставить, так как у него во второй руке пистолет с тем же калибром патронов который потом в бою нужно будет перезарядить, а нечем!!!! сечешь)
Crafty
19 April 2015 | 03:21
QUOTE |
Ты не подумал о ситуации |
Притянуто за уши, но разумно (ох уж эти любители создавать себе проблемы) ;)
Поправил если макс.количество пачек патронов больше значения переменной ReloadReserve (по умолчанию = 1), то возвращает "макс.количество пачек минус ReloadReserve", или 1.
Fakeman
19 April 2015 | 13:21
Я бы тебе посоветовал сделать это немного по другому.
оставить окошко но с возможностью отключения его в ini-файле, и при перетаскивании патронов на слот с оружием в окошке устанавливалось бы макс.количество патронов... ну так как ты реализовал это изначально.
как тебе идея?
Crafty
19 April 2015 | 14:55
Не :-p
Drobovik
19 April 2015 | 19:36
CraftyПредлагаю внедрить
данный фикс.