Гайд-Парк
X3 Terran Conflict / X3 Земной конфликт
 
X3 Terran conflict  
 

На сайте онлайн (человек): 91



 



Гайд-Парк

Форумы: Terran Conflict (X3TC) / X3 Земной конфликт / Скрипты и моды для X3 Terran Conflict / Гайд-ПаркВойти
Количество: 8
1
Гайд-Парк
01.10.2011 20:06:24
YOYOMAN

Репутация: 1800
Сообщений: 4277
Регистрация: 20.11.2009
 Всем привет!!!

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


 
Правила размещения уроков:

  • Урок должен быть изложен в доступной форме с достаточным для урока обьемом информации. Текст на 1 абзац не принимается!
  • Обязательно содержать изображения и схемы, которые должны быть доступными для понимания и соттвествовать изложеной информации.
  •  Текст урока должен содержать подробное описание хода работ.
  • Рекомендованый максимальный размер изображения или схемы - не больше 580 пикселей для типа "Картинка в тексте" если превышаете  лимит размера размещайте превью.
  •  Запрещается дублирование уроков в теме.
 


Флуд в даной теме строго запрещается!!! Все сообщения не по теме будут удалены!




Быстрый переход


НазваниеПереход
1Структура файлов TWare B,E,F,M,N,T и создание нового товара в них=>
2Создание полнофункциональных врат=>
3Структура файла TShields и создание нового щита=>
4WareLists aka Списки встроенных товаров=>
5Изменение параметров тренировки десанта и абордажа с помощью HEX-редактора. Модификация obj-файла=>
6Структура файла TCockpits и создание нового набора вооружения=>


Редактировалось 10 раз (а). Последний раз 19.02.2012 23:06:52.

01.10.2011 20:06:50
YOYOMAN

Репутация: 1800
Сообщений: 4277
Регистрация: 20.11.2009
Структура файлов TWare B,E,F,M,N,T и создание нового товара в них.

Общие сведения

    
 Файлы типа TWare B,E,F,M,N,T - это файлы, которые хранят все товары имеющися в игре, а также информацию о них.
  В игре все товары разделены на определённые категории. Если открыть в игре энциклопедию,
