diff --git a/examples/mods/aim1_community_fix/aim.exe.fixes.h b/examples/mods/aim1_community_fix/aim.exe.fixes.h new file mode 100644 index 0000000..2ec6993 --- /dev/null +++ b/examples/mods/aim1_community_fix/aim.exe.fixes.h @@ -0,0 +1,381 @@ +#include +#include + +#include +#include + +/*struct char20 { + char string[20]; +};*/ + +#define _BYTE uint8_t +#define this +#define __unaligned +#include "aim.exe.h" +#undef this +#undef __unaligned + +using namespace std::literals; + +constexpr auto call_command_length = 5; + +enum aim1_fix : uint32_t { + script_function__ISGLIDER = 0x0043A1F6, + trade_actions_weapon_checks = 0x004072FA, + setup_proper_weapon_slots_for_a_glider = 0x004D62E4, + put_weapon_into_the_right_slot_after_purchase = 0x00417A6D, + sell_correct_weapon = 0x004176BC, + empty_light_weapon_message = 0x004067C4, + empty_heavy_weapon_message = 0x0040688B, +}; +uint32_t known_caller; +auto player_ptr = (Player **)0x005B7B38; +auto get_player_ptr() { + auto player_ptr2 = (Player *)0x00678FEC; + return player_ptr2; +} + +enum class glider_id : uint32_t { + nargoon = 0x7, + eyedstone = 0xe, + finder1 = 0x19, + finder2 = 0x1A, +}; + +#define NOP1 __asm { nop } +#define NOP2 NOP1 NOP1 +#define NOP4 NOP2 NOP2 +#define NOP8 NOP4 NOP4 +#define NOP16 NOP8 NOP8 +#define NOP32 NOP16 NOP16 +#define NOP64 NOP32 NOP32 +#define NOP128 NOP64 NOP64 +#define NOP256 NOP128 NOP128 +#define NOP512 NOP256 NOP256 +#define NOP1024 NOP512 NOP512 +#define NOP4K NOP1024 NOP1024 NOP1024 NOP1024 + +bool __stdcall strequ(const char *s1, const char *s2) { + do { + if (*s1 != *s2) { + return false; + } + } while (*s1++ && *s2++); + return true; +} + +__declspec(naked) void fix_script_function__ISGLIDER() { + __asm { + ; restore values + popad + pushad + + mov edi, eax ; my glider + mov esi, [esp+20h+4+8*4] ; arg + + label_cmp: + mov al, [edi] + mov cl, [esi] + cmp al, cl + jne bad + cmp al, 0 + je end + inc edi + inc esi + jmp label_cmp + end: + cmp al, cl + jne bad + popad + ; push some regs as required by success branch + push ebx + push ebp + push esi + push edi + push 0x0043A2DA + ret + + bad: + popad + ; original thunk + copy: + mov cl, [eax]; injection point + inc eax + mov[edx], cl + inc edx + test cl, cl + jnz copy + + ; epilogue + push known_caller + ret + } +} + +bool is_double_light_weapons_glider() { + return false + || get_player_ptr()->glider_name.idx == (int)glider_id::nargoon + || get_player_ptr()->glider_name.idx == (int)glider_id::finder1 + ; +} +bool is_double_heavy_weapons_glider() { + return false + || get_player_ptr()->glider_name.idx == (int)glider_id::eyedstone + || get_player_ptr()->glider_name.idx == (int)glider_id::finder2 + ; +} +bool is_special_glider() { + return is_double_light_weapons_glider() || is_double_heavy_weapons_glider(); +} + +bool is_double_light_weapons_glider(glider_id id) { + return false + || id == glider_id::nargoon + || id == glider_id::finder1 + ; +} +bool is_double_heavy_weapons_glider(glider_id id) { + return false + || id == glider_id::eyedstone + || id == glider_id::finder2 + ; +} +bool is_special_glider(glider_id id) { + return is_double_light_weapons_glider(id) || is_double_heavy_weapons_glider(id); +} + +bool __stdcall can_buy_weapon(int selected_weapon_type, int *canbuy) { + if (is_special_glider()) { + if (selected_weapon_type == light && is_double_heavy_weapons_glider()) { + *(uint8_t*)canbuy = 0; + } + if (selected_weapon_type == heavy && is_double_light_weapons_glider()) { + *(uint8_t *)canbuy = 0; + } + return true; + } + return false; +} +__declspec(naked) void fix_trade_actions_weapon_checks() { + __asm { + ; restore values + popad + pushad + + ; ebx = selected weapon type in the store + ; esi = gun_desc + ; [esp + 102h] bool is_buy_change + ; [esp + 103h] bool can_buy + + mov edx, esp + add edx, 123h + lea edx, [edx] + push edx + + push ebx + call can_buy_weapon + test al, 1 + jz epi + popad + push 0x00407308 + ret + + epi: + ; epilogue + popad + mov eax, ebx + sub eax, 0 + push known_caller + ret + } +} + +bool can_have_light_weapon_slot(glider *obj, glider_id id, int special) { + if (is_special_glider(id)) { + return true; + } + return ((special >> 1) & 0x1) == 0; +} +bool can_have_heavy_weapon_slot(glider *obj, glider_id id, int special) { + if (is_special_glider(id)) { + return true; + } + return obj->standard > 2 && (special & 0x1) == 0; +} +void __stdcall can_have_weapon_slots(glider *gliders, glider *obj, int special) { + auto id = obj - gliders; + obj->can_have_light_weap = can_have_light_weapon_slot(obj, (glider_id)id, special); + obj->can_have_heavy_weap = can_have_heavy_weapon_slot(obj, (glider_id)id, special); +} +__declspec(naked) void fix_can_have_weapon_slots_for_a_glider() { + __asm { + ; restore values + popad + pushad + + push eax; SPECIAL field value + mov ecx, edx; + add ecx, ebx; + push ecx ; glider* + push edx ; glider** + call can_have_weapon_slots + + popad + push 0x004D6351 + ret + } +} + +bool __stdcall put_purchased_weapon_into_light_slot(int purchased_weapon_type) { + if (is_special_glider()) { + return get_player_ptr()->glider_object->light_gun_id == -1; + } + return purchased_weapon_type == 0; +} +__declspec(naked) void fix_put_weapon_into_the_right_slot_after_purchase() { + __asm { + ; restore values + popad + pushad + + push eax ; purchased weapon type + + call put_purchased_weapon_into_light_slot + cmp al, 1 + jne heavy_exit + popad + push 0x00417AA1 + ret + + heavy_exit: + popad + push 0x00417A75 + ret + } +} + +bool __stdcall sell_light_weapon(int sold_weapon_type) { + if (is_special_glider()) { + return get_player_ptr()->glider_object->light_gun_id != -1; + } + return sold_weapon_type == 0; +} +__declspec(naked) void fix_sell_correct_weapon() { + __asm { + ; restore values + popad + pushad + + push eax; purchased weapon type + + call sell_light_weapon + cmp al, 1 + jne heavy_exit + popad + push 0x004176F1 + ret + + heavy_exit: + popad + push 0x004176C4 + ret + } +} + +uint32_t empty_weapon_message; +void __stdcall fix_empty_weapon_message(int light_slot) { + constexpr auto INT_EMPTY_LIGHT_GUN = 0x00521AA8; + constexpr auto INT_EMPTY_HEAVY_GUN = 0x00521A94; + if (is_double_light_weapons_glider()) { + empty_weapon_message = INT_EMPTY_LIGHT_GUN; + } else if (is_double_heavy_weapons_glider()) { + empty_weapon_message = INT_EMPTY_HEAVY_GUN; + } else { + empty_weapon_message = light_slot ? INT_EMPTY_LIGHT_GUN : INT_EMPTY_HEAVY_GUN; + } +} +__declspec(naked) void fix_empty_light_weapon_message() { + __asm { + ; restore values + popad + pushad + + mov eax, 1 + push eax + call fix_empty_weapon_message + + popad + push empty_weapon_message + push known_caller + ret + } +} +__declspec(naked) void fix_empty_heavy_weapon_message() { + __asm { + ; restore values + popad + pushad + + mov eax, 0 + push eax + call fix_empty_weapon_message + + popad + push empty_weapon_message + push known_caller + ret + } +} + +extern "C" __declspec(dllexport) __declspec(naked) void dispatcher() { + __asm { + pop known_caller + pushad + } + switch (known_caller - call_command_length) { + case aim1_fix::script_function__ISGLIDER: + known_caller += 0xA - call_command_length; // make normal ret + __asm jmp fix_script_function__ISGLIDER + break; + case aim1_fix::trade_actions_weapon_checks: + __asm jmp fix_trade_actions_weapon_checks + break; + case aim1_fix::setup_proper_weapon_slots_for_a_glider: + __asm jmp fix_can_have_weapon_slots_for_a_glider + break; + case aim1_fix::put_weapon_into_the_right_slot_after_purchase: + __asm jmp fix_put_weapon_into_the_right_slot_after_purchase + break; + case aim1_fix::sell_correct_weapon: + __asm jmp fix_sell_correct_weapon + break; + case aim1_fix::empty_light_weapon_message: + __asm jmp fix_empty_light_weapon_message + break; + case aim1_fix::empty_heavy_weapon_message: + __asm jmp fix_empty_heavy_weapon_message + break; + default: + break; + } + // just return + __asm { + popad + push known_caller + ret + } +} + +void setup() { + //constexpr uint32_t free_data_base = 0x006929C0; + constexpr uint32_t free_data_base = 0x00692FF0; + auto mem = (uint8_t *)free_data_base; + mem[0] = 0xE9; + *(uint32_t*)&mem[1] = (uint32_t)&dispatcher - free_data_base - call_command_length; +} +BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID) { + if (fdwReason == DLL_PROCESS_ATTACH) { + setup(); + } + return TRUE; +} diff --git a/examples/mods/aim1_community_fix/aim.exe.h b/examples/mods/aim1_community_fix/aim.exe.h new file mode 100644 index 0000000..e9564cc --- /dev/null +++ b/examples/mods/aim1_community_fix/aim.exe.h @@ -0,0 +1,2323 @@ +/* + This file has been generated by IDA. + It contains local type definitions from + the type library 'aim.exe' +*/ + +#define __int8 char +#define __int16 short +#define __int32 int +#define __int64 long long + +struct equipment1; +struct CEquipment; +struct CEquipment_vtable1; +struct glider; +struct gun_desc; +struct CGliderObject; + +/* 92 */ +struct char20 +{ + char string[32]; +}; + +/* 95 */ +struct id_and_name +{ + int idx; + char str; + char field_5; + char field_6; + char field_7; + char field_8; + char field_9; + char field_A; + char field_B; + char field_C; + char field_D; + char field_E; + char field_F; + char field_10; + char field_11; + char field_12; + char field_13; + char field_14; + char field_15; + char field_16; + char field_17; + char field_18; + char field_19; + char field_1A; + char field_1B; + char field_1C; + char field_1D; + char field_1E; + char field_1F; +}; + +/* 84 */ +struct player_equipment +{ + CEquipment_vtable1 *vtable; + id_and_name name; + float damaged; + float weight; + char can_have_light_weap; + char can_have_heavy_weap; + __int16 field_2E; + glider *glider; + float some_float; +}; + +/* 82 */ +struct Player +{ + char20 name; + float rating; + int field_24; + int field_28; + int field_2C; + int field_30; + float balance; + int field_38; + void *tovars; + CGliderObject *glider_object; + void *some_ptr; + player_equipment reactor; + player_equipment drive; + player_equipment shield; + player_equipment armor; + player_equipment glider; + float armor_value1; + int field_164; + int field_168; + int field_16C; + int field_170; + int field_174; + int field_178; + int field_17C; + int field_180; + int field_184; + int field_188; + int field_18C; + int field_190; + int field_194; + int field_198; + int field_19C; + int field_1A0; + int field_1A4; + int field_1A8; + int field_1AC; + int field_1B0; + int field_1B4; + int number_of_cargo_items; + int field_1BC; + char20 field_1C0; + int field_1E0; + char20 field_1E4; + int field_204; + char20 field_208; + int field_228; + char20 field_22C; + int field_24C; + int field_250; + int field_254; + int field_258; + int field_25C; + int field_260; + int field_264; + int field_268; + int field_26C; + int field_270; + int field_274; + int field_278; + int field_27C; + int field_280; + int field_284; + int field_288; + int field_28C; + int field_290; + int field_294; + int field_298; + int field_29C; + int field_2A0; + int field_2A4; + int field_2A8; + int field_2AC; + int field_2B0; + int field_2B4; + int field_2B8; + int field_2BC; + int field_2C0; + int field_2C4; + int field_2C8; + int field_2CC; + int field_2D0; + int field_2D4; + int field_2D8; + int field_2DC; + int field_2E0; + int field_2E4; + int field_2E8; + int field_2EC; + int field_2F0; + int field_2F4; + int field_2F8; + int field_2FC; + int field_300; + int field_304; + int field_308; + int field_30C; + int field_310; + int field_314; + int field_318; + int field_31C; + int field_320; + int configuration_id; + char20 configuration_name; + int field_348; + int field_34C; + int field_350; + int field_354; + int field_358; + int field_35C; + int field_360; + int field_364; + int field_368; + int field_36C; + int field_370; + int field_374; + int field_378; + int field_37C; + int field_380; + int field_384; + int field_388; + int field_38C; + int field_390; + int field_394; + int field_398; + int field_39C; + int field_3A0; + int field_3A4; + int field_3A8; + id_and_name glider_name; + id_and_name light_weapon_name; + id_and_name heavy_weapon_name; + id_and_name rocket_weapon_name; + id_and_name reactor_name; + id_and_name drive_name; + id_and_name shield_generator_name; + id_and_name armor_name; + char20 bomb_name; + int field_4CC; + char20 field_4D0; + int field_4F0; + char20 rocket; + int field_514[24]; + int field_574; + int field_578; + int field_57C; + int field_580; + int field_584; + int field_588; +}; + +/* 128 */ +struct CGliderObject +{ + int vtable; + int field_4; + int field_8; + glider *glider_desc; + int field_10; + int field_14; + int field_18; + int field_1C; + int field_20; + int field_24; + int field_28; + int field_2C; + int field_30; + id_and_name field_34; + int field_54; + int field_58; + int field_5C; + int field_60; + int field_64; + int field_68; + int field_6C; + int field_70; + int field_74; + int field_78; + int field_7C; + int field_80; + int field_84; + int field_88; + int field_8C; + int field_90; + int field_94; + int field_98; + int field_9C; + int field_A0; + int field_A4; + int field_A8; + int field_AC; + int field_B0; + int field_B4; + int field_B8; + int field_BC; + int field_C0; + int field_C4; + int field_C8; + int field_CC; + int field_D0; + int field_D4; + int field_D8; + int field_DC; + int field_E0; + int field_E4; + int field_E8; + int field_EC; + int field_F0; + int field_F4; + int field_F8; + int field_FC; + int field_100; + int field_104; + int field_108; + int field_10C; + int field_110; + int field_114; + int field_118; + int field_11C; + int field_120; + int field_124; + int field_128; + int field_12C; + int field_130; + int field_134; + int field_138; + int field_13C; + int field_140; + int field_144; + int field_148; + int field_14C; + int field_150; + int field_154; + int field_158; + int field_15C; + int field_160; + int field_164; + int field_168; + int field_16C; + int field_170; + int field_174; + int field_178; + int field_17C; + int field_180; + int field_184; + int field_188; + int field_18C; + int field_190; + int field_194; + int field_198; + float field_19C; + int field_1A0; + int field_1A4; + int field_1A8; + int field_1AC; + float field_1B0; + int field_1B4; + int field_1B8; + int field_1BC; + int field_1C0; + int field_1C4; + int field_1C8; + int field_1CC; + int field_1D0; + int field_1D4; + int field_1D8; + int field_1DC; + int field_1E0; + int field_1E4; + int field_1E8; + int field_1EC; + int field_1F0; + int field_1F4; + int field_1F8; + int field_1FC; + int field_200; + int field_204; + int field_208; + int field_20C; + int field_210; + int field_214; + int field_218; + int field_21C; + int field_220; + int field_224; + int field_228; + int field_22C; + int field_230; + int field_234; + int field_238; + int field_23C; + int field_240; + int field_244; + int field_248; + int field_24C; + int field_250; + int field_254; + int field_258; + int field_25C; + int field_260; + int field_264; + int field_268; + int field_26C; + int field_270; + int field_274; + int field_278; + int field_27C; + int field_280; + int field_284; + int field_288; + int field_28C; + int field_290; + int field_294; + int field_298; + int field_29C; + int field_2A0; + int field_2A4; + int field_2A8; + int field_2AC; + int field_2B0; + int field_2B4; + int field_2B8; + int field_2BC; + int field_2C0; + int field_2C4; + int field_2C8; + int field_2CC; + int field_2D0; + int field_2D4; + _BYTE gap2D8[4]; + int field_2DC; + int field_2E0; + int field_2E4; + int field_2E8; + int field_2EC; + int field_2F0; + int field_2F4; + int field_2F8; + int field_2FC; + int field_300; + int field_304; + int field_308; + int field_30C; + int field_310; + int field_314; + int field_318; + int field_31C; + int field_320; + int field_324; + int field_328; + int field_32C; + int field_330; + int field_334; + int field_338; + int field_33C; + int field_340; + int field_344; + int field_348; + int field_34C; + int field_350; + int field_354; + int field_358; + int field_35C; + int field_360; + int field_364; + int field_368; + int field_36C; + int field_370; + int field_374; + int field_378; + int field_37C; + int field_380; + int field_384; + int field_388; + int field_38C; + int field_390; + int field_394; + int field_398; + int field_39C; + int field_3A0; + int field_3A4; + int field_3A8; + int field_3AC; + int field_3B0; + int field_3B4; + int field_3B8; + int field_3BC; + int field_3C0; + int field_3C4; + int field_3C8; + int field_3CC; + int field_3D0; + int field_3D4; + int field_3D8; + int field_3DC; + int field_3E0; + int field_3E4; + int field_3E8; + int field_3EC; + int field_3F0; + int field_3F4; + int field_3F8; + int field_3FC; + int field_400; + int field_404; + int field_408; + int field_40C; + int field_410; + int field_414; + int field_418; + int field_41C; + int field_420; + int field_424; + int field_428; + int field_42C; + int field_430; + int field_434; + int field_438; + int field_43C; + int field_440; + int field_444; + int field_448; + int field_44C; + int field_450; + int field_454; + int field_458; + int field_45C; + int field_460; + int field_464; + int field_468; + int field_46C; + int field_470; + int field_474; + int field_478; + int field_47C; + int field_480; + int field_484; + int field_488; + int field_48C; + int field_490; + int field_494; + int field_498; + int field_49C; + int field_4A0; + int field_4A4; + int field_4A8; + int field_4AC; + int field_4B0; + int field_4B4; + int field_4B8; + int field_4BC; + int field_4C0; + int field_4C4; + int field_4C8; + int field_4CC; + int field_4D0; + int field_4D4; + int field_4D8; + int field_4DC; + int field_4E0; + int field_4E4; + int field_4E8; + int field_4EC; + int field_4F0; + int field_4F4; + int field_4F8; + int field_4FC; + int field_500; + int field_504; + int field_508; + int field_50C; + int field_510; + int field_514; + int field_518; + int field_51C; + int field_520; + int field_524; + int field_528; + int field_52C; + int field_530; + int field_534; + int field_538; + int field_53C; + int field_540; + int field_544; + int field_548; + int field_54C; + int field_550; + int field_554; + int field_558; + int field_55C; + int field_560; + int field_564; + int field_568; + int field_56C; + int field_570; + int field_574; + int field_578; + int field_57C; + int field_580; + int field_584; + int field_588; + int field_58C; + int field_590; + int field_594; + int field_598; + int field_59C; + int field_5A0; + int field_5A4; + int field_5A8; + int field_5AC; + int field_5B0; + int field_5B4; + int field_5B8; + int field_5BC; + int field_5C0; + int field_5C4; + int field_5C8; + int field_5CC; + int field_5D0; + int field_5D4; + int field_5D8; + int field_5DC; + int field_5E0; + int field_5E4; + int field_5E8; + int field_5EC; + int field_5F0; + int field_5F4; + int field_5F8; + int field_5FC; + int field_600; + int field_604; + int field_608; + int field_60C; + int field_610; + int field_614; + int field_618; + int field_61C; + int field_620; + int field_624; + int field_628; + int field_62C; + int field_630; + int field_634; + int field_638; + int field_63C; + int field_640; + int field_644; + int field_648; + int field_64C; + int field_650; + int field_654; + int field_658; + int field_65C; + int field_660; + int field_664; + int field_668; + int field_66C; + int field_670; + int field_674; + int field_678; + int field_67C; + int field_680; + int field_684; + int field_688; + int field_68C; + int field_690; + int field_694; + int field_698; + int field_69C; + int field_6A0; + int field_6A4; + int field_6A8; + int field_6AC; + int field_6B0; + int field_6B4; + int field_6B8; + int field_6BC; + int field_6C0; + int field_6C4; + int field_6C8; + int field_6CC; + int field_6D0; + int field_6D4; + int field_6D8; + int field_6DC; + int field_6E0; + int field_6E4; + int field_6E8; + int field_6EC; + int field_6F0; + int field_6F4; + int field_6F8; + int field_6FC; + int field_700; + int field_704; + int field_708; + int field_70C; + int field_710; + int field_714; + int field_718; + int field_71C; + int field_720; + int field_724; + int field_728; + int field_72C; + int field_730; + int field_734; + int field_738; + int field_73C; + int field_740; + int field_744; + int field_748; + int field_74C; + int field_750; + int field_754; + int field_758; + int field_75C; + int field_760; + int field_764; + int field_768; + int field_76C; + int field_770; + int field_774; + int field_778; + int field_77C; + int field_780; + int field_784; + int field_788; + int field_78C; + int field_790; + int field_794; + int field_798; + int field_79C; + int field_7A0; + int field_7A4; + int field_7A8; + int field_7AC; + int field_7B0; + int field_7B4; + int field_7B8; + int field_7BC; + int field_7C0; + int field_7C4; + int field_7C8; + int field_7CC; + int field_7D0; + int field_7D4; + int field_7D8; + int field_7DC; + int field_7E0; + int field_7E4; + int field_7E8; + int field_7EC; + int field_7F0; + int field_7F4; + int field_7F8; + int field_7FC; + int field_800; + int field_804; + int field_808; + int field_80C; + int field_810; + int field_814; + int field_818; + int field_81C; + int field_820; + int field_824; + int field_828; + int field_82C; + int field_830; + int field_834; + int field_838; + int field_83C; + int field_840; + int field_844; + int field_848; + int field_84C; + int field_850; + int field_854; + int field_858; + int field_85C; + int field_860; + int field_864; + int field_868; + int field_86C; + int field_870; + int field_874; + int field_878; + int field_87C; + int field_880; + int field_884; + int field_888; + int field_88C; + int field_890; + int field_894; + int field_898; + int field_89C; + int field_8A0; + int field_8A4; + int field_8A8; + int field_8AC; + int field_8B0; + int field_8B4; + int field_8B8; + int field_8BC; + int field_8C0; + int field_8C4; + int field_8C8; + int field_8CC; + int field_8D0; + int field_8D4; + int field_8D8; + int field_8DC; + int field_8E0; + int field_8E4; + int field_8E8; + int field_8EC; + int field_8F0; + int field_8F4; + int field_8F8; + int field_8FC; + int field_900; + int field_904; + int field_908; + int field_90C; + int field_910; + int field_914; + int field_918; + int field_91C; + int field_920; + int field_924; + int field_928; + int field_92C; + int field_930; + int field_934; + int field_938; + int field_93C; + int field_940; + int field_944; + int field_948; + int field_94C; + int field_950; + int field_954; + int field_958; + int field_95C; + int field_960; + int field_964; + int field_968; + int field_96C; + int field_970; + int field_974; + int field_978; + int field_97C; + int field_980; + int field_984; + int field_988; + int field_98C; + int field_990; + int field_994; + int field_998; + int field_99C; + int field_9A0; + int field_9A4; + int field_9A8; + int field_9AC; + int field_9B0; + int field_9B4; + int field_9B8; + int field_9BC; + int field_9C0; + int field_9C4; + int field_9C8; + int field_9CC; + int field_9D0; + int field_9D4; + int field_9D8; + int field_9DC; + int field_9E0; + int field_9E4; + int field_9E8; + int field_9EC; + int field_9F0; + int field_9F4; + int field_9F8; + int field_9FC; + int field_A00; + int field_A04; + int field_A08; + int field_A0C; + int field_A10; + int field_A14; + int field_A18; + int field_A1C; + int field_A20; + int field_A24; + int field_A28; + int field_A2C; + int field_A30; + int field_A34; + int field_A38; + int field_A3C; + int field_A40; + int field_A44; + int field_A48; + int field_A4C; + int field_A50; + int field_A54; + int field_A58; + int field_A5C; + int field_A60; + int field_A64; + int field_A68; + int field_A6C; + int field_A70; + int field_A74; + int field_A78; + int field_A7C; + int field_A80; + int field_A84; + int field_A88; + int field_A8C; + int field_A90; + int field_A94; + int field_A98; + int field_A9C; + int field_AA0; + int field_AA4; + int field_AA8; + int field_AAC; + int field_AB0; + int field_AB4; + int field_AB8; + int field_ABC; + int field_AC0; + int field_AC4; + int field_AC8; + int field_ACC; + int field_AD0; + int field_AD4; + int field_AD8; + int field_ADC; + int field_AE0; + int field_AE4; + int field_AE8; + int field_AEC; + int field_AF0; + int field_AF4; + int field_AF8; + int field_AFC; + int field_B00; + int field_B04; + int field_B08; + int field_B0C; + int field_B10; + int field_B14; + int field_B18; + int field_B1C; + int field_B20; + int field_B24; + int field_B28; + int field_B2C; + int field_B30; + int field_B34; + int field_B38; + int field_B3C; + int field_B40; + int field_B44; + int field_B48; + int field_B4C; + int field_B50; + int field_B54; + int field_B58; + int field_B5C; + int field_B60; + int field_B64; + int field_B68; + int field_B6C; + int field_B70; + int field_B74; + int field_B78; + int field_B7C; + int field_B80; + int field_B84; + int field_B88; + int field_B8C; + int field_B90; + int field_B94; + int field_B98; + int field_B9C; + int field_BA0; + CEquipment *light_guns; + int field_BA8; + int field_BAC; + int field_BB0; + int field_BB4; + int field_BB8; + int field_BBC; + int field_BC0; + int field_BC4; + int field_BC8; + int field_BCC; + int field_BD0; + int field_BD4; + int field_BD8; + int field_BDC; + int field_BE0; + int field_BE4; + int field_BE8; + int field_BEC; + int field_BF0; + int field_BF4; + int field_BF8; + int field_BFC; + int field_C00; + int field_C04; + int field_C08; + int field_C0C; + int field_C10; + int field_C14; + int field_C18; + int field_C1C; + int field_C20; + int field_C24; + int field_C28; + int field_C2C; + int field_C30; + int field_C34; + int field_C38; + int field_C3C; + int field_C40; + int field_C44; + int field_C48; + int field_C4C; + int field_C50; + int field_C54; + int field_C58; + int field_C5C; + int field_C60; + int field_C64; + int field_C68; + int field_C6C; + int field_C70; + int field_C74; + int field_C78; + int field_C7C; + int field_C80; + int field_C84; + int light_gun_id; + int field_C8C; + int field_C90; + int field_C94; + int field_C98; + int field_C9C; + int field_CA0; + int field_CA4; + int field_CA8; + int field_CAC; + int field_CB0; + int field_CB4; + gun_desc *light_gun_desc_guessed; + int field_CBC; + int field_CC0; + int field_CC4; + int field_CC8; + int field_CCC; + int field_CD0; + int field_CD4; + int field_CD8; + int field_CDC; + float current_light_ammo_guessed; + char has_light_weap; + _BYTE gapCE5[2]; + char is_light_weap; + int field_CE8; + gun_desc *heavy_guns; + int field_CF0; + int field_CF4; + int field_CF8; + int field_CFC; + int field_D00; + int field_D04; + int field_D08; + int field_D0C; + int field_D10; + int field_D14; + int field_D18; + int field_D1C; + int field_D20; + int field_D24; + int field_D28; + int field_D2C; + int field_D30; + int field_D34; + int field_D38; + int field_D3C; + int field_D40; + int field_D44; + int field_D48; + int field_D4C; + int field_D50; + int field_D54; + int field_D58; + int field_D5C; + int field_D60; + int field_D64; + int field_D68; + int field_D6C; + int field_D70; + int field_D74; + int field_D78; + int field_D7C; + int field_D80; + int field_D84; + int field_D88; + int field_D8C; + int field_D90; + int field_D94; + int field_D98; + int field_D9C; + int field_DA0; + int field_DA4; + int field_DA8; + int field_DAC; + int field_DB0; + int field_DB4; + int field_DB8; + int field_DBC; + int field_DC0; + int field_DC4; + int field_DC8; + int field_DCC; + int heavy_gun_id; + int field_DD4; + int field_DD8; + int field_DDC; + int field_DE0; + int field_DE4; + int field_DE8; + int field_DEC; + int field_DF0; + int field_DF4; + int field_DF8; + int field_DFC; + gun_desc *heavy_gun_desc_guessed; + int field_E04; + int field_E08; + int field_E0C; + int field_E10; + int field_E14; + int field_E18; + int field_E1C; + int field_E20; + int field_E24; + float current_heavy_ammo_guessed; + char has_heavy_gun; + _BYTE gapE2D[2]; + char field_E2F; + int field_E30; + int field_E34; + int field_E38; + int field_E3C; + int field_E40; + int field_E44; + int field_E48; + int field_E4C; + int field_E50; + int field_E54; + int field_E58; + int field_E5C; + int field_E60; + int field_E64; + int field_E68; + int field_E6C; + int field_E70; + int field_E74; + int field_E78; + int field_E7C; + int field_E80; + int field_E84; + int field_E88; + int field_E8C; + int field_E90; + int field_E94; + int field_E98; + int field_E9C; + int field_EA0; + int field_EA4; + int field_EA8; + int field_EAC; + int field_EB0; + int field_EB4; + int field_EB8; + int field_EBC; + int field_EC0; + int field_EC4; + int field_EC8; + int field_ECC; + int field_ED0; + int field_ED4; + int field_ED8; + int field_EDC; + int field_EE0; + int field_EE4; + int field_EE8; + int field_EEC; + int field_EF0; + int field_EF4; + int field_EF8; + int field_EFC; + int field_F00; + int field_F04; + int field_F08; + int field_F0C; + int field_F10; + int field_F14; + int field_F18; + int field_F1C; + int field_F20; + int field_F24; + int field_F28; + int field_F2C; + int field_F30; + int field_F34; + int field_F38; + int field_F3C; + int field_F40; + int field_F44; + int field_F48; + int field_F4C; + int field_F50; + int field_F54; + int field_F58; + int field_F5C; + int field_F60; + int field_F64; + int field_F68; + int field_F6C; + int field_F70; + int field_F74; + int field_F78; + int field_F7C; + int field_F80; + int field_F84; + int field_F88; + int field_F8C; + int field_F90; + int field_F94; + int field_F98; + int field_F9C; + int field_FA0; + int field_FA4; + int field_FA8; + int field_FAC; + int field_FB0; + int field_FB4; + int field_FB8; + int field_FBC; + int field_FC0; + int field_FC4; + int field_FC8; + int field_FCC; + int field_FD0; + int field_FD4; + int field_FD8; + int field_FDC; + int field_FE0; + int field_FE4; + int field_FE8; + int field_FEC; + int field_FF0; + int field_FF4; + int field_FF8; + int field_FFC; + int field_1000; + int field_1004; + int field_1008; + int field_100C; + int field_1010; + int field_1014; + int field_1018; + int field_101C; + int field_1020; + int field_1024; + int field_1028; + int field_102C; + int field_1030; + int field_1034; + int field_1038; + int field_103C; + int field_1040; + int field_1044; + int field_1048; + int field_104C; + int field_1050; + int field_1054; + int field_1058; + int field_105C; + int field_1060; + int field_1064; + int field_1068; + int field_106C; + int field_1070; + int field_1074; + int field_1078; + int field_107C; + int field_1080; + int field_1084; + int field_1088; + int field_108C; + int field_1090; + int field_1094; + int field_1098; + int field_109C; + int field_10A0; + int field_10A4; + int field_10A8; + int field_10AC; + int field_10B0; + int field_10B4; + int field_10B8; + int field_10BC; + int field_10C0; + int field_10C4; + int field_10C8; + int field_10CC; + int field_10D0; + int field_10D4; + int field_10D8; + int field_10DC; + int field_10E0; + int field_10E4; + int field_10E8; + int field_10EC; + int field_10F0; + int field_10F4; + int field_10F8; + int field_10FC; + int field_1100; + int field_1104; + int field_1108; + int field_110C; + int field_1110; + int field_1114; + int field_1118; + int field_111C; + int field_1120; + int field_1124; + int field_1128; + int field_112C; + int field_1130; + int field_1134; + int field_1138; + int field_113C; + int field_1140; + int field_1144; + int field_1148; + int field_114C; + int field_1150; + int field_1154; + int field_1158; + int field_115C; + int field_1160; + int field_1164; + int field_1168; + int field_116C; + int field_1170; + int field_1174; + int field_1178; + int field_117C; + int field_1180; + int field_1184; + int field_1188; + int field_118C; + int field_1190; + int field_1194; + int field_1198; + int field_119C; + int field_11A0; + int field_11A4; + int field_11A8; + int field_11AC; + int field_11B0; + int field_11B4; + int field_11B8; + int field_11BC; + int field_11C0; + int field_11C4; + int field_11C8; + int field_11CC; + int field_11D0; + int field_11D4; + int field_11D8; + int field_11DC; + int field_11E0; + int field_11E4; + int field_11E8; + int field_11EC; + int field_11F0; + int field_11F4; + int field_11F8; + int field_11FC; + int field_1200; + int field_1204; + int field_1208; + int field_120C; + int field_1210; + int field_1214; + int field_1218; + int field_121C; + int field_1220; + int field_1224; + int field_1228; + int field_122C; + int field_1230; + int field_1234; + int field_1238; + int field_123C; + int field_1240; + int field_1244; + int field_1248; + int field_124C; + int field_1250; + int field_1254; + int field_1258; + int field_125C; + int field_1260; + int field_1264; + int field_1268; + int field_126C; + int field_1270; + int field_1274; + int field_1278; + int field_127C; + int field_1280; + int field_1284; + int field_1288; + int field_128C; + int field_1290; + int field_1294; + int field_1298; + int field_129C; + int field_12A0; + int field_12A4; + int field_12A8; + int field_12AC; + int field_12B0; + int field_12B4; + int field_12B8; + int field_12BC; + int field_12C0; + int field_12C4; + int field_12C8; + int field_12CC; + int field_12D0; + int field_12D4; + int field_12D8; + int field_12DC; + int field_12E0; + int field_12E4; + int field_12E8; + int field_12EC; + int field_12F0; + int field_12F4; + int field_12F8; + int field_12FC; + int field_1300; + int field_1304; + int field_1308; + int field_130C; + int field_1310; + int field_1314; + int field_1318; + int field_131C; + int field_1320; + int field_1324; + int field_1328; + int field_132C; + int field_1330; + int field_1334; + int field_1338; + int field_133C; + int field_1340; + int field_1344; + int field_1348; + int field_134C; + int field_1350; + int field_1354; + int field_1358; + int field_135C; + int field_1360; + int field_1364; + int field_1368; + int field_136C; + int field_1370; + int field_1374; + int field_1378; + int field_137C; + int field_1380; + int field_1384; + int field_1388; + int field_138C; + int field_1390; + int field_1394; + int field_1398; + int field_139C; + int field_13A0; + int field_13A4; + int field_13A8; + int field_13AC; + int field_13B0; + int field_13B4; + int field_13B8; + int field_13BC; + int field_13C0; + int field_13C4; + int field_13C8; + int field_13CC; + int field_13D0; + int field_13D4; + int field_13D8; + int field_13DC; + int field_13E0; + int field_13E4; + int field_13E8; + int field_13EC; + int field_13F0; + int field_13F4; + int field_13F8; + int field_13FC; + int field_1400; + int field_1404; + int field_1408; + int field_140C; + int field_1410; + int field_1414; + int field_1418; + int field_141C; + int field_1420; + int field_1424; + int field_1428; + int field_142C; + int field_1430; + int field_1434; + int field_1438; + int field_143C; + int field_1440; + int field_1444; + int field_1448; + int field_144C; +}; + +/* 89 */ +struct CEquipment_vtable1 +{ + CEquipment_vtable1 *field_0; + equipment1 *(__thiscall *apply_weight)(player_equipment *this, id_and_name name_4); + int field_8; + int field_C; +}; + +/* 93 */ +struct glider +{ + id_and_name model_id; + int field_20; + int field_24; + int field_28; + int field_2C; + int field_30; + int field_34; + int field_38; + int field_3C; + int field_40; + int field_44; + int field_48; + int field_4C; + int field_50; + int field_54; + int field_58; + int field_5C; + float weight; + float maxweight; + int standard; + float damage; + float resfront; + float resside; + float restop; + float turbulence; + float stabfront; + float stabside; + float rotatespeed; + float careen; + float deltat; + int field_94; + int field_98; + int field_9C; + int field_A0; + int field_A4; + int field_A8; + int field_AC; + int field_B0; + int field_B4; + int field_B8; + int field_BC; + int field_C0; + int field_C4; + int field_C8; + float field_CC; + int field_D0; + int field_D4; + int field_D8; + int field_DC; + int field_E0; + int field_E4; + int field_E8; + int field_EC; + int field_F0; + int field_F4; + int field_F8; + int field_FC; + int field_100; + int field_104; + int field_108; + int field_10C; + int field_110; + int field_114; + int field_118; + int field_11C; + int field_120; + int field_124; + int field_128; + int field_12C; + int field_130; + int field_134; + int field_138; + int field_13C; + int field_140; + int field_144; + int field_148; + int field_14C; + int field_150; + int field_154; + int field_158; + int field_15C; + int field_160; + int field_164; + int field_168; + int field_16C; + int field_170; + int field_174; + int field_178; + int field_17C; + int field_180; + float price; + float restore; + char can_have_light_weap; + char can_have_heavy_weap; + int field_190; + int field_194; + int field_198; + int field_19C; + int field_1A0; + int field_1A4; + int field_1A8; + int field_1AC; + int field_1B0; + int field_1B4; + int field_1B8; + int field_1BC; + int field_1C0; + int field_1C4; + int field_1C8; + int field_1CC; + int field_1D0; + int field_1D4; + int field_1D8; + int field_1DC; + int field_1E0; + int field_1E4; + int field_1E8; + int field_1EC; + int field_1F0; + int field_1F4; + int field_1F8; + int field_1FC; + int field_200; + int field_204; + int field_208; + int field_20C; + int field_210; +}; + +/* 87 */ +struct CEquipment +{ + CEquipment_vtable1 *vtable; + void (__thiscall *glider_vtable_or_some_func)(CEquipment **); + int field_8; + int field_C; + int field_10; + int field_14; + int field_18; + int field_1C; + int field_20; + int field_24; + int field_28; + int field_2C; + int field_30; + int field_34; + int field_38; + int field_3C; + int field_40; + int field_44; + int field_48; + int field_4C; + int field_50; + int field_54; + int field_58; + int field_5C; + int field_60; + int field_64; + int field_68; + int field_6C; + int field_70; + int field_74; + int field_78; + int field_7C; + int field_80; + int field_84; + int field_88; + int field_8C; + int field_90; + int field_94; + int field_98; + int field_9C; + int field_A0; + int field_A4; + int field_A8; + int field_AC; + int field_B0; + int field_B4; + int field_B8; + int field_BC; + int field_C0; + int field_C4; + int field_C8; + int field_CC; + int field_D0; + int field_D4; + int field_D8; + int field_DC; + int field_E0; + int field_E4; + int field_E8; + int field_EC; + int field_F0; + int field_F4; + int field_F8; + int field_FC; + int field_100; + int field_104; + int field_108; + int field_10C; + int field_110; + int field_114; + int field_118; + int field_11C; + int field_120; + int field_124; + int field_128; + int field_12C; + int field_130; + int field_134; + int field_138; + int field_13C; + int field_140; + int field_144; + int field_148; + int field_14C; + int field_150; + int field_154; + int field_158; + int field_15C; + int field_160; + int field_164; + int field_168; + int field_16C; + int field_170; + int field_174; + int field_178; + int field_17C; + int field_180; + int field_184; + int field_188; + int field_18C; + int field_190; + int field_194; + int field_198; + int field_19C; + int field_1A0; + int field_1A4; + int field_1A8; + int field_1AC; + int field_1B0; + int field_1B4; + int field_1B8; + int field_1BC; + int field_1C0; + int field_1C4; + int field_1C8; + int field_1CC; + int field_1D0; + int field_1D4; + int field_1D8; + int field_1DC; + int field_1E0; + int field_1E4; + int field_1E8; + int field_1EC; + int field_1F0; + int field_1F4; + int field_1F8; + int field_1FC; + int field_200; + int field_204; + int field_208; + int field_20C; + int field_210; + int field_214; + int field_218; + int field_21C; + int field_220; + int field_224; + int field_228; + int field_22C; + int field_230; + int field_234; + int field_238; + int field_23C; + int field_240; + int field_244; + int field_248; + int field_24C; + int field_250; + int field_254; + int field_258; + int field_25C; + int field_260; + int field_264; + int field_268; + int field_26C; + int field_270; + int field_274; + int field_278; + int field_27C; + int field_280; + int field_284; + int field_288; + int field_28C; + int field_290; + int field_294; + int field_298; + int field_29C; + int field_2A0; + int field_2A4; + int field_2A8; + int field_2AC; + int field_2B0; + int field_2B4; + int field_2B8; + int field_2BC; + int field_2C0; + int field_2C4; + int field_2C8; + int field_2CC; + int field_2D0; + int field_2D4; + int field_2D8; + int field_2DC; + int field_2E0; + int field_2E4; + int field_2E8; + int field_2EC; + int field_2F0; + int field_2F4; + int field_2F8; + int field_2FC; + int field_300; + int field_304; + int field_308; + int field_30C; + int field_310; + int field_314; + int field_318; + int field_31C; + int field_320; + int field_324; + int field_328; + int field_32C; + int field_330; + int field_334; + int field_338; + int field_33C; + int field_340; + int field_344; + int field_348; + int field_34C; + int field_350; + int field_354; + int field_358; + int field_35C; + int field_360; + int field_364; + int field_368; + int field_36C; + int field_370; + int field_374; + int field_378; + int field_37C; + int field_380; + int field_384; + int field_388; + int field_38C; + int field_390; + int field_394; + int field_398; + int field_39C; + int field_3A0; + int field_3A4; + int field_3A8; + int field_3AC; + int field_3B0; + int field_3B4; + int field_3B8; + int field_3BC; + int field_3C0; + int field_3C4; + int field_3C8; + int field_3CC; + int field_3D0; + int field_3D4; + int field_3D8; + int field_3DC; + int field_3E0; + int field_3E4; + int field_3E8; + int field_3EC; + int field_3F0; + int field_3F4; + int field_3F8; + int field_3FC; + int field_400; + int field_404; + int field_408; + int field_40C; + int field_410; + int field_414; + int field_418; + int field_41C; + int field_420; + int field_424; + int field_428; + int field_42C; + int field_430; + int field_434; + int field_438; + int field_43C; + int field_440; + int field_444; + int field_448; + int field_44C; + int field_450; + int field_454; + int field_458; + int field_45C; + int field_460; + int field_464; + int field_468; + int field_46C; + int field_470; + int field_474; + int field_478; + int field_47C; + int field_480; + int field_484; + int field_488; + int field_48C; + int field_490; + int field_494; + int field_498; + int field_49C; + int field_4A0; + int field_4A4; + int field_4A8; + int field_4AC; + int field_4B0; + int field_4B4; + int field_4B8; + int field_4BC; + int field_4C0; + int field_4C4; + int field_4C8; + int field_4CC; + int field_4D0; + int field_4D4; + int field_4D8; + int field_4DC; + int field_4E0; + int field_4E4; + int field_4E8; + int field_4EC; + int field_4F0; + int field_4F4; + int field_4F8; + int field_4FC; + int field_500; + int field_504; + int field_508; + int field_50C; + int field_510; + int field_514; + int field_518; + int field_51C; + int field_520; + int field_524; + int field_528; + int field_52C; + int field_530; + int field_534; + int field_538; + int field_53C; + int field_540; + int field_544; + int field_548; + int field_54C; + int field_550; + int field_554; + int field_558; + int field_55C; + int field_560; + int field_564; + int field_568; + int field_56C; + int field_570; + int field_574; + int field_578; + int field_57C; + int field_580; + int field_584; + int field_588; + int field_58C; + int field_590; + int field_594; + int field_598; + int field_59C; + int field_5A0; + int field_5A4; + int field_5A8; + int field_5AC; + int field_5B0; + int field_5B4; + int field_5B8; + int field_5BC; + int field_5C0; + int field_5C4; + int field_5C8; + int field_5CC; + int field_5D0; + int field_5D4; + int field_5D8; + int field_5DC; + int field_5E0; + int field_5E4; + int field_5E8; + int field_5EC; + int field_5F0; + int field_5F4; + int field_5F8; + int field_5FC; + int field_600; + int field_604; + int field_608; + int field_60C; + int field_610; + int field_614; + int field_618; + int field_61C; + int field_620; + int field_624; + int field_628; + int field_62C; + int field_630; + int field_634; + int field_638; + int field_63C; + int field_640; + int field_644; + int field_648; + int field_64C; + int field_650; + int field_654; + int field_658; + int field_65C; + int field_660; + int field_664; + int field_668; + int field_66C; + int field_670; + int field_674; + int field_678; + int field_67C; + int field_680; + int field_684; + int field_688; + int field_68C; + int field_690; + int field_694; + int field_698; + int field_69C; + int field_6A0; + int field_6A4; + int field_6A8; + int field_6AC; + int field_6B0; + int field_6B4; + int field_6B8; + int field_6BC; + int field_6C0; + int field_6C4; + int field_6C8; + int field_6CC; + int field_6D0; + int field_6D4; + int field_6D8; + int field_6DC; + int field_6E0; + int field_6E4; + int field_6E8; + int field_6EC; + int field_6F0; + int field_6F4; + int field_6F8; + int field_6FC; + int field_700; + int field_704; + int field_708; + int field_70C; + int field_710; + int field_714; + int field_718; + int field_71C; + int field_720; + int field_724; + int field_728; + int field_72C; + int field_730; + int field_734; + int field_738; + int field_73C; + int field_740; + int field_744; + int field_748; + int field_74C; + int field_750; + int field_754; + int field_758; + int field_75C; + int field_760; + int field_764; + int field_768; + int field_76C; + int field_770; + int field_774; + int field_778; + int field_77C; + int field_780; + int field_784; + int field_788; + int field_78C; + int field_790; + int field_794; + int field_798; + int field_79C; + int field_7A0; + int field_7A4; + int field_7A8; + int field_7AC; + int field_7B0; + int field_7B4; + int field_7B8; + int field_7BC; + int field_7C0; + int field_7C4; + int field_7C8; + int field_7CC; + int field_7D0; + int field_7D4; + int field_7D8; +}; + +/* 119 */ +enum weapon_type +{ + light = 0x0, + heavy = 0x1, + rocket_launcher = 0x2, + rocket = 0x3, +}; + +/* 113 */ +struct gun_desc +{ + int count; + char name[32]; + char fx_name[32]; + int standard; + weapon_type type; + int field_4C; + int field_50; + int field_54; + int field_58; + int field_5C; + int field_60; + int field_64; + int field_68; + int field_6C; + int field_70; + int field_74; + int field_78; + int field_7C; + int field_80; + int field_84; + int field_88; + int field_8C; + int field_90; + int field_94; + int field_98; + int field_9C; + int field_A0; + int field_A4; + int field_A8; + int field_AC; + int field_B0; + int field_B4; + int field_B8; + int field_BC; + int field_C0; + int field_C4; + int field_C8; + int field_CC; + int field_D0; + int field_D4; + int field_D8; + int field_DC; + int field_E0; + int field_E4; + int field_E8; + int field_EC; + int field_F0; + int field_F4; + int field_F8; + int field_FC; + int field_100; + int field_104; + int field_108; + float some_modificator; + int field_110; + char name2[32]; + char field_134[32]; + char name3[32]; + char field_174; + char field_175; + char field_176; + char field_177; + char field_178; + char field_179; + char field_17A; + char field_17B; + char field_17C; + char field_17D; + char field_17E; + char field_17F; + char field_180; + char field_181; + char field_182; + char field_183; + char field_184; + char field_185; + char field_186; + char field_187; + char field_188; + char field_189; + char field_18A; + char field_18B; + char field_18C; + char field_18D; + char field_18E; + char field_18F; + float damage; + char field_194; + char field_195; + char field_196; + char field_197; + float field_198; + float max_ammo_amount; + float field_1A0; + char field_1A4; + char field_1A5; + char field_1A6; + char field_1A7; + char field_1A8; + char field_1A9; + char field_1AA; + char field_1AB; + char guntype; + char field_1AD; + char field_1AE; + char field_1AF; + float price; + char field_1B4; + char field_1B5; + char field_1B6; + char field_1B7; + char field_1B8; + char field_1B9; + char field_1BA; + char field_1BB; + float weight; + char field_1C0; + char field_1C1; + char field_1C2; + char field_1C3; +}; + +/* 83 */ +struct equipment1 +{ + int type; + float weight; + int standard; + int unk; + char name[32]; + float value1; + float value2; + float value3; +}; + diff --git a/examples/my_mod.cpp b/examples/mods/aim1_community_fix/my_mod.cpp similarity index 67% rename from examples/my_mod.cpp rename to examples/mods/aim1_community_fix/my_mod.cpp index 5aabfff..af35986 100644 --- a/examples/my_mod.cpp +++ b/examples/mods/aim1_community_fix/my_mod.cpp @@ -12,6 +12,9 @@ deps: pub.lzwdgc.Polygon4.Tools.aim1_mod_maker-master * You can also distribute mod archive (requires 7z program). **/ +#define AIM_TYPES_FILE_NAME "aim.exe.h" +#define INJECTIONS_FILE_NAME "aim.exe.fixes.h" + #ifndef INJECTED_DLL #include "aim1_mod_maker.h" @@ -19,7 +22,7 @@ deps: pub.lzwdgc.Polygon4.Tools.aim1_mod_maker-master // patch note: lz, Solant, Streef // patch note: // patch note: Description -// patch note: This mod fixes some issues with the original AIM v1.04 game. +// patch note: This mod fixes some issues with the original AIM v1.06 (DRM-free) (1.0.6.3) game. // patch note: // patch note: Installation // patch note: Unpack and drop all files near original aim.exe. Replace files if necessary. @@ -27,6 +30,16 @@ deps: pub.lzwdgc.Polygon4.Tools.aim1_mod_maker-master int main(int argc, char *argv[]) { mod_maker mod; + mod.files_to_distribute.insert(INJECTIONS_FILE_NAME); + mod.files_to_distribute.insert(AIM_TYPES_FILE_NAME); + + // patch note: enable double weap gliders (still have many bugs related) + mod.make_injection(0x004072FA); // can trade for buy purposes + mod.make_injection(0x004D62E4); // setup proper weapon slots for a glider + mod.make_injection(0x00417A6D); // put weapon into the right slot after purchase + mod.make_injection(0x004176BC); // sell correct weapon + mod.make_injection(0x004067C4); // empty light weap + mod.make_injection(0x0040688B); // empty heavy weap // patch note: CHANGES // patch note: @@ -65,7 +78,6 @@ int main(int argc, char *argv[]) { // patch note: // patch note: Script Changes - // patch note: _ISGLIDER() function can check exact glider name now, for example _ISGLIDER(GL_M3_A_FIRST1) (lz) // patch note: fix joining First Ones having one of four required gliders (lz, Streef) mod.replace("ORG_FIRST.scr", "IF(_PLAYERHAS(GL_M3_A_FIRST1)||_PLAYERHAS(GL_M3_A_FIRST1))", @@ -77,24 +89,30 @@ int main(int argc, char *argv[]) { mod.replace("ORG_SINIGR.scr", "IF(_PLAYERHAS(GL_S2_PA_SINYGR)|_PLAYERHAS(GL_S4_S_SINYGR))", "IF(_ISGLIDER(GL_S2_PA_SINYGR)|_ISGLIDER(GL_S4_S_SINYGR))"); + + // patch note: _ISGLIDER() function can check exact glider name now, for example _ISGLIDER(GL_M3_A_FIRST1) (lz) + mod.make_injection(0x0043A1F6, 10); + // + + // end of scripts section // patch note: - /*mod.replace("Script/bin/B_L1_BASE1.scr", "_ADDBALANCE(300)", R"( + mod.replace("Script/bin/B_L1_BASE1.scr", "_ADDBALANCE(300)", R"( _ADDBALANCE(300 ) - _ADDOBJECT(GL_M3_PA_EYEDSTONE) + _ADDOBJECT(GL_S3_PS_FINDER1) _ADDOBJECT(EQP_VACUUM_DRIVE_S3) _ADDOBJECT(EQP_ZERO_ARMOR_S3) _ADDOBJECT(EQP_SHIELD_GENERATOR4_S3) - _ADDOBJECT(GL_M4_S_FIRST2) - _ADDOBJECT(EQP_VACUUM_DRIVE_S4) + //_ADDOBJECT(GL_M4_S_FIRST2) + //_ADDOBJECT(EQP_VACUUM_DRIVE_S4) //_ADDOBJECT(EQP_MEZON_REACTOR_S4) //_ADDOBJECT(EQP_GLUON_REACTOR_S1) - _ADDOBJECT(EQP_ZERO_ARMOR_S4) - _ADDOBJECT(EQP_SHIELD_GENERATOR4_S4) - _ADDOBJECT(GUN_MICROWAVE_OSCILLATOR) - _ADDOBJECT(GUN_RAILGUN) + //_ADDOBJECT(EQP_ZERO_ARMOR_S4) + //_ADDOBJECT(EQP_SHIELD_GENERATOR4_S4) + //_ADDOBJECT(GUN_MICROWAVE_OSCILLATOR) + //_ADDOBJECT(GUN_RAILGUN) _ADDRATING(300000000) _ADDBALANCE(30000000) @@ -115,7 +133,7 @@ int main(int argc, char *argv[]) { _SETEVENT(SECTOR7.ACCESS) //_SETEVENT(SECTOR8.VISIT) _SETEVENT(SECTOR8.ACCESS) -)");*/ +)"); // patch note: Release Manager // patch note: lz @@ -144,100 +162,5 @@ int main(int argc, char *argv[]) { } #else // INJECTED_DLL - -#include -#include - -constexpr auto call_command_length = 5; - -enum aim1_fix : uint32_t { - script_function__ISGLIDER = 0x0043A1F6, -}; -uint32_t known_caller; - -__declspec(naked) void fix_script_function__ISGLIDER() { - __asm { - ; restore values - popad - pushad - - mov edi, eax; my glider - mov esi, [esp + 20h + 4 + 8 * 4]; arg - - label_cmp : - mov al, [edi] - mov cl, [esi] - cmp al, cl - jne bad - cmp al, 0 - je end - cmp cl, 0 - je end - inc edi - inc esi - jmp label_cmp - end : - cmp al, cl - jne bad - popad - ; push some regs as required by success branch - push ebx - push ebp - push esi - push edi - push 0x0043A2DA - ret - - bad : - popad - ; popf - ; original thunk - copy : - mov cl, [eax]; injection point - inc eax - mov[edx], cl - inc edx - test cl, cl - jnz copy - - ; epilogue - push known_caller - ret - } -} - -extern "C" __declspec(dllexport) __declspec(naked) void dispatcher() { - __asm { - pop known_caller - pushad - } - switch (known_caller - call_command_length) { - case aim1_fix::script_function__ISGLIDER: - known_caller += 0xA - call_command_length; // make normal ret - __asm jmp fix_script_function__ISGLIDER - break; - default: - break; - } - // just return - __asm { - popa - push known_caller - ret - } -} - -void setup() { - constexpr uint32_t free_data_base = 0x006929C0; - auto mem = (uint8_t *)free_data_base; - mem[0] = 0xE9; - *(uint32_t *)&mem[1] = (uint32_t)&dispatcher - free_data_base - call_command_length; -} -BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID) { - if (fdwReason == DLL_PROCESS_ATTACH) { - setup(); - } - return TRUE; -} - +#include INJECTIONS_FILE_NAME #endif diff --git a/src/aim1_mod_maker/aim1_mod_maker.h b/src/aim1_mod_maker/aim1_mod_maker.h index 8db8286..32a9446 100644 --- a/src/aim1_mod_maker/aim1_mod_maker.h +++ b/src/aim1_mod_maker/aim1_mod_maker.h @@ -51,6 +51,18 @@ auto operator""_bin(const char *ptr, uint64_t len) { return ret; } +struct aim_exe_v1_06_constants { + enum : uint32_t { + trampoline_base_real = 0x00025100, + trampoline_target_real = 0x001207f0, + //code_base = 0x00401000, + //data_base = 0x00540000, + //free_data_base_virtual = 0x006929C0, + free_data_base_virtual = 0x00692FF0, + our_code_start_virtual = 0x005207F0, // place to put out dll load + }; +}; + struct mod_maker { enum class file_type { unknown, @@ -164,6 +176,24 @@ struct mod_maker { return patch_raw(fn, offset, oldval, val); } + // all you need is to provide injection address (virtual) with size + // handle the call instruction in 'dispatcher' symbol (naked) of your dll + constexpr static inline auto call_command_length = 5; + void make_injection(uint32_t virtual_address, uint32_t size = call_command_length) { + uint32_t len = size; + if (len < call_command_length) { + throw std::runtime_error{"jumppad must be 5 bytes atleast"}; + } + primitives::templates2::mmap_file f{find_real_filename(aim_exe), + primitives::templates2::mmap_file::rw{}}; + auto ptr = f.p + virtual_address - aim_exe_v1_06_constants::our_code_start_virtual + aim_exe_v1_06_constants::trampoline_target_real; + memcpy(ptr, make_insn_with_address("e8"_bin, aim_exe_v1_06_constants::free_data_base_virtual - + (virtual_address + call_command_length))); + memcpy(ptr, make_nops(len - call_command_length)); + std::println("making injection on the virtual address 0x{:0X} (real address 0x{:0X}), size {}", virtual_address, ptr - f.p, + size); + } + #define ENABLE_DISABLE_FUNC(name, enable, disable) \ void enable_##name() { name(enable); } \ void disable_##name() { name(disable); } @@ -226,7 +256,7 @@ private: *(uint32_t *)(&arr[insn.size()]) = addr; return arr; } - static auto make_nops(uint32_t len) { + static byte_array make_nops(uint32_t len) { byte_array arr(len, 0x90); return arr; } @@ -279,28 +309,26 @@ private: make_injected_dll(); files_to_distribute.insert(aim_exe); primitives::templates2::mmap_file f{find_real_filename(aim_exe), primitives::templates2::mmap_file::rw{}}; - constexpr uint32_t trampoline_base = 0x00025100; - constexpr uint32_t trampoline_target = 0x001207f0; - constexpr uint32_t code_base = 0x00401000; - constexpr uint32_t data_base = 0x00540000; - constexpr uint32_t free_data_base = 0x006929C0; - //constexpr uint32_t our_data = 0x00550FD0; - const uint32_t our_data_start = 0x005207F0; - uint32_t our_data = 0x005207F0; - //constexpr uint32_t free_data_base_real = 0x140000 + our_data - 0x00540000; + uint32_t our_data = aim_exe_v1_06_constants::our_code_start_virtual; - auto ptr = f.p + trampoline_target; - //strcpy((char *)f.p + free_data_base_real, get_dll_name().c_str()); - strcpy((char *)ptr, get_dll_name().c_str()); + auto ptr = f.p + aim_exe_v1_06_constants::trampoline_target_real; +#ifdef NDEBUG + auto dllnamelen = get_sw_dll_name().size() + 1; + strcpy((char *)ptr, get_sw_dll_name().c_str()); +#else + auto dllname = "h:\\Games\\AIM\\1\\.sw\\out\\d\\aim_fixes-0.0.1.dll"s; + auto dllnamelen = dllname.size() + 1; + strcpy((char *)ptr, dllname.c_str()); +#endif + ptr += dllnamelen; auto push_dll_name = make_insn_with_address("68"_bin, our_data); // push - ptr += 0x20; our_data += 0x20; strcpy((char *)ptr, "dispatcher"); auto dispatcher_func_name = make_insn_with_address("68"_bin, our_data); // push ptr += 0x20; our_data += 0x20; const auto jumppad = "68 30 B8 51 00"_bin; // push offset SEH_425100 - uint32_t jump_offset = ptr - f.p - trampoline_base - jumppad.size() * 2; + uint32_t jump_offset = ptr - f.p - aim_exe_v1_06_constants::trampoline_base_real - jumppad.size() * 2; memreplace(f.p, f.sz, jumppad, make_insn_with_address("e9"_bin, jump_offset)); memcpy(ptr, jumppad); // put our removed insn memcpy(ptr, R"( @@ -331,15 +359,7 @@ FF D7 ; call edi memcpy(ptr, R"( 61 ; popa )"_bin); - memcpy(ptr, make_insn_with_address("e9"_bin, -(ptr - f.p - trampoline_base - jumppad.size()))); - - // E8 C5 87 25 00 - constexpr auto call_command_length = 5; - uint32_t start_addr = 0x0043A1F6; - uint32_t len = 10; - ptr = f.p + start_addr - our_data_start + trampoline_target; - memcpy(ptr, make_insn_with_address("e8"_bin, free_data_base - (start_addr + call_command_length))); - memcpy(ptr, make_nops(len - call_command_length)); + memcpy(ptr, make_insn_with_address("e9"_bin, -(ptr - f.p - aim_exe_v1_06_constants::trampoline_base_real - jumppad.size()))); } path find_real_filename(path fn) const { auto s = fn.wstring(); diff --git a/src/common/common.natvis b/src/common/common.natvis index e36c1e9..6b00581 100644 --- a/src/common/common.natvis +++ b/src/common/common.natvis @@ -22,4 +22,43 @@ + + + n_tables + n_fields + + n_tables + (db2::tab::table*)(&n_fields+1) + + + n_fields + (db2::tab::field*)((db2::tab::table*)(&n_fields+1)+n_tables) + + + + + + {id},{name,s} + + + + + {table_id},{id},{name,s},{type} + + + + + n_values + + n_values + (db2::value*)(&n_values+1) + + + + + + {table_id},{name,s} + + + diff --git a/src/common/types.h b/src/common/types.h index 2a93aff..072b12c 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -183,7 +183,7 @@ struct Good }; std::string name; - char unk1[0x40]; + char condition_variable[0x40]; // when this var is set, we can access the good float unk1_2 = 0; float price = 0; // unk, quantity? float unk2[10]; @@ -199,7 +199,7 @@ struct Good { READ_STRING(b, name); if (gameType == GameType::Aim1) - READ(b, unk1); + READ(b, condition_variable); else READ(b, unk1_2); READ(b, price); diff --git a/sw.cpp b/sw.cpp index 23c36bc..005dbab 100644 --- a/sw.cpp +++ b/sw.cpp @@ -8,10 +8,13 @@ void build(Solution &s) auto cppstd = cpp23; auto &common = tools.addStaticLibrary("common"); - common += cppstd; - common.setRootDirectory("src/common"); - common.Public += "pub.egorpugin.primitives.filesystem"_dep; - common.Public += "pub.egorpugin.primitives.templates2"_dep; + { + common += cppstd; + common.setRootDirectory("src/common"); + common += ".*"_rr; + common.Public += "pub.egorpugin.primitives.filesystem"_dep; + common.Public += "pub.egorpugin.primitives.templates2"_dep; + } auto add_exe_base = [&](const String &name) -> decltype(auto) { @@ -73,16 +76,16 @@ void build(Solution &s) ; } - auto &aim1_mod_maker = tools.addStaticLibrary("aim1_mod_maker"); + auto &aim1_mod_maker = add_exe_with_common("aim1_mod_maker"); // actually a library + aim1_mod_maker.Public += "pub.egorpugin.primitives.command"_dep; + + auto &aim1_community_fix = tools.addExecutable("examples.mods.aim1_community_fix"); { - auto &t = aim1_mod_maker; - auto name = "aim1_mod_maker"; + auto &t = aim1_community_fix; t.PackageDefinitions = true; t += cppstd; - t.setRootDirectory("src/"s + name); - //t.Public += "pub.egorpugin.primitives.sw.main"_dep; - t.Public += "pub.egorpugin.primitives.command"_dep; - t.Public += common; + t += "examples/mods/aim1_community_fix/.*"_rr; + t += aim1_mod_maker; } add_exe("mod_reader") += model;