Суббота, 20.04.2024, 15:13
Качественные скрипты, моды и дополнения для GTA без регистрации
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Форум » Игры серии ГТА » Скриптинг » Вопросы по созданию КЛЕО-скриптов 2
Вопросы по созданию КЛЕО-скриптов 2
DK22PacДата: Среда, 12.06.2013, 00:42 | Сообщение # 316
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
ILYALION, если не ошибаюсь, у каждого из наследователей CVehicle есть метод BlowUp. Туда и смотри.

Добавлено (12.06.2013, 00:42)
---------------------------------------------
ILYALION, попробуй так применять код ко всему поезду.

Код
{$CLEO}

{$I inloop}
{$I forallcars}

     0A97: 0@ = car veh struct
     0A8E: 1@ = 0@ + 0x590
     0A8D: 2@ = read_memory 1@ size 1 virtual_protect 0
     0A8E: 1@ = 0@ + 0x5B8
     0A8D: 3@ = read_memory 1@ size 1 virtual_protect 0
     if and
          2@ == 6  // if(train->m_bVehicleType == VEHICLETYPE_TRAIN && (train->m_bFlags & TRAINFLAG_IS_FRONT_CARRIAGE))
          08B7: test 3@ bit 3
     then
          //
               // код для этого вагона
          //
          // for(i = train->m_pNextCarriage; i; i = i->m_pNextCarriage)
          0A8E: 1@ = 0@ + 0x5B4
          0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0
          while 1@ <> 0
               //
                   // код для других вагонов, 0@ - структура главного вагона, 1@ - структура этого вагона
               //
               0A8E: 1@ = 1@ + 0x5B4
               0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0
          end
     end

{$I for_end}
{$I end}
 
Den_spbДата: Среда, 12.06.2013, 17:12 | Сообщение # 317
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
ILYALION, 
1.В цикле сведения поезда с рельсов ты двигаешься от найденного вагона к концу состава (0x5D4 - смещение структуры вагона, по которому записан адрес структуры следующего вагона). Чтобы свести с рельсов весь поезд, нужно сначала найти нулевой вагон, а затем уже применять цикл ко всем вагонам этого поезда. Вагон является нулевым, если предыдущие вагоны отсутствуют, т.е. по смещению "предыдущий вагон" (0x5D0) записан ноль.
Вот как ищет поезда скрипт animtrain:
Код
while true
     32@ = 0
     wait 5
     if
         not player.Defined($PLAYER_CHAR)
     then
         continue
     end

     if
         0AE2: 0_Train = random_vehicle_near_point 0.0 0.0 0.0 in_radius 6000.0 find_next 0 pass_wrecked 1 //IF and SET
     then
         repeat
             0A97: 0_CarriageStruct = car 0_Train struct
             0A8E: 31@ = 0_CarriageStruct + 1424 // int
             0A8D: 31@ = read_memory 31@ size 1 virtual_protect 0
             if
                 31@ == 6
             then     
                 0_CarriageStruct += 0x5D0
                 0A8D: 0_CarriageStruct = read_memory 0_CarriageStruct size 4 virtual_protect 0
                 if
                     0_CarriageStruct == 0   // предыдущий вагон отсутствует (данный вагон является нулевым)
                 then
                     if
                         8981: not train 0_Train wrecked  
                     then
                         gosub @_CTrain_process_control
                     end
                 end
             end
         until 8AE2: not 0_Train = random_vehicle_near_point 0.0 0.0 0.0 in_radius 6000.0 find_next 1 pass_wrecked 1 //IF and SET
     end
end
В результате скрипт сразу находит нулевые вагоны всех существующих поездов.
2.Колёса у сошедшего поезда продолжают крутиться потому, что animtrain проверяет на схождение только нулевой вагон каждого поезда. Чтобы колёса не крутились нужно либо сводить с рельсов весь поезд, либо (если какие-то вагоны остаются на рельсах) обнулять значения 0x5D4 в последнем уцелевшем вагоне и 0x5D0 в первом сошедшем с рельсов вагоне.
3.FPS падает возможно из-за того, что увеличивается время отработки скрипта animtrain. Это можно исправить после выполнения п.2.
Vital, цикл здесь выполняется столько раз, сколько существует вагонов в поезде, т.е. не более 20, т.е. исполняются 12 х 20 = 240 опкодов, что не занимает много времени. Поэтому прерывать исполнение скрипта командой wait здесь не нужно.
 
