Полная Версия: Неофициальный патч для Fallout 2 от 1C
nicknn
Задумал я вновь пройти Фаллаут спустя 6 лет :) На этот раз с переводом от 1С и патчем Киллапа.
Но начал издалека, с проверки изменений 1c и совместимости с патчем. Чтобы в очередной раз не видеть *ERROR*.

1C Unofficial patch

Анализируя изменения внесённые разработчиками 1c, я обнаружил что часть скриптов была взята из версии 1.00 вместо 1.02.
Причём часть была взята без изменений, а в другие внесены правки для разделения фраз в зависимости от пола избранного.
Различия в этих скриптах между версиями 1.00 и 1.02 были в удалении op_global_var(18) из части проверок. А вот в скриптах 1c
они остались.
CODE
-  if ((op_metarule(16, 0) - op_global_var(18)) > 1) then
+  if (op_metarule(16, 0) > 1) then

gvar 18 это GVAR_PLAYER_GOT_CAR. То есть флаг означающий, что избранный собрал машину. Проанализировав один из скриптов, я
пришёл к выводу, что баг заметный. Мне попался часовой из Наварро, охраняющий вход на базу. В ходе диалога выполняется проверка
на количество спутников избранного. Если оно не нулевое, то он должен не пускать под предлогом, что новобранцы заходят по одному.
Но так как в 1.02 машина уже не является партийцем, то вычитание машины из количества партийцев приведёт к ситуации, когда
избранного пустят на базу с одним партийцем при наличии машины.
Нехорошо. Поэтому я решили исправить этот недостаток. Скрипты без модификаций от 1с я просто взял из 1.02. Скрипты с модификациями
я исправил.

В архиве patch000.dat. В него уже включён последний патч от 1C. Достаточно распаковать в директорию с игрой, с заменой оригинального
файла, если у вас он есть. Начинать заново не нужно, ничего, что влияет на сохранения там не меняется.
Скрипты отдельно, если кому-то нужно :)

Скрипты, что попали в 1c из 1.00 вместо 1.02 без изменений.
CODE
ccacon.int
ccatech.int
cccomp1.int
cccomp2.int
cccook.int
ccdoctor.int
ccdrill.int
ccggbak.int
ccgguard.int
ccmandr.int
ccqmstr.int
ccraul.int
cctech1.int
cctech2.int
dcsheila.int
fcfmatt.int
fcskids.int
hcdoc.int
ksbboard.int
ocjul.int
qcturret.int
schal.int


А это скрипты, что были взяты из 1.00 вместо 1.02 и модифицированы:
CODE
ccchris.int
ccgrdca.int
ccgrdpa.int
cckevin.int
ccmedgrd.int
ccquincy.int
qcbird.int
qccurlng.int
qcgengrd.int
qcmurray.int
rcjosh.int
rcsavine.int
rcstanwl.int
rcwade.int
sckarl.int
vcandy.int
vcskeeve.int


P.S.
Сам ещё не запускал, отпишите если есть проблемы ;)
The Master
Привет, круто, надо проверить, если патч Киллапа последний не перекрывает твои исправления, то я был бы рад включить их в следующую версию своего русификатора :) Можно же, или эта работа уже была проделана?
nicknn
Привет.
Часть скриптов пересекается, это я уже точно выяснил. Нужно объединять. А выкладывать чуток не пересекающихся не спортивно.
Вообще я анализировал возможность соединить 1c и RP и на данный момент видно, что из 249 пересекающихся скриптов, 203 удачно объединяются автоматически.
Так что не все так плохо. Но я хочу точно убедится, что не сломаю чёнить.

Вообще я не точно выразился, я хочу попробовать Restoration Project и изначально хотел объединить с ним.
Но ведь Killap's Fallout 2 Unofficial Patch его часть ;) и там меньше скриптов.
Значит сделаю для обоих:
  • Unofficial Patch
  • Restoration Project
Сделаю точно, но по времени ничего не скажу. Может за три дня а может и за три недели :(

Можно тебя попросить протестировать мой этот патчик. Я собирал скрипты через noid compiller используя более новую версию ruby (на котором этот компиллер написан).
Посему не совсем уверен в работоспособности. А поиграть самому на работе нет возможности.
The Master
Да без проблем, но возьмусь только через пару дней, не раньше, потому что работа.
QUOTE
Я собирал скрипты через noid compiller используя более новую версию ruby (на котором этот компиллер написан).

Один великий товарищ сделал BIS-компилер, х32 совместимый, с препроцессором. Надо попросить поделиться :)
Drobovik
Nicknn, не хочу тебя сильно огорчать, но чтобы ты знал, скрипты собранные без сорсов Киллапа Вы зовут проблемы. Он использует собственные заточенные headers. Даже если тебе покажется, что скрипт работает, он может создать проблемы в другом скрипте. Поверь мне. Я недавно с Киллапом общался на эту тему. Пока он не выложил первоисточник, скрипты лучше не трогать.
nicknn
Я не использую сорсы. Я декомпилирую int. При условии, что декомпилятор корректен (а нойдовский вполне успешно докопилировал то, что не осилил int2ss), то мой труд не бесполезен.

