Code:
#include "stdafx.h"
#include "..\..\include\homm3.h"
#include "..\..\include\era.h"
using namespace Era;
Patcher* _P;
PatcherInstance* _PI;
///////////////////////////////////////////////////////////////////
class Background {
  public:
    int id;
    int x;
    int y;    
    std::string pcxname;
};
class Button {
  public:    
    int id;
    int x;
    int y;    
    int caption_color;
    std::string defname;
    std::string caption_font;
    std::string caption_text;
    std::string popup_text;
    std::string hint_text;
};
class Namb {
  public:
    int qty;
    int align;
    Background *background;
    Button *buttons;
  Namb (int qty, int align) {
    this->qty = qty;
    this->align = align;
    this->background = new Background;
    this->buttons = new Button[qty];
  }
  ~Namb() {
    delete background;
    delete[] buttons;
  }
};
Namb *namb = NULL;
///////////////////////////////////////////////////////////////////
char* GetJsonStr(const char* json_string_name) {
    return tr(json_string_name);
}
int GetJsonInt(const char* json_string_name) {
    return atoi(GetJsonStr(json_string_name));
}
char* GetButtonsParamStr(int i, const char* key) {    
    sprintf(o_TextBuffer, "namb.button%d.%s", i, key);
    return GetJsonStr(o_TextBuffer);
}
int GetButtonsParamInt(int i, const char* key) {
    sprintf(o_TextBuffer, "namb.button%d.%s", i, key);
    return GetJsonInt(o_TextBuffer);
}
///////////////////////////////////////////////////////////////////
    
// функция загрузки параметров из json
int __stdcall ReadJsonConfig()
{    
    int qty = GetJsonInt("namb.qty");
    int align = GetJsonInt("namb.align");
    namb = new Namb(qty, align);
    namb->background->pcxname = GetJsonStr("namb.background.pcxname");
    namb->background->id = GetJsonInt("namb.background.id");
    namb->background->x = GetJsonInt("namb.background.x");
    namb->background->y = GetJsonInt("namb.background.y");
    for(int i = 0; i < qty; i++) {
        namb->buttons[i].id = GetButtonsParamInt(i, "id");
        namb->buttons[i].x = GetButtonsParamInt(i, "x");
        namb->buttons[i].y = GetButtonsParamInt(i, "y");
        namb->buttons[i].caption_color = GetButtonsParamInt(i, "caption_color");
        namb->buttons[i].defname = GetButtonsParamStr(i, "defname");
        namb->buttons[i].caption_font = GetButtonsParamStr(i, "caption_font");
        namb->buttons[i].caption_text = GetButtonsParamStr(i, "caption_text");
        namb->buttons[i].popup_text = GetButtonsParamStr(i, "popup_text");
        namb->buttons[i].hint_text = GetButtonsParamStr(i, "hint_text");
    }
    return 1;
}
///////////////////////////////////////////////////////////////////
_Dlg_* __stdcall hook_AdvMapDlg_Construct(HiHook* hook, _Dlg_* dlg)
{
    int HDResX, HDResY, offsetx, offsety, x, y, id, color;
    char *name, *caption, *font;
    
//    HDResX = *(int*)0x4F81BC;    HDResY = *(int*)0x4F81C3;
    HDResX = o_WndMgr->screen_pcx16->width;
    HDResY = o_WndMgr->screen_pcx16->height;
    switch (namb->align)    {
        case 0:        
            offsetx = 0; 
            break;
        case 2:        
            offsetx = HDResX - 800; 
            break;
        case 1:        
        default:
            offsetx = (HDResX - 800)/2; 
            break;                
    }    
    offsety = HDResY - 600; 
    CALL_1(_Dlg_*, __thiscall, hook->GetDefaultFunc(), dlg);
    x = namb->background->x; 
    y = namb->background->y; 
    id = namb->background->id; 
    name = (char*)(namb->background->pcxname.c_str());
    
    dlg->AddItem(_DlgStaticPcx8_::Create(x + offsetx, y + offsety, id, name) );
    for (int i=0; i < namb->qty; i++)    {
        x = namb->buttons[i].x; 
        y = namb->buttons[i].y; 
        id = namb->buttons[i].id; 
        color = namb->buttons[i].caption_color;
        name = (char*)(namb->buttons[i].defname.c_str());
        caption = (char*)(namb->buttons[i].caption_text.c_str());
        font = (char*)(namb->buttons[i].caption_font.c_str());
        
        _DlgTextButton_* bttn = _DlgTextButton_::Create(x + offsetx, y + offsety, id, name, caption, font, 0, 1, 0, 0, color);
            bttn->short_tip_text = (char*)(namb->buttons[i].caption_text.c_str());
            bttn->full_tip_text = (char*)(namb->buttons[i].popup_text.c_str());
        dlg->AddItem(bttn);
    }
    return dlg;    
}
int __stdcall hook_BeforeDrawAgems(HiHook* hook, _AdvMgr_* pAdvManager)
{
    _Dlg_* pDlgAdvMap;
    _DlgItem_* pItem;
    pDlgAdvMap = pAdvManager->dlg;
    pItem = pDlgAdvMap->GetItem(namb->background->id);
    pItem->Draw();
    for (int i = 0; i < namb->qty; i++) {
        pItem = pDlgAdvMap->GetItem(namb->buttons[i].id);
        pItem->Draw();
    }
    return CALL_1(int, __thiscall, hook->GetDefaultFunc(), pAdvManager);
}
_LHF_(LoHook_InitTxtFiles)
{
    ReadJsonConfig();
    return EXEC_DEFAULT;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    static _bool_ plugin_On = 0;
    if ( (ul_reason_for_call==DLL_PROCESS_ATTACH) && (!plugin_On) ) {
        plugin_On = 1;
        _P = GetPatcher();
        _PI = _P->CreateInstance("new_buttons");
        ConnectEra();
        _PI->WriteLoHook(0x4EEAC0, LoHook_InitTxtFiles);
        _PI->WriteHiHook(0x401510, SPLICE_, EXTENDED_, THISCALL_, hook_AdvMapDlg_Construct);
        _PI->WriteHiHook(0x40F250, SPLICE_, EXTENDED_, THISCALL_, hook_BeforeDrawAgems);
    }
    return TRUE;
}