Показать сообщение отдельно
Старый 10.01.2006, 18:20   #682
Vam

AGFC
Гость
 
Сообщений: n/a

По умолчанию Re: Декомпилятор скриптов Готики

2TSYLin:
Получается, если дописать эту строчку то компилятор будет воспринимать переменную int itemInstance как локальную? Я прав?
Нет, не прав. В любом случае, если переменная объявлена внутри функции, то она является локальной. Строка int# b_doupgrade.itemInstance; говорит компилятору что в функции b_doupgrade локальная переменная itemInstance имеет переопределенный тип (int -> instance).
Другой вопрос - для чего это нужно?
Разработчики языка скриптов упростили некоторые типы переменных: есть основные переменные (int, float, string, func, class, instance и т.д.), но нет производных переменных - указателей и ссылок (формат записи: тип* - указатель, тип& - ссылка), которые представляют из себя адреса места в памяти, где расположена переменная.
Попробую пояснить: например, функция
C_ITEM Npc_GetEquippedArmor(C_NPC n0); возвращает не сам класс C_ITEM, а только адрес класса, в нормальном языке программирования это должно бы выглядеть так C_ITEM* (указатель) или C_ITEM& (ссылка), тоже относится и к аргументу с типом C_NPC.
В связи с такими упрощениями в скриптах невозможно создать функцию возвращающую производный тип. Это могут делать только встроенные функции экзешника, но жить-то надо - и было принято упрощение использовать вместо производных типов (адресов объектов) простой тип INT. К типу INT переопределяется только тип INSTANCE.
Поясню: например, функция void Npc_RemoveInvItem(c_npc owner,int itemInstance);, второй аргумент функции имеет тип int, но это не простой тип, а переопределенный, при вызове функции здесь записывается имя конкретной инстанции (например, ItFo_Apple - яблоко будет удалено из инвентаря). Но так как проверки на типы раньше не было, можно было бы записать в качестве второго аргумента любое число, например 10345, - всё бы скомпилировалось, но в игре из инвентаря был бы удален предмет, имеющий номер инстанции 10345, а что это - сказать трудно (в процессе компиляции первая инстанция получает номер 1, вторая - 2 и т.д.).
Дальше - чтобы проверить правильность присвоения таких переопределенных типов необходимо их отделить от типа int, вот это и выполняется в файлах RedefinedFunc.d - переопределенные параметры (помечены #) функций и RedefinedLocalVariable.d - переопределенные локальные переменные.
Далее - Декомпиляция: встретив число, например, 10345 типа int декомпилятор должен распознать, что это действительно int или номер (ссылка) инстанции, если правильного распознавания не будет, то к чему это приведет - смотри выше, правда, если скрипты не править, а только декомпилировать, а потом компилировать, то ошибки не будет, её не будет и в том случае, если новую инстанцию добавить в конец списка; а если в середину, то все номера инстанций будут смещены, в итоге вместо яблока получишь что-то другое.
Эти же два файла нужны и для правильного распознавания переопределенных типов при декомпиляции. В них записаны функции и переменные оригинальных скриптов (какие встретил), если же в модах Готик встречаются новые функции с переопределенными параметрами, то их необходимо зарегистрировать в этих файлах для избежания возможных ошибок.
Если что не понятно, спрашивайте! *;)
Ответить с цитированием