Хедеры полезны при написании своего мода. А для соединения изменений это не имеет значения. Ведь 1C то свои не выложит :)

Drobovik
Ну, тогда хозяин — барин.

Так ты получается код реплик женских из 1С тоже внедряешь в Киллапские скрипты?
Wasteland Ghost
Нойдовский компилер, мягко говоря, устарел. Настоятельно не советую. Чем там ныне народ компилирует? Кажись, заточенным под sfall вариантом? Или Анхоритовскую версию с архивов ТимЫкс утянуть можно. Ибо если не декомпилируется нормально — значит что-то не так. А Нойд это "не так" может банально игнорировать.
nicknn
QUOTE
Так ты получается код реплик женских из 1С тоже внедряешь в Киллапские скрипты?

Именно это и есть основная цель модификации скриптов. Хочется чтобы старания переводчиков не пропадали даром. Ведь в русификации RP добавленные 1С фразы остались. Но без модификации скриптов они бесполезны. Этот недостаток я и хочу исправить. Ну а вот этот патч для 1C это побочный продукт.
QUOTE
Нойдовский компилер, мягко говоря, устарел. Настоятельно не советую. Чем там ныне народ компилирует? Кажись, заточенным под sfall вариантом? Или Анхоритовскую версию с архивов ТимЫкс утянуть можно. Ибо если не декомпилируется нормально — значит что-то не так. А Нойд это "не так" может банально игнорировать.

Я скачал архив целиком. в разделе утилит есть следующее:
  • int2ssl Декомпилятор для FO1/2. Синтаксис BIS компилятора. Anchorite
  • sslc2 Компилятор для FO2. Синтаксис BIS компилятора. Anchorite
  • Noid Compiler Компилятор/декомпилятор Noid'а. Noid
  • Noid Decompiler Декомпилятор Noid'а в виде одного исполняемого файла. Noid
Похоже здесь нету заточенного под sfall варианта.

int2ssl не смог декомпилировать 22 скрипта Каллапа, сославшись на неизвестный опткод. Но нужных мне из низ всего 3. Именно по этому я решил перейти на нойдовский.
Он отлично справился с задачей. Хотя он не имеет в себе опткодов, добавленных в sfall. При встрече неизвестной конструкции он генерирует "asm вставки" вместо неизвестных ему конструкций.
CODE

 if ((op_game_time() - game_timer2) >= (7 * (24 * (60 * (60 * 10))))) then
 begin
   op_set_global_var(26, 0);
   op_set_critter_stat(op_dude_obj(), 1, 2);
   asm(0x801a);
   op_display_msg(op_msg_string(1, 802));
   if (not op_has_trait(2, op_dude_obj(), 11)) then
   begin
     asm_push_value(4);
     asm(0x81dd);
   end
 end


То есть записывает для себя последовательность операций в скомпилированном int. В компиляторе затем эти конструкции обрабатываются и превращаются вновь в "байткод". Очень красивое решение на мой взгляд.

Так чем же сейчас принято пользоваться? исходники + компилятор ? Уже никто не декомпилирует ? :)
Drobovik
Я делал то же самое, что и ты. Менял скрипты, вставляя женские варианты. Было сделано около 25 скриптов. Использовал декомпилятор Noid's Ruby sFall Compiler-Decompiler от Nirrana отсюда. Он обновлен для использования функций sfall. Там же есть SSL-sFall decompiler by Anchorite.

Еще есть sfall script editor от Timeslip.

Но, опять же повторюсь, я лучше дождусь исходников + хедеров Киллапа. Все таки он автор мода и знает, что делает, когда говорит, что лучше с декомпиляторами не баловаться для серьезного релиза. Так надежнее.

К тому же версия RP 2.3 и патча 1.02.29 на носу (первая половина декабря 2013). Ты уверен, что хочешь заново перепроверять скрипты?)
Wasteland Ghost
Таймслиповским, кажись, народ на НМА пользуется.

