Спасибо за наводки и подсказки, удалось с помощью артмани добыть всю необходимую информацию!
Если кому тоже интересен этот вопрос, то результаты получились такими (справедливо для клиента ультимы 2.0.3 - на других не пробовал):
По адресу 0x00CC535C хранится указатель, где по смещению +248 хранится следующий указатель, указывающий на структуру, описывающую бэкпак в памяти.
Далее, оказалось, что все предметы описаны одной и той же структурой. Предметы, находящиеся в одном контейнере хранятся в виде двусвязанного списка.
Структура такая (цифры 16-ричные, W - 2 байта, D - 4 байта):
itemAddr + 24: (W) X-координата объекта в контейнере
itemAddr + 26: (W) Y-координата объекта в контейнере
itemAddr + 3С: (W) Тип
itemAddr + 40: (W) Количество штук в куче
itemAddr + 42: (W) Цвет
itemAddr + 44: (D) Указатель на предыдущий объект в списке
itemAddr + 48: (D) Указатель на следующий объект в списке
itemAddr + 7C: (D) ID объекта
itemAddr + 80: (D) Указатель на контейнер
itemAddr + 84: (D) Указатель на предыдущий связанный объект
itemAddr + 88: (D) Указатель на следующий связанный объект
itemAddr + B0: (D) Если объект - контейнер, то указатель на объект с координатами контейнера на экране
В объекте с координатами контейнера по смещению +0x30 хранится координата X (D), а по смещению +0x34 хранится координата Y (D).
Для контейнеров указатель на следующий связанный объект (+0x88) указывает либо на первый предмет в контейнере, либо на ещё один какой-то объект, у которого уже по смещению +0x88 будет указатель на первый предмет.
У предмета по смещению +0x48 хранится указатель на следующий предмет. У последнего - равен нулю.
Вот небольшой скрипт, демонстрирующий использование этой информации в пилоте (выводит идентификаторы всех объектов в паке):
Код
readmem #addr 0x00CC535C D
set #addr #addr + 284
readmem #bpackAddr #addr D
set #nextItemAddrRef #bpackAddr + 0x88
while 1 = 1
readmem #itemAddr #nextItemAddrRef D
if #itemAddr = 0
break
end_if
set #addr #itemAddr + 0x80
readmem #containerAddr #addr D
if #containerAddr <> #bpackAddr
// какая-то не понятная запись. идём к следующей
set #nextItemAddrRef #itemAddr + 0x88
continue
end_if
// нашли следующий предмет
// выведем ID предмета
set #addr #itemAddr + 0x7c
readmem #itemID #addr D
msg #itemID
set #nextItemAddrRef #itemAddr + 0x48
end_while
stop_script
Ну и естественно, это всё работает только, если пак - открыт.
Хорошо бы соответствующую функциональность по работе с объектами UO встроить в пилот. Или в плагин для пилота.
Цитата(pet)
Для клиента 1.26.4а все смещения совпадают. Единственное различие в адресе бэкпака, точнее ссылке на него. Ссылка храниться по адресу 0х00C88AE0, далее по смещению 0х11С. Все остальное совпадает.
Сообщение отредактировал DarkMaster - 22.9.2013, 13:50