то в разделе "Товары" можно видеть несколько категорий:
 
  • Корабельное оборудование.
  • Усовершенствования корабля.
  • Другие товары.

     В свою очередь, раздел "Другие товары" содержит ещё разделы:
     
    • Биотовары.
       
    • Минералы.
       
    • Продукты питания.
       
    • Сельхозпродукты.
       
    • Техника.
       
    • Енергия.
  •  

     Ну а теперь более конкретно про файлы товаров:
     
     
  • TWare B "Bio" - в даном файле храняться товары, которые находяться в подразделе "Биотовары" раздела "Товары" игровой энциклопедии. Содержит 16 обьектов.
     
  •  TWare E "Energy" - все товары, которые считаются енергие  прописаны тут, на даный момент в оригинальном файле есть только товар "Батареи". Содержит 1 обьект.
     
  • TWare F"Food"  -  сюда относятся товары занесёные в категорию "Продукты питания". Содержит 13 обьектов.
     
  • TWare M "Minerals" -  все ресурсы которые содержаться в астероидах, записаны тут. Содержит 4 обьекта.
     
  • TWare N "No trade" -  все товары, которые не используются как ресурсы и продукты файбрик, заводов или доков находятся в этом файле. В основном они используются для общей имитации жизни в игре, ипользуемые мисиоными скриптами (MD) или просто генерящися в трюмах кораблей НПС. Содержит 80 обьектов.
     
  •  TWare T "Tech" - в этом файле собраны товары  различных категорий, которые используются для торговли на станциях, оборудование кораблей (в том числе недействующее), использующееся как боеприпасы к некоторым видам оружия и даже особые обьекты, такие как  мины, лазерная башня,боевые дроны и спутники, которые при помещениии в трюм корабля считаются товаром а при покидании трюма становятся обьектами. Содержит 113 обьектов.
  •  



             



    Структура файлов TWare B,E,F,M,N,T

       Файлы TWare B,E,F,M,N,T имеют одинаковую структуру поэтому для примера выбран файл TWare B.







    Как видно на картинке сверху :

     1) Имя файла в Х3 Edior 2.
     2) Переключатель режима отображения  товаров: по идентификатору или по имени. В даный момент установлен режим отображения имени товаров, если нажать переключатель режима "ID' то товары будут выглядеть так как на картинке  снизу.
     3) Поле имени/идентификаторов товара. В этом поле редактора отображаются товары  в зависимости от режима, по имени или по идентификатору а также порядковый номер, который всегда начинается с цифры "1".
     4) Поле даных выбраного товара (обьекта в файле). Поле содержит такой список редактируемых даных:
     
     
    • ID - идентификатор товара-обьекта, имеет вид SS_WARE_призвольное имя для товаров которые отображаються непосредственно в трюме корабля и относятся к категории "Товары" в игровой энциклопедии. Вид SS_WARE_SW_призвольное имя  для товаров которые относятся к категории "Корабельное оборудование" и "Усовершенствования корабля".
       
    • Model file -  число в даной строке ничего не ознчает и ни на что не влияет, ставте значение тот которое в соседних товарах, это погоды не сделает.
       
    • Picture ID - Даное число тоже ни на что не влияет, так как визуальное отображение товаров проводится видеороликом. 
       
    • Rotation A,Y,Z - данный параметр не используеться для товаров.
       
    • Subtype - Номер товара, подтип, который используется скриптами SE или внутреним редактором галактики  а также внешними редакторами. Субтип файлов в даном типе файлов: порядковый номер-1
       
    • Name ID - Номер строки на странице 17 "boardcomp objects" в языковом файле 0001-L007.xml.
       
    • Name - Имя товара или оборудования, которое выводится при чтениии идентификатора имени (Name ID).
       
    • Volume - Обьем товара в трюме. Каждый товар занимает место в трюме, исключение составляет оборудование и модернизации, они ничего не занимают в трюме.
       
    • Relative value - значение для выичисления цены товара, которое вычисляеться абсолютно также как и установка цены для кораблей, станций, оружия, ракет и других товаров имеющих цену в игре для НПС. Чем больше значение, тем дороже товар.
       
    • Price modifier 1 - модификатор цены,  используется для вычисление минимальной цены товара. 
       
    • Price modifier 2 -  модификатор цены, используется для вычисления максимальной цены товара
       
    • Size - размер товара согласно класу грузового отсека (типа контейнера). Можно выбрать размер S,M,L,XL,ST.
       
    • Relative value (player) - значение для вычисления цены товара конкретно для игрока. Может иметь отличное значение для Relative value НПС.
       
    • Minimum notoriety - Значение минимального рейтинга репутации для доступа у товару в поинтах.
       
    • Video ID - видеоидентификатор, используеться для визуального отображение товара. Реализуется видеороликом из файла 00001.dat в папке mov.
       
    • Skin index - данный параметр не используеться для товаров.
     
     

    Добавление нового товара в файлы TWare B,E,F,M,N,T


     
    Добавление нового товара абсолютно одинаково для все файлов TWare B,E,F,M,N,T. Для примера выбран  TWare E.

     
     Необходимый инструментарий:
     
  • Х3 Editor 2*
     
  • Языковый файл 0001-L007.xml.
     
  • TWare E, Можно использовать другой файл этого типа, но учтите к какой категории вы хотите сделать новый товар. В уроке я добавлю новый товар категории "Енергия"
  •  

     
    Процес работы:


     
    1) Создайте в папке с игрой новую папку с названием "types" или создайте новый архив cat/dat.
    2) Распакуйте самые свежие файлы TWare B,E,F,M,N,T из папки "types" в оригинальных катах.
    3) Распакуйте в папку "t" в корне игры самый свежий языковый файл 0001-L007.xml.
    4) Создайте на странице 17 "boardcomp objects" в языковом файле 0001-L007.xml новую строку с нужным названием вашого товара, сохраняете, запоминаете в голове или записываете номер вашей строки, выходите из языкового файла.
    5) Запускаете нужный вам файл TWare...
    6) Выделяете самый последний обьект в списке и щёлкаете на нём правой кнопкой мыши, в контксном меню нажимаете "Copy" и потом нажав опять правой кнопкой  нажмаете "Paste to End"
    7) изменяете ID  на свой уникальный, в строке "Subtype" увеличиваете на 1 от предидущего, в строке "Name ID" ставите номер вашей страницы, настраиваете остальные параметры по вкусу: обьем, тип контейнера и цену.
    8) Сохраняете и закрываете редактор.
    9) Снова запускаете редактор и видите что у вашего новго товара есть имя. Зная ваш новый идентификатор, можно его запросто использовать в любых целях.
     

     У вас должно быть вот так, только имя ваше на товаре:





    * -  Умение пользоваться Х3 Editor 2 обязательно!!!

    Редактировалось 2 раз (а). Последний раз 02.10.2011 10:19:26.

    01.10.2011 20:07:44
    YOYOMAN

    Репутация: 1800
    Сообщений: 4277
    Регистрация: 20.11.2009
    Создание полнофункциональных врат

         Привет модостроители!! Наверное, делая множество модов, вы когда-нибудь сталкивались с созданием новых врат (типов), вдобавок к оригинальным 25 типам врат. Но всегда вы видели весьма странный значок на всех новых вратах - "Х" - и также загадочные "???" перед названием ваших новых врат, ну и, конечно, Readtext в поле серийного номера.
         В этом уроке я расскажу, как создать и корректно "засунуть "  новые типы врат.

    Инструментарий для работы:

    • Х3 Editor 2*
    •  для obj файлов от Cheker Two.
    • WordPad.

    *Знание Х3 Editor 2 обязательно!

    Необходимые файлы для работы:

    • Ваши новые модели врат и их сцены.
    • TGates.
    • IconTypes.
    • L001-007.
    • x3story.obj.
    • x3intro.obj.



         Все готовы? Вперёд!!!

    Этап 1: Создание строк врат в файле TGates.

         Открываем Х3 Editor 2  и ищем TGates (он находится в 07. сат\types). Создаём новый каталог, называем его 14 (дат тоже кстати). Копируем в наш архив, открываем. Вот главные элементы окна TGates: 



    1 - номер и имя врат в списке.
    2 - идентификатор (ID) - очень важная часть  строки врат.
    3 - субтип - он всегда равен "-1", ( Об этом чуть дальше.)
    4 - номер строчки в языковом файле, где находится имя.
    5 - путь к сцене врат.

         Все остальные поля без изменений.


    1. Копируем любую строчку правой кнопкой и выбираем "Paste to end". Копируем 4 раза, так как врата имеют направление на 4 стороны: север, юг, запад, восток. ( ХАБовские врата специальные!)
    2. Ставим свои идентификаторы. Идентификатор  вот такого вида: SS_WG_ваше уникальное имя_NORTH, ..._SOUTH, ..._WEST и ..._EAST
    3. Дописываем в языковый файл имя своих врат, ставим сюда номер вашей строки или же используем стандартное имя (3731).
    4. Прописываем путь к сцене новых врат. Формат пути для примера: others\ваше имя_scene .
    5. Сохраняем файл и закрываем редактор.  Потом заново запускаем. Я делаю это для того, чтобы новые элементы заняли свои места нормально, хотя, может, это мой прикол...

     

    Этап 2: Установка значков (иконок).

         Все новые добавленные типы врат имеют весьма странный значок (иконку) - "Х". Кстати, именно новые Земные врата с такой иконкой. Текущая иконка нас не устраивает, поэтому нужно всем новым типам врат установить нормальные иконки, соответствующие направлению врат, а именно: N, S, W, E.
         Для этого нужно дописать идентификаторы (ID) новых типов врат в файл IconTypes. Берём его из 03.сат\types, копируем и переносим в наш архив. Открываем IconTypes и листаем до тех пор, пока не найдем вот такую конструкцию:



    1. - Название раздела, соответственно  в этом разделе  прописываются значки типам врат.
    2. - Общее количество прописанных типов врат - идентификаторов (ID).
    3. - Весь список строк, которые хранятся в этом разделе.


    1) Прописываем в конец строк свои 4 вот так:
     Код:
    1. SS_WG_имя_NORTH;ICON_TRG_GATE_N;0;0;
    2. SS_WG_имя_SOUTH;ICON_TRG_GATE_S;0;0;
    3. SS_WG_имя_WEST;ICON_TRG_GATE_W;0;0;
    4. SS_WG_имя_EAST;ICON_TRG_GATE_E;0;0;
     

    2) Увеличиваем общее число строк в разделе SSTYPE_WARPGATE; на 4 , так как мы добавили только 4 новых строки.
     Код:
    1. SSTYPE_WARPGATE;
    2. ICON_TRG_GATE_X;0;0;
    3. 0;0;0;
    4. <b>18</b>;
     


         Полная конструкция должна выйти вот такая:
     Код:
    1. SSTYPE_WARPGATE;
    2. ICON_TRG_GATE_X;0;0;
    3. 0;0;0;
    4. 18;
    5. SS_WG_NORTH;ICON_TRG_GATE_N;0;0;
    6. SS_WG_SOUTH;ICON_TRG_GATE_S;0;0;
    7. SS_WG_WEST;ICON_TRG_GATE_W;0;0;
    8. SS_WG_EAST;ICON_TRG_GATE_E;0;0;
    9. SS_WG_T_NORTH;ICON_TRG_GATE_N;0;0;
    10. SS_WG_T_SOUTH;ICON_TRG_GATE_S;0;0;
    11. SS_WG_T_WEST;ICON_TRG_GATE_W;0;0;
    12. SS_WG_T_EAST;ICON_TRG_GATE_E;0;0;
    13. SS_WG_HUB_NORTH;ICON_TRG_GATE_CRC1;0;0;
    14. SS_WG_HUB_SOUTH;ICON_TRG_GATE_CRC2;0;0;
    15. SS_WG_HUB_WEST;ICON_TRG_GATE_SQR1;0;0;
    16. SS_WG_HUB_EAST;ICON_TRG_GATE_SQR2;0;0;
    17. SS_WG_HUB_UP;ICON_TRG_GATE_TRI1;0;0;
    18. SS_WG_HUB_DOWN;ICON_TRG_GATE_TRI2;0;0;
    19. SS_WG_имя_NORTH;ICON_TRG_GATE_N;0;0;
    20. SS_WG_имя_SOUTH;ICON_TRG_GATE_S;0;0;
    21. SS_WG_имя_WEST;ICON_TRG_GATE_W;0;0;
    22. SS_WG_имя_EAST;ICON_TRG_GATE_E;0;0;
     

         Сохраняем файл и закрываем редактор.


    Этап 3: Исправление Readtext в серийном номере новых врат.

         После создания новых врат может появиться Readtext в серийном номере. Увидеть это можно только включив игру и соединив новые врата. Если всё таки Readtext присутствует вместо первых двух букв серийного номера (Readtext-1263-строка необходимая игре серийном номере новых врат), это означает, что не загружена строка на странице 1263 "Shipclass IDs" и её нужно создать.

     

    1. - Страница 1263 "Shipclass IDs"
    2. - Строки на этой странице.


         Для устранения этой проблемы нужно выполнить несколько действий:
    1. Открываем с помощью Х3 Editor 2 языковый файл L001-007.
    2. Прокручиваем список и находим страницу 1263 "Shipclass IDs".
    3. Создаём новую строку с  номером тем что требует игра. Возможно нужно будет создать несколько таких строк.

    Сохраняем и закрываем Х3 Editor 2. Больше он нам не понадобится.


    Этап 4: Правка x3story.obj - прописывание новых типов врат.


         Итак, мы подошли к предпоследнему и очень важному этапу. Править x3story.obj мы будем WordPadoм, предварительно диссасемблировав его. Делаем вот так:
    1.  Качаем Ассемблер и Дисассемблер
    2.  Создаем отдельную для удобства папку с произвольным именем, я назвал "OBJ".
    3.  В ней создадим ещё  две папки с названиями понятными: COMPILE и DECOMPILE (Названия произвольные, лишь бы вам понятно было)
    4.  В папку COMPILE распаковуем архив с ассемблером (xa4_10b_824.zip) в папку DECOMPILE - дисассемблер (do4_13b_122.zip)
    5.  Достаем самый свежий x3story.obj версии 3.1, находящися в 13.сат\l
    6.  В папке DECOMPILE берём и тащим x3story.obj на dobj.exe и ждём пока обж будет декомпилирован.
    7.  После декомпиляции получается много файлов  в этой папке, нас же интересует файл x3story.asm, открываем его WordPadoм.
    8.  Теперь нам нужно найти фунции, которые отвечают за типы врат. Вбиваем в поиск первую функцию:
       Код:
      1. <b>function  GATE.GetDirectionName()</b>
       

      WordPad находит секцию с именем: GetDirectionName, листаем немного вниз. Нас интересует длинный список команд:
       Код:
      1. L00086379: xjump      25d, 0
      2.                  .long      L00086373 ; 0 : default
      3.                  .long      L00086337 ; 1 : 0
      4.                  .long      L00086343 ; 2 : 1
      5.                  .long      L0008634F ; 3 : 2
      6.                  .long      L0008635B ; 4 : 3
      7.                  .long      L00086373 ; 5 : 4
      8.                  .long      L00086337 ; 6 : 5
      9.                  .long      L00086343 ; 7 : 6
      10.                  .long      L0008634F ; 8 : 7
      11.                  .long      L0008635B ; 9 : 8
      12.                  .long      L00086367 ; 10 : 9
      13.                  .long      L00086367 ; 11 : 10
      14.                  .long      L00086367 ; 12 : 11
      15.                  .long      L00086367 ; 13 : 12
      16.                  .long      L00086367 ; 14 : 13
      17.                  .long      L00086367 ; 15 : 14
      18.                  .long      L00086367 ; 16 : 15
      19.                  .long      L00086367 ; 17 : 16
      20.                  .long      L00086367 ; 18 : 17
      21.                  .long      L00086367 ; 19 : 18
      22.                  .long      L00086367 ; 20 : 19
      23.                  .long      L00086367 ; 21 : 20
      24.                  .long      L00086337 ; 22 : 21
      25.                  .long      L00086343 ; 23 : 22
      26.                  .long      L0008635B ; 24 : 23
      27.                  .long      L0008634F ; 25 : 24
       

           Сверху - 25d - это общее число прописаных адресов  (типов врат). На данный момент их 25. Увеличиваем это число на 4, то есть должно выйти:
       Код:
      1. L00086379: xjump      29d, 0
       

           Дальше переходим к самим командам. Обратите внимание на запись цифр после каждого адреса вида  L00086ХХ. Первая цифра - это номер врат по порядку в TGates, вторая - субтип. Я раньше говорил про Субтип врат и что он равен -1. Вот вторая цифра и означет  "номер врат -1". Для прописки своих типов врат копируем эти строки в конец:
        
       Код:
      1.                  .long      L00086337 ; 1 : 0
      2.                  .long      L00086343 ; 2 : 1
      3.                  .long      L0008634F ; 3 : 2
      4.                  .long      L0008635B ; 4 : 3
       

       и меняем  вот так:
       Код:
      1.                  .long      L00086337 ; 26 : 25
      2.                  .long      L00086343 ; 27 : 26
      3.                  .long      L0008634F ; 28 : 27
      4.                  .long      L0008635B ; 29 : 28
       

      В результате выходит код с 29 строками:
       Код:
      1. L00086379: xjump      29d, 0
      2.                  .long      L00086373 ; 0 : default
      3.                  .long      L00086337 ; 1 : 0
      4.                  .long      L00086343 ; 2 : 1
      5.                  .long      L0008634F ; 3 : 2
      6.                  .long      L0008635B ; 4 : 3
      7.                  .long      L00086373 ; 5 : 4
      8.                  .long      L00086337 ; 6 : 5
      9.                  .long      L00086343 ; 7 : 6
      10.                  .long      L0008634F ; 8 : 7
      11.                  .long      L0008635B ; 9 : 8
      12.                  .long      L00086367 ; 10 : 9
      13.                  .long      L00086367 ; 11 : 10
      14.                  .long      L00086367 ; 12 : 11
      15.                  .long      L00086367 ; 13 : 12
      16.                  .long      L00086367 ; 14 : 13
      17.                  .long      L00086367 ; 15 : 14
      18.                  .long      L00086367 ; 16 : 15
      19.                  .long      L00086367 ; 17 : 16
      20.                  .long      L00086367 ; 18 : 17
      21.                  .long      L00086367 ; 19 : 18
      22.                  .long      L00086367 ; 20 : 19
      23.                  .long      L00086367 ; 21 : 20
      24.                  .long      L00086337 ; 22 : 21
      25.                  .long      L00086343 ; 23 : 22
      26.                  .long      L0008635B ; 24 : 23
      27.                  .long      L0008634F ; 25 : 24
      28.                  .long      L00086337 ; 26 : 25
      29.                  .long      L00086343 ; 27 : 26
      30.                  .long      L0008634F ; 28 : 27
      31.                  .long      L0008635B ; 29 : 28
       

    9.  Следующая на очереди функция. Вбиваем в поиск вот эту функцию:
       Код:
      1. <b>function  GATE.GetDirectionFromSubtype()</b>
       

           WordPad находит секцию с именем: GetDirectionFromSubtype. В этой секции сделать так же, как в пункте 8! Единственное, тут другие адреса, но также брать вот эти:
       Код:
      1.                  .long      L000864C7 ; 1 : 0
      2.                  .long      L000864C9 ; 2 : 1
      3.                  .long      L000864CB ; 3 : 2
      4.                  .long      L000864CD ; 4 : 3
       

    10.  Последнее, что нужно править в x3story.obj , это версию. Просто при любой компиляции .obj файла версия игры будет "?". Это происходит, если вы начнёте новую игру, сохранитесь и захотите загрузить эту сохранку. Тем более, вам полюбому придётся начать заново, ведь имена назначения врат записываются в сохранения - старые сохрания больше не поддерживаются!

    Итак, вносим в поиск эту функцию:
     Код:
    1. <b>function  GetVersionString(arg1)</b>
     

    попадаем в секцию GetVersionString здесь можно увидеть все версии, которые были пропатчены до версии 3.1. Листаем в конец списка, нужно найти вот этот кусочек:
     Код:
    1. L00000D68: pushw      3600d ; 0E10h
    2.            if SP[0]<=SP[1] then push 0 else push 1
    3.            if SP[0]=0 then jump L00000D77
    4.            get_strg   S0001B993 ; "v3.1"
    5.            ret
    6. L00000D77: get_strg   S0000055B ; "?"
    7.            ret
    8. ;           push       0
    9. ;           ret
     

    Менять нужно самую последнюю строчку:
     Код:
    1. L00000D77: get_strg   S0000055B ; "?"
     

         Нужно скопировать адрес строки версии 3.1 ("v3.1") и вставить вместо адреса строки для неизвестной версии ("?"), вот так:
     Код:
    1. L00000D68: pushw      3600d ; 0E10h
    2.            if SP[0]<=SP[1] then push 0 else push 1
    3.            if SP[0]=0 then jump L00000D77
    4.            get_strg   S0001B993 ; "v3.1"
    5.            ret
    6. L00000D77: get_strg   <i><b>S0001B993</b></i> ; "?"
    7.            ret
    8. ;           push       0
    9. ;           ret
     

         Далее после всех операций сохраняем наш asm файл.
         Правка x3story.obj успешно завершена, можете его компилить, перетащив x3story.asm на асемблер xa_asm.exe, ждём компиляции. Если вы не сделали ошибок при правке x3story.asm, то в папке с асемблером появится файлик с именем: x3story.cod, теперь смело меняем расширение файла .cod на .obj. Всё, новый x3story.obj у вас есть, можете его переместить в ваш модархив.

    Этап 5: Правка x3intro.obj - установка соотвествия значений версий игры.


         Это последний этап даного урока, идентичный последнему пункту из этапа 4. Чтобы версия игры правильно отображалась, мало изменить адрес строки версии в x3story.obj. Необходимо чтобы строки версии x3story.obj и x3intro.obj  совпадали, иначе вместо версии 3.1 так и останется "?".
     1) Диссаасемблируем x3intro.obj  так же как и x3story.obj. Открываем WordPadом и вписываем в поиск уже знакомую функцию:
     Код:
    1. <b>function  GetVersionString(arg1)</b>
     

    Снова находим кусочек кода:
     Код:
    1. L00002B7D: pushw      3600d ; 0E10h
    2.            if SP[0]<=SP[1] then push 0 else push 1
    3.            if SP[0]=0 then jump L00002B8C
    4.            get_strg   S00000AD2 ; "v3.1"
    5.            ret
    6. L00002B8C: get_strg   S00000AD7 ; "?"
    7.            ret
    8. ;           push       0
    9. ;           ret
     

         Меняем адрес к строке версии, должно выглядеть вот так:
     Код:
    1. [code]L00002B7D: pushw      3600d ; 0E10h
    2.            if SP[0]<=SP[1] then push 0 else push 1
    3.            if SP[0]=0 then jump L00002B8C
    4.            get_strg   S00000AD2 ; "v3.1"
    5.            ret
    6. L00002B8C: get_strg   <i><b>S00000AD2</b></i> ; "?"
    7.            ret
    8. ;           push       0
    9. ;           ret
     

         Сохраняем  asm файл. Компилируем точно так же, как и x3story.asm и меняем расширение .cod на .obj , x3intro.obj - успешно изменён.

    Редактировалось 2 раз (а). Последний раз 02.10.2011 10:18:26.

    01.10.2011 20:08:14
    YOYOMAN

    Репутация: 1800
    Сообщений: 4277
    Регистрация: 20.11.2009
    Структура файла TShields и создание нового щита

    Общие сведения


     
    TShields - файл, который собержит все щиты. которые используються в игре. Всего в оригинальной игре имееться 6 видов щитов:

     
     
    • 1 Мдж щит.
       
    • 5 Мдж щит.
       
    • 25 Мдж щит.
       
    • 200 Мдж щит.
       
    • 1 Гдж щит.
       
    • 2 Гдж щит.
     


    Поэтому TShields содержит всего 6 обьектов.


    Структура файла TShields





     





    Как видно на картинке сверху :

     1) Имя файла в Х3 Edior 2.
     2) Переключатель режима отображения  щитов: по идентификатору или по имени. В даный момент установлен режим отображения имени щитов, если нажать переключатель режима "ID' то товары будут выглядеть так как на картинке  снизу.
     3) Поле имени/идентификаторов щитов. В этом поле редактора отображаются щиты  в зависимости от режима, по имени или по идентификатору а также порядковый номер, который всегда начинается с цифры "1".
     4) Поле даных выбраного щита (обьекта в файле). Поле содержит такой список редактируемых даных:
     
     
    • ID - идентификатор щита-обьекта, имеет вид SS_SHIELD_призвольное имя для щитов которые отображаються непосредственно в трюме корабля. (я рекомендую писать идентификатор подобно егософту - ставля следющую букву английского алфавита
       
    • Model file -  число в даной строке ничего не ознчает и ни на что не влияет, ставте значение которое стоит на оригинальных щитах.
       
    • Picture ID - Даное число тоже ни на что не влияет, так как визуальное отображение товаров проводится видеороликом. 
       
    • Rotation A,Y,Z - данный параметр не используеться для щитов.
       
    • Subtype - Номер щита, подтип, который используется скриптами SE или внутреним редактором галактики  а также внешними редакторами. Субтип файлов в даном типе файлов: порядковый номер-1
       
    • Name ID - Номер строки на странице 17 "boardcomp objects" в языковом файле 0001-L007.xml.
       
    • Name - Имя щита, которое выводится при чтениии идентификатора имени (Name ID).
       
    • Capacity -  Мощность щита в киловатах (KW).
       
    • Power drain - скорсть зарядки щита  в киловатах в секунду (KW/с). Также можно трактовать как Кдж/с.
       
    • Hit effect - ефект попадания, всегда у всех щитов значение равно 1.
       
    • Efficiency - КПД щита, чем выше тем выше ефективность щита. Не увлекайтесь накручиванием этого параметра!      
       
    • Volume - Обьем щита в трюме. ДА. щит тоже занимает место в трюме как и оружие, товары и неекоторе оборудование.
       
    • Relative value - значение для выичисления цены щита, которое вычисляеться абсолютно также как и установка цены для кораблей, станций, оружия, ракет, товаров имеющих цену в игре для НПС. Чем больше значение, тем дороже щит.
       
    • Price modifier 1 - модификатор цены,  используется для вычисление минимальной цены щита. 
       
    • Price modifier 2 -  модификатор цены, используется для вычисления максимальной цены щита.
       
    • Size - размер товара согласно класу грузового отсека (типа контейнера). Можно выбрать размер S,M,L,XL,ST.
       
    • Relative value (player) - значение для вычисления цены щита конкретно для игрока. Может иметь отличное значение для Relative value НПС.
       
    • Minimum notoriety - Значение минимального рейтинга репутации для доступа к щиту в поинтах.
       
    • Video ID - видеоидентификатор, используеться для визуального отображение щита. Реализуется видеороликом из файла 00001.dat в папке mov.
       
    • Skin index - данный параметр не используеться для щитов.
     


    Добавление нового щита в файл TShields


     
    Добавление нового щита подобно созданию товаров. Для примера я создам новый щит мощьностью в 5 Гдж.

     
     Необходимый инструментарий:
     
  • Х3 Editor 2*
     
  • Языковый файл 0001-L007.xml.
     
  • TShields
  •  

     
    Процес работы:


     
    1) Создайте в папке с игрой новую папку с названием "types" или создайте новый архив cat/dat.
    2) Распакуйте самый свежий файлы TShields из папки "types" в оригинальных катах.
    3) Распакуйте в папку "t" в корне игры самый свежий языковый файл 0001-L007.xml.
    4) Создайте на странице 17 "boardcomp objects" в языковом файле 0001-L007.xml новую строку с нужным названием вашого товара, сохраняете, запоминаете в голове или записываете номер вашей строки, выходите из языкового файла.
    5) Запускаете  файл TShields
    6) Выделяете самый последний обьект в списке и щёлкаете на нём правой кнопкой мыши, в контксном меню нажимаете "Copy" и потом нажав опять правой кнопкой  нажмаете "Paste to End"
    7) изменяете ID  на свой уникальный, в строке "Subtype" увеличиваете на 1 от предидущего, в строке "Name ID" ставите номер вашей страницы, настраиваете остальные параметры по вкусу.
    8) Сохраняете и закрываете редактор.
    9) Снова запускаете редактор и видите что у вашего новго щита есть имя. Зная ваш новый идентификатор, можно его запросто использовать в любых целях.
     

     У вас должно быть вот так, только имя ваше на щите:





    * -  Умение пользоваться Х3 Editor 2 обязательно!!!

    Редактировалось 2 раз (а). Последний раз 12.01.2012 12:47:15.

    12.01.2012 12:48:21
    YOYOMAN

    Репутация: 1800
    Сообщений: 4277
    Регистрация: 20.11.2009
    WareLists aka Списки встроенных товаров

    Общие сведения


    WareLists -  это файл, который содержит списки встроенных товаров и оборудование на разных кораблях. Товары или оборудование в трюме корабля отображаются отдельно от общего трюма и их невозможно катапультировать/продать/передать другому кораблю! 

    Известный всем пример - Ремонтный лазер в Скафандре. его можно убирать/устанавливать но не выбросить (как вариант, ешё  щит на 200 Мдж у лазерной башни). Все корабли класса ТР изначально имеют встроееную СЖО, это прописано в TShips записях этих кораблей. Файл имеет простую текстовую структуру, давайте рассмотрим её.


    Структура файла WareLists







    Как видно на картинке сверху :

     1) Имя файла в Х3 Edior 2.
     2) Общее число товарных списков в файле WareLists. В оригинальном файле оно равно 134!



    Добавление нового списка в файл WareLists


    Добавление нового списка невероятно просто и реализовывается простой допиской в конец файла нужных товаров для будущего списка. Для примера добавим в наш список вот эти товары:

     
    • Боевой программный модуль БПМ-1.
       
    • Боевой программный модуль БПМ-2.
       
    • Сканер С-3.
       
    • Специальный программный модуль СПМ-1.
       
    • Исследовательский программный модуль.
       
    • Навигационный программный модуль НПМ-1.
       
    • Система жизнеобеспечения.
       
    • Транспортер.
       
    • Прыжковый двигатель.
     


    У нас вышло 9 товаров.

     
     Необходимый инструментарий:
     
  • Х3 Editor 2*
     
  • В зависимости от цели файлы с товарами на выбор:TWare B,E,F,M,N,T.
     
  • WareLists
  •  

    Процес работы:


     
    1) Создайте в папке с игрой новую папку с названием "types" или создайте новый архив cat/dat.
    2) Распакуйте самый свежий файлы WareLists из папки "types" в оригинальных катах.
    3) Распакуйте в папку "t" в корне игры самый свежий языковый файл 0001-L007.xml (если у вас есть свой модифицированый языковый файл!).
    4) Откройте файл WareLists в X3 Editr 2 в режиме Text Viewer.
    5)  В самом верху будет такая запись о общем числе списков.
     Код:
    1. /WareLists.txt
    2. 134;
    3. 0; /0
     


    Меняем число на 134 на 135, потом двинемся в них файла для составления спска, это чтобы потом не забыть
    Нужный результат:
     Код:
    1. /WareLists.txt
    2. 135;
    3. 0; /0
     

    6) Мы готовы для написания нового списка. Откройте ваши файлы и выберите нужные товары. В этом примере я выбрал TWareТ, так как у нас  все нужные элементы как раз в этом файле.
    Опускаемся на низ и копипастим идентификаторы нужных товаров, таким вот образом:

     Код:
    1. 9;SS_WARE_SW_FIGHT_1;SS_WARE_SW_FIGHT_2;SS_WARE_SCANNER3;SS_WARE_SW_SPECIAL_1;SS_WARE_SW_NAV_1;
    2. SS_WARE_SW_EXPLORE_1;SS_WARE_LIFESUPPORT;SS_WARE_BEAMING;SS_WARE_WARPING; /135
     


    Сначало напишем общее число все товаров нашего списка. Их 9, значит ставим цыфру 9 и знак ";". Записываем товары через этот знак в ряд. Не переносите строки в эдиторе 2! В конце записи поставте комент в виде номера строки по порядку: /135.

    7)Сохраните файл WareLists и закройте програму.
     


    Просмотр и назначение  списков товаров кораблям в TShips


    Мы создали новый список товаров и теперь его нужно назначить кораблю. В качестве примера я выбрал Гонерский Странник.

    Итак открываем нужный TShips переходим на вкладку Wares





    Как видно на картинке сверху :

     1) Имя файла в Х3 Edior 2.
     2) Кнопка, которая показывает идентификатор текущего установленого списка товаров.
     3) Окошко смены идентификатора списка.

    Процес работы:


     
    1) Откройте свой файл TShips.
    2) Найдите корабль Странник и перейдите на вкладку Wares.
    3) Щелкните на кнопке Ware list ID:.
    4) Поставте идентификатор нового списка товаров и нажмите ОК. У нас он - 135!
     


    Как только вы поменяете идентификатор на наш список, увидите вот такой результат:






     Сохраняйте и закрывайте редактор. Новый список добавлен. Удачи Вам!

    * -  Умение пользоваться Х3 Editor 2 обязательно!!!

    Редактировалось 4 раз (а). Последний раз 12.01.2012 19:18:55.

    19.02.2012 02:37:55
    denissaha

    Репутация: 8
    Сообщений: 29
    Регистрация: 16.01.2010
    Изменение параметров тренировки десанта и абордажа с помощью HEX-редактора. Модификация obj-файла.



    Инструментарий:
    1. Дизассемблер obj-файлов.
    2. X3 Editor 2. Качайте версию поновее - не ошибетесь.
    3. Любой HEX-редактор. HxD, UltraEdit, Hiew - в общем любой.

    Необходимые знания: 
    1. X3Editor - нужно!
    2. Программирование - не больно то и нужно , но если есть базовые познания в ассемблере, будет проще разобраться.

    Причина возникновения данного урока: Весьма частый и весьма справедливый вопрос:
    почему десант тренируется дольше, чем длится сюжетка + все побочные + миссии корпораций + "та када ж они там натренируются?" + "надоело уже ждать" + "та я уже на хаб натаскал всего, а они еще трениру...".
    В общем, надеюсь, понятно.

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

    Дополнительно добавлю, что здесь рассматривается как-раз "грубая" модификация obj (я бы даже сказал "взлом"), а не через дизассемблер - ассемблер.

    Урок будет делаться на чистой Х3ТС v 3.2.

    Итак, подготовка.

    1. Выдираем X3Editor-ом файл x3story.obj, который находится в 13.cat (справедливо для чистой Х3ТС 3.2)
    2. Создаем где вам удобно папку и называем ее, к примеру, "asm". В этой папке мы будем держать исходный + декомпилированный x3story.obj.
    3. Помещаем в вашу папку "asm" все файлы из архива с декомпилятором, в эту же папку закидываем свежевыдранный x3story.obj
    4. В папке "asm" находим файл "dobj.exe", жмем правой мышей и выбираем пункт "создать ярлык". Потом выбираем только что созданный ярлык, жмем его правой мышей, выбираем "свойства" и в самом конце дописываем x3story.obj после пробела (!!!)
    5. Запускаем сей ярлык. После непродолжительного черного окошка с бегущими буквами/цифрами видим в папке "asm" кучу файлов. Нас интересует один - "x3story.out" - в этом файле приведен листинг на ассемблере, а слева вид в машинном коде, самое то, что доктор прописал.

    Собственно, подготовка закончена, теперь немного матчасти.

    Прежде всего следует прочитать этот материал, чтобы хоть немного понять, почему мы будем менять те или иные коды в нашем подопытном x3story.obj.

    Сразу выделю основные данные из вышеприведенной статьи, а именно:
    1. Время (одного быстрого курса)
     
    Продолжительность (в минутах) быстрого обучения по одной дисциплине составляет:
    5 + (<текущий уровень> / 5 + 1)2
     

    2. Бабос (за один быстрый курс)
     
    Стоимость быстрого обучения по одной дисциплине составляет:
    5000 + 2000 x (<текущий уровень> / 5 + 1)
     


    По логике вещей, чем выше уже натренированный уровень, тем дольше/дороже будет тот самый быстрый курс.

    Давайте вычислим.

    Задача: имеем двух десов, дес1 и дес2.
    Необходимо рассчитать время/сумму быстрого обучения хакерству при следующих условиях:
    дес1 - текущее хакерство = 5
    дес2 - текущее хакерство = 87

    Ответ:
    1.а) время быстрого курса для дес1 = 5 + ( 5 / 5 + 1) * (5 / 5 + 1) = 6 минут, ясен пень, игровых
    1.б) бабос быстрого курса для дес1 = 5т + 2т * (5 / 5 + 1) = 5т + 2т * 2 = 9т, что, в общем, недорого
    2.а) время быстрого курса для дес2 = 5 + ( 87 / 5 + 1) * (87 / 5 + 1) = 5 + 18,4 * 18,4 = 343,56 минут, то есть примерно 6 часов
    2.б) бабос быстрого курса для дес2 = 5т + 2т * (87 / 5 + 1) = 5т + 2т * 18,4 = 41800, что, в общем, опять недорого

    Немного отвлекусь.
    Для более-менее успешного захвата М6 вам необходимы как минимум 8 хорошо прокачанных десов, минимум 2 из которых должны быть "мега-механикусами", 2 - "кулхацкерами", остальные какие-никакие "технари", иначе они развялят жертву так и не добравшись до заветного статуса "взлом ядра".
    Предположим вы долго играете и поэтому богаче, чем генеральный директор "Плутарх майнинг". Потратиться на обучение вы себе позволить можете.
    Но есть одно но - покупая на станции хакера, вы замечаете, что он не драчун, так сказать. То же с механиками и технарями. Поэтому, когда вся эта разнорасовая банда ломится по кораблю, логика программы расчитана так, чтобы на каждой палубе дохли слабейшие по характеристикам боя. Справедливо, ничего не попишешь. А кто у нас слабейшие по бою? Как раз они, кулхацкеры. У тренированных hacker-only шанс добраться до последней палубы катастрофически приближается к нулю с каждой палубой, а там то они как раз и нужны.
    Итог: для сколачивания команды вы должны найти 8 нихрена себе бойцов, 2 из которых потом натренируете на хак, 2 других на пробой корпуса (механики), а остальных натаскаете на технику.

    Приведу цитату из статьи про захват ракетного фрегата, которая описывает создание деса "на продажу":
     
    Создание десантника:
     Создается десантник с навыком боя от 1 до 40 и остальными навыками от 1 до 15.
     С вероятностью 20% на этом процесс создания заканчивается.
     В остальных 80% случаев случайно выбирается один навык и он повышается на 20-49 единиц.

    Последствия:
     У хороших бойцов все прочие навыки не дотягивают даже до одной звезды.
     Максимальный боевой уровень десанта, доступного в продаже - 89 (пять звезд).
     Максимальный уровень небоевых навыков - 64 (три звезды).
     Максимальный боевой уровень хорошего хакера, механика или инженера - 40 (две звезды).
     


    Итого, покупая деса-бойца, вы получаете никакого хакера/технаря/механика, с небоевым навыком максимум 15. Предоставлю вам самостоятельно посчитать, сколько по времени займет тренировка от 15 до заветных 98-100 одного деса.

    Итак, с матчастью закончили, "начинаем хак системы".

    Для целей урока я установил себе x3_tc_cheats и начал новую "свою игру" (без сюжета). Потом я через чит меню создал себе корабль TM, установил в него биосканер, добавил бабоса, открыл все сектора и стыковался с военным аванпостом в секторе "Черное солнце". Да простят меня все "античитеры", но мне хочется объяснить как это сделать, но не хочется летать туда-сюда.

    В списке "продажных" десов был некий Элисон Дана с такими характеристиками: бой - 65, техника - 5, механика - 6, хакерство - 13. Я его купил нанял и решил замерить сколько времени займет тренировка одного подробного курса по хакерству.

    Сохранив игру прямо перед тренировкой, я запустил тренировку Элисона на хакерство - подробно (95000 кредитов)

    Тренировка начата в "00:11:58" по игровому времени. Я не стал дожидаться окончания тренировки, а остановил замеры на 20% тренировки. Игровое время было "01:24:10". Итого разница примерно 1 час 12 минут. Если умножить на 5 - то на полную тренировку нужно было бы почти 6 часов игрового времени. При этом дес добрался бы до уровня хакерства от 38 до 58. Последующая тренировка заняла бы еще большее время. Нас это не устраивает.

    В полученном нами раньше x3story.out находится двойной листинг почти всей логики Х3ТС. За время/стоимость подготовки десанта отвечает класс "SHIP_SPEAKER", а именно два метода этого класса "GetNextTrainingCost" и "GetNextTrainingDuration". За сам процесс подготовки, отвечеат метод "RunTraining", класса "STATION". Этот метод вызывается из метода "StartTraining" того-же класса.

    Давайте сначала разберем код метода "RunTraining".

    Открываем x3story.out любым редактором, к примеру, блокнотом и ищем в нем следующий текст "RunTraining" до тех пор, пока не найдем следующий код:
    Листинг 1.

     Код:
    1. ;
    2. ; === RunTraining ===============================================
    3. ; function  STATION.RunTraining();
    4. ;
    5.                                |      STATION.RunTraining:
    6. 0008B44A: 6E 0006              |    0            enter      0, 6
    7. 0008B44D: 0F 0027              |    0 L0008B44D: read       STATION.var_2016_29 ; [39d ; 27h]
    8. 0008B450: 34 0008B469          |    1            if SP[0]=0 then jump L0008B469
    9. 0008B455: 0F 0027              |    0            read       STATION.var_2016_29 ; [39d ; 27h]
    10. 0008B458: 02                   |    1            push       1
    11. 0008B459: 82 0000057A          |    2            callasm    SE_ArraySize
    12. 0008B45E: 34 0008B469          |    1            if SP[0]=0 then jump L0008B469
    13. 0008B463: 02                   |    0            push       1
    14. 0008B464: 32 0008B46A          |    1            jump       L0008B46A
    15. 0008B469: 01                   |    0 L0008B469: push       0
    16. 0008B46A: 34 0008B4F8          |    1 L0008B46A: if SP[0]=0 then jump L0008B4F8
    17. [color=yellow]0008B46F: 06 03E8              |    0            pushw      1000d ; 03E8h[/color]
    18. 0008B472: 02                   |    1            push       1
    19. [color=yellow]0008B473: 82 00002561          |    2            callasm    TI_Delay[/color]
    20. 0008B478: 24                   |    1            pop
    21. 0008B479: 01                   |    0            push       0
    22. 0008B47A: 0F 0027              |    1            read       STATION.var_2016_29 ; [39d ; 27h]
    23. 0008B47D: 02                   |    2            push       1
    24. 0008B47E: 82 0000057A          |    3            callasm    SE_ArraySize
    25. 0008B483: 02                   |    2            push       1
    26. 0008B484: 4B                   |    3            sub        SP[0],SP[1]
     


    Процесс начала и хода тренировки выглядит так:
    1. При начале тренировки система запрашивает сколько времени "GetNextTrainingDuration" и бабоса "GetNextTrainigCost" необходимо для повышения выбранных навыка(-ов) текущего деса.
    2. Если у игрока хватает кредитов, бабос снимается со счета, данные о времени заносятся в специальный внутренний массив, который потом использует функция "RunTraining"
    3. Функция "RunTraining" ежесекундно отнимает от оставшегося на тренировку времени по секунде и, когда оставшихся на тренировку секунд = 0, передает управление на метод "FinishedTraining", который увеличивает тренируемый навык на 5 + SE_Random(5) и маячит игроку о том, что "тут чувак, накачался, ждет тебя там-то"

    Как мы можем это использовать:
    Вариант 1. "Заставить" систему чаще отнимать одну секунду.
    Обратите внимание на две желтых строчки кода, которые я выделил.
    Переводя на понятный нам, гуманоидам, язык - в первой желтой строчке устанавливается время задержки в миллисекундах, во второй желтой строчке, вызывается сама задержка (TI_Delay), после которой уже и идет отнимание секунд и прочая программистская дрянь, которая нам сейчес не суть важна.

    Давайте вместо 1000d сделаем задержку в 0001d. По логике, метод "RunTraining" будет задерживаться на тысячу раз меньше, соответственно система будет вызывать его в тысячу раз чаще, что приведет к тысячекратному увеличению скорости тренировки.

    Приступим. Внутри папки, в которую вы установили игру, есть папка "L". Если нет создайте ее. Внутрь этой папки необходимо поместить файл x3story.obj, который раньше мы выдрали из 13.cat. Теперь откройте этот файл любым HEX-редактором. Я использовал HxD.
    Теперь вернемся к листингу программы. В первой желтой строчке указано 16-ричное смещение от начала файла, в котором находится необходимый нам машинный код, а именно помещение в вершину стека значения задержки - 1000. В НЕХ-редакторе нам нужно перейти/прокрутить до тех пор, пока мы не встретим данный адрес. В HxD я нажал CTRL+G и ввел туда адрес 0008B46F. Сразу оговорюсь, что декомпилятор не всегда точно определяет смещение внутри obj-файла. Но именно здесь нам поможет то, что в файле x3story.out слева указаны машинные коды необходимых нам команд. Поэтому мы начинаем искать ту последовательность цифр, которая указана сразу после адреса, а именно 06 03E8. Я обнаружил эти цифры чуть дальше по ходу, в адресе 0008B483.
    Если вы не хотите искать или не можете найти, тогда просто переходите в НЕХ-редакторе по найденному мной адресу. Теперь мы должны заменить 06 03E8 на 06 0001 и сохранить изменения.

    Запускаем Х3ТС и повторно пытаемся тренировать того-же Элисона Дану. Тренировка начата "00:11:53", закончена в "00:16:26" - итог примерно 4,5 минуты. Проверяем данные Элисона - все ОК, хакерство 53.

    Подведем итоговую черту под Вариантом №1.
    Плюсы: 
    1. Мы добились увеличения скорости тренировки.
    А теперь минусы: тут поболее будет
    1. Мы не уменьшили время тренировки, а увеличили частоту вызова функции
    2. Исходя из п.1 мы "нагрузили" систему, заставив ее 1000 раз в секунду исполнять то, что расчитано на 1 раз в секунду
    3. Если у вас установлен мод, который показывает время тренировки, то вы обнаружите, что время идет не посекудно, а скачками по несколько секунд
    4. СУВ (SETA) может слабо влиять на время тренировки, т.к. компьютер просто не будет успевать выделять необходимые 1000 вызовов процессорного времени на нашу функцию "RunTraining"
    5. Мы не добились снижения стоимости тренировки

    Результат: данный вариант можно использовать как "ленивый", или когда мы хотим увеличить скорость например в 2-3 раза, то есть подставлять вместо 1000, 500 или к, примеру 300. При всем при этом нам не важно, что моды типа "время тренировки десанта" будут врать.

    Вариант 2. Действительно уменьшить время/стоимость тренировки одного быстрого курса.

    Прежде всего, в папку "L" внутри папки с игрой заново скопируем исходный x3story.obj, так как там находится "исковерканный" вариантом 1.

    Давайте снова вернемся к вышеприведенным цитатам:
     
    Продолжительность (в минутах) быстрого обучения по одной дисциплине составляет:
    5 + (<текущий уровень> / 5 + 1)2
    Стоимость быстрого обучения по одной дисциплине составляет:
    5000 + 2000 x (<текущий уровень> / 5 + 1)
     


    Сначала попробуем "выделить" числа, которые, скажем так, "константны".

    В формуле расчета времени - это исходные 5 минут, делитель на 5 и, как видим, возведение в квадрат.
    Заменим исходные "5 + (<..." на "0 + (<...". Что это нам дает?
    Возьмем навык 87 и рассчитаем быстрый курс по навыку: 0 + (87 / 5 + 1) * (87 / 5 + 1) = (17,4 + 1) * (17,4 + 1) = 338,56 = 5 часов 64 минуты. М-да. Не фонтан!
    Теперь давайте заменим делитель (т.е. "<текущий уровень> / 5")
    Возьмем навык 87 и рассчитаем быстрый курс по навыку при делителе 50: 5 + (87 / 50 + 1) * (87 / 50 + 1) = 5 + 2,74 * 2,74 = примерно 13 минут. Вот это уже похоже на "оно".
    Если же мы еще и возведение в квадрат заменим сложением, тогда вообще десант будет тренироваться за считанные минуты.

    То же с денюжкой:
    5000 + 2000 * (<текущий уровень> / 5 + 1)
    Например заменив "2000 * (<..." на "500 * (<..." мы заметим резкое снижение стоимости тренировки. Причем это будет заметно на более высоких уровнях тренировки.

    Давайте перейдем к делу.

    Сначала найдем в нашем декомпилированном x3sotry.out необходимые функции. Как мы уже выяснили это функции "GetNextTrainingCost" и "GetNextTrainingDuration"

    Листинг 2. (GetNextTrainingCost)

     Код:
    1. ;
    2. ; === GetNextTrainingCost =======================================
    3. ; function  SHIP_SPEAKER.GetNextTrainingCost(arg1, arg2);
    4. ;
    5.                                |      SHIP_SPEAKER.GetNextTrainingCost:
    6. 000C628B: 6E 0008              |    0            enter      2, 8
    7. 000C628E: 01                   |    0            push       0
    8. ... тут коды-коды-коды и вот то, что нам нужно...
    9. 000C6312: 0D 0002              |    3 L000C6312: push       SP[1] ; loc2
    10. 000C6315: 05 05                |    4            pushb      5
    11. 000C6317: 51                   |    5            div        SP[0],SP[1]
    12. 000C6318: 02                   |    4            push       1
    13. 000C6319: 46                   |    5            add        SP[0],SP[1]
    14. 000C631A: 0D 0004              |    4            push       SP[3] ; loc1
    15. [color=yellow]000C631D: 06 1388              |    5            pushw      5000d ; 1388h[/color]
    16. 000C6320: 0D 0003              |    6            push       SP[2] ; loc4
    17. [color=yellow]000C6323: 06 07D0              |    7            pushw      2000d ; 07D0h[/color]
    18. 000C6326: 50                   |    8            mul        SP[0],SP[1]
    19. 000C6327: 46                   |    7            add        SP[0],SP[1]
    20. 000C6328: 46                   |    6            add        SP[0],SP[1]
    21. 000C6329: 14 0005              |    5            mov        SP[4],SP[0] ; loc1
    22. 000C632C: 24                   |    5            pop
    23. 000C632D: 0D 0003              |    4            push       SP[2] ; loc2
     


    В листинге 2 мы снова обнаруживаем наши "константные числа", поменяв которые мы сможем уменьшить стоимость тренировки. Итак, по накатанной, в НЕХ-редакторе открываем x3stroy.obj, переходим по адресу 000C6323, чуть "дальше" ищем 06 07D0 и меняем на 06 01F4, что в "переводе" на ассемблер будет значить "pushw      500d ; 01F4h".

    Запускаем Х3ТС, пытаемся тренировать нашего многострадального Элисона Дану - стоимость вместо 95000 равна 42500.

    В итог, мы безболезненно для системы уменьшили стоимость тренировки.

    Сразу пойдем дальше, ведь еще необходимо уменьшить и время тренировки. Находим функцию "GetNextTrainingDuration".

    Листинг 3. (GetNextTrainingDuration)

     Код:
    1. ;
    2. ; === GetNextTrainingDuration ===================================
    3. ; function  SHIP_SPEAKER.GetNextTrainingDuration(arg1, arg2);
    4. ;
    5.                                |      SHIP_SPEAKER.GetNextTrainingDuration:
    6. 000C634B: 6E 0008              |    0            enter      2, 8
    7. 000C634E: 01                   |    0            push       0
    8. ... коды-коды-коды, стоп, кажется нашли...
    9. 000C63D2: 0D 0002              |    3 L000C63D2: push       SP[1] ; loc2
    10. 000C63D5: 05 05                |    4            pushb      5 ; ДЕЛИТЕЛЬ
    11. 000C63D7: 51                   |    5            div        SP[0],SP[1]
    12. 000C63D8: 02                   |    4            push       1
    13. 000C63D9: 46                   |    5            add        SP[0],SP[1]
    14. 000C63DA: 0D 0004              |    4            push       SP[3] ; loc1
    15. 000C63DD: 06 012C              |    5            pushw      300d ; 012Ch исходные 5 минут * 60 сек
    16. 000C63E0: 0D 0003              |    6            push       SP[2] ; loc4
    17. 000C63E3: 0D 0004              |    7            push       SP[3] ; loc4
    18. 000C63E6: 50                   |    8            mul        SP[0],SP[1] ; возведение в квадрат
    19. 000C63E7: 05 3C                |    7            pushb      60d ; 3Ch
    20. 000C63E9: 50                   |    8            mul        SP[0],SP[1] ; умножение результата в минутах на 60 сек
    21. 000C63EA: 46                   |    7            add        SP[0],SP[1]
    22. 000C63EB: 46                   |    6            add        SP[0],SP[1]
    23. 000C63EC: 14 0005              |    5            mov        SP[4],SP[0] ; loc1
    24. 000C63EF: 24                   |    5            pop
     


    Ну, здесь я уже не буду в подробностях расписывать как заменить.
    Возможностей - куча:
    Если по адресу 000C63D5 (не забудьте, что в НЕХ-е искать надо чуть "дальше")
    000C63D5: 05 05                |    4            pushb      5 ;
    заменить 0505 на 0532 - получим делитель не 5 а 50
    000C63D5: 05 32                |    4            pushb      50d ; 32h

    Если по адресу 000C63DD
    000C63DD: 06 012C              |    5            pushw      300d ; 012Ch ; // исходные 5 минут * 60 сек
    заменить 06012C на 060000 - исходные 5 минут станут 0
    000C63DD: 06 0000              |    5            pushw      0d ; 0000h ; // исходные 5 минут * 60 сек

    Если по адресу 000C63E6
    000C63E6: 50                   |    8            mul        SP[0],SP[1] ; возведение в квадрат
    заменить 50 на 46 - вместо квадрата получим просто сложение двух результатов
    000C63E6: 46                   |    8            add        SP[0],SP[1] ; сложение!!!

    Ну и на закуску:
    Если по адресу 000C63E7
    000C63E7: 05 3C                |    7            pushb      60d ; 3Ch
    заменить 053C на 0501 - вместо (Х минут * 60 сек) получим (Х минут * 1 сек.)
    000C63E7: 05 01                |    7            pushb      1

    Фух, устал!
    Ладно, вроде изменить время/стоимость тренировок мы умеем. А что же по поводу абордажа.
    Вернее по поводу уничтожения оборудования.
    Давайте рассмотрим такую ситуацию с абордажем:
    Летит себе такой не спеша М1. А куда ему торопиться? У него 2ГДж щитов пара-тройка, десятки больших пух, да и сам по себе он не какой-то там М5. Мы его закидали ракетами, сняли щиты, позагоняли на него кучу десантников, которые "Есть! Входим в корабль... Пошли!", "Смотреть, куда стреляете", "Санитар! Здесь раненый!" и "Мы в центре управления...". Наконец слышим заветное "Передача управления кораблем завершена". Классно, короче.
    И вот, после взлома компьютера, начинается самое, я бы сказал, фееричное. Исчезает практически все! Куда оно все девается? Если, по замыслу разрабов, десы воруют, тогда почему не слышно фраз типа "Ребята, тащите эту фотонку на капсулу, столкнем на торговой станции". Или, может, десы все переломали. Ну, например, 8 выживших десантников от счастья забухали и давай пинать "берцами" щиты. Огромные такие, которые могут держать мощные выстрелы фотонок. А щиты же не приспособлены, чтобы их ногами пинали. Вот и ломаются. Так десам этого мало, они еще и пухи все давай пинать. А потом идет пятизвездочный Мули Ха по второй палубе, а там к корме прыжковый двигатель прикручен. И рядом пара тысяч DURACELL сложена. Он такой, типа "А эт чё за ...?!?!". И давай это все добро пинать "берцами".
    В общем не понравилась мне эта задумка разрабов. Конечно, кто-нибудь скажет, что так интереснее, надо сначала захватить, потом по новой оснастить, и т.д. Но, не нравится мне такая задумка и все. Хоть ты трескни!
    Решил я это дело подправить, заодно и вам расскажу как уменьшить потери оборудования от неумеренного  злоупотребления десантников.

    Итак, вернемся к нашему файлу x3story.out. В нем описан класс "SHIP", у которого есть метод "DowngradeTakeOver". Метод этот вызывается в двух случаях: когда вражеский пилот сливается с мелкого корабля и когда наши развеселые десы захватывают бигшип. А в самом методе описывается алгоритм исчезновения оборудования. Давайте взглянем на листинг:
    Листинг 4.

     Код:
    1. ;
    2. ; === DowngradeTakeOver =========================================
    3. ; function  SHIP.DowngradeTakeOver();
    4. ;
    5.                                |      SHIP.DowngradeTakeOver:
    6. 000BB93C: 6E 0009              |    0            enter      0, 9
    7. 000BB93F: 06 03E8              |    0            pushw      1000d ; 03E8h
    8. 000BB942: 02                   |    1            push       1
    9. 000BB943: 82 00002561          |    2            callasm    TI_Delay
    10. 000BB948: 24                   |    1            pop
    11. 000BB949: 01                   |    0            push       0
    12. 000BB94A: 01                   |    1            push       0
    13. 000BB94B: 14 0002              |    2            mov        SP[1],SP[0] ; loc1
    14. 000BB94E: 24                   |    2            pop
    15. 000BB94F: 0D 0001              |    1 L000BB94F: push       SP[0] ; loc1
    16. 000BB952: 05 08                |    2            pushb      8
    17. 000BB954: 02                   |    3            push       1
    18. 000BB955: 82 000002E2          |    4            callasm    SA_GetNumSubTypes
    19. 000BB95A: 5C                   |    3            if SP[0]<=SP[1] then push 0 else push 1
    20. 000BB95B: 34 000BB9CE          |    2            if SP[0]=0 then jump L000BB9CE
    21. 000BB960: 32 000BB973          |    1            jump       L000BB973
    22. 000BB965: 0D 0001              |    1 L000BB965: push       SP[0] ; loc1
    23. 000BB968: 02                   |    2            push       1
    24. 000BB969: 46                   |    3            add        SP[0],SP[1]
    25. 000BB96A: 14 0002              |    2            mov        SP[1],SP[0] ; loc1
    26. 000BB96D: 24                   |    2            pop
    27. 000BB96E: 32 000BB94F          |    1            jump       L000BB94F
    28. 000BB973: 01                   |    1 L000BB973: push       0
    29. 000BB974: 0D 0002              |    2            push       SP[1] ; loc1
    30. 000BB977: 05 08                |    3            pushb      8
    31. 000BB979: 03                   |    4            push       2
    32. 000BB97A: 88 000A8CB9          |    5            call88     SHIP.GetWareTypeCount
    33. 000BB97F: 14 0002              |    3            mov        SP[1],SP[0] ; loc2
    34. 000BB982: 34 000BB9C8          |    3            if SP[0]=0 then jump L000BB9C8
    35. 000BB987: 0F 000C              |    2            read       SHIP.var_2004_2 ; [12d ; 0Ch]
    36. 000BB98A: 05 07                |    3            pushb      7
    37. 000BB98C: 03                   |    4            push       2
    38. 000BB98D: 82 00000E2C          |    5            callasm    SA_GetTypeDefaultRace
    39. 000BB992: 05 07                |    3            pushb      7
    40. 000BB994: 5B                   |    4            if SP[0]<>SP[1] then push 0 else push 1
    41. 000BB995: 0D 0001              |    3            push       SP[0] ; loc3
    42. 000BB998: 34 000BB9A4          |    4            if SP[0]=0 then jump L000BB9A4
    43. [color=yellow]000BB99D: 05 32                |    3            pushb      50d ; 32h[/color]
    44. 000BB99F: 32 000BB9A6          |    4            jump       L000BB9A6
    45. [color=yellow]000BB9A4: 05 5A                |    3 L000BB9A4: pushb      90d ; 5Ah[/color]
    46. 000BB9A6: 05 64                |    4 L000BB9A6: pushb      100d ; 64h
    47. 000BB9A8: 02                   |    5            push       1
    48. 000BB9A9: 82 000002C4          |    6            callasm    SE_Random
    49. 000BB9AE: 0D 0002              |    5            push       SP[1] ; loc4
    50. 000BB9B1: 5C                   |    6            if SP[0]<=SP[1] then push 0 else push 1
    51. 000BB9B2: 34 000BB9C5          |    5            if SP[0]=0 then jump L000BB9C5
    52. 000BB9B7: 0D 0003              |    4            push       SP[2] ; loc2
    53. 000BB9BA: 65                   |    5            neg        SP[0]
    54. 000BB9BB: 0D 0005              |    5            push       SP[4] ; loc1
    55. 000BB9BE: 03                   |    6            push       2
    56. 000BB9BF: 88 000A4A76          |    7            call88     SHIP.AddLaser
    57. 000BB9C4: 24                   |    5            pop
    58. 000BB9C5: 23 0002              |    4 L000BB9C5: popx       2
    59. 000BB9C8: 24                   |    2 L000BB9C8: pop
    60. 000BB9C9: 32 000BB965          |    1            jump       L000BB965
    61. 000BB9CE: 01                   |    1 L000BB9CE: push       0
    62. 000BB9CF: 14 0002              |    2            mov        SP[1],SP[0] ; loc1
    63. 000BB9D2: 24                   |    2            pop
    64. 000BB9D3: 0D 0001              |    1 L000BB9D3: push       SP[0] ; loc1
    65. 000BB9D6: 05 09                |    2            pushb      9
    66. 000BB9D8: 02                   |    3            push       1
    67. 000BB9D9: 82 000002E2          |    4            callasm    SA_GetNumSubTypes
    68. 000BB9DE: 5C                   |    3            if SP[0]<=SP[1] then push 0 else push 1
    69. 000BB9DF: 34 000BBA2F          |    2            if SP[0]=0 then jump L000BBA2F
    70. 000BB9E4: 32 000BB9F7          |    1            jump       L000BB9F7
    71. 000BB9E9: 0D 0001              |    1 L000BB9E9: push       SP[0] ; loc1
    72. 000BB9EC: 02                   |    2            push       1
    73. 000BB9ED: 46                   |    3            add        SP[0],SP[1]
    74. 000BB9EE: 14 0002              |    2            mov        SP[1],SP[0] ; loc1
    75. 000BB9F1: 24                   |    2            pop
    76. 000BB9F2: 32 000BB9D3          |    1            jump       L000BB9D3
    77. 000BB9F7: 01                   |    1 L000BB9F7: push       0
    78. 000BB9F8: 0D 0002              |    2            push       SP[1] ; loc1
    79. 000BB9FB: 05 09                |    3            pushb      9
    80. 000BB9FD: 03                   |    4            push       2
    81. 000BB9FE: 88 000A8CB9          |    5            call88     SHIP.GetWareTypeCount
    82. 000BBA03: 14 0002              |    3            mov        SP[1],SP[0] ; loc2
    83. 000BBA06: 34 000BBA29          |    3            if SP[0]=0 then jump L000BBA29
    84. 000BBA0B: 05 64                |    2            pushb      100d ; 64h
    85. 000BBA0D: 02                   |    3            push       1
    86. 000BBA0E: 82 000002C4          |    4            callasm    SE_Random
    87. [color=yellow]000BBA13: 05 5A                |    3            pushb      90d ; 5Ah[/color]
    88. 000BBA15: 5C                   |    4            if SP[0]<=SP[1] then push 0 else push 1
    89. 000BBA16: 34 000BBA29          |    3            if SP[0]=0 then jump L000BBA29
    90. 000BBA1B: 0D 0001              |    2            push       SP[0] ; loc2
    91. 000BBA1E: 65                   |    3            neg        SP[0]
    92. 000BBA1F: 0D 0003              |    3            push       SP[2] ; loc1
    93. 000BBA22: 03                   |    4            push       2
    94. 000BBA23: 88 000A48AC          |    5            call88     SHIP.AddShield
    95. 000BBA28: 24                   |    3            pop
    96. 000BBA29: 24                   |    2 L000BBA29: pop
    97. 000BBA2A: 32 000BB9E9          |    1            jump       L000BB9E9
    98. 000BBA2F: 01                   |    1 L000BBA2F: push       0
    99. 000BBA30: 14 0002              |    2            mov        SP[1],SP[0] ; loc1
    100. 000BBA33: 24                   |    2            pop
    101. 000BBA34: 0D 0001              |    1 L000BBA34: push       SP[0] ; loc1
    102. 000BBA37: 05 0A                |    2            pushb      10d ; 0Ah
    103. 000BBA39: 02                   |    3            push       1
    104. 000BBA3A: 82 000002E2          |    4            callasm    SA_GetNumSubTypes
    105. 000BBA3F: 5C                   |    3            if SP[0]<=SP[1] then push 0 else push 1
    106. 000BBA40: 34 000BBA90          |    2            if SP[0]=0 then jump L000BBA90
    107. 000BBA45: 32 000BBA58          |    1            jump       L000BBA58
    108. 000BBA4A: 0D 0001              |    1 L000BBA4A: push       SP[0] ; loc1
    109. 000BBA4D: 02                   |    2            push       1
    110. 000BBA4E: 46                   |    3            add        SP[0],SP[1]
    111. 000BBA4F: 14 0002              |    2            mov        SP[1],SP[0] ; loc1
    112. 000BBA52: 24                   |    2            pop
    113. 000BBA53: 32 000BBA34          |    1            jump       L000BBA34
    114. 000BBA58: 01                   |    1 L000BBA58: push       0
    115. 000BBA59: 0D 0002              |    2            push       SP[1] ; loc1
    116. 000BBA5C: 05 0A                |    3            pushb      10d ; 0Ah
    117. 000BBA5E: 03                   |    4            push       2
    118. 000BBA5F: 88 000A8CB9          |    5            call88     SHIP.GetWareTypeCount
    119. 000BBA64: 14 0002              |    3            mov        SP[1],SP[0] ; loc2
    120. 000BBA67: 34 000BBA8A          |    3            if SP[0]=0 then jump L000BBA8A
    121. 000BBA6C: 05 64                |    2            pushb      100d ; 64h
    122. 000BBA6E: 02                   |    3            push       1
    123. 000BBA6F: 82 000002C4          |    4            callasm    SE_Random
    124. [color=yellow]000BBA74: 05 5A                |    3            pushb      90d ; 5Ah[/color]
    125. 000BBA76: 5C                   |    4            if SP[0]<=SP[1] then push 0 else push 1
    126. 000BBA77: 34 000BBA8A          |    3            if SP[0]=0 then jump L000BBA8A
    127. 000BBA7C: 0D 0001              |    2            push       SP[0] ; loc2
    128. 000BBA7F: 65                   |    3            neg        SP[0]
    129. 000BBA80: 0D 0003              |    3            push       SP[2] ; loc1
    130. 000BBA83: 03                   |    4            push       2
    131. 000BBA84: 88 000A61DC          |    5            call88     SHIP.AddMissile
    132. 000BBA89: 24                   |    3            pop
    133. 000BBA8A: 24                   |    2 L000BBA8A: pop
    134. 000BBA8B: 32 000BBA4A          |    1            jump       L000BBA4A
    135. 000BBA90: 05 0B                |    1 L000BBA90: pushb      11d ; 0Bh
    136. 000BBA92: 14 0002              |    2            mov        SP[1],SP[0] ; loc1
    137. 000BBA95: 24                   |    2            pop
    138. 000BBA96: 0D 0001              |    1 L000BBA96: push       SP[0] ; loc1
    139. 000BBA99: 05 10                |    2            pushb      16d ; 10h
    140. 000BBA9B: 5E                   |    3            if SP[0]<SP[1] then push 0 else push 1
    141. 000BBA9C: 34 000BBB28          |    2            if SP[0]=0 then jump L000BBB28
    142. 000BBAA1: 32 000BBAB4          |    1            jump       L000BBAB4
    143. 000BBAA6: 0D 0001              |    1 L000BBAA6: push       SP[0] ; loc1
    144. 000BBAA9: 02                   |    2            push       1
    145. 000BBAAA: 46                   |    3            add        SP[0],SP[1]
    146. 000BBAAB: 14 0002              |    2            mov        SP[1],SP[0] ; loc1
    147. 000BBAAE: 24                   |    2            pop
    148. 000BBAAF: 32 000BBA96          |    1            jump       L000BBA96
    149. 000BBAB4: 01                   |    1 L000BBAB4: push       0
    150. 000BBAB5: 01                   |    2            push       0
    151. 000BBAB6: 14 0002              |    3            mov        SP[1],SP[0] ; loc2
    152. 000BBAB9: 24                   |    3            pop
    153. 000BBABA: 0D 0001              |    2 L000BBABA: push       SP[0] ; loc2
    154. 000BBABD: 0D 0003              |    3            push       SP[2] ; loc1
    155. 000BBAC0: 02                   |    4            push       1
    156. 000BBAC1: 82 000002E2          |    5            callasm    SA_GetNumSubTypes
    157. 000BBAC6: 5C                   |    4            if SP[0]<=SP[1] then push 0 else push 1
    158. 000BBAC7: 34 000BBB22          |    3            if SP[0]=0 then jump L000BBB22
    159. 000BBACC: 32 000BBADF          |    2            jump       L000BBADF
    160. 000BBAD1: 0D 0001              |    2 L000BBAD1: push       SP[0] ; loc2
    161. 000BBAD4: 02                   |    3            push       1
    162. 000BBAD5: 46                   |    4            add        SP[0],SP[1]
    163. 000BBAD6: 14 0002              |    3            mov        SP[1],SP[0] ; loc2
    164. 000BBAD9: 24                   |    3            pop
    165. 000BBADA: 32 000BBABA          |    2            jump       L000BBABA
    166. 000BBADF: 0D 0001              |    2 L000BBADF: push       SP[0] ; loc2
    167. 000BBAE2: 0D 0003              |    3            push       SP[2] ; loc1
    168. 000BBAE5: 03                   |    4            push       2
    169. 000BBAE6: 88 000A8CB9          |    5            call88     SHIP.GetWareTypeCount
    170. 000BBAEB: 0D 0001              |    3            push       SP[0] ; loc3
    171. 000BBAEE: 34 000BBB1C          |    4            if SP[0]=0 then jump L000BBB1C
    172. 000BBAF3: 02                   |    3            push       1
    173. 000BBAF4: 02                   |    4            push       1
    174. 000BBAF5: 0D 0003              |    5            push       SP[2] ; loc3
    175. 000BBAF8: 46                   |    6            add        SP[0],SP[1]
    176. 000BBAF9: 02                   |    5            push       1
    177. 000BBAFA: 82 000002C4          |    6            callasm    SE_Random
    178. 000BBAFF: 46                   |    5            add        SP[0],SP[1]
    179. 000BBB00: 02                   |    4            push       1
    180. 000BBB01: 82 000002C4          |    5            callasm    SE_Random
    181. 000BBB06: 0D 0002              |    4            push       SP[1] ; loc3
    182. 000BBB09: 65                   |    5            neg        SP[0]
    183. 000BBB0A: 0D 0002              |    5            push       SP[1] ; loc4
    184. 000BBB0D: 46                   |    6            add        SP[0],SP[1]
    185. 000BBB0E: 0D 0004              |    5            push       SP[3] ; loc2
    186. 000BBB11: 0D 0006              |    6            push       SP[5] ; loc1
    187. 000BBB14: 04                   |    7            push       3
    188. 000BBB15: 87 0000000C          |    8            call87     AddWare
    189. 000BBB1A: 24                   |    5            pop
    190. 000BBB1B: 24                   |    4            pop
    191. 000BBB1C: 24                   |    3 L000BBB1C: pop
    192. 000BBB1D: 32 000BBAD1          |    2            jump       L000BBAD1
    193. 000BBB22: 24                   |    2 L000BBB22: pop
    194. 000BBB23: 32 000BBAA6          |    1            jump       L000BBAA6
    195. 000BBB28: 0F 0003              |    1 L000BBB28: read       GBODY.var_1000_3 ; [3]
    196. 000BBB2B: 34 000BBB58          |    2            if SP[0]=0 then jump L000BBB58
    197. 000BBB30: 05 11                |    1            pushb      17d ; 11h
    198. 000BBB32: 05 10                |    2            pushb      16d ; 10h
    199. 000BBB34: 03                   |    3            push       2
    200. 000BBB35: 88 000A8E67          |    4            call88     SHIP.GetWareTypeCountWithPredefined
    201. 000BBB3A: 0F 0003              |    2            read       GBODY.var_1000_3 ; [3]
    202. 000BBB3D: 03                   |    3            push       2
    203. 000BBB3E: 82 0000E253          |    4            callasm    SA_SetExtraSpeed
    204. 000BBB43: 24                   |    2            pop
    205. 000BBB44: 05 12                |    1            pushb      18d ; 12h
    206. 000BBB46: 05 10                |    2            pushb      16d ; 10h
    207. 000BBB48: 03                   |    3            push       2
    208. 000BBB49: 88 000A8E67          |    4            call88     SHIP.GetWareTypeCountWithPredefined
    209. 000BBB4E: 0F 0003              |    2            read       GBODY.var_1000_3 ; [3]
    210. 000BBB51: 03                   |    3            push       2
    211. 000BBB52: 82 0000E264          |    4            callasm    SA_SetExtraRotSpeed
    212. 000BBB57: 24                   |    2            pop
    213. 000BBB58: 24                   |    1 L000BBB58: pop
    214. 000BBB59: 01                   |    0            push       0
    215. 000BBB5A: 83                   |    1            ret
     


    Вкратце, суть алгоритма такая. Программа запрашивает количество лазеров на борту. Потом проверяет - если они хаакские, значит устанвливается нижняя планка шанса на 50
     Код:
    1. 000BB99D: 05 32                |    3            pushb      50d ; 32h
     

    иначе - на 90
     Код:
    1. 000BB9A4: 05 5A                |    3 L000BB9A4: pushb      90d ; 5Ah
     

    Если шаровое число до 100 меньше, чем нижняя планка шанса, то все, нет больше лазеров.
    Потом то же со щитами, но там уже побоку чьи, наши, ваши, любой щит исчезает с 90% вероятностью.
    Потом - ракеты.
    Затем по замысловатой формуле все оборудование и груз. Формула, кстати, хорошо описана  здесь

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

    Редактировалось 5 раз (а). Последний раз 19.02.2012 17:29:32.

    19.02.2012 22:51:33
    YOYOMAN

    Репутация: 1800
    Сообщений: 4277
    Регистрация: 20.11.2009
    Структура файла TCockpits и создание нового набора вооружения

    Общие сведения


     
    TCockpits - файл, который содержит наборы вооружения для турелей. Оригинальный файл содержит  162 набора.


    Структура файла TCockpits









    Как видно на картинке сверху :

     1) Имя файла в Х3 Edior 2.
     2) Переключатель режима отображения  вооружения: по идентификатору или по имени. В данном файле все объекты не имеют строки для имени, поэтому  всегда отображается только идентификатор.
     3) Поле имени/идентификаторов наборов  вооружения. В этом поле редактора отображаются наборы вооружения  по идентификатору а также порядковый номер, который всегда начинается с цифры "1".
     4) ID - идентификатор набора. Имеет вид: SS_COCKPIT_произвольное имя.
     5) Model scene - путь к камере. Указывается именно 4512 (сцена в папке cut, содержит стандартную максовскую 18 mm камеру и цель  и является камерой через которую мы видим из кабин корабля). есть ещё другие сцены камер, но все они одинаковы и не влияют ни начто.



    файл 4512: вид в 3d max



     6) Compatible guns - поле, отображающие все пушки которые добавлены в текущий кокпит.
     7) Кнопки Add/Remowe - Эти кнопки позволяют Добавить/Удалить выбраные пушки из поля всех доступных пушек справа. Для большей простоты можно добавлять пушки выбрав их в поле доступных лазеров и нажав 2 раза левой кнопкой мыши. Аналогично для удаления, но выбирать нужно в поле совместимых лазеров.
     8)  Avalaible guns - список все пушек в игре, которые храняться в TLaser.


    Добавление нового набора вооружения (кокпита) в файл TCockpits


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

     
     Необходимый инструментарий:
     
  • Х3 Editor 2*
     
  • TCockpits
  •  


     
    Процес работы:


     
    1) Создайте в папке с игрой новую папку с названием "types" или создайте новый архив cat/dat.
    2) Распакуйте самый свежий файлы TCockpits из папки "types" в оригинальных катах.
    3) Запускаете  файл TCockpits
    4) Выделяете самый последний обьект в списке и щёлкаете на нём правой кнопкой мыши, в контксном меню нажимаете "Copy" и потом нажав опять правой кнопкой  нажмаете "Paste to End"
    5) изменяете ID  на свой уникальный, у меня он будет таким:SS_COCKPIT_NEW_TER_UNIVERSAL
    6) добавляете нужные пушки из списка всех возможных лазеров, я же добавлю: Световая пушка, Проэктор сингулярных точек, Бомбомет материя/антиматерия, Эксп. Электромагнитная плазменная пушка, Прототип  Бомбомет материя/антиматерия, Прототип Световая пушка, Электромагнитная плазменная пушка.
    7) Сохраняете и закрываете редактор.
    8) Снова запускаете редактор. Новый набор оружия успешно создан. Зная ваш новый идентификатор, можно его запросто использовать в любом корабле
     

         У вас должно быть вот так, только название и пушки другие:






    Добавление нового набора вооружения (кокпита) к кораблю в TShips


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

     
     Необходимый инструментарий:
     
  • Х3 Editor 2*
     
  • TCockpits
     
  • TShips
  •  


     
    Процес работы:


     
    1) Распакуйте самый свежий файл TShips из папки "types" в оригинальных катах.
    2) Переместите его в свой новый архив в папку "types"
    3) Запускаете  файл TShips
    4) Переходите на вкладку Turrets? в списке всех турелей корабля выделяете кокпит носовой турели - front.
    5) Щелкаете на него 2 раза левой кнопкой мыши, теперь откроется окно настройки этой турели, необходимо выполнить следующие действия:
     
    •  Проверьте, что вы открыли именно нужную турель.
       
    •   В окне настройки турели корабля в поле Viewport  щелкните на старый кокпит.
       
    •   В открывшеся списке выберите свой новый набор вооружения (кокпит).






    6) Сохраняете и закрываете редактор.
    7) Снова запускаете редактор. Новый набор оружия успешно применен к кораблю. Тепреь данная турель будет поддерживать те пушки, которые вы назначили при создании набора вооружения (кокпита).
     

    У вас должно быть вот так, только корабль и набор вооружения другие:






    * -  Умение пользоваться Х3 Editor 2 обязательно!!!

    Редактировалось 1 раз (а). Последний раз 19.02.2012 23:34:43.

    20.02.2012 15:11:01
    Странник (модератор)
     AZ писал(а):
    Нечто совершенно нечитаемое
     

    Это не гайд. Это поток сознания. В телевизионном исполнении сей феномен еще называется "говорящая голова".

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


    Удалил.
    1
    дерево темы → Гайд-Парк

    Список игр