From 536f3586ed402a28e3c1cabe71cf2ca09f43ba75 Mon Sep 17 00:00:00 2001 From: Mind Rapist Date: Wed, 18 Feb 2026 00:59:26 +0200 Subject: [PATCH 1/2] Various fixes and improvements --- README.md | 8 +++++--- src/game/char.h | 6 ++++-- src/game/char_item.cpp | 45 ++++++++++++++++++++++++++--------------- src/game/input_main.cpp | 12 ++++++++--- 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index db7093d..90d3682 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,11 @@ It builds as it is, without external dependencies. ## πŸ“‹ Changelog -### πŸ› Bug fixes - - **Dragonsoul Qualification**: Minimum level hardcoded in the checks for qualification. - - **USE_AFFECT flag**: Now allows overrriding the same affect if its value is about to increase. +### πŸ› Bug Fixes + - **Refinement**: Fixed refinement by item (scroll/stone) + +### ⬆️ Improvements + - **Refinement**: Updated translations for the refinement dialogs and added conditional failed messages (from official)

diff --git a/src/game/char.h b/src/game/char.h index 10b07b4..be31b9f 100644 --- a/src/game/char.h +++ b/src/game/char.h @@ -1094,10 +1094,12 @@ class CHARACTER : public CEntity, public CFSM, public CHorseRider void SpecificEffectPacket(const std::string& stEffectName); // ADD_MONSTER_REFINE - bool DoRefine(LPITEM item, bool bMoneyOnly = false); + // MR-15: Include refine method type in upgrade result + bool DoRefine(LPITEM item, bool bMoneyOnly, int iType); // END_OF_ADD_MONSTER_REFINE - bool DoRefineWithScroll(LPITEM item); + bool DoRefineWithScroll(LPITEM item, int iType); + // MR-15: -- END_OF -- Include refine method type in upgrade result bool RefineInformation(BYTE bCell, BYTE bType, int iAdditionalCell = -1); void SetRefineMode(int iAdditionalCell = -1); diff --git a/src/game/char_item.cpp b/src/game/char_item.cpp index 2db72fa..b4f7fe6 100644 --- a/src/game/char_item.cpp +++ b/src/game/char_item.cpp @@ -775,21 +775,21 @@ void TransformRefineItem(LPITEM pkOldItem, LPITEM pkNewItem) pkOldItem->CopyAttributeTo(pkNewItem); } -void NotifyRefineSuccess(LPCHARACTER ch, LPITEM item, const char* way) +void NotifyRefineSuccess(LPCHARACTER ch, LPITEM item, const char* way, int iType) { if (NULL != ch && item != NULL) { - ch->ChatPacket(CHAT_TYPE_COMMAND, "RefineSuceeded"); + ch->ChatPacket(CHAT_TYPE_COMMAND, "RefineSuceeded %d", iType); LogManager::instance().RefineLog(ch->GetPlayerID(), item->GetName(), item->GetID(), item->GetRefineLevel(), 1, way); } } -void NotifyRefineFail(LPCHARACTER ch, LPITEM item, const char* way, int success = 0) +void NotifyRefineFail(LPCHARACTER ch, LPITEM item, const char* way, int iType, int success = 0) { if (NULL != ch && NULL != item) { - ch->ChatPacket(CHAT_TYPE_COMMAND, "RefineFailed"); + ch->ChatPacket(CHAT_TYPE_COMMAND, "RefineFailed %d", iType); LogManager::instance().RefineLog(ch->GetPlayerID(), item->GetName(), item->GetID(), item->GetRefineLevel(), success, way); } @@ -807,7 +807,7 @@ void CHARACTER::SetRefineNPC(LPCHARACTER ch) } } -bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly) +bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly, int iType) { if (!CanHandleItem(true)) { @@ -935,7 +935,7 @@ bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly) BYTE bCell = item->GetCell(); // DETAIL_REFINE_LOG - NotifyRefineSuccess(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER"); + NotifyRefineSuccess(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER", iType); DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -cost); ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE SUCCESS)"); // END_OF_DETAIL_REFINE_LOG @@ -955,7 +955,7 @@ bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly) // DETAIL_REFINE_LOG // μ•„μ΄ν…œ 생성에 μ‹€νŒ¨ -> κ°œλŸ‰ μ‹€νŒ¨λ‘œ κ°„μ£Ό sys_err("cannot create item %u", result_vnum); - NotifyRefineFail(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER"); + NotifyRefineFail(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER", iType); // END_OF_DETAIL_REFINE_LOG } } @@ -963,7 +963,7 @@ bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly) { // μ‹€νŒ¨! λͺ¨λ“  μ•„μ΄ν…œμ΄ 사라짐. DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -cost); - NotifyRefineFail(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER"); + NotifyRefineFail(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER", iType); item->AttrLog(); ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE FAIL)"); @@ -985,7 +985,7 @@ enum enum_RefineScrolls BDRAGON_SCROLL = 6, }; -bool CHARACTER::DoRefineWithScroll(LPITEM item) +bool CHARACTER::DoRefineWithScroll(LPITEM item, int iType) { if (!CanHandleItem(true)) { @@ -1207,7 +1207,10 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) BYTE bCell = item->GetCell(); - NotifyRefineSuccess(this, item, szRefineType); + // MR-15: Include refine method type in upgrade result + NotifyRefineSuccess(this, item, szRefineType, iType); + // MR-15: -- END OF -- Include refine method type in upgrade result + DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost); ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE SUCCESS)"); @@ -1221,7 +1224,9 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) { // μ•„μ΄ν…œ 생성에 μ‹€νŒ¨ -> κ°œλŸ‰ μ‹€νŒ¨λ‘œ κ°„μ£Ό sys_err("cannot create item %u", result_vnum); - NotifyRefineFail(this, item, szRefineType); + // MR-15: Include refine method type in upgrade result + NotifyRefineFail(this, item, szRefineType, iType); + // MR-15: -- END OF -- Include refine method type in upgrade result } } else if (!bDestroyWhenFail && result_fail_vnum) @@ -1237,7 +1242,9 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) BYTE bCell = item->GetCell(); DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost); - NotifyRefineFail(this, item, szRefineType, -1); + // MR-15: Include refine method type in upgrade result + NotifyRefineFail(this, item, szRefineType, iType, -1); + // MR-15: -- END OF -- Include refine method type in upgrade result ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE FAIL)"); pkNewItem->AddToCharacter(this, TItemPos(INVENTORY, bCell)); @@ -1252,13 +1259,17 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) { // μ•„μ΄ν…œ 생성에 μ‹€νŒ¨ -> κ°œλŸ‰ μ‹€νŒ¨λ‘œ κ°„μ£Ό sys_err("cannot create item %u", result_fail_vnum); - NotifyRefineFail(this, item, szRefineType); + // MR-15: Include refine method type in upgrade result + NotifyRefineFail(this, item, szRefineType, iType); + // MR-15: -- END OF -- Include refine method type in upgrade result } } else { - NotifyRefineFail(this, item, szRefineType); // κ°œλŸ‰μ‹œ μ•„μ΄ν…œ 사라지지 μ•ŠμŒ - + // MR-15: Include refine method type in upgrade result + NotifyRefineFail(this, item, szRefineType, iType); // κ°œλŸ‰μ‹œ μ•„μ΄ν…œ 사라지지 μ•ŠμŒ + // MR-15: -- END OF -- Include refine method type in upgrade result + PayRefineFee(prt->cost); } @@ -1285,7 +1296,9 @@ bool CHARACTER::RefineInformation(BYTE bCell, BYTE bType, int iAdditionalCell) TPacketGCRefineInformation p; - p.header = GC::REFINE_INFORMATION; + // MR-15: Fix refining by item + p.header = GC::REFINE_INFORMATION_NEW; + // MR-15: -- END OF -- Fix refining by item p.length = sizeof(p); p.pos = bCell; p.src_vnum = item->GetVnum(); diff --git a/src/game/input_main.cpp b/src/game/input_main.cpp index a9fe56d..df4ace2 100644 --- a/src/game/input_main.cpp +++ b/src/game/input_main.cpp @@ -3169,12 +3169,16 @@ void CInputMain::Refine(LPCHARACTER ch, const char* c_pData) if (p->type == REFINE_TYPE_NORMAL) { sys_log (0, "refine_type_noraml"); - ch->DoRefine(item); + // MR-15: Fix refining by item + ch->DoRefine(item, false, p->type); + // MR-15: -- END OF -- Fix refining by item } else if (p->type == REFINE_TYPE_SCROLL || p->type == REFINE_TYPE_HYUNIRON || p->type == REFINE_TYPE_MUSIN || p->type == REFINE_TYPE_BDRAGON) { sys_log (0, "refine_type_scroll, ..."); - ch->DoRefineWithScroll(item); + // MR-15: Fix refining by item + ch->DoRefineWithScroll(item, p->type); + // MR-15: -- END OF -- Fix refining by item } else if (p->type == REFINE_TYPE_MONEY_ONLY) { @@ -3190,7 +3194,9 @@ void CInputMain::Refine(LPCHARACTER ch, const char* c_pData) { if (ch->GetQuestFlag("deviltower_zone.can_refine")) { - ch->DoRefine(item, true); + // MR-15: Fix refining by item + ch->DoRefine(item, true, p->type); + // MR-15: -- END OF -- Fix refining by item ch->SetQuestFlag("deviltower_zone.can_refine", 0); } else From bf4de6e84f86f0a73050a1d6f8e5dfbd4ae01754 Mon Sep 17 00:00:00 2001 From: Mind Rapist Date: Wed, 18 Feb 2026 13:28:00 +0200 Subject: [PATCH 2/2] Dragonsoul qualification level fix --- src/game/char_dragonsoul.cpp | 2 +- src/game/questlua_dragonsoul.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/char_dragonsoul.cpp b/src/game/char_dragonsoul.cpp index bace6a1..5b7bd99 100644 --- a/src/game/char_dragonsoul.cpp +++ b/src/game/char_dragonsoul.cpp @@ -50,7 +50,7 @@ bool CHARACTER::DragonSoul_IsQualified() const void CHARACTER::DragonSoul_GiveQualification() { // MR-12: Check min level for Dragonsoul qualification - if (GetLevel() > 30) + if (GetLevel() < 30) { return; } diff --git a/src/game/questlua_dragonsoul.cpp b/src/game/questlua_dragonsoul.cpp index c11ded2..f5bdd81 100644 --- a/src/game/questlua_dragonsoul.cpp +++ b/src/game/questlua_dragonsoul.cpp @@ -47,7 +47,7 @@ namespace quest } // MR-12: Check min level for Dragonsoul qualification - if (ch->GetLevel() <= 30) + if (ch->GetLevel() < 30) { sys_err("DS_QUEST_GIVE_QUALIFICATION:: LEVEL TOO LOW"); return 0; @@ -71,7 +71,7 @@ namespace quest } // MR-12: Check min level for Dragonsoul qualification - if (ch->GetLevel() <= 30) + if (ch->GetLevel() < 30) { sys_err("DS_QUEST_IS_QUALIFIED:: LEVEL TOO LOW"); lua_pushnumber(L, 0);