Не буду врать, ибо давно это было :), но, кажется, с Нойдовским компилером были какие-то проблемы. С тех пор, как Анхорит переделал KA под Фол, пользовались sslc. Таймслип позже выпустила набор утилит, совместимых с дополнительными функциями sFall. Кроме того, был ещё малоизвестный вариант с подправленными функциями обработки строк, не знаю, вошло куда-то или так и кануло в лету...
nicknn
QUOTE
Я делал то же самое, что и ты. Менял скрипты, вставляя женские варианты. Было сделано около 25 скриптов.

То есть мои труды всё же бесполезны ?
Ну ладно, хоть патчик для 1C получился. Проверю и покопаю скрипты тогда для себя.
Drobovik
Почему же бесполензно. Когда у меня будут сорсы может мы объединимся и ты поможешь мне исправить скрипты для женского населения?
Wasteland Ghost
Править скрипты для ради только перевода — в принципе бесполезное занятие. Тем более для перевода 1С: там 99% фраз можно безболезненно "обезличить".
nicknn
Итак поколупал я компиляторы и декомпиляторы из пакета modderspack 3.1.7z. Там обновленные скрипты от Noid, sslc int2ssl.
Тестировал всё на скриптах killap. В начале скрипты были декомпилированы, а затем собраны вновь. Две версии int файлов сравнил по md5. Всего скриптов 1315.
Первым был набор от Noid. Он успешно декомпилировал всё. Но один скрипт собрать назад не смог. После лёгкой правки полученного ssl все собралось успешно. Проблема была с процедурой, которая внезапно была создана как принимающая параметры. Хотя они никогда не используются. Причём именно в таком виде она присутствует в оригинальных исходниках F2. Видно Noid не предвидел такого поворота событий :) Это похоже единственная процедура с параметрами.
Не сошлось контрольных сумм 322.
Далее тоже самое было проделано с int2ss и sslc. int2ssl успешно декомпилировал всё. Но не собралось назад 3 файла. В одном получился перл вида if (foo --100 > 0). В других были ошибки связанные с неверными расстановками ";". собрать не удалось.
Не сошлось контрольных сумм 128. Неплохой результат.

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

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

Далее я продолжил анализ Niod. Сразу повезло. Нашёлся скрипт, в котором адрес перехода для if был равен _нулю_. Это происходит если встречается пустой блок if.
CODE
if (foo > 0)
Begin
End

sslc корректно вставляет адрес следующей за O_IF инструкции, а вот нойдовский вставляет ноль. Что-то мне подсказывает, что если проверка не выполнится, то будет вылет при такой конструкции. Такая пустая проверка присутствует в хедерах от оригинального F2. Видно и такого поворота событий Noid не предвидел :) На этом я закончил его анализировать.

Далее перешёл к sslc. У него обнаружилось очень неприятная особенность. Он иногда добавляет O_POP в самый конец процедуры. Я не знаю насколько опасна эта особенность, но она сильно затрудняет анализ кода. Так как меняются все смещения и diff получается почти на весь файл. Слудующая особенность так же связана с O_IF. Если встречается вложенный if, причём после это ифа кода больше нет. В опткодах в оригинале это будет выглядеть как:
CODE
адрес на "дальнейший код". (1)
аргументы
O_IF
адрес на "дальнейший код" (2)
аргументы
O_IF
полезный код
безусловный переход на следующую строку :)
дальнейший код

sslc же в случае (2) ставит адрес на "безусловный переход на следующую строку"
Вроди не сильно критично, но не приятно, md5 от этого не сходится.
Следующее выявленное различие было в использовании импортируемой переменной. скрипт bcgengrd импортирует i_Guard_Count. Её использование в опткодах везде выглядит как
CODE
O_STRINGOP(0x0000037e)
O_FETCH_EXTERNAL

но вот когда к ней добавляют 1 в оригинале используется O_INTOP(0x0000037e).
sslc по прежнему использует O_STRINGOP. Опять же не знаю насколько это безопасно. На этом остановился, так как дальше в основном были O_POP и нужно было прилагать много усилий для анализа. Может ещё продолжу очистив дампы от адресов. тогда различия будут видны лучше.

Можно сделать вывод, что всё отстой и тлен. Даже корректный скрипт может привести к вылету после компиляции.
Но ничего лучше у нас нет. Так что для модификации Лучше использовать сырцы Киллапа и уточнить у него чем он собирал.

QUOTE
Когда у меня будут сорсы может мы объединимся и ты поможешь мне исправить скрипты для женского населения?

Вновь глянул в правки 1C. Наверное лучше согласится с Wasteland Ghost. Все проверки на пол 1C делает у избранного (op_dude_obj), а значит _сильно_ проще иметь два комплекта msg. Для мужского и для женского персонажа. Так как в F2 сейчас будут играть тока олдфаги, то им не составит труда установить нужную версию диалоговых скриптов. Ведь каждый, кто садится переигрывать уже зарание создал план. Кто-то будет мужиком, а кто-то сразу станет Баффи ради халявных гранат.

