-
feanor
- Новичок
-
- Сообщения: 14
- Зарегистрирован: 15 мар 2016, 16:23
- Пол:
- Поблагодарили: 15 раз.
|
feanor » 19 мар 2019, 16:57
Если чо, по дипле - реализация двоечной механики частичного присоединения из TSW. Код на самом деле не мой, но разрешение автора получено. - Код: Выделить всё
Patcher * globalPatcher; PatcherInstance *patcher;
/* void __stdcall PatchIt (PEvent e) {
}*/
#pragma pack(push, 1) struct _HeroSpec_ { int Spec; int Spec1; int Spec2; int Spec3; int Spec4; int Spec5; int Spec6; void *SpShort; void *SpFull; void *SpDescr; }; #pragma pack(pop)
int join_coeffs[4] = { 1, 2, 3, 4 }; int dip = 0; int full_count = 0; int game_skill = 1; int price = 0; _Hero_* vision_hero = 0;
long double __stdcall NewDiplomacyHandler(HiHook* h, _Hero_* hero) { float coeffs[4] = { 0.0f, 0.2f, 0.4f, 0.6f };
int skill_level = hero->second_skill[4];
float ret = 1.0f - coeffs[skill_level];
if (hero->DoesWearArtifact(66)) { ret = 0.1f; }
return ret; }
float GetDiplomacyLevel(_Hero_* hero) { int diplo_level = hero->second_skill[4]; float join_coeffs[4] = { 0.1f, 0.2f, 0.3f, 0.4f };
float ret = join_coeffs[diplo_level];
_HeroSpec_* spec = *(_HeroSpec_**)0x679C80; if (spec[hero->id].Spec == 0 && spec[hero->id].Spec1 == 4) { ret += hero->level * 0.01f; } if (ret > 1.0f) ret = 1.0f;
return ret; }
int __stdcall MoneyJoinCount(LoHook* h, HookContext* c) { _HeroSpec_* spec = *(_HeroSpec_**)0x679C80; _Hero_* hero = *(_Hero_**)(c->ebp + 8);
int skill_level = hero->second_skill[4];
full_count = c->edi;
/*int edi = c->edi * join_coeffs[skill_level] / 10;
if (skill_level > 0) { if (spec[hero->id].Spec == 0 && spec[hero->id].Spec1 == 4) { edi += hero->level; } }*/ int edi = (int)(GetDiplomacyLevel(hero)*c->edi);
if (c->edi != 0 && edi == 0) ++edi;
if (edi <= c->edi) c->edi = edi;
return EXEC_DEFAULT; }
int __stdcall FreeJoinChance(LoHook* h, HookContext* c) { _Hero_* hero = (_Hero_*)c->edi;
dip = c->ecx; c->eax -= dip;
if (hero->DoesHasArtifact(54)) { c->esi = 10; }
return EXEC_DEFAULT; }
int __stdcall MoneyJoinChance(LoHook* h, HookContext* c) { c->ecx -= dip;
return EXEC_DEFAULT; }
int __stdcall DisableEasyBonus(LoHook* h, HookContext* c) { game_skill = *((char*)o_GameMgr + 0x1F6D8);
c->return_address = 0x4A7520;
return NO_EXEC_DEFAULT; }
int __stdcall NewEasyBonus(LoHook* h, HookContext* c) { if (!game_skill) ++c->edx;
return EXEC_DEFAULT; }
int __stdcall OneCountFix(LoHook* h, HookContext* c) { if (full_count == 1) c->return_address = 0x4A6F53; else c->return_address = 0x4A6F90;
return NO_EXEC_DEFAULT; }
/* int __stdcall EditStackMoneyJoinPrint(LoHook* h, HookContext* c) { int a1 = c->Pop(); int a2 = c->Pop(); int a3 = c->Pop();
c->Push(full_count); c->Push(a3); c->Push(a2); c->Push(a1);
return EXEC_DEFAULT; }
int __stdcall RestoreStack(LoHook* h, HookContext* c) { int a1 = c->Pop(); int a2 = c->Pop(); int a3 = c->Pop();
c->Pop(); c->Push(a3); c->Push(a2); c->Push(a1); return EXEC_DEFAULT; }*/
int __stdcall VisionGetHero(LoHook* h, HookContext* c) { vision_hero = (_Hero_*)c->esi; game_skill = *((char*)o_GameMgr + 0x1F6D8);
return EXEC_DEFAULT; }
int __stdcall VisionFreeJoinChance(LoHook* h, HookContext* c) { dip = *(int*)(c->ebp - 0x14); c->esi -= dip;
if (!game_skill) ++c->esi;
if (vision_hero->DoesHasArtifact(54)) { c->ecx = 10; }
return EXEC_DEFAULT; }
int __stdcall VisionMoneyJoinChance(LoHook* h, HookContext* c) { c->edx -= dip;
if (!game_skill) ++c->edx;
return EXEC_DEFAULT; }
int __stdcall VisionGetFullCount(LoHook* h, HookContext* c) { full_count = c->ecx;
return EXEC_DEFAULT; }
int __stdcall VisionEditStackMoneyJoinPrint(LoHook* h, HookContext* c) { _HeroSpec_* spec = *(_HeroSpec_**)0x679C80;
int a1 = c->Pop(); int a2 = c->Pop(); price = c->Pop();
int new_price = price;
/*int skill_level = vision_hero->second_skill[4];
int join_count = full_count * join_coeffs[skill_level] / 10;
if (skill_level > 0) { if (spec[vision_hero->id].Spec == 0 && spec[vision_hero->id].Spec1 == 4) { join_count += vision_hero->level; } }*/ int join_count = (int)(GetDiplomacyLevel(vision_hero)*full_count);
if (full_count != 0 && join_count == 0) ++join_count;
if (full_count <= join_count) join_count = full_count;
if (full_count != 0) new_price = new_price / full_count * join_count; else new_price = 0;
c->Push(new_price); c->Push(join_count); c->Push(a2); c->Push(a1); return EXEC_DEFAULT; }
int __stdcall VisionRestoreStack(LoHook* h, HookContext* c) { int a1 = c->Pop(); int a2 = c->Pop(); c->Pop(); c->Pop(); c->Push(price); c->Push(a2); c->Push(a1); return EXEC_DEFAULT; }
int DiploMessage(HiHook* h, int a1, int a2, int a3, int a4, int a5) { return CALL_6(int,__cdecl, h->GetOriginalFunc(), a1, a2, a3, full_count, a4, a5); }
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { if (ul_reason_for_call == DLL_PROCESS_ATTACH) { globalPatcher = GetPatcher(); patcher = globalPatcher->CreateInstance((char*)"h3sw_diplomacy"); //ConnectEra();
patcher->WriteHiHook(0x4E47F0, SPLICE_, EXTENDED_, THISCALL_, (void*)NewDiplomacyHandler); patcher->WriteLoHook(0x4A6EE8, (void*)MoneyJoinCount); patcher->WriteLoHook(0x4A7557, (void*)FreeJoinChance); patcher->WriteLoHook(0x4A75A7, (void*)MoneyJoinChance); patcher->WriteLoHook(0x4A74F4, (void*)DisableEasyBonus); patcher->WriteLoHook(0x4A7550, (void*)NewEasyBonus); patcher->WriteLoHook(0x4A6F4E, (void*)OneCountFix); // patcher->WriteLoHook(0x4A6FF1, (void*)EditStackMoneyJoinPrint); //patcher->WriteLoHook(0x4A6FFC, (void*)RestoreStack); patcher->WriteHiHook(0x4A6FF1, CALL_, EXTENDED_, CDECL_, (void*)DiploMessage);
patcher->WriteLoHook(0x417124, (void*)VisionGetHero); patcher->WriteLoHook(0x417232, (void*)VisionFreeJoinChance); patcher->WriteLoHook(0x417244, (void*)VisionMoneyJoinChance); patcher->WriteLoHook(0x52FFF1, (void*)VisionGetFullCount);
patcher->WriteLoHook(0x530134, (void*)VisionEditStackMoneyJoinPrint); patcher->WriteLoHook(0x53013C, (void*)VisionRestoreStack); //RegisterHandler(PatchIt,"OnAfterCreateWindow"); } return TRUE; }
|