From 74a93ad11604d7d51e5639e5e574661095f869c5 Mon Sep 17 00:00:00 2001 From: Mind Rapist Date: Sun, 15 Feb 2026 21:40:52 +0200 Subject: [PATCH] Various fixes --- README.md | 22 +++++----------------- src/EterGrnLib/Material.cpp | 9 +++++++-- src/EterGrnLib/Material.h | 7 ++++++- src/EterGrnLib/ModelInstance.cpp | 9 +++++++-- src/EterGrnLib/ModelInstance.h | 3 +++ src/EterGrnLib/ModelInstanceRender.cpp | 12 +++++++++++- src/ScriptLib/PythonDebugModule.cpp | 11 +++++++++++ src/UserInterface/PythonPlayerModule.cpp | 3 +++ src/UserInterface/PythonPlayerSkill.cpp | 24 ++++++++++++++++++++++++ 9 files changed, 77 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index c7ce99a..63d4770 100644 --- a/README.md +++ b/README.md @@ -15,23 +15,11 @@ This repository contains the source code necessary to compile the game client ex --- ## 📋 Changelog - -### ⬆️ Feature Improvements - - **Packet dump has its own log file**: The debug process now generates 4 log files: - - `log.txt`: What you know and love, minus packet dumps - - `syserr.txt`: What you know and hate to see, as you know and hate it! - - `packetdump.txt`: All packet dumps go here - - `pdlog.txt`: The complete log with everything included - - **Console outputs are now colored!**: Not a big difference, red for syserr outputs, dimmer color for packet dumps. - - **TempTrace**: A type of output made to stand out in the console! Made to be used as a temporary debugging helper, it has blue background so you can easily spot it in the console. It logs normally in files and it is exported to the Python system via the C++ API! - Available C++ calls: - - `TraceTemp` - - `TraceTempf` - - `TraceTempn` - - `TraceTempfn` - Available Python calls: - - `TempTrace` - Usage: same as `Trace(f/n/fn)`, and `ErrorTrace` for Python +### 🐛 Bug fixes + - **TempTrace**: Added `n` support for Python + - **Togglable slots**: Fixed slots not deactivating on death + - **Affects**: Added affect shower support for Mall Attack Speed + - **Specular**: Fixed a bug where specular would not isolate to the targeted item. Swapping for example to a weapon with different specular would cause all surrounding weapon meshes to change specular as well. The issue has been fixed.