Могу скриптом сделать два вида msg вставив сообщения добавленный 1C в места которые они заменяют. Получится два варианта перевода М и Ж.
Из того что можно взять у 1C и в этом я готов помочь:
1. Правка охранника у входа в город убежище.
Тут перепутаны местами фразы о том что нельзя заходить в город с гулями и мутантами. 1c правили это в скрипте но это нужно исправить в диалоге! Причём в двух местах. (Тут 1c зафейлили не заметив.). Файл vcgatgrd.msg. Нужно поменять местами строки 109 и 110, 111 и 112. Опционально 129 и 130, но они хоть и присутствуют но процедуры их использующие не задействованы.
2. Локализация отсчёта времени до взрыва вышки и Сиерра.
3. Посмотреть, что можно сделать с проверкой op_msg_string(403, 100) == "You see one of the Reno townsfolk."
С этим условием мне вообще не ясно, оно правда может не выполниться ? Это похоже на бред!
в любом случае sslc отлично реагирует даже на юникод в переменных :) Если бисовкий компилятор не осилит ничего кроме ASCII то можно отредактировать бинарник. Главное чтобы длина строк в байтах совпадала. Ну и конечно неясно как поведёт себя движок...


Drobovik, я вижу, что ты пишешь на nma. Не мог бы ты написать Киллапу о баге vcgatgrd.msg. Я вижу, что у него нет этого исправления.
Давно не заглядывал туда, Киллап согласился дать исходники?
Drobovik
1. ОК, про баг охранника напишу ему, если еще не исправлено.
2. а что там с отчетом. Я его после убийства Френки правил.
3. Проблема уже решена в грядущей версии РП 2.3

Edit: у меня в РП, Маркуса называют мутантом. Не вижу никакого бага. Может ты не те скрипты смотришь.
nicknn
С Маркусом и Ленний мой косяк :(
Не заметил, что Киллап действительно это исправил. Я подумал, что это логично править в диалоговом скрипте, а он исправил это как и 1C в скриптах. Тока в другом месте.

CODE
procedure Node005
begin
-  op_float_msg(op_self_obj(), op_msg_string(94, 109), 8);
+  op_float_msg(op_self_obj(), op_msg_string(94, 110), 8);

procedure Node006
begin
-  op_float_msg(op_self_obj(), op_msg_string(94, 110), 8);
+  op_float_msg(op_self_obj(), op_msg_string(94, 109), 8);

procedure Node007
begin
-  op_float_msg(op_self_obj(), op_msg_string(94, 111), 8);
+  op_float_msg(op_self_obj(), op_msg_string(94, 112), 8);

procedure Node008
begin
-  op_float_msg(op_self_obj(), op_msg_string(94, 112), 8);
+  op_float_msg(op_self_obj(), op_msg_string(94, 111), 8);



Отправлено: 9 дек 13 17:17
С отсчётом времени твой вариант хорош
CODE
{112}{}{ минут(ы) и }
{113}{}{ секунд(ы) для эвакуации.}
{114}{}{ минута и }
{115}{}{ секунда для эвакуации.}

Но можно и в скриптах добавить проверку
Там не сложно
CODE
-      if (LVar2 == 1) then
-        op_display_msg(LVar1 + op_msg_string(146, 114) + LVar2 + op_msg_string(146, 115));
+      if ((LVar2 % 10) == 1) then
+        op_display_msg(LVar1 + op_msg_string(146, 112) + LVar2 + op_msg_string(146, 115));
+      else if (((LVar2 % 10) > 1) and ((LVar2 % 10) < 5)) then
+        op_display_msg(LVar1 + op_msg_string(146, 112) + LVar2 + op_msg_string(146, 116));
      else
-        op_display_msg(LVar1 + op_msg_string(146, 114) + LVar2 + op_msg_string(146, 113));
+        op_display_msg(LVar1 + op_msg_string(146, 112) + LVar2 + op_msg_string(146, 117));


Правки от 1C:
 — охранник ворот волтсити: Есть у Киллапа
 — комп управления турелями на вышке: Есть у Киллапа
Значит из полезного тока отсчёт времени.

Что там слышно с исходниками RP? Киллап не горит желанием их выложить ? Или вначале хочет выпустить обновление ?
Drobovik
Да, походу не горит, пока не выпустит финальную версию.
Он настроен на дату перед Рождеством, где-то в районе 23 декабря.
Ваш ответ: