LV
0
- Joined
- Dec 27, 2025
- Messages
- 4
- Reaction score
- 1
- Points
- 3
UIStateForm.cpp
1) Находим строку:
Под ней вставляем:
2) Находим существующую функцию:
Заменяем целиком функцию на:
3) Найти функцию:
Если в функции есть строки ниже, их удалить или замутить, остальное без изменения:
Это все!
1) Находим строку:
C++:
using namespace GUI;
Под ней вставляем:
C++:
namespace {
enum class EStatBtn { NONE, STR, AGI, CON, STA, DEX };
static bool s_holdActive = false;
static EStatBtn s_activeBtn = EStatBtn::NONE;
static int s_stage = 0;
static DWORD s_intervalMs = 300;
static DWORD s_nextTick = 0;
static int s_holdCount = 0;
static EStatBtn ResolveStatBtnByName(const std::string& n) {
if (n == "btnStr") return EStatBtn::STR;
if (n == "btnAgi") return EStatBtn::AGI;
if (n == "btnCon") return EStatBtn::CON;
if (n == "btnSta") return EStatBtn::STA;
if (n == "btnDex") return EStatBtn::DEX;
return EStatBtn::NONE;
}
static int AttrIdFromBtn(EStatBtn b) {
switch (b) {
case EStatBtn::STR: return ATTR_STR;
case EStatBtn::AGI: return ATTR_AGI;
case EStatBtn::CON: return ATTR_CON;
case EStatBtn::STA: return ATTR_STA;
case EStatBtn::DEX: return ATTR_DEX;
default: return -1;
}
}
static void DoAddOne(EStatBtn btn) {
const int attrId = AttrIdFromBtn(btn);
if (attrId < 0) return;
CCharacter* pCha = g_stUIBoat.GetHuman();
if (!pCha) return;
SGameAttr* ga = pCha->getGameAttr();
if (!ga || ga->get(ATTR_AP) <= 0) return;
CChaAttr attr;
attr.ResetChangeFlag();
attr.DirectSetAttr(attrId, 1);
attr.SetChangeBitFlag(attrId);
if (auto* proCir = (CProCirculateCS*)g_NetIF->GetProCir())
proCir->SynBaseAttribute(&attr);
}
static POINT GetClientCursor(HWND hwnd) {
POINT p; ::GetCursorPos(&p);
if (hwnd) ::ScreenToClient(hwnd, &p);
return p;
}
static bool IsMouseOverBtn(HWND hwnd, CForm* frm, CGuiData* btn) {
if (!frm || !btn || !btn->GetIsShow()) return false;
POINT c = GetClientCursor(hwnd);
const int x = frm->GetLeft() + btn->GetLeft();
const int y = frm->GetTop() + btn->GetTop();
const int w = btn->GetWidth();
const int h = btn->GetHeight();
return (c.x >= x && c.x < x + w && c.y >= y && c.y < y + h);
}
static CGuiData* ButtonByEnum(CTextButton* btnStr, CTextButton* btnAgi,
CTextButton* btnCon, CTextButton* btnSta,
CTextButton* btnDex, EStatBtn b) {
switch (b) {
case EStatBtn::STR: return btnStr;
case EStatBtn::AGI: return btnAgi;
case EStatBtn::CON: return btnCon;
case EStatBtn::STA: return btnSta;
case EStatBtn::DEX: return btnDex;
default: return nullptr;
}
}
static void StartHold(EStatBtn b) {
s_activeBtn = b;
s_holdActive = (b != EStatBtn::NONE);
s_stage = 0;
s_intervalMs = 300;
s_nextTick = ::GetTickCount() + s_intervalMs;
s_holdCount = 0;
}
static void StopHold() {
s_holdActive = false;
s_activeBtn = EStatBtn::NONE;
}
}
2) Находим существующую функцию:
C++:
void CStateMgr::FrameMove(DWORD dwTime)
{
if( frmState->GetIsShow() )
{
static CTimeWork time(100);
if( time.IsTimeOut( dwTime ) )
RefreshStateFrm();
}
}
Заменяем целиком функцию на:
C++:
void CStateMgr::FrameMove(DWORD dwTime)
{
if (frmState->GetIsShow())
{
static CTimeWork time(100);
if (time.IsTimeOut(dwTime))
RefreshStateFrm();
}
HWND hwnd = ::GetActiveWindow();
const bool lmbDown = (::GetAsyncKeyState(VK_LBUTTON) & 0x8000) != 0;
if (lmbDown && !s_holdActive) {
if (IsMouseOverBtn(hwnd, frmState, btnStr)) StartHold(EStatBtn::STR);
else if (IsMouseOverBtn(hwnd, frmState, btnAgi)) StartHold(EStatBtn::AGI);
else if (IsMouseOverBtn(hwnd, frmState, btnCon)) StartHold(EStatBtn::CON);
else if (IsMouseOverBtn(hwnd, frmState, btnSta)) StartHold(EStatBtn::STA);
else if (IsMouseOverBtn(hwnd, frmState, btnDex)) StartHold(EStatBtn::DEX);
}
if (s_holdActive) {
CGuiData* activeBtnPtr = ButtonByEnum(btnStr, btnAgi, btnCon, btnSta, btnDex, s_activeBtn);
const bool stillOver = IsMouseOverBtn(hwnd, frmState, activeBtnPtr);
if (!lmbDown || !stillOver) {
StopHold();
}
}
if (s_holdActive) {
DWORD now = ::GetTickCount();
if (now >= s_nextTick) {
if (s_holdCount >= 25) {
StopHold();
return;
}
CCharacter* pCha = g_stUIBoat.GetHuman();
if (!pCha) { StopHold(); return; }
SGameAttr* ga = pCha->getGameAttr();
if (!ga || ga->get(ATTR_AP) <= 0) { StopHold(); return; }
DoAddOne(s_activeBtn);
++s_holdCount;
if (s_stage == 0) s_intervalMs = 150;
else if (s_stage == 1) s_intervalMs = 100;
else s_intervalMs = 80;
++s_stage;
s_nextTick = now + s_intervalMs;
}
}
}
3) Найти функцию:
C++:
void CStateMgr::MainMouseDown(CGuiData *pSender, int x, int y, DWORD key)
Если в функции есть строки ниже, их удалить или замутить, остальное без изменения:
Code:
s_activeBtn = ResolveStatBtnByName(name); // ← Delete or mute
s_holdActive = true; // ← Delete or mute
Это все!