У CBike есть CBMX 😁Тот случай, когда сын превзошел отца.
У CBike есть CBMX 😁Тот случай, когда сын превзошел отца.
А про деда CPlaceable все забыли...У CBike есть CBMX 😁
В спойлере скилл локального игрока в процентах. Может быть можно обратным способом записать туда значение. https://www.blast.hk/threads/10970/post-98968Добрый вечер, вот что из этого всего реально отвечает за смену навыков владения оружием?
1. CPed +0x72C = [byte] Навык владения оружием (0-4)
2. 0xC8AAB8 - Начало блока, куда считывается информация об оружии с меткой J (оружие ближнего боя) и $ (остальное оружие). В этом блоке 0x50 элементов по 0x70 байт в каждом. Индекс элемента высчитывается по формуле: <номер оружия> + <смещение>. Смещение определяется навыком оружия skilllevel: STD - 0, POOR - 25, PRO - 36, особое (характеристики пистолета копов) - 47. Все имена взяты из заголовка оригинального weapon.dat.
3.
- +0x30 = [dword] Владение оружием
- 0 - POOR //Наихудшее
- 1 - STD //Среднее
- 2 - PRO //Наилучшее
- 3 - особое
- +0x34 = [dword] statrequired. Уровень статистики, необходимый для получения текущего навыка владения оружи
Ну так там считывают, а изменять то как? Что записать? ID оружия + 0x36?В спойлере скилл локального игрока в процентах. Может быть можно обратным способом записать туда значение. https://www.blast.hk/threads/10970/post-98968
Таким же образом, только тебе ReadProcessMemory надо на WriteProcessMemory сменитьНу так там считывают, а изменять то как? Что записать? ID оружия + 0x36?
в dwAddr просто перед адресом добавь (DWORD*)Ну так там считывают, а изменять то как? Что записать? ID оружия + 0x36?
template <typename T>
void WriteMem(DWORD* dwAddr, size_t size, T value)
{
DWORD NewProtection;
VirtualProtect(dwAddr, size, PAGE_EXECUTE_READWRITE, &NewProtection);
*reinterpret_cast<T*>(dwAddr) = value;
VirtualProtect(dwAddr, size, NewProtection, &NewProtection);
}
Он экстреналы делаетв dwAddr просто перед адресом добавь (DWORD*)
C++:template <typename T> void WriteMem(DWORD* dwAddr, size_t size, T value) { DWORD NewProtection; VirtualProtect(dwAddr, size, PAGE_EXECUTE_READWRITE, &NewProtection); *reinterpret_cast<T*>(dwAddr) = value; VirtualProtect(dwAddr, size, NewProtection, &NewProtection); }
ты точно этот код прикрепить хотел? Wpm для примера вполне хватитв dwAddr просто перед адресом добавь (DWORD*)
C++:template <typename T> void WriteMem(DWORD* dwAddr, size_t size, T value) { DWORD NewProtection; VirtualProtect(dwAddr, size, PAGE_EXECUTE_READWRITE, &NewProtection); *reinterpret_cast<T*>(dwAddr) = value; VirtualProtect(dwAddr, size, NewProtection, &NewProtection); }
Да без разницы в принципе, главное чтобы без SF)Он экстреналы делает
Меня тоже бесит когда везде все через SF делаетсяДа без разницы в принципе, главное чтобы без SF)
Добрый вечер, вот что из этого всего реально отвечает за смену навыков владения оружием?
1. CPed +0x72C = [byte] Навык владения оружием (0-4)
2. 0xC8AAB8 - Начало блока, куда считывается информация об оружии с меткой J (оружие ближнего боя) и $ (остальное оружие). В этом блоке 0x50 элементов по 0x70 байт в каждом. Индекс элемента высчитывается по формуле: <номер оружия> + <смещение>. Смещение определяется навыком оружия skilllevel: STD - 0, POOR - 25, PRO - 36, особое (характеристики пистолета копов) - 47. Все имена взяты из заголовка оригинального weapon.dat.
3.
- +0x30 = [dword] Владение оружием
- 0 - POOR //Наихудшее
- 1 - STD //Среднее
- 2 - PRO //Наилучшее
- 3 - особое
- +0x34 = [dword] statrequired. Уровень статистики, необходимый для получения текущего навыка владения оружи
// Для internal'a
// weaponType - ID оружия.
// cSkill - сам скилл.
void CPed::SetWeaponSkill(eWeaponType weaponType, char cSkill)
{
// Вместо eWeaponType можно и int
reinterpret_cast<void(__thiscall*)(CPed*, eWeaponType, char)>(0x5E3C10)(this, weaponType, cSkill);
}
*reinterpret_cast<void**>(0xB6F5F0)а почему инменно reinterept_cast а не static_cast и не простое разименование указателя?this можно заменитьC++:// Для internal'a // weaponType - ID оружия. // cSkill - сам скилл. void CPed::SetWeaponSkill(eWeaponType weaponType, char cSkill) { // Вместо eWeaponType можно и int reinterpret_cast<void(__thiscall*)(CPed*, eWeaponType, char)>(0x5E3C10, this, weaponType, cSkill); }reinterpret_cast<void*>(0xB6F5F0)
Ну и понятное дело вместо CPed* поставить void*
Потому что reinterpret_cast буквально говорит: Видишь тут хранится float? Вот, считай что теперь это intа почему инменно reinterept_cast а не static_cast и не простое разименование указателя?
Нет. *reinterpret_cast<class CPed **>(0xB6F5F0). В данном случае ты сделал абсолютно бессмысленное кастование, одно и то же, что reinterpret_cast<uint32_t>(0xB6F5F0)reinterpret_cast<void*>(0xB6F5F0)