diff --git a/src/EterGrnLib/Material.cpp b/src/EterGrnLib/Material.cpp index 6d26f1b..a7de095 100644 --- a/src/EterGrnLib/Material.cpp +++ b/src/EterGrnLib/Material.cpp @@ -148,6 +148,7 @@ LPDIRECT3DTEXTURE9 CGrannyMaterial::GetD3DTexture(int iStage) const CGraphicImage * pImage = ratImage.GetPointer(); const CGraphicTexture * pTexture = pImage->GetTexturePointer(); + return pTexture->GetD3DTexture(); } @@ -183,10 +184,12 @@ BOOL CGrannyMaterial::__IsSpecularEnable() const return m_bSpecularEnable; } -float CGrannyMaterial::__GetSpecularPower() const +// MR-12: Fix specular isolation issue +float CGrannyMaterial::GetSpecularPower() const { return m_fSpecularPower; } +// MR-12: -- END OF -- Fix specular isolation issue extern const std::string& GetModelLocalPath(); @@ -316,7 +319,9 @@ void CGrannyMaterial::__ApplySpecularRenderState() else STATEMANAGER.SetTexture(1, NULL); - STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(g_fSpecularColor.r, g_fSpecularColor.g, g_fSpecularColor.b, __GetSpecularPower())); + // MR-12: Fix specular isolation issue + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(g_fSpecularColor.r, g_fSpecularColor.g, g_fSpecularColor.b, GetSpecularPower())); + // MR-12: -- END OF -- Fix specular isolation issue STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); diff --git a/src/EterGrnLib/Material.h b/src/EterGrnLib/Material.h index 265666c..f415142 100644 --- a/src/EterGrnLib/Material.h +++ b/src/EterGrnLib/Material.h @@ -60,6 +60,12 @@ class CGrannyMaterial : public CReferenceObject LPDIRECT3DTEXTURE9 GetD3DTexture(int iStage) const; + // MR-12: Fix specular isolation issue + float GetSpecularPower() const; + bool IsSpecularEnabled() const { return m_bSpecularEnable; } + BYTE GetSphereMapIndex() const { return m_bSphereMapIndex; } + // MR-12: -- END OF -- Fix specular isolation issue + bool IsTwoSided() const { return m_bTwoSideRender; } @@ -67,7 +73,6 @@ class CGrannyMaterial : public CReferenceObject CGraphicImage * __GetImagePointer(const char * c_szFileName); BOOL __IsSpecularEnable() const; - float __GetSpecularPower() const; void __ApplyDiffuseRenderState(); void __RestoreDiffuseRenderState(); diff --git a/src/EterGrnLib/ModelInstance.cpp b/src/EterGrnLib/ModelInstance.cpp index 610a571..932d3fc 100644 --- a/src/EterGrnLib/ModelInstance.cpp +++ b/src/EterGrnLib/ModelInstance.cpp @@ -17,6 +17,8 @@ void CGrannyModelInstance::SetMaterialImagePointer(const char* c_szImageName, CG void CGrannyModelInstance::SetMaterialData(const char* c_szImageName, const SMaterialData& c_rkMaterialData) { m_kMtrlPal.SetMaterialData(c_szImageName, c_rkMaterialData); + + material_data_ = c_rkMaterialData; } void CGrannyModelInstance::SetSpecularInfo(const char* c_szMtrlName, BOOL bEnable, float fPower) @@ -87,6 +89,7 @@ void CGrannyModelInstance::__Initialize() { m_pModel->Release(); } + m_pModel = NULL; mc_pParentInstance = NULL; m_iParentBoneIndex = 0; @@ -106,8 +109,10 @@ void CGrannyModelInstance::__Initialize() m_pgrnCtrl = NULL; m_pgrnAni = NULL; - m_dwOldUpdateFrame=0; - + // MR-12: Fix specular isolation issue + material_data_ = {}; + m_dwOldUpdateFrame = 0; + // MR-12: -- END OF -- Fix specular isolation issue } CGrannyModelInstance::CGrannyModelInstance() diff --git a/src/EterGrnLib/ModelInstance.h b/src/EterGrnLib/ModelInstance.h index 82687b2..0dbb9e1 100644 --- a/src/EterGrnLib/ModelInstance.h +++ b/src/EterGrnLib/ModelInstance.h @@ -193,6 +193,9 @@ class CGrannyModelInstance : public CGraphicCollisionObject // TEST CGrannyModelInstance** m_ppkSkeletonInst; + // MR-12: Fix specular isolation issue + SMaterialData material_data_; + // MR-12: -- END OF -- Fix specular isolation issue // END_OF_TEST #ifdef _TEST D3DXMATRIX TEST_matWorld; diff --git a/src/EterGrnLib/ModelInstanceRender.cpp b/src/EterGrnLib/ModelInstanceRender.cpp index eceaaa8..bcc479f 100644 --- a/src/EterGrnLib/ModelInstanceRender.cpp +++ b/src/EterGrnLib/ModelInstanceRender.cpp @@ -211,11 +211,21 @@ void CGrannyModelInstance::RenderMeshNodeListWithOneTexture(CGrannyMesh::EType e ///// const CGrannyMesh::TTriGroupNode* pTriGroupNode = pMesh->GetTriGroupNodeList(eMtrlType); int vtxCount = pMesh->GetVertexCount(); + while (pTriGroupNode) { ms_faceCount += pTriGroupNode->triCount; - CGrannyMaterial& rkMtrl=m_kMtrlPal.GetMaterialRef(pTriGroupNode->mtrlIndex); + // MR-12: Fix specular isolation issue + CGrannyMaterial& rkMtrl = m_kMtrlPal.GetMaterialRef(pTriGroupNode->mtrlIndex); + + if (!material_data_.pImage) + { + if (std::fabs(rkMtrl.GetSpecularPower() - material_data_.fSpecularPower) >= std::numeric_limits::epsilon()) + rkMtrl.SetSpecularInfo(material_data_.isSpecularEnable, material_data_.fSpecularPower, material_data_.bSphereMapIndex); + } + // MR-12: -- END OF -- Fix specular isolation issue + rkMtrl.ApplyRenderState(); STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vtxMeshBasePos, 0, vtxCount, pTriGroupNode->idxPos, pTriGroupNode->triCount); rkMtrl.RestoreRenderState(); diff --git a/src/ScriptLib/PythonDebugModule.cpp b/src/ScriptLib/PythonDebugModule.cpp index 590fe97..78972ef 100644 --- a/src/ScriptLib/PythonDebugModule.cpp +++ b/src/ScriptLib/PythonDebugModule.cpp @@ -59,6 +59,16 @@ PyObject* dbgTraceTemp(PyObject* poSelf, PyObject* poArgs) TempTrace(szMsg, false); return Py_BuildNone(); } + +PyObject* dbgTraceTempn(PyObject* poSelf, PyObject* poArgs) +{ + char* szMsg; + if (!PyTuple_GetString(poArgs, 0, &szMsg)) + return Py_BuildException(); + + TempTracen(szMsg, false); + return Py_BuildNone(); +} // MR-11: -- END OF -- Temporary trace functions for debugging (not for regular logging) PyObject* dbgRegisterExceptionString(PyObject* poSelf, PyObject* poArgs) @@ -83,6 +93,7 @@ void initdbg() { "TraceError", dbgTraceError, METH_VARARGS }, // MR-11: Temporary trace functions for debugging (not for regular logging) { "TraceTemp", dbgTraceTemp, METH_VARARGS }, + { "TraceTempn", dbgTraceTempn, METH_VARARGS }, // MR-11: -- END OF -- Temporary trace functions for debugging (not for regular logging) { "RegisterExceptionString", dbgRegisterExceptionString, METH_VARARGS }, { NULL, NULL }, diff --git a/src/UserInterface/PythonPlayerModule.cpp b/src/UserInterface/PythonPlayerModule.cpp index 5f94502..e1c4127 100644 --- a/src/UserInterface/PythonPlayerModule.cpp +++ b/src/UserInterface/PythonPlayerModule.cpp @@ -2377,6 +2377,9 @@ void initPlayer() PyModule_AddIntConstant(poModule, "ATTACKER_BONUS", POINT_PARTY_ATT_GRADE); PyModule_AddIntConstant(poModule, "MAX_NUM", POINT_MAX_NUM); //// + // MR-12: Add Mall Attack speed affect + PyModule_AddIntConstant(poModule, "POINT_ATT_SPEED", POINT_ATT_SPEED); + // MR-12: -- END OF -- Add Mall Attack speed affect PyModule_AddIntConstant(poModule, "POINT_CRITICAL_PCT", POINT_CRITICAL_PCT); PyModule_AddIntConstant(poModule, "POINT_PENETRATE_PCT", POINT_PENETRATE_PCT); PyModule_AddIntConstant(poModule, "POINT_MALL_ATTBONUS", POINT_MALL_ATTBONUS); diff --git a/src/UserInterface/PythonPlayerSkill.cpp b/src/UserInterface/PythonPlayerSkill.cpp index 4a78b59..9cd1bae 100644 --- a/src/UserInterface/PythonPlayerSkill.cpp +++ b/src/UserInterface/PythonPlayerSkill.cpp @@ -10,6 +10,30 @@ void CPythonPlayer::ClearAffects() { PyCallClassMemberFunc(m_ppyGameWindow, "ClearAffects", Py_BuildValue("()")); + + // MR-12: Deactivate all active toggle skills when affects are cleared (e.g., on death) + for (int i = 0; i < SKILL_MAX_NUM; ++i) + { + TSkillInstance & rkSkillInst = m_playerStatus.aSkill[i]; + + // Skip empty skill slots + if (0 == rkSkillInst.dwIndex) + continue; + + CPythonSkill::TSkillData * pSkillData; + if (!CPythonSkill::Instance().GetSkillData(rkSkillInst.dwIndex, &pSkillData)) + continue; + + // Only deactivate toggle skills that are currently active + if (!pSkillData->IsToggleSkill()) + continue; + + if (!rkSkillInst.bActive) + continue; + + __DeactivateSkillSlot(i); + } + // MR-12: -- END OF -- Deactivate all active toggle skills when affects are cleared (e.g., on death) } void CPythonPlayer::SetAffect(UINT uAffect)