теперь допустим берём emun OBJECTIVE_SOLICIT_VEHICLE, какие параметры передать в функцию SetObjective.
CPed *ped;
CVehicle *vehicle;
ped->SetObjective(OBJECTIVE_SOLICIT_VEHICLE, vehicle);
Пытаюсь разобрать функции в псевдокоде, иногда псевкод простой функции отражается так. Может, он не так должен отображается?
Учиться разбирать надо с маленьких функций.
Возьмём для примера функцию
CPed::SetObjectiveTimerНажимаем F5 и получаем такой псевдокод:
unsigned int __thiscall CPed::SetObjectiveTimer(int this, int a2)
{
unsigned int result; // eax@2
if ( a2 )
{
result = *(_DWORD *)(this + 1360);
if ( CTimer::m_snTimeInMilliseconds > result )
{
result = CTimer::m_snTimeInMilliseconds + a2;
*(_DWORD *)(this + 1360) = CTimer::m_snTimeInMilliseconds + a2;
}
}
else
{
*(_DWORD *)(this + 1360) = 0;
}
return result;
}
Это метод класса CPed, значит первым параметром передаётся указатель на этот класс.
Ставим курсор мышки на this, нажимаем Y и вводим вместо int CPed* (или можно нажать правую клавишу мыши и в контекстном меню выбрать Convert to struct* и выбрать из списка имеющихся в базе структур CPed)
Получается так:
unsigned int __thiscall CPed::SetObjectiveTimer(CPed *this, int a2)
Смотрим тип второго аргумента, там должен быть unsigned int, а у нас int, исправляем (курсор мыши на a2, нажимаем Y и добавляем unsigned перед int):
unsigned int __thiscall CPed::SetObjectiveTimer(CPed *this, unsigned int a2)
Переменную a2 переименуем в time, курсор мыши на a2, нажимаем N и вводим time:
unsigned int __thiscall CPed::SetObjectiveTimer(CPed *this, unsigned int time)
Смотрим в тех функциях, где вызывается эта функция есть ли возвращаемое значение (клавиша X и переход в место, где эта функция вызывается).
В данном случае возвращаемого значения нет. Меняем тип возвращаемого значения на void, курсор на названии функции и Y, воодим void вместо unsigned int:
void __thiscall CPed::SetObjectiveTimer(CPed *this, unsigned int time)
Можно было все вышеперечисленные правки сделать в этом последнем действии (Y на названии функции и ввод нужных данных и изменение названий переменных), показал отдельно для наглядности.
В итоге получилось так:
void __thiscall CPed::SetObjectiveTimer(CPed *this, unsigned int time)
{
if ( time )
{
if ( CTimer::m_snTimeInMilliseconds > this->m_nObjectiveTimer )
this->m_nObjectiveTimer = CTimer::m_snTimeInMilliseconds + time;
}
else
{
this->m_nObjectiveTimer = 0;
}
}
Всё стало ясно и понятно, не так ли?
Ну это простая функция и разбирать её легко, но начинать надо именно с таких простых функций.
Изменения надо сохранить в базе (нажать на иконку сохранения).
Возьмём для второго примера ещё одну небольшую функцию
CPed::TeleportНажимаем F5 и получаем такой псевдокод:
char __thiscall CPed::Teleport(CEntity *this, float a2, int a3, int a4)
{
CEntity *v4; // ebx@1
v4 = this;
CWorld::Remove(this);
v4->m_placement.m_matrix.pos.x = a2;
v4->m_placement.m_matrix.pos.y = *(float *)&a3;
v4->m_placement.m_matrix.pos.z = *(float *)&a4;
LOBYTE(v4[3].m_placement.m_matrix.pad1) &= 0xFEu;
v4[5].m_pRwObject = 0;
v4[5].m_placement.m_matrix.pAttached = 0;
v4[5].m_placement.m_matrix.bDeleteOnDetach = 0;
v4[2].m_placement.m_matrix.pad4 = 0;
return CWorld::Add((CPhysical *)v4);
}
Это метод класса CPed, но сейчас в псевдокоде почему-то класс CEntity, вместо второго параметра CVector одна переменная типа float и две типа int, возвращаемое значение стоит char, хотя функция ничего не должна возвращать. Будем исправлять.
Нажимаем Y на названии функции и водим нужные данные:
void __thiscall CPed__Teleport(CPed *this, CVector point)
Переименовываем переменную v2 в ped.
Получаем такой псевдокод:
void __thiscall CPed::Teleport(CPed *this, CVector point)
{
CPed *ped; // ebx@1
ped = this;
CWorld::Remove(&this->physical.entity);
ped->physical.entity.m_placement.matrix.pos = point;
ped->bfFlagsA &= 0xFEu;
ped->m_nActionTimer = 0;
ped->fActionX = 0;
ped->fActionY = 0;
ped->physical.m_pPhysColliding = 0;
CWorld::Add(&ped->physical);
}
Ну тут тоже всё стало понятно (за исключением установки какого-то флага, но это отдельная история, не все флаги названы).
Изменения надо сохранить в базе (нажать на иконку сохранения).