ILYALIONДата: Суббота, 15.06.2013, 20:16 | Сообщение # 318
Группа: Проверенные
Сообщений: 325
Статус: Offline
Den_spb, для нахождения первого вагона поезда я использовал следующий код:
Код
while true  
       0A97: 7@ = car 6@ struct   
       7@ += 0x5D0  
       0A8D: 7@ = read_memory 7@ size 4 virtual_protect 0   
       if   
            7@ == 0  
       then  
            break  
       else  
            0085: 6@ = 7@ // (int)  
       end  
end

Но происходит вылет. Почему?
 
Den_spbДата: Воскресенье, 16.06.2013, 01:07 | Сообщение # 319
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
Вылетит на второй раз выполнения цикла во время исполнения 0A97: в 6@ должен быть записан хэндл, а вместо него будет подан адрес структуры. Поэтому 0A97 надо вынести из цикла:
Код
0A97: 6@ = car 6@ struct  
while 6@ <> 0
     0085: 7@ = 6@ // (int)
     6@ += 0x5D0   
     0A8D: 6@ = read_memory 6@ size 4 virtual_protect 0     
end
// Теперь в 7@ записан адрес структуры 0 вагона
Вообще хэндлы используются только в скриптах, в exe применяются только адреса структур.
 
ILYALIONДата: Воскресенье, 16.06.2013, 12:31 | Сообщение # 320
Группа: Проверенные
Сообщений: 325
Статус: Offline
Что означат данная запись? &0(30@,1i)
Если изменить &0 или 1i изменится ли что-то?
 
Den_spbДата: Воскресенье, 16.06.2013, 14:05 | Сообщение # 321
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
Это старая технология чтения и записи памяти через массивы - она применялась до того, как появились специальные опкоды для чтения и записи памяти: 0A8C и 0A8D.
В справке SB есть подробная статья на эту тему: Статьи - Опытным пользователям - Меняем игровую память через SCM (San Andreas).
Перед изучением данной статьи надо вспомнить что такое массивы и как они реализуются в скриптах: Справка SB - Кодинг - Массивы.
 
VitalДата: Воскресенье, 16.06.2013, 18:08 | Сообщение # 322
Группа: Проверенные
Сообщений: 206
Статус: Offline
Кто-нибудь знает, сколько можно всего создать 2D объектов, если конкретнее - корон? И как можно реализовать рисование линий в 3D пространстве игры без применения create_M4_shoot (если возможно)?

SCRIPTER
 
Den_spbДата: Воскресенье, 16.06.2013, 22:46 | Сообщение # 323
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
Цитата (Vital)
Кто-нибудь знает, сколько можно всего создать 2D объектов, если конкретнее - корон?

64 штуки
http://gtamodding.ru/wiki/Адреса_Памяти_(SA)#CRegisteredCorona
 
ILYALIONДата: Понедельник, 17.06.2013, 08:28 | Сообщение # 324
Группа: Проверенные
Сообщений: 325
Статус: Offline
На wiki есть это:
Код
CGlass (Осколки стекла)

Начало: 0xC3E058 Размер одного элемента: 112 байт   
   CGlass +0x0 =  [RwMatrix]Матрица поворота и позиции   
   CGlass +0x60 =  [dword]Время создания   
   CGlass +0x6D =  [byte]Флаг существования
А как можно создать осколки стекла?

------------------------------------------------
Есть такой адрес:
Код
0x05A0 | WORD               pathPointID        // Текущий номер точки маршрута (номер строчки в tracks, нумерация от нуля)
А можно узнать координаты этой точки?


Сообщение отредактировал ILYALION - Понедельник, 17.06.2013, 09:50
 
Den_spbДата: Понедельник, 17.06.2013, 22:15 | Сообщение # 325
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
Цитата (ILYALION)
А можно узнать координаты этой точки?

Можно. Вот как это реализуется в скрипте animtrain:
Код


0A8E: 0_TrainRoute = 0_CarriageStruct + 0x5C0 // int Читаем номер маршрута - он записан в структуре вагона по смещению 0x5C0
0A8D: 0_TrainRoute = read_memory 0_TrainRoute size 1 virtual_protect 0 // train route
0_TrainRoute *= 4 // далее вычисляем адрес массива структур точек данного маршрута

0A8E: 0_StartOfTracksNdatContent = 0_TrainRoute + 0xC38024 // _tracksDatContents // int  
0A8D: 0_StartOfTracksNdatContent = read_memory 0_StartOfTracksNdatContent size 4 virtual_protect 0 // start of tracksN.dat content

0A8E: 0_CurrentPointAdress = 0_CarriageStruct + 0x5A0 // int Получаем номер текущей точки
0A8D: 0_CurrentPointAdress = read_memory 0_CurrentPointAdress size 2 virtual_protect 0 // current point of train
0_CurrentPointAdress *= 10 // умножаем на размер структуры точки - 10 байтов
005A: 0_CurrentPointAdress += 0_StartOfTracksNdatContent // прибавили смещение к началу массива - получили адрес текущей точки

0085: 6@ = 0_CurrentPointAdress // (int)  
0A8E: 7@ = 0_CurrentPointAdress + 2 // int  Y NPoint
0A8E: 8@ = 0_CurrentPointAdress + 4 // int  Z NPoint

for 31@ = 0 to 2
     0A8D: 6@(31@,3i) = read_memory 6@(31@,3i) size 2 virtual_protect 0
     if
         6@(31@,3i) >= 0x8000 // negative word
     then
         6@(31@,3i) += 0xFFFF0000 // convert to negative dword
     end  
     0093: 6@(31@,3f) = integer 6@(31@,3i) to_float
     6@(31@,3f) /= 8.0       
end  
// координаты записаны в 6@, 7@, 8@


Цитата (ILYALION)
А как можно создать осколки стекла?

На адрес 0xC3E058 ссылаются 3 функции: 0x6FADF0, 0x6FC180, 0x6FC4D0 - возможно одна из них и предназначена для создания осколков. Надо экспериментировать.
 
DK22PacДата: Вторник, 18.06.2013, 04:42 | Сообщение # 326
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
Vital, во время выполнения скрипта выводить что-либо на экран невозможно. Основной рендеринг происходит уже после того, как игра обработает скрипты.
 
VitalДата: Понедельник, 24.06.2013, 21:25 | Сообщение # 327
Группа: Проверенные
Сообщений: 206
Статус: Offline
Den_spb, хотел уточнить про for. Задержка в 0 мс нужна в каких случаях? Я имею в виду, при каком значении счётчика? Вот у меня такой цикл:

Код
for 0@ = 0 to 619 //4
             0A90: 1@ = 32 * 0@ // int
             1@ += 0x9788C0
И дальше проверки, 0A8D и в конце, при успешном выполнении всех условий, есть ещё 0A8C и wait 0 (только при успешном выполнении, просто для проверки производительности игры).
Если идёт такое число, как 620, то игра не потеряет в производительности? Какое число максимальное в таком случае, и как его высчитать. Я, например, пробовал for для тысячи (или чуть более) объектов, причём выполнял не много действий над ними, но при этом игра притормаживала без wait 0.


SCRIPTER
 
Den_spbДата: Понедельник, 24.06.2013, 21:40 | Сообщение # 328
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
http://sannybuilder.com/forums/viewtopic.php?pid=16957#p16957
 
VitalДата: Понедельник, 24.06.2013, 22:59 | Сообщение # 329
Группа: Проверенные
Сообщений: 206
Статус: Offline
То есть, если я использую такой цикл, то надо подсчитать все повторения и умножить их на кол-во опкодов, правильно ли я понял? В таком случае, если считать все end и if, то выходит около 20 тысяч за цикл, при этом wait 0 может не выполниться вовсе, а может и выполниться, но только при удачном выполнении всего, что было ранее. В принципе, игра не тормозит и не выдаёт слайд шоу, что радует, но хотелось бы дополнительно узнать, влияет ли то, что я использую так много if для отбора нужного значения? 
P.S. Я опять вожусь с памятью, что-то удаётся сделать с пикапами, вот я их и хочу разобрать в цикле. 
Спасибо за ответы. Я порой думаю, что выгляжу для вас как полный нуб, который только достаёт вопросами...

Добавлено (24.06.2013, 22:59)
---------------------------------------------
Как рассчитать координаты пикапа через память? Я уже запарился над этими вычислениями, не понимаю системы, делю на 8, так как там умножено на 8, беру 2 байта (хотя float - это 4), пробовал после этого всё подряд, но ничего не работает... Странно, почему так. И каждый раз выходят нулевые координаты.


SCRIPTER
 
DK22PacДата: Вторник, 25.06.2013, 00:20 | Сообщение # 330
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
В ексе есть готовая функция, которая возвращает координаты пикапа (на входе - то ли сам пикап, то ли индекс).
Жаль, у меня базы под рукой нет.
 
Форум » Игры серии ГТА » Скриптинг » Вопросы по созданию КЛЕО-скриптов 2
Поиск: