-
RoseKavalier
- Мастер
-
- Сообщения: 331
- Зарегистрирован: 23 сен 2017, 17:00
- Пол:
- Поблагодарили: 234 раз.
|
RoseKavalier » 04 ноя 2017, 20:43
Seems to work fine for human, on SoD and HotA. Of course it will need to be fine-tuned (possibly make cost higher based on hero level?) and could add some extra information (like current player gold). First time creating something in DEFTool, it's not perfect but a good start I think! [youtube]http://youtu.be/MTGQ8s6pwVk[/youtube] main.cpp is below; I have added some extra things in includes which you can copy from GitHub. [removed some files per request] Compiled DLL & 2 DEF files are attached. I did not add anything for AI. - Код: Выделить всё
#include "includes\HoMM3_Extra.h"
Patcher* _P; PatcherInstance* _PI;
#pragma pack(push, 1) struct _SSkillInfo_ { char* name; char* desc[3]; }; #pragma pack(pop)
#define BID_MARKET_OF_TIME 50 #define o_SSkillInfo (*(_SSkillInfo_**)0x67DCF0) #define o_SkillLevel(level) (*(char**)(0x6A75D4 + 4 * skill_level)) #define GOLD_NAME (*(char**)0x6A5EE4) #define MARKET_OF_TIME_NAME (*(char**)0x6A7B1C)
#define COST1 2000 #define COST2 3500 #define COST3 5000
#define ENOUGH_GOLD 0 #define NOT_ENOUGH_GOLD 1
_Hero_ *hero; _Player_ *me;
void UpdateMarket(_Dlg_ *dlg, int gold) { int cost[3] = { COST1, COST2, COST3 }; _DlgStaticDef_ *SSkill; int skill_level;
for (int i = 0; i < 8; i++) { if (SSkill = (_DlgStaticDef_*)dlg->GetItem(101 + i)) { if (SSkill->def_frame_index >= 3) { skill_level = SSkill->def_frame_index % 3 + 1; if (gold < cost[skill_level - 1]) { ((_DlgStaticDef_*)(dlg->GetItem(201 + i)))->def_frame_index = NOT_ENOUGH_GOLD; ((_DlgStaticDef_*)(dlg->GetItem(301 + i)))->def_frame_index = NOT_ENOUGH_GOLD; } // not enough gold } // if this skill still exists on hero } // if SSkill } // loop }
_DlgStaticTextPcx8ed_* market_of_time_statbar; int __stdcall MarketOfTimeProc(_Dlg_* dlg, _EventMsg_* msg) { int r = dlg->DefProc(msg); char text[100]; _DlgStaticDef_ *SSkill; int skill_id, skill_level; int cost[3] = { COST1, COST2, COST3 }; text[0] = 0; if (msg->type == MT_MOUSEOVER) { // update text of status bar _DlgItem_* it = dlg->FindItem(msg->x_abs, msg->y_abs); if (it) { switch (it->id) { case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 108: SSkill = (_DlgStaticDef_*)it; if (SSkill->def_frame_index >= 3) { skill_level = SSkill->def_frame_index % 3 + 1; skill_id = SSkill->def_frame_index / 3 - 1; sprintf(text, "Forget %s %s for %d %s.", o_SkillLevel(skill_level), o_SSkillInfo[skill_id].name, cost[skill_level - 1], GOLD_NAME); } break; case DIID_OK: sprintf(text, "Exit the %s", MARKET_OF_TIME_NAME); break; default: break; } } market_of_time_statbar->SetText(text); market_of_time_statbar->Draw(); market_of_time_statbar->RedrawScreen(); } if (msg->type == MT_MOUSEBUTTON) { // handle left click of DEFs if (msg->subtype == MST_LBUTTONCLICK) { _DlgItem_* it = dlg->FindItem(msg->x_abs, msg->y_abs); if (it) { switch (it->id) { case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 108: SSkill = (_DlgStaticDef_*)it; if (SSkill->def_frame_index >= 3) { skill_level = SSkill->def_frame_index % 3 + 1; skill_id = SSkill->def_frame_index / 3 - 1; if (me->resourses.gold >= cost[skill_level - 1]) { e_ClickSound(); sprintf(o_TextBuffer, "The old man asks: 'Are you sure you want to forget this skill? This cannot be undone.'\n\nThe fee is %d %s.", cost[skill_level - 1], GOLD_NAME); CALL_12(void, __fastcall, 0x4F6C00, o_TextBuffer, MBX_OKCANCEL, -1, -1, 0x14, SSkill->def_frame_index, -1, 0, -1, 0, -1, 0); if (o_WndMgr->result_dlg_item_id == DIID_OK) { me->resourses.gold -= cost[skill_level - 1]; hero->UnlearnSkill(skill_id); SSkill->def_frame_index = 0; dlg->GetItem(it->id + 100)->Hide(); // Hide top bar dlg->GetItem(it->id + 200)->Hide(); // Hide bot bar dlg->GetItem(it->id + 300)->Hide(); // Hide SSkill name dlg->GetItem(it->id + 400)->Hide(); // Hide SSkill level UpdateMarket(dlg, me->resourses.gold); dlg->Redraw(); } } } break; default: break; } // switch } // it } // MST_LBUTTONCLICK
if (msg->subtype == MST_RBUTTONDOWN) { // show SSkill information _DlgItem_* it = dlg->FindItem(msg->x_abs, msg->y_abs); if (it) { switch (it->id) { case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 108: SSkill = (_DlgStaticDef_*)it; if (SSkill->def_frame_index >= 3) { skill_level = SSkill->def_frame_index % 3 + 1; skill_id = SSkill->def_frame_index / 3 - 1; CALL_12(void, __fastcall, 0x4F6C00, o_SSkillInfo[skill_id].desc[skill_level - 1], MBX_RMC, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0); } break; default: break; } // switch } // it } // MT_RBUTTONDOWN } // MT_MOUSEBUTTON
return r; }
void MarketOfTime(_Hero_ *hero, _Player_ *me) { // simple array that holds cost int cost[3] = { COST1, COST2, COST3 };
////////////////////// // // Creation // ////////////////////// _Dlg_ *dlg; dlg = _CustomDlg_::Create(DLG_X_CENTER, DLG_Y_CENTER, 512, 450, DF_SCREENSHOT | DF_SHADOW, MarketOfTimeProc);
// background dlg->AddItem(_DlgStaticDef_::Create(0, 0, 0, "MarketTime.def", 0, 0, 0));
// color border to player's hue CALL_5(int, __thiscall, 0x5FF400, dlg, 512, 13, 0, me->id);
// title dlg->AddItem(_DlgStaticText_::Create(0, 30, 512, 30, MARKET_OF_TIME_NAME, "bigfont.fnt", 2, 1, ALIGN_H_CENTER | ALIGN_V_CENTER, 0));
// description char* description; description = "An old bearded man beckons you over to hear him out. After a few moments, you discover that this strange place allows you to alter some of your past decisions. For a fee, you can forget any of the Secondary Skills you may have learned."; dlg->AddItem(_DlgStaticText_::Create(50, 80, 405, 64, description, "smalfont.fnt", 1, 1, ALIGN_H_CENTER | ALIGN_V_CENTER, 0));
////////////////////// // // Secondary Skills // //////////////////////
int sskill_y = 182; int sskill_x = 75; int dx = 104; int dy = 119; int bar_x = 47; int top_bar_y = 160; int bot_bar_y = 230; int sskill_count = hero->second_skill_count;
for (int i = 0; i < sskill_count; i++) { int row = i / 4; int col = i % 4; int skill = hero->ShownSSkillPosition(i + 1); int skill_level = hero->second_skill[skill]; int def_frame = 2 + 3 * skill + skill_level;
// skill def dlg->AddItem(_DlgStaticDef_::Create(sskill_x + dx * col, sskill_y + dy * row, 101 + i, "Secskill.def", def_frame, 0, 0));
// allowed/disallowed colors int allowed_disallowed = me->resourses.gold >= cost[skill_level - 1] ? ENOUGH_GOLD : NOT_ENOUGH_GOLD; dlg->AddItem(_DlgStaticDef_::Create(bar_x + dx * col, top_bar_y + dy * row, 201 + i, "MarketBars.def", allowed_disallowed, 0, 0)); dlg->AddItem(_DlgStaticDef_::Create(bar_x + dx * col, bot_bar_y + dy * row, 301 + i, "MarketBars.def", allowed_disallowed, 0, 0));
// skill name text dlg->AddItem(_DlgStaticText_::Create(bar_x + dx * col, top_bar_y + dy * row, 100, 18, o_SSkillInfo[skill].name, "smalfont.fnt", 1, 401 + i, ALIGN_H_CENTER | ALIGN_V_CENTER, 0));
// skill level text dlg->AddItem(_DlgStaticText_::Create(bar_x + dx * col, bot_bar_y + dy * row, 100, 18, o_SkillLevel(skill_level), "smalfont.fnt", 1, 501 + i, ALIGN_H_CENTER | ALIGN_V_CENTER, 0)); }
////////////////////// // // Status Bar // ////////////////////// market_of_time_statbar = _DlgStaticTextPcx8ed_::Create(8, 425, 512 - 16, 18, "", "smalfont.fnt", "HD_TStat.bmp", 1, 4000, ALIGN_H_CENTER | ALIGN_V_CENTER); dlg->AddItem(market_of_time_statbar);
////////////////////// // // Exit Button // ////////////////////// dlg->AddItem(_DlgStaticPcx8_::Create(512 / 2 - 33, 450 - 72, 1234, "Box64x30.pcx")); dlg->AddItem(_DlgButton_::Create(512 / 2 - 32, 450 - 71, 64, 30, DIID_OK, "iOkay.def", 0, 1, 1, 28, 2));
////////////////////// // // Finish up // ////////////////////// o_SoundMgr->PlaySample("HASTE.wav"); o_MouseMgr->ChangeCursor(0, 0); dlg->Run(); dlg->Destroy(TRUE); }
int __stdcall EnterMarketTime(LoHook *h, HookContext *c) { if (c->ebx == BID_MARKET_OF_TIME) { hero = (_Hero_*)c->arg_n(1); me = o_GameMgr->GetPlayer(hero->owner_id); if (c->arg_n(4)) { // human MarketOfTime(hero, me); } else { // AI
} } return EXEC_DEFAULT; }
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { static _bool_ plugin_On = 0; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: if (!plugin_On) { plugin_On = 1; _P = GetPatcher(); _PI = _P->CreateInstance("MarketOfTime"); _PI->WriteLoHook(0x4A8194, EnterMarketTime); // same spot HotA uses } break;
case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
- Вложения
-
- MarketOfTime.zip
- Beta
- (89.24 КБ) Скачиваний: 160
Последний раз редактировалось RoseKavalier 04 дек 2017, 17:27, всего редактировалось 1 раз.
|