You are not logged in.
{$CLEO} Thread 'fbmp_move' :1 wait 0 if 0256: player $PLAYER_CHAR defined jf @1 if 00DF: actor $PLAYER_ACTOR driving jf @1 03C0: 0@ = actor $PLAYER_ACTOR car 0A97: 1@ = car 0@ struct 1@ += 1082 // В этом смещении не уверен, оно почемуто работает и для заднего бампера и для других частей 0A8D: 2@ = read_memory 1@ size 2 virtual_protect 0 :2 wait 0 if 00DB: actor $PLAYER_ACTOR in_car 0@ jf @1 0A8D: 3@ = read_memory 1@ size 2 virtual_protect 0 if 803B: not 3@ == 2@ jf @2 :3 // запоминаем координаты старого бампера, и переносем его вперед на 5 метров wait 0 0A97: 1@ = car 0@ struct 1@ += 0x678 // передний бампер 0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0 if 8039: not 1@ == 0 jf @3 1@ += 0x10 1@ += 52 0A8D: 2@ = read_memory 1@ size 4 virtual_protect 0 0A8D: 3@ = read_memory 1@ size 4 virtual_protect 0 0A8D: 4@ = read_memory 1@ size 4 virtual_protect 0 000B: 2@ += 5.0 0A8C: write_memory 1@ size 4 value 2@ virtual_protect 0 000F: 3@ -= 0.15 000B: 4@ += 0.15 :4 // цикл перемещения наместо нового бампера wait 0 0A8D: 2@ = read_memory 1@ size 4 virtual_protect 0 if and 0025: 2@ > 3@ 0025: 4@ > 2@ jf @5 000B: 3@ += 0.15 0A8C: write_memory 1@ size 4 value 3@ virtual_protect 0 jump @1 :5 wait 0 000B: 2@ += -0.15 0A8C: write_memory 1@ size 4 value 2@ virtual_protect 0 jump @4
По быстрому написал скрипт, в архангелах при смене бампера.. ну короче сами все увидете)
Offline
какой адрес нужен для проверки состояния этих компонентов?
Ты же писал уже блок для проверки, но можно вот это
0A97: 1@ = car 0@ struct 1@ += 0x5A0 0AA8: call_function_method 0x6C2230 struct 1@ num_params 1 pop 0 0{0,1,2,3,4,5} 2@ Значение 2@ 0 - компонент целый 2 - компонент повреждён 4 - компонент отсутствует
заменить вот на это:
0A97: 1@ = car 0@ struct 1@ += 0x5A0 // тоже что и у тебя, т.е. капот 1@ += 9 // для наглядности, незнаю почему 9, нашел в артмани хд 0A8D: 2@ = read_memory 1@ size 2 virtual_protect 0 // тоже что и у тебя только не функция Значение 2@ 0 - компонент целый 1 - компонент целый и открыт (наверно, не проверял а предпологаю) 2 - компонент повреждён 3 - Компонент поврежден и открыт 4 - компонент отсутствует
Offline
Ещё немного дополнений:
Смещение___Обозначение в иерархии модели___Пояснение +372_______ug_spoiler______________________спойлер +436_______ug_wing_left____________________юбка левая часть +468_______ug_wing_right___________________юбка правая часть +628_______ug_roof_________________________ковш на крыше +660_______ug_nitro________________________нитробалон
Находятся координаты этих дамми по тому же методу, что был описан выше для фары, бензобака и т.д. Следует учитывать, что при перезаписи этих координат новыми значениями изменятся положения дамми на ВСЕХ авто этой модели! Это же относится к дамми фары, бензобака и т.д (т.е. ко всем дамми, координаты которых определяются этим способом). После перезаписи координат соответствующая деталь тюнинга не сдвигается. Надо установить деталь заново - тогда деталь тюнинга уже установится по новым координатам.
Работа с опкодами для тюнинга:
06E9: load_car_component 2@ //загрузка модели компонента тюнинга 06EB: release_car_component 2@ //выгрузка модели компонента тюнинга 06E7: 3@ = add_car_component 2@ to_car 0@ //добавление компонента тюнинга на авто 06E8: car 0@ destroy_component 2@ //удаление компонента тюнинга 2@ - номер ID 06E6: get_itemID 2@ destinated_component_slot_to 3@ // получает по ID компонента тюнинга его номер 0-15,(11-нет) 096D: get_car 0@ car_component 3@ on_slot 2@ // получает по номеру компонента тюнинга 0-15,(11-нет) его ID 06E5: get_car 0@ possible_to_built_in_component_pool_index 1@ itemID_to 2@ //записывает в 2@ ID компонента тюнинга из carmods.dat
Пример. Считывание данных из carmods.dat и установка на авто деталей тюнинга. Внимание: данные в carmods.dat должны быть корректными. Если стандартная модель была заменена, то надо редактировать соответствующую запись в carmods.dat. Иначе будет вылет игры при установке компонента тюнинга!
{$CLEO .cs} 0000: while true wait 0 if Player.Defined($PLAYER_CHAR) then if and 0AB0: key_pressed 49 Actor.Driving($PLAYER_ACTOR) then 03C0: 0@ = actor $PLAYER_ACTOR car repeat 06E5: get_car 0@ possible_to_built_in_component_pool_index 1@ itemID_to 2@ if and 2@ <> -1 2@ <> 1086 jf break 06E9: load_car_component 2@ 038B: load_requested_models 06E7: 3@ = add_car_component 2@ to_car 0@ 06EB: release_car_component 2@ 1@ += 1 until not Car.Defined(0@) 1@ = 0 end end end
Номера компонентов тюнинга:
0 - ковш капот 1 - вентиляция на капоте 2 - спойлер 3 - юбка 4 - модинг на передний бампер 5 - модинг на задний бампер 6 - противотуманки 7 - ковш на крыше (крыша) 8 - нитробалон 9 - гидравлика 10 - стерео 11 - нет! 12 - колёса 13 - глушитель 14 - бампер передний 15 - бампер задний 16 - передняя решётка
Offline
Хочу лишь заметить, что такой вариант записи
repeat 06E5: get_car 0@ possible_to_built_in_component_pool_index 1@ itemID_to 2@ ... until not Car.Defined(0@)
Может привести к вылету, лучше оформить это так:
while car.Defined(0@) 06E5: get_car 0@ possible_to_built_in_component_pool_index 1@ itemID_to 2@ ... end
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Какой смысл проверять существует ли авто сразу после записи этого авто в переменную (непосредственно после проверки Actor.Driving($PLAYER_ACTOR))? Ведь если актёр водитель, то естественно авто существует. Вылет здесь исключён. Там нет wait. Весь цикл выполняется сразу после записи в переменную авто игрока. Это моё мнение (возможно оно ошибочно=)).
Offline
Вылет здесь исключён. Там нет wait. Весь цикл выполняется сразу после записи в переменную авто игрока.
Действительно. Недосмотрел=)
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Нашёл возможность для вращения колёс (а также для перемещения их по оси Z). Правда для этого надо редактировать саму модель. Надо создать произвольный дамми и поместить в него дамми колеса. Смотреть на скрине (по оси Y произвольный дамми должен распологаться на нулевой отметке, иначе колёса будут изначально на модели распологаться выше или ниже нужной позиции). После в скрипте при вращении/перемещении произвольного дамми будет вращаться/перемещаться и колесо. В общем может разработчикам моделей транспорта для игры это пригодится.
Offline
По части корректности написания вот так будет корректно ->
{$CLEO .cs} 0000: while true wait 0 if Player.Defined($PLAYER_CHAR) then if and 0AB0: key_pressed 49 Actor.Driving($PLAYER_ACTOR) then 03C0: 0@ = actor $PLAYER_ACTOR car while true 06E5: get_car 0@ possible_to_built_in_component_pool_index 1@ itemID_to 2@ if and 2@ <> -1 2@ <> 1086 jf break 06E9: load_car_component 2@ while not Model.Load(2@) wait 0 end if not Car.Wrecked(0@) jf break 06E7: 3@ = add_car_component 2@ to_car 0@ 06EB: release_car_component 2@ 1@ += 1 end 1@ = 0 end end end
Здесь важные моменты подчеркнуты, это проверка - загружена ли модель компонента, и это проверка - не испорчено ли авто во время загрузки модели.
Во основном же все четко.
I know everything and nothing...
Offline
По поводу проверки загружена ли модель компонента - написано здесь.
Проверку заменяет опкод 038B: load_requested_models. А раз цикл:
while not Model.Load(2@) wait 0 end
становится ненужным, то не надо ставить и wait. И далее соответственно проверка:
if not Car.Wrecked(0@) jf break
становится тоже ненужна, т.к. всё, что выполнялось в данный момент в игре выполнялось только в цикле данного скрипта (и с авто ничего не могло произойти) опять же в следствии отсутствия wait. В результате приходим к тому варианту, что я и написал. Опять же это только моё мнение (возможно оно ошибочно=)).
Offline
Такие новости, все проверено!
Благодаря пытливому уму стало все гораздо проще.
Den_spb нашел, что текущие экстры хранятся по смещениям +1080 и +1081.
Но это не самая приятная новость, как оказалось эти экстры работают, обе!
Т.е. в опкоде
0506: set_car_model #PICADOR next_variation 4 4 // first param is useless
рабочими параметрами являются оба, а не один, как заявлено. Мы можем комбинировать две любые экстры на машине, например 1 и 3. В результате на машине будет вот эти две экстры.
Далее как оказалось по следующим смещениям
+1082 +1084 +1086 +1088 +1090 +1092 +1094 +1096 +1098 +1100 +1102 +1104 +1106 +1108 +1110
где каждое по 2 байта целое, хранятся те самые злосчастные компоненты.
При проверке компонентов обнаружилось, что их порядок отличается от того который описал kenking.
I know everything and nothing...
Offline
как оказалось эти экстры работают, обе! Мы можем комбинировать две любые экстры на машине, например 1 и 3. В результате на машине будет вот эти две экстры.
Отличные новости!:clap:
При проверке компонентов обнаружилось, что их порядок отличается от того который описал kenking.
Если речь идёт об этом:
0 - ковш капот 1 - вентиляция на капоте 2 - спойлер 3 - юбка 4 - модинг на передний бампер 5 - модинг на задний бампер 6 - противотуманки 7 - ковш на крыше (крыша) 8 - нитробалон 9 - гидравлика 10 - стерео 11 - нет! 12 - колёса 13 - глушитель 14 - бампер передний 15 - бампер задний 16 - передняя решётка
то всё взято из оригинального main и тоже проверено. Никаких отличий не может быть.;-) Или речь идёт о чём-то другом?
EDIT:
Я кажется понял, что ты имел ввиду. Эти смещения для конкретного авто. И даже для одного и того же авто по одному и тому же смещению может быть записано разное значение. Это зависит от того, какой компонент тюнинга установлен на авто (и сколько компонентов установлено). Вот пример:
{$CLEO .cs} 31@ = 1082 // первое смещение const i = 10@ end while true wait 0 if Player.Defined($PLAYER_CHAR) then if Actor.DrivingVehicleType($PLAYER_ACTOR, #JESTER) // только для оригинальной модели then 20@ = 1158 // спойлер 03C0: 0@ = actor $PLAYER_ACTOR car for i = 1 to 3 if Car.Defined(0@) jf break 06E9: load_car_component 20@ 038B: load_requested_models 06E7: 30@ = add_car_component 20@ to_car 0@ 06EB: release_car_component 20@ 0A97: 1@ = car 0@ struct 005A: 1@ += 31@ // (int) 0A8D: 1@ = read_memory 1@ size 2 virtual_protect 0 32@ = 0 while not 32@ > 5000 if Car.Defined(0@) jf break if 00DB: actor $PLAYER_ACTOR in_car 0@ jf break 03F0: enable_text_draw 1 045A: draw_text_1number 5.0 20.0 GXT 'NUMBER' number 31@ // будет показывать всё время 1082 045A: draw_text_1number 5.0 40.0 GXT 'NUMBER' number 1@ // хотя компоненты разные wait 0 end 06E8: car 0@ destroy_component 20@ 20@ += 1 // ставим другой компонент тюнинга 1159 - задний бампер, потом 1160 - передний бампер end end end end
По смещению +1082 будут записаны 3 разных значения в зависимости от установленого компонента. В общем с этим всё понятно.
А вот непонятно мне другое, а именно:
1)
0000043A field_43A db 28 dup(?) 00000456 db ? ; undefined
db - 1 байт, почему считывать надо 2 байта?
2) Почему далее при попытке прочитать координаты получается вылет игры?
1@ += 0x10 // указатель на матрицу 1@ += 56 // Z 0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0 // здесь вылет
Last edited by kenking (21-04-2011 05:57)
Offline
db - 1 байт, почему считывать надо 2 байта?
Возможно в базе поставлено неверное обозначение.
Я провёл небольшой эксперимент - установил на авто гидравлику. При этом изменились значения в двух байтах структуры авто: +1082 и +1083
2) Почему далее при попытке прочитать координаты получается вылет игры?
В 0A8D подан некорректный адрес памяти (диапазон адресов памяти имеет значения 0x400000 - 0xCB0600), при попытке чтения которого игра вылетает.
В смещениях структуры авто, соответствующих колёсам, дверям и т.п. компонентам были записаны адреса памяти - указатели на структуры компонентов. А в смещениях +1082 - ... записаны не адреса памяти структур, а просто какие-то числа. Тем более, что в 2 байта невозможно записать целое число, превышающее 0xFFFF, что явно меньше 0x400000.
Last edited by Den_spb (21-04-2011 20:48)
Offline
В общем получается диапазон смещений 0x43A---0x456 - это своеобразный буффер в структуре авто для хранения ID компонентов тюнинга установленных на это авто. При установке на авто компонента тюнинга ID этого компонента записывается по первому смещению. Устанавливается следующий компонент тюнинга - его ID записывается по следующему смещению и т.д. Вот пример:
{$CLEO .cs} 25@ = 1082 // первое смещение 26@ = 1084 // второе смещение 27@ = 1086 // третье смещение const i = 10@ end while true wait 0 if Player.Defined($PLAYER_CHAR) then if Actor.DrivingVehicleType($PLAYER_ACTOR, #JESTER) // только для оригинальной модели then 20@ = 1158 // спойлер 21@ = 1159 // задний бампер 22@ = 1160 // передний бампер 03C0: 0@ = actor $PLAYER_ACTOR car for i = 1 to 2 if Car.Defined(0@) jf break 06E9: load_car_component 20@ 06E9: load_car_component 21@ 06E9: load_car_component 22@ 038B: load_requested_models 06E7: 30@ = add_car_component 20@ to_car 0@ 06E7: 30@ = add_car_component 21@ to_car 0@ 06E7: 30@ = add_car_component 22@ to_car 0@ 06EB: release_car_component 20@ 06EB: release_car_component 21@ 06EB: release_car_component 22@ 0A97: 1@ = car 0@ struct 0085: 2@ = 1@ // (int) 0085: 3@ = 1@ // (int) 005A: 1@ += 25@ // (int) 0A8D: 1@ = read_memory 1@ size 2 virtual_protect 0 005A: 2@ += 26@ // (int) 0A8D: 2@ = read_memory 2@ size 2 virtual_protect 0 005A: 3@ += 27@ // (int) 0A8D: 3@ = read_memory 3@ size 2 virtual_protect 0 32@ = 0 while not 32@ > 5000 if Car.Defined(0@) jf break if 00DB: actor $PLAYER_ACTOR in_car 0@ jf break 03F0: enable_text_draw 1 045A: draw_text_1number 5.0 20.0 GXT 'NUMBER' number 25@ // первое смещение 045A: draw_text_1number 55.0 20.0 GXT 'NUMBER' number 1@ // ID первого компонента 045A: draw_text_1number 5.0 40.0 GXT 'NUMBER' number 26@ // второе смещение 045A: draw_text_1number 55.0 40.0 GXT 'NUMBER' number 2@ // ID второго компонента 045A: draw_text_1number 5.0 60.0 GXT 'NUMBER' number 27@ // третье смещение 045A: draw_text_1number 55.0 60.0 GXT 'NUMBER' number 3@ // ID третьего компонента wait 0 end 06E8: car 0@ destroy_component 20@ 06E8: car 0@ destroy_component 21@ 06E8: car 0@ destroy_component 22@ 20@ = 1159 // меняем местами компоненты 21@ = 1160 // теперь эти же компоненты будут устанавливаться на авто 22@ = 1158 // в другом порядке end end end end
Первая итерация цикла for:
первым устанавливается компонент с ID = 1158 - записывается по смещению 1082
вторым устанавливается компонент с ID = 1159 - записывается по смещению 1084
третьим устанавливается компонент с ID = 1160 - записывается по смещению 1086
Вторая итерация цикла for (меняем порядок установки тех же компонентов):
первым устанавливается компонент с ID = 1159 - записывается по смещению 1082
вторым устанавливается компонент с ID = 1160 - записывается по смещению 1084
третьим устанавливается компонент с ID = 1158 - записывается по смещению 1086
Offline
Кто знает, а как не вращать детали, а считывать на сколько они повернуты сейчас?
Offline
Как правило, вращение компонентов осуществляется не во всех трёх направлениях, а только в одном (двери, спецкомпоненты) или в двух (колёса), причём во втором направлении компонент поворачивается менее, чем на 90 градусов. В этом случае надо просто посчитать углы между осями систем координат компонента и его родителя. Для вычисления угла между двумя векторами применяется опкод:
0604: get_angle_between_vectors_{a,b} $TEMPVAR_FLOAT_1 $TEMPVAR_FLOAT_2 and_{0,1}_store_to $TEMPVAR_ANGLE
где {a;b} - это вектор {x;y}, {z;x} или {y;z}.
Пример: вычислим угол поворота правого переднего колеса автомобиля вокруг вертикальной оси
0A97: 1@ = car 0@ struct 1@ += 0x650 0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0 // получили указатель на структуру компонента if 1@ <> 0 then 1@ += 0x10 // получили указатель на матрицу позиции компонента в системе координат родителя 0A8D: 2@ = read_memory 1@ size 4 virtual_protect 0 // читаем X-координату вектора Right 1@ += 4 0A8D: 3@ = read_memory 1@ size 4 virtual_protect 0 // читаем Y-координату вектора Right 0604: get_angle_between_vectors_{a,b} 2@ 3@ and_{0,1}_store_to 4@ // считаем угол между осями 4@ -= 270.0 end
Last edited by Den_spb (23-04-2011 04:13)
Offline
СПАСИБО! то что надо!
Offline
немножко вопрос не в тему:
Если я правельно все понял, то машины ездиют по путям. пути состоят из точек, матриц поворота итд
Возможно ли вычеслеть следующую точку пути у рандомной машины?Если да то как?
Offline
Вот что я нашел интересного с помощью artmoney.
Пригодиться тому кто хочет узнать номер авто. Для этого надо прочитать смещение +1416 в структуре CVehicle. Затем полученный указатель (а он судя по всему указатель) со смещением +16 прочитать 8 байт и в результате на выходе текст 8 байтовый, хотя какой тип текста не столь важно.
Например:
0A97: 31@ = car 0@ struct 31@ += 1416 0A8D: 31@ = read_memory 31@ size 4 virtual_protect 0 if 31@ <> 0 //здесь проверяем если номер у авто, или иначе есть ли указатель then 31@ += 16 0A8D: 1@ = read_memory 31@ size 4 virtual_protect 0 31@ += 4 0A8D: 2@ = read_memory 31@ size 4 virtual_protect 0 //здесь в переменной 1@s будет номер машины end
I know everything and nothing...
Offline
что ты понимаешь под номером авто?
Offline
Если не затруднит, то полностью код напиши пожалуйста, с выводом на экран полученного номера.
Offline
{$CLEO .cs} wait 250 while true wait 0 if not Player.Defined($PLAYER_CHAR) then continue end if not Actor.Driving($PLAYER_ACTOR) then continue end 03C0: 0@ = actor $PLAYER_ACTOR car 0A97: 31@ = car 0@ struct 31@ += 1416 0A8D: 31@ = read_memory 31@ size 4 virtual_protect 0 if 31@ <> 0 then 31@ += 16 0ACD: show_text_highpriority 31@ time 1000 end end
Вот, выводится numberplate, как заказывали, если игрок в авто.
I know everything and nothing...
Offline
Спасибо.=) Только получается корректно будет работать только в англоязычной версии игры. В русифицированной текст получается не тот.
Offline