|
|
|
Канал X3: Reunion »
Модовый и скриптовый отсек X3: Reunion: «Кодинг в обже, вопросы и ответы» |
|
|
LM 70 EGP
Рейтинг канала: 5(123) Репутация: 6 Сообщения: 99
Зарегистрирован: 05.04.2009 |
|
А меня интересуют вот такие вопросы. Какие глобальные переменные и функции за что отвечают, где в обже зашито: размер трюма станций, стыковка кораблей к станциям и друг к другу. Наверняка это все давно известно знающим людям. А выложить для общего пользования? Или это информация из раздела мы сами разбирались и ты сам разбирайся.
add:
Ну и ладно сам разобрался. Значит так. Чтобы увеличить размер трюма торговых станций и доков оборудования лезем в ОБЖ находим класс TDOCK в нем находим метод TDOCK.GetWareTypeBestStore. Этот метод перекрывает родительский метод класса TSTATION. Этот метод вызывается для определения свободного места на станции или полной вместимости склада например в методе GetWareTypeMaxStore, GetWareTypeContainerSize, GetWareTypeFree которые в свою очередь используются для отображения максимального количества товара в классе TMENU_TRADE и других методах отвечающих за отображение и транфер товара со станции и на станцию в меню и скриптах.
Так вот в методе TDOCK.GetWareTypeBestStore для получения конечного результата вызывается глобальная функция global.GetWareTypeBestStoreOfResource(arg1,arg2,0,0). Меняем ее на N*global.GetWareTypeBestStore(arg1,arg2), где N*2 это то во сколько раз мы хотим увеличить размер трюма.
Оказывается нет никакой глобальной переменной или своиства класса отвечающего за размер трюма нет никакого коэффициента на который бы что-то умножалось или делилось. Размер трюма вычисляется всеми методами классов и скриптами обращающимися к этой теме "на лету" по формуле 10000/RelVal(товара), а не как у кораблей хранится в одном из свойств. Эта формула и зашита в методе global.GetWareTypeBestStore(arg1,arg2). Если изменить эту формулу автоматически изменятся трюмы продуктов всех типов станций, доков и наверное верфей тоже (для ресурсов метод global.GetWareTypeBestStoreOfResource). Больше ничего там особенного нет кроме проверки на ноль. Все оказалось очень просто.
Аналогичный метод есть у класса TFACTORY так же перекрывающий родительский из TSTATION. Покопавшись в нем можно аналогичным и очень простым способом увеличить или уменьшить размер трюма фабрики.
_________________ Нет никакой ложки
Последний раз редактировалось: LM (03:41 04-04-2010), всего редактировалось 5 раз(а) |
|
|
LM 70 EGP
Рейтинг канала: 5(123) Репутация: 6 Сообщения: 99
Зарегистрирован: 05.04.2009 |
|
Вход и выход корабля из гиперпространства прописан в соответствующих методах класса TSHIP.__EnterHyperSpace и TSHIP.__LeaveHyperSpace. Так вот на время нахождения корабля в гипере приостанавливается работа скриптов. При выходе из гипера эта работа возобновляется. Стеки "размораживаются" в обратном порядке. То есть нулевой стек запускается последним. В связи с этим может возникать инетерсная ситуация. Если вы в своих скриптах используете какой-либо управляющий скрипт сидящий например в стеке №30, который управляет стеком №0 то опасайтесь менять скрипт в 0-м стеке в процессе прохождения кораблем врат или гиперпрыжка. Получается что инициализированный 30 стек пытается вызвать скрипт в еще неинициализированном 0-м стеке. Это вызовет вис корабля. У меня это выглядело так. Висящий в центре сектора корабль не реагирующий ни на что и не имеющий визуальной модели. Такая ситуация возможна например когда корабль до входа в сектор выполнял скрипт ship.cmd.movesector.pl, а после входа в сектор сразу запускается ship.cmd.attack.pl или любой другой и корабль "виснет".
Такое происходит только в секторе с игроком в удаленном секторе все работает нормально. При повторном выходе/входе игрока в сектор все зависшие корабли "размораживаются".
Например
while 1
...
if not [THIS]->is the same sector as !ship
skip if is script !ship.cmd.movesector.pl in task 0
START [THIS]->call script !ship.cmd.movesector.pl sector = !sector
else
skip if is script !ship.cmd.attack.pl in task 0
START [THIS]->call script !ship.cmd.attack.pl victim = !ship
end
...
end
Приведет к "вису".
Да и кстати вы знали, что врата в Х3 это ангар и для старта из врат используются те же методы что и для старта из ангара. Это например было бы полезно знать если хочешь написать команду респауна корабля из врат.
_________________ Нет никакой ложки
Последний раз редактировалось: LM (17:46 29-04-2010), всего редактировалось 3 раз(а) |
|
|
Vilko 145 EGP
Рейтинг канала: 1(9) Репутация: 62 Сообщения: 83 Откуда: StarWind world Зарегистрирован: 19.12.2006 |
|
Подскажите плиз, нужны ли (с практической точки зрения) для работы игры cat/dat файлы? или лучше отключить проверку их наличия и пользоваться только распакованными?
|
|
|
AlexYar 1850 EGP
Рейтинг канала: 13(2096) Репутация: 328 Сообщения: 31615
Зарегистрирован: 26.10.2003 |
|
Vilko : |
(с практической точки зрения) для работы игры cat/dat файлы?
|
Это контейнеры, чтобы в папке игры не было кучи файлов.
С практической точки зрения они нужны Повышает быстродействие (и компа вцелом и игры).
Vilko : |
и пользоваться только распакованными?
|
Это не архивы, время на распаковку не тратится.
|
|
|
Vilko 145 EGP
Рейтинг канала: 1(9) Репутация: 62 Сообщения: 83 Откуда: StarWind world Зарегистрирован: 19.12.2006 |
|
что они такое - я вкурсе
и кстати время на распаковку таки тратится, поскольку внутри них практически все в pck (тобишь gzip). а внешние файлы можно хранить уже распакованными
|
|
|
AlexYar 1850 EGP
Рейтинг канала: 13(2096) Репутация: 328 Сообщения: 31615
Зарегистрирован: 26.10.2003 |
|
Vilko : |
поскольку внутри них практически все в pck
|
В любой папке тоже можно хранить внутри gzip-архивы, но это же не значит, что сама папка - gzip-архив
|
|
|
Xenon J 949 EGP
Рейтинг канала: 11(1674) Репутация: 161 Сообщения: 3280 Откуда: Ксенонский сектор 472 Зарегистрирован: 30.03.2007 |
|
Выяснилась интересная особенность (то бишь баг ) работы команды:
<RetVar/IF><RefObj> is of type <Var/Ship Type/Station Type>
Оказывается, при работе с доками (5 майнтайп) она проверяет не тип, а класс объекта, то есть при проверке
Код: |
Аргонская торговая станция is of type Торговая станция телади |
всё равно выдаст [TRUE]. Умеет отличать только торговки от доков оборудования. Собственно, вопрос в том, как это поправить?
Последний раз редактировалось: Xenon J (10:24 07-08-2010), всего редактировалось 1 раз |
|
|
Vilko 145 EGP
Рейтинг канала: 1(9) Репутация: 62 Сообщения: 83 Откуда: StarWind world Зарегистрирован: 19.12.2006 |
|
Xenon J : |
Выяснилась интересная особенность (то бишь баг Хы... ) работы команды:
<RetVar/IF><RefObj> is of type <Var/Ship Type/Station Type>
Оказывается, при работе с доками (5 майнтайп) она проверяет не тип, а класс объекта
|
может кто-нибудь сказать номер опкода этой операции?
у меня в exe найден и разобран процесс обработки байткода obj-ей, но еще нет ассоциации кодов с мнемониками команд...
имхо эту проблему легко поправить достаточно простым патчем, благо места свободного (неиспользуемых процедур) в ехе полно
|
|
|
Xenon J 949 EGP
Рейтинг канала: 11(1674) Репутация: 161 Сообщения: 3280 Откуда: Ксенонский сектор 472 Зарегистрирован: 30.03.2007 |
|
Vilko : |
может кто-нибудь сказать номер опкода этой операции?
|
Номер чего?
Vilko : |
у меня в exe найден и разобран процесс обработки байткода obj-ей, но еще нет ассоциации кодов с мнемониками команд...
|
Ого, народ уже экзешники ковыряет. А случайно формулу вычисления позиций рамок на экране вокруг объектов не знаешь? Хотелось бы FOV как в Х2 сделать, а то рамки съедут.
ЗЫЖ Насчет вопроса типов частично решил путем добавки новых ДО (землян и хааков) в соотв ф-цию - GetDockTypeFromSubType. Команда по-прежнему отличает только ТС и ДО (а не типы станций), но для конкретного скрипта этого пока хватает. В остальных случаях придётся по субтайпу фильтровать базар
_________________ Последний раз редактировалось: Xenon J (23:23 23-03-2023), всего редактировалось 16 раз
Последний раз редактировалось: Xenon J (12:21 11-08-2010), всего редактировалось 1 раз |
|
|
Vilko 145 EGP
Рейтинг канала: 1(9) Репутация: 62 Сообщения: 83 Откуда: StarWind world Зарегистрирован: 19.12.2006 |
|
С рамками - чуть попозже отпишу. нашел где они рендерятся, но формулу еще не вычленил, там полно кода...
а вот это помжет, кому пригодится:
если нужно, чтобы сейвы (и все прочее, что лезет в мои документы) находились в папке игры (X3\save) - нужно пропатчить 1 байт в ехе.
для версии 2.5: оффсет 0x6061E, байт 74 меняем на EB.
|
|
|
Xenon J 949 EGP
Рейтинг канала: 11(1674) Репутация: 161 Сообщения: 3280 Откуда: Ксенонский сектор 472 Зарегистрирован: 30.03.2007 |
|
А как в обже сделать глобальную переменную-массив, которая будет определяться один раз при старте новой игры? Массив предварительно загрузить нужными значениями - номерами в текстовом файле.
Хочу всё-таки решить проблему названий секторов на своей рандомной карте - номера будут браться из массива, куда их надо занести в зависимости от расы-владельца сектора.
_________________ Последний раз редактировалось: Xenon J (23:23 23-03-2023), всего редактировалось 16 раз |
|
|
AlexYar 1850 EGP
Рейтинг канала: 13(2096) Репутация: 328 Сообщения: 31615
Зарегистрирован: 26.10.2003 |
|
Xenon J : |
А как в обже сделать глобальную переменную-массив, которая будет определяться
|
Типа мануал
1. Создаём/объявляем новую глобальную переменную.
Для этого в теле x3story.cpp ищем строчку:
Код: |
.classdef TX_AUDIO, 1 |
И перед ней, отступя строчек пять, пишем новую строку:
Код: |
.varray ay_MyExtraArray1 |
Вместо ay подставьте буквы из своего ника, так удобнее группировать вводимые изменения в обж, оставляя совместимость с другими модами и уникальность ваших переменных.
Вместо MyExtraArray1 напишите своё название массива. Лучше, чтобы название отражало смысл массива, т.е. что именно в нём хранится (чтобы сами потом не забыли).
2. Объявляем новую глобальную функцию.
Сразу под той строкой, что создали выше, пишем новую строку:
Код: |
.vfunc ay_Init_MyExtraArray1 |
Название функции так же меняем согласно своему нику и назначению инициализируемого массива.
3. Создаём свою новую глобальную функцию.
Отступаем от предыдущих строк строчки три (раздвигаем текст кода клавишей Enter, чтобы секция Audio уехала ниже) и пишем саму функцию:
Код: |
function ay_Init_MyExtraArray1()
{
global.ay_MyExtraArray1=array(Value1,Value2,Value3,ValueN);
return(0);
}
|
Где Value1 - ValueN - числовые значения вашего массива (сколько нужно значений, столько и пишем через запятую). Например так:
global.ay_MyExtraArray1=array(1,3,9,15);
Если нужны текстовые значения... (кликните здесь для просмотра)
Если нужны текстовые значения - пишем их в кавычках и только латиницей (код обжа не приемлет кириллицу, для неё используйте файлы-описатели и команду SE_ReadText). Например так:
global.ay_MyExtraArray1=array("Medved","Vushanke","Isbalalaykoy","NaKrasnoy","Ploshadi");
или так:
global.ay_MyExtraArray1=array(SE_ReadText(100,500),SE_ReadText(100,501));
где 100/500 и 100/501 - это Page и Tid вашего текста на странице-описателе (в языковом файле). Если языковой файл у вас стандартный или свой собственный, например 70012 - сперва подгружаем его функцией LoadText класса TINIT.
В таком случае ваша ф-ия будет выглядеть так:
Код: |
function ay_Init_MyExtraArray1()
{
TINIT.LoadText(12);
global.ay_MyExtraArray1=array(SE_ReadText(100,500),SE_ReadText(100,501));
return(0);
}
|
Обращаем внимание, что вместо 70012 нужно писать только 12, так как текущий язык в игре определяется автоматически, а номер файла считается как LanguageCode*10000+Number. Если вы используете файл-описатель с номером 440012, а игра использует английский язык, то она загрузит его.
|
Если нужно использовать числовые значения, но читать их из файла-описателя, не забивая намертво в обж... (кликните здесь для просмотра)
Если нужно использовать числовые значения, но читать их из файла-описателя, не забивая намертво в обж - тогда делаем так:
а) Создаём свой файл описатель (или берём уже созданный), добавляем туда новую страницу Page (или используем имеющуюся), создаём новые строки Tid (или берём те, что уже есть) и заносим в них значения для массива.
б) Так как обж считывает данные из файла-описателя как строковые, а не числовые - нам нужно их сконвертировать в числовые. Для этого немного изменяем ф-ию из примера для строковых данных, чтобы она выглядела вот так:
Код: |
function ay_Init_MyExtraArray1()
{
TINIT.LoadText(12);
global.ay_MyExtraArray1=array(SE_StringToInt(SE_ReadText(100,500)),SE_StringToInt(SE_ReadText(100,501)));
return(0);
}
|
Стараемся не запутаться со скобками..
|
4. Вставляем наш код на исполнение в игре.
Сперва определяемся, когда мы хотим инициализировать свой массив - в начале игры всего один раз или при каждой загрузке/сохранении.
При каждой загрузке будет удобнее, если предполагается возможность изменений значений в патчах к моду без надобности заменять сам обж и начинать новую игру.
Однократная инициализация целесообразнее, если обновление данных массива не планируется без начала игры заново.
Вариант с однократной загрузкой (кликните здесь для просмотра)
В теле x3story.cpp ищем такую строку:
Далее по тексту этой ф-ии перед строкой:
Код: |
var loc1=SA_GetNumSubTypes(16); |
раздвигаем Enter-ом текст и вставляем такую свою строку:
Код: |
global.ay_Init_MyExtraArray1();
|
Название после global. будет вашим собственным (той функции, которую вы создавали в примере выше).
|
Вариант с многократной загрузкой (кликните здесь для просмотра)
В теле x3story.cpp ищем такую строку:
Код: |
function _Restart(arg1)
|
Далее по тексту этой ф-ии перед строкой:
Код: |
TSCRIPT_EDITOR.ReInit();
|
раздвигаем Enter-ом текст и вставляем такую свою строку:
Код: |
global.ay_Init_MyExtraArray1();
|
Название после global. будет вашим собственным (той функции, которую вы создавали в примере выше).
|
Вот, собственно, и всё. Вроде ничего не забыл и не перепутал
А я вроде уже отвечал когда-то на этот вопрос, или мне приснилось?
|
|
|
AlexYar 1850 EGP
Рейтинг канала: 13(2096) Репутация: 328 Сообщения: 31615
Зарегистрирован: 26.10.2003 |
|
Кстати, предлагаю сменить название темы на менее пугающее для новичков и более прогрессивное:
Cкрытый текст (кликните здесь для просмотра)
Некромантия - изучаем внутренности Х3.
|
добавлено спустя 8 минут:
Обосную.
Кафедра - само по себе отталкивающее слово для людей без ВО.
Иеромантия - вообще не понятно, чё такое.
Внутренности - это к паталогоанатому.
Вобщем, название темы сути не отражает вообще.
Можно назвать "Кодинг в обже, вопросы и ответы".
И то понятнее будет
Последний раз редактировалось: AlexYar (18:26 27-04-2011), всего редактировалось 1 раз |
|
|
Gannibal 1457 EGP
Репутация: 273 Сообщения: 9668 Откуда: ЯНАО, Новый Уругвай Зарегистрирован: 14.10.2006 |
|
AlexYar : |
Кстати, предлагаю сменить название темы на менее пугающее для новичков и более прогрессивное:
|
Думаю да... А то так смотри и всякие демоны и вурдалаки кодить начнут...
AlexYar : |
И то понятнее будет
|
поменял...
_________________ В России дураков много, а умных ещё больше... |
|
|
Xenon J 949 EGP
Рейтинг канала: 11(1674) Репутация: 161 Сообщения: 3280 Откуда: Ксенонский сектор 472 Зарегистрирован: 30.03.2007 |
|
А к какому классу относится функция _Init ? Там так напрямую не написано.
_________________ Последний раз редактировалось: Xenon J (23:23 23-03-2023), всего редактировалось 16 раз |
|
|
AlexYar 1850 EGP
Рейтинг канала: 13(2096) Репутация: 328 Сообщения: 31615
Зарегистрирован: 26.10.2003 |
|
Xenon J : |
Там так напрямую не написано.
|
Если не написано, значит глобальная.
|
|
|
ULiX 320 EGP
Рейтинг канала: 7(691) Репутация: 146 Сообщения: 573 Откуда: Комсомольск на-Амуре Зарегистрирован: 12.07.2005 |
|
Darth Revan : |
На самом деле, он как раз сам по себе и создавался. KC я не пользолся вообще, хотя, конечно, знал, что он C-подобный. Всё дело в том, что asm-код от KC без оптимизации, поэтому всё относительно легко восстанавливается.
|
Тогда это был реально титанический труд.
Возможно, еслиб у тебя были исходники, ты бы зделал транслятор более похожий на KC
Я так понимаю, раз автор не знаком с исходниками KC, то нужно развеять туман над неопределенными моментами.
(loc1=loc1-1)+1
В KC исходниках на местах подобных конструкций стоит loc1--
Итоговый вариант с лишней операцией - это уже странное поведение эгософтовского компилятора KC.
Именно из за этой особенности я в своих проекта предпочел использовать для инкрементации и декрементации полную запись как бейсике loc1=loc1+1 или loc1=loc1-1
Если подумать, то в принципе поведение компилятора закономерное. Дело в том, что операции ++ и -- задумывалось использовать в упрощенных условных конструкциях и циклах. Приблизительно так:
for(i=0;i++ < 10){}
Вместо:
for(i=0;i < 10; i++){}
Или
int i=0;
while(i++ < 10){}
Если бы программисты на KC писали бы именно так, то код был бы оптимизирован. Что делает такая конструкция в обже, значение переменной меняется, а в верхушку стека помещается значение до преобразования переменной, и это значение можно уже использовать в условных операциях без повторного помещения переменной в стек.
В общем устранение незначащего кода это уже задача компилятора на стадии оптимизации кода. А вопрос автоматической оптимизации извечно будет больным местом любого компилятора.
В местах встечи
if(0){}
В исходниках KC частенько видим
if(DebugMode){}
Константа DebugMode определется через #define
В итоге константы заменяются числовыми значениями, а компилятор продолжает включать в итоговый проект код отладки.
Ну а теперь вопросы от надолго пропавшего.
Есть ли обновленные версии трансляторов XC<->XAsm?
Где их можно взять?
Хотя, возможно успею найти ответы и сам заглянув в ветку X3:TT, но вдруг не найду. По старым темам прошёлся, пока не нашёл.
Если уже делать дроида для X3, то уже лучше освоить X3:TС. Я ещё, кстати, в неё не поиграл. Когда купил три года назад, тачка почти не тянула, потом времени не было. Живой сын лучше программного дроида. Можно сказать потратил годы на лучший проект в своей жизни - сына! А теперь стало полегче, появилось время, и можно заниматься проектами параллельно. Надеюсь, что ещё не вся команда модеров разбежалась.
_________________ Новое ещё не значит лучшее
Последний раз редактировалось: ULiX (05:09 15-09-2011), всего редактировалось 1 раз |
|
|
AlexYar 1850 EGP
Рейтинг канала: 13(2096) Репутация: 328 Сообщения: 31615
Зарегистрирован: 26.10.2003 |
|
ULiX : |
Есть ли обновленные версии трансляторов XC<->XAsm?
Где их можно взять?
|
Ответил в канале х2.
|
|
|
Xenon J 949 EGP
Рейтинг канала: 11(1674) Репутация: 161 Сообщения: 3280 Откуда: Ксенонский сектор 472 Зарегистрирован: 30.03.2007 |
|
А как добавить новые команды в скриптредактор? Конкретно интересует команда переименования секторов (т. е. присвоения им отдельного кода, а не вычисления его по координатам).
_________________ Последний раз редактировалось: Xenon J (23:23 23-03-2023), всего редактировалось 16 раз |
|
|
AlexYar 1850 EGP
Рейтинг канала: 13(2096) Репутация: 328 Сообщения: 31615
Зарегистрирован: 26.10.2003 |
|
Xenon J : |
т. е. присвоения им отдельного кода, а не вычисления его по координатам
|
Сперва сделать поддержку этой команды в движке игры (создать нужные переменные и функции в классе TSECTOR, изменить работу существующих ф-ий по определению имени сектора), затем сделать саму команду в интерфейсе редактора.
|
|
|
|
|
|
Канал X3: Reunion ->
Модовый и скриптовый отсек X3: Reunion: «Кодинг в обже, вопросы и ответы» |
|