Перейти к содержанию

Grand Theft Auto Vice City, метод указателей


Рекомендуемые сообщения

//keng в смысле - ты имеешь в виду, что я непонятно написал?

Нет, я про пост Uchiha Sasuke - ему не лень было ответить автору, но по факту пост особенной пользы автору не принёс, так что это выглядит довольно иронично на мой взляд. :)

Ссылка на комментарий
Поделиться на другие сайты

Повреждение машин - float, прокол шин - byte в структуре машины. Первый адрес ищется за 5 минут, второй - через структуру, полученную при отладке первого. wink.gif

спасибо 1 помогло.я пока еще не умею в структурах лазить, какие статьи мне надо почитать что бы понять как с ним работать?

Ссылка на комментарий
Поделиться на другие сайты

спасибо 1 помогло.я пока еще не умею в структурах лазить, какие статьи мне надо почитать что бы понять как с ним работать?

Ну какбе если ты с трудом представляешь, что такое структура вообще, давай я тебе попробую показать. Вот, например

Struct Player
{
int id;
string name;
int health;
int ammo
}

Значит, представим ситуацию, что в неком сферическом игровом (в вакууме) мире есть три персонажа. Все трое описываются структурой Player. Типа вот так:

Us = new Playser(1, "teh player", 100, 50);
Bot1 = new Player(2, "teh bot1", 100, 50);
Bot2 = new Player(2, "teh bot2", 100, 50);

Всё три объекта - структуры типа Player. Одинаковые? Ну да, почти. У нашего персонажа поле id равно единичке, а у ботов - двойке.

Теперь представим, что нашли мы здоровье нашего перса, воткнули отладчик и нам выползла вот такая функция:

00123456: MOV [EAX+00С],EBX

EBX у нас, к примеру, 99 - потому что этой инструкцией игра безжалостно стреляет в персонажей. Значит, EAX хранит базовый адрес структуры того персонажа, в которого стреляют. Предположим, что каждый член структуры имеет размер в 4 байта. Следовательно, здоровье получается как раз по смещению [EAX+00С] (004h+004h+004h = 00Сh).

Клёво? Клёво! Соответственно, по смещению [EAX+4] у нас получается ID, а по смещению [EAX+8] - имя персонажа. В общем, фишка в том, что в том же СЕ можно все эти смещения радостно посмотреть, а что ещё круче - сравнить два объекта, в которых какие-то из полей структуры изменились.

Теперь представим такое:

Struct Venicle
{
int type;
float health;
bool isBroken;
}

Эта вот структура описывает средство передвижения. type - тип средства (марсоход, авианосец, тележка из супермаркета), health - понятно, а вот isBroken говорит нам о состоянии шин (уровня воды под килем в случае крейсера). Оно умеет принимать два значения (потому что тип - bool) - 1 или 0. Соответственно, 0 - всё круто, едем дальше, 1 - всё плохо, сели на мель, алярм упячка и так далее.

Значится, взяли мы, пошли на автостоянку - стоит там две машины. Мы нашли адрес здоровья одной из них (стрельнули - unknown float - стрельнули - decreased - стрельнули - менты decreased и т.д.), повесили отладчик, вылезла инструкция:

0054356: FSUB DWORD PTR [EDX+008],EAX

Соответственно, всё то же самое - оно отнимает урон у машины, если по ней стрелять или грызть зубами. Не суть важно. Важно то, что [EDX+008] указывает нам на здоровье. Теперь делаем финт ушами - берём значение EAX и идём в Browse Memory Region:

00344999: 00 00 00 01 00 00 C8 42 00

Первые четыре байта - тип машины, следующие четыре - количество здоровья, последний - сломаны ли колёса.

Стамим брейкпоинт на функцию причинения тяжких телесных машине, которую мы нашли чуток раньше, стреляем по соседней машине, смотрим в отладчике значение EAX, топаем в Browse Memory Region:

003449A2: 00 00 00 02 00 00 FF FF 01

Смотрим на последний байт, видим единичку, думаем. А НЕ ПРОКОЛЫТЫ ЛИ У ЭТОГО КРЕЙСЕРА КОЛЁСА???

В GTA же в структуре машины будет флажок isPlayerSitting, обозначающий, едет ли игрок на этой машине. Мы находим функцию стрельбы по машинам и меняем её на вот такое:

CMP [EAX+1234],0 ;(смещение до isPlayerSitting в структуре машины)
JNE EXIT ;Посмотрели, сидим ли мы в машине, если не сидим - выходим, мотороллер не наш
MOV [EAX+0FF],0 ;(смещение до isBroken) - явно указываем, что если машина наша - колёса у неё ну вот точно не проколоты
EXIT: ;Сюда прыгаем, если машина не наша
RET ;Выходим

Вот как-то типа того. Надеюсь, понятно написал. :ninja:

Ссылка на комментарий
Поделиться на другие сайты

получилось что то.но я еще не до конца понял.как то сделал только на свою машину. а как вапще определяются какой адрес структуры к какой функции принадлежит?

Ссылка на комментарий
Поделиться на другие сайты

Как бы, есть некоторая функция, типа:

DamageCar(carObj, playerObj);

Ей в аргументах приходит объект carObj, который представляет собой структуру машины и playerObj - объект, предствляющий структуру того, кто стреляет по этой машине, будь то игрок или кто-нибудь ещё. В структуре carObj творится что-то вроде:


CarObj struct
{
int id;
int type;
float health;
bool isPlayer;
float x;
float y;
float z;
}

id - номер объекта в мире, глобальный.

type - тип транспортного средства, машина\мотоцикл\самолёт и т.д.

health - здоровье объекта.

isPlayer - показывает, принадлежит ли этот объект игроку. Скажем, сидит ли он в ней.

x\y\z - координаты этого объекта в игровом мире.

Когда вызывается функция DamageCar(), ей абсолютно пофиг, кто стреляет по машине - она просто берёт из структуры playerObj оружие этого игрока (если это полицейский - то пистолет, если спецназовец - то М4А1 и т.п.), берёт урон этого оружия и отнимает его из поля health в структуре carObj, которая пришла в аргументы.

Получается, что такой-то playerObj нанёс урон такой-то carObj, всё круто.

В этот момент вклиниваемся мы и ставим дополнительное условие -

"Если playerObj = наш игрок или же carObj.isPlayer = true, то урон не наносить". Мол, нафига наносить урон по нашей машине?

Вот как-то так и выходит.

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.