-
Posts
19 -
Joined
-
Last visited
-
Feedback
0%
About StormyFF

Recent Profile Visitors
1109 profile views
StormyFF's Achievements
-
Little difference between lv 10 swords Map (Atlas view) differences on the left closed beta, on right open beta from here:
-
StormyFF started following EterManager 64bit , Closed Beta Client Contents , Metin2 on another game engine? UE5/Unity and 6 others
-
Hi everyone. I don't post on this forum often, but since I first learned about this material right here, I thought it would be nice to share what I've found—and also to dispel a few myths about the closed beta client. Below, you'll find the *actual* content of the closed beta client; there are substantial differences compared to the old screenshots of the alpha client, which only the original development team ever got to test. There are also many differences between the various open beta clients released online (not just in terms of structure, but obviously in content as well). With that said, let's get straight to the point. Here are some screenshots of content that I believe is exclusive to the closed beta client. I'll likely update this post with new material over time, as the file organization differs somewhat from the shipping clients we're used to seeing; as I "discover" new things, I'll post them here. GM affect: into the folder "\ymir work\effect" i found an additional subfolder named "test" that contains another folder named "20" into this folder i found these cpp code, idk if it is an experimental effectlib part or other, i will watch better at these files during the time Some little differences in minimap radar (i compared with rain 35 client) About the skillcommon.dds the only difference i found is about the icon for fishing skill and another icon that seems a red globe, but i ve no idea what it is. In addition as far as i understood, in addition the hair styles were defined in the model itself, there weren t a modular attacching system for hairstyles. ARMOR MAJOR DIFFERENCES NINJA: ARMOR MAJOR DIFFERENCES Shaman: ARMOR MAJOR DIFFERENCES Sura: ARMOR MAJOR DIFFERENCES Warrior: ofc i didn t posted other sex because in this version of the client there is only pc into the pack archive, so only Sura_M, War_M, Ninja_F, Shamy_F about the maps there are only these folders: Outdoor: "metin2_map" outdoora1: "metin2_map_a1" outdoora2: "map_a2" outdoora3: "metin2_map_a3" and so on... i only watched the atlas... and are a bit different from the one we know, when i ve time i watche the map into worldeditor or in game directly and post some other screenshots. Animations
-
I copied from google translate gnegne, and nanite is an optimization system ofc, one of the best in unreal engine, but i don t expect you to understand what i wrote because you have probably no experience about unreal engine. and the guy just said u what he is doing... and what he is doing is completelly normal on unreal engine... the ultra realistic graphic is mostly used for cinematic trailer, but when you send a game in production ofc you don t need to burn your gpu after some seconds . Pass to a graphic engine doesn t mean "ei i want the best graphic".... use unreal engine means avoid hacks, scalability, already made optimization systems, visual editing (ye we are in 2026), the possibility to run your game in editor, integrated profilation tools... it means switch from a 2004 source to an engine... if you port metin2 to unreal just for graphics probably you have no idea what is unreal engine... or probably you just saw some videos on youtube without never run a single session by you i love people who talks without any kind of idea about what they say, good subject for flame a bit... but atm i have no time for flame, i m in holiday, so have a great day and go study a bit unreal engine if you want talk about unreal engine to a guy who ported metin2 to (bet?) unreal engine and has been working on it for 3 years. ignorant
-
It's not a matter of "removing" from Unreal, because the Unreal Engine, being an engine suitable for both cinematic rendering and real-time in-game rendering, has great scalability and modularity. Consequently, it gives you the ability to use optimization tricks directly from within the engine, specifically designed to scale well without significantly losing AAA graphics (one of the most important systems in this regard is the nanite system, which, when used well, is incredible for performance). Attached is a clip of how metin2 looks on Unreal Engine.
-
There is a thread on the forum where you can find all the pics of every year and patch, comprensive the loading and login ones
-
It is wrote on the download page
-
GM Feature: Click Material in Refine = Auto Give to Inventory
StormyFF replied to TAUMP's topic in Features & Metin2 Systems
it is my payrefinefee function void CHARACTER::PayRefineFee(int iTotalMoney) { int iFee = iTotalMoney / 10; CGuild* pGuild = GetRefineGuild(); int iRemain = iTotalMoney; if (pGuild) { if (pGuild != GetGuild()) { pGuild->RequestDepositMoney(this, iFee); iRemain -= iFee; } } PointChange(POINT_GOLD, -iRemain); } in addition... it is not a good practice to call a function for just escape it... sometimes faster solutions arent good solutions, i could say something also about the fact that you don t know in wich other functions except dorefine/dorefinescroll could be called PayRefineFee and if you could have side effects or bugs for example... but it is another argument.. -
GM Feature: Click Material in Refine = Auto Give to Inventory
StormyFF replied to TAUMP's topic in Features & Metin2 Systems
bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly) { if (!CanHandleItem(true)) { ClearRefineMode(); return false; } if (quest::CQuestManager::instance().GetEventFlag("update_refine_time") != 0) { if (get_global_time() < quest::CQuestManager::instance().GetEventFlag("update_refine_time") + (60 * 5)) { sys_log(0, "can't refine %d %s", GetPlayerID(), GetName()); return false; } } const TRefineTable * prt = CRefineManager::instance().GetRefineRecipe(item->GetRefineSet()); if (!prt) return false; DWORD result_vnum = item->GetRefinedVnum(); // REFINE_COST long long cost = ComputeRefineFee(prt->cost); #ifdef GM_UPGRADE_BYPASS const bool bGMFree = IsGM(); #endif int RefineChance = GetQuestFlag("main_quest_lv7.refine_chance"); if (RefineChance > 0) { if (!item->CheckItemUseLevel(20) || item->GetType() != ITEM_WEAPON) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¹«·á °³·® ±âȸ´Â 20 ÀÌÇÏÀÇ ¹«±â¸¸ °¡´ÉÇÕ´Ï´Ù")); return false; } cost = 0; SetQuestFlag("main_quest_lv7.refine_chance", RefineChance - 1); } // END_OF_REFINE_COST if (result_vnum == 0) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´õ ÀÌ»ó °³·®ÇÒ ¼ö ¾ø½À´Ï´Ù.")); return false; } if (item->GetType() == ITEM_USE && item->GetSubType() == USE_TUNING) return false; TItemTable * pProto = ITEM_MANAGER::instance().GetTable(item->GetRefinedVnum()); if (!pProto) { sys_err("DoRefine NOT GET ITEM PROTO %d", item->GetRefinedVnum()); ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ÀÌ ¾ÆÀÌÅÛÀº °³·®ÇÒ ¼ö ¾ø½À´Ï´Ù.")); return false; } // REFINE_COST #ifdef GM_UPGRADE_BYPASS if (!bGMFree && GetGold() < cost) #else if (GetGold() < cost) #endif { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°³·®À» Çϱâ À§ÇÑ µ·ÀÌ ºÎÁ·ÇÕ´Ï´Ù.")); return false; } #ifdef GM_UPGRADE_BYPASS if (!bGMFree && !bMoneyOnly && !RefineChance) #else if (!bMoneyOnly && !RefineChance) #endif { for (int i = 0; i < prt->material_count; ++i) { if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count) { if (test_server) { ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count); } ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°³·®À» Çϱâ À§ÇÑ Àç·á°¡ ºÎÁ·ÇÕ´Ï´Ù.")); return false; } } for (int i = 0; i < prt->material_count; ++i) RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count); } int prob = number(1, 100); if (IsRefineThroughGuild() || bMoneyOnly) prob -= 10; // END_OF_REFINE_COST if (prob <= prt->prob) { LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_vnum, 1, 0, false); if (pkNewItem) { ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem); LogManager::instance().ItemLog(this, pkNewItem, "REFINE SUCCESS", pkNewItem->GetName()); BYTE bCell = item->GetCell(); // DETAIL_REFINE_LOG NotifyRefineSuccess(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER"); #ifdef GM_UPGRADE_BYPASS if (!bGMFree) DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -cost); #else DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -cost); #endif ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE SUCCESS)"); // END_OF_DETAIL_REFINE_LOG pkNewItem->AddToCharacter(this, TItemPos(INVENTORY, bCell)); ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem); sys_log(0, "Refine Success %d", cost); pkNewItem->AttrLog(); //PointChange(POINT_GOLD, -cost); sys_log(0, "PayPee %d", cost); #ifdef GM_UPGRADE_BYPASS if (!bGMFree) PayRefineFee(cost); #else PayRefineFee(cost); #endif sys_log(0, "PayPee End %d", cost); } else { // DETAIL_REFINE_LOG sys_err("cannot create item %u", result_vnum); NotifyRefineFail(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER"); // END_OF_DETAIL_REFINE_LOG } } else { #ifdef GM_UPGRADE_BYPASS if (!bGMFree) DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -cost); #else DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -cost); #endif NotifyRefineFail(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER"); item->AttrLog(); ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE FAIL)"); //PointChange(POINT_GOLD, -cost); #ifdef GM_UPGRADE_BYPASS if (!bGMFree) PayRefineFee(cost); #else PayRefineFee(cost); #endif } return true; } bool CHARACTER::DoRefineWithScroll(LPITEM item) { if (!CanHandleItem(true)) { ClearRefineMode(); return false; } ClearRefineMode(); if (quest::CQuestManager::instance().GetEventFlag("update_refine_time") != 0) { if (get_global_time() < quest::CQuestManager::instance().GetEventFlag("update_refine_time") + (60 * 5)) { sys_log(0, "can't refine %d %s", GetPlayerID(), GetName()); return false; } } const TRefineTable * prt = CRefineManager::instance().GetRefineRecipe(item->GetRefineSet()); if (!prt) return false; #ifdef GM_UPGRADE_BYPASS const bool bGMFree = IsGM(); #endif LPITEM pkItemScroll; if (m_iRefineAdditionalCell < 0) return false; pkItemScroll = GetInventoryItem(m_iRefineAdditionalCell); if (!pkItemScroll) return false; if (!(pkItemScroll->GetType() == ITEM_USE && pkItemScroll->GetSubType() == USE_TUNING)) return false; if (pkItemScroll->GetVnum() == item->GetVnum()) return false; DWORD result_vnum = item->GetRefinedVnum(); DWORD result_fail_vnum = item->GetRefineFromVnum(); if (result_vnum == 0) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´õ ÀÌ»ó °³·®ÇÒ ¼ö ¾ø½À´Ï´Ù.")); return false; } // MUSIN_SCROLL if (pkItemScroll->GetValue(0) == MUSIN_SCROLL) { if (item->GetRefineLevel() >= 4) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ÀÌ °³·®¼·Î ´õ ÀÌ»ó °³·®ÇÒ ¼ö ¾ø½À´Ï´Ù.")); return false; } } // END_OF_MUSIC_SCROLL else if (pkItemScroll->GetValue(0) == MEMO_SCROLL) { if (item->GetRefineLevel() != pkItemScroll->GetValue(1)) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ÀÌ °³·®¼·Î °³·®ÇÒ ¼ö ¾ø½À´Ï´Ù.")); return false; } } else if (pkItemScroll->GetValue(0) == BDRAGON_SCROLL) { if (item->GetType() != ITEM_METIN || item->GetRefineLevel() != 4) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ÀÌ ¾ÆÀÌÅÛÀ¸·Î °³·®ÇÒ ¼ö ¾ø½À´Ï´Ù.")); return false; } } else if (pkItemScroll->GetValue(0) == RITUALS_SCROLL) { if (item->GetLevelLimit() < pkItemScroll->GetValue(1)) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("you can only upgrade items above level %d"), pkItemScroll->GetValue(1)); return false; } } TItemTable * pProto = ITEM_MANAGER::instance().GetTable(item->GetRefinedVnum()); if (!pProto) { sys_err("DoRefineWithScroll NOT GET ITEM PROTO %d", item->GetRefinedVnum()); ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ÀÌ ¾ÆÀÌÅÛÀº °³·®ÇÒ ¼ö ¾ø½À´Ï´Ù.")); return false; } #ifdef GM_UPGRADE_BYPASS if (!bGMFree && GetGold() < prt->cost) #else if (GetGold() < prt->cost) #endif { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°³·®À» Çϱâ À§ÇÑ µ·ÀÌ ºÎÁ·ÇÕ´Ï´Ù.")); return false; } #ifdef GM_UPGRADE_BYPASS if (!bGMFree) #endif { for (int i = 0; i < prt->material_count; ++i) { if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count) { if (test_server) { ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count); } ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°³·®À» Çϱâ À§ÇÑ Àç·á°¡ ºÎÁ·ÇÕ´Ï´Ù.")); return false; } } for (int i = 0; i < prt->material_count; ++i) RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count); } int prob = number(1, 100); int success_prob = prt->prob; bool bDestroyWhenFail = false; const char* szRefineType = "SCROLL"; if (pkItemScroll->GetValue(0) == HYUNIRON_CHN || pkItemScroll->GetValue(0) == YONGSIN_SCROLL || pkItemScroll->GetValue(0) == YAGONG_SCROLL || pkItemScroll->GetValue(0) == RITUALS_SCROLL ) { const char hyuniron_prob[9] = { 100, 75, 65, 55, 45, 40, 35, 25, 20 }; const char yagong_prob[9] = { 100, 100, 90, 80, 70, 60, 50, 30, 20 }; if (pkItemScroll->GetValue(0) == YONGSIN_SCROLL) { success_prob = hyuniron_prob[MINMAX(0, item->GetRefineLevel(), 8)]; } else if (pkItemScroll->GetValue(0) == YAGONG_SCROLL) { success_prob = yagong_prob[MINMAX(0, item->GetRefineLevel(), 8)]; } else if (pkItemScroll->GetValue(0) == HYUNIRON_CHN || pkItemScroll->GetValue(0) == RITUALS_SCROLL) {} // @fixme121 else { sys_err("REFINE : Unknown refine scroll item. Value0: %d", pkItemScroll->GetValue(0)); } if (test_server) { ChatPacket(CHAT_TYPE_INFO, "[Only Test] Success_Prob %d, RefineLevel %d ", success_prob, item->GetRefineLevel()); } if (pkItemScroll->GetValue(0) == HYUNIRON_CHN || pkItemScroll->GetValue(0) == RITUALS_SCROLL) bDestroyWhenFail = true; // DETAIL_REFINE_LOG if (pkItemScroll->GetValue(0) == HYUNIRON_CHN) { szRefineType = "HYUNIRON"; } else if (pkItemScroll->GetValue(0) == YONGSIN_SCROLL) { szRefineType = "GOD_SCROLL"; } else if (pkItemScroll->GetValue(0) == YAGONG_SCROLL) { szRefineType = "YAGONG_SCROLL"; } else if (pkItemScroll->GetValue(0) == RITUALS_SCROLL) { success_prob += pkItemScroll->GetValue(2); //increases the success probability by Value(2)% szRefineType = "RITUALS_SCROLL"; } // END_OF_DETAIL_REFINE_LOG } // DETAIL_REFINE_LOG if (pkItemScroll->GetValue(0) == MUSIN_SCROLL) { success_prob = 100; szRefineType = "MUSIN_SCROLL"; } // END_OF_DETAIL_REFINE_LOG else if (pkItemScroll->GetValue(0) == MEMO_SCROLL) { success_prob = 100; szRefineType = "MEMO_SCROLL"; } else if (pkItemScroll->GetValue(0) == BDRAGON_SCROLL) { success_prob = 80; szRefineType = "BDRAGON_SCROLL"; } #ifdef GM_UPGRADE_BYPASS if (!bGMFree) #endif pkItemScroll->SetCount(pkItemScroll->GetCount() - 1); if (prob <= success_prob) { LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_vnum, 1, 0, false); if (pkNewItem) { ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem); LogManager::instance().ItemLog(this, pkNewItem, "REFINE SUCCESS", pkNewItem->GetName()); BYTE bCell = item->GetCell(); NotifyRefineSuccess(this, item, szRefineType); #ifdef GM_UPGRADE_BYPASS if (!bGMFree) DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost); #else DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost); #endif ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE SUCCESS)"); pkNewItem->AddToCharacter(this, TItemPos(INVENTORY, bCell)); ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem); pkNewItem->AttrLog(); //PointChange(POINT_GOLD, -prt->cost); #ifdef GM_UPGRADE_BYPASS if (!bGMFree) PayRefineFee(prt->cost); #else PayRefineFee(prt->cost); #endif } else { sys_err("cannot create item %u", result_vnum); NotifyRefineFail(this, item, szRefineType); } } else if (!bDestroyWhenFail && result_fail_vnum) { LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_fail_vnum, 1, 0, false); if (pkNewItem) { ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem); LogManager::instance().ItemLog(this, pkNewItem, "REFINE FAIL", pkNewItem->GetName()); BYTE bCell = item->GetCell(); #ifdef GM_UPGRADE_BYPASS if (!bGMFree) DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost); #else DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost); #endif NotifyRefineFail(this, item, szRefineType, -1); ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE FAIL)"); pkNewItem->AddToCharacter(this, TItemPos(INVENTORY, bCell)); ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem); pkNewItem->AttrLog(); //PointChange(POINT_GOLD, -prt->cost); #ifdef GM_UPGRADE_BYPASS if (!bGMFree) PayRefineFee(prt->cost); #else PayRefineFee(prt->cost); #endif } else { sys_err("cannot create item %u", result_fail_vnum); NotifyRefineFail(this, item, szRefineType); } } else { NotifyRefineFail(this, item, szRefineType); #ifdef GM_UPGRADE_BYPASS if (!bGMFree) PayRefineFee(prt->cost); #else PayRefineFee(prt->cost); #endif } return true; } -
Status problem sometimes
StormyFF replied to ricardo1813's topic in Community Support - Questions & Answers
When you mount on a mount there is a function called that recalc your stats (it is called because sometimes the mounts can give you an apply_point, so probably there is a bug on these status and it is showed only when you use the item for mount and it refreshes your stats... or maybe you can make a test for see if it happens using every mount or only for specific mounts ( i suppose it happens for every mount) -
Requirements: Include these two headers into "eterPythonLib": in addition include this code into an header named "watermark_logo.h" in eterPythonLib-->StdAfx.cpp, after "#include StdAfx.h": #ifdef WATER_MARK #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #endif in eterPythonLib-->PythonGraphic.h: #ifdef WATER_MARK #include "watermark_logo.h" #include "font8x8_basic.h" #include "stb_image.h" #endif in eterPythonLib-->PythonGraphic.cpp, after "bool g_isScreenShotKey = false;" same file, into--> bool CPythonGraphic::SaveScreenShot, before " bool bSaved = SaveJPEG(c_pszFileName, (LPBYTE)pbyBuffer, uWidth, uHeight);": #ifdef WATER_MARK DrawRepeatedWatermarkText(pbyBuffer, uWidth, uHeight, "StormyFF", 10); //add your text to display on the top. #ifdef FULL_WATERMARK DrawFullWatermarkRepeated(pbyBuffer, uWidth, uHeight, WATERMARK_BASE64); #else DrawWatermarkFromBase64PNG(pbyBuffer, uWidth, uHeight, WATERMARK_BASE64); #endif #endif Do not forget define WATER_MARK into locale_inc.h Results: #define FULL_WATERMARK into "watermark_logo.h": basic:
-
- 16
-
-
-
-
-
-
void CGrannyModelInstance::UpdateWorldMatrices(const D3DXMATRIX* c_pWorldMatrix) // FIX_WEAPON_UPSCALING { // NO_MESH_BUG_FIX if (!m_meshMatrices) return; // END_OF_NO_MESH_BUG_FIX assert(m_pModel != NULL); assert(ms_lpd3dMatStack != NULL); int meshCount = m_pModel->GetMeshCount(); granny_matrix_4x4* pgrnMatCompositeBuffer = GrannyGetWorldPoseComposite4x4Array(__GetWorldPosePtr()); D3DXMATRIX* boneMatrices = (D3DXMATRIX*)pgrnMatCompositeBuffer; for (int i = 0; i < meshCount; ++i) { D3DXMATRIX& rWorldMatrix = m_meshMatrices[i]; const CGrannyMesh* pMesh = m_pModel->GetMeshPointer(i); // WORK #if GrannyProductMinorVersion==4 int* boneIndices = __GetMeshBoneIndices(i); #elif GrannyProductMinorVersion==11 || GrannyProductMinorVersion==9 || GrannyProductMinorVersion==8 || GrannyProductMinorVersion==7 const granny_int32x* boneIndices = __GetMeshBoneIndices(i); #else #error "unknown granny version" #endif if (pMesh->CanDeformPNTVertices()) { rWorldMatrix = *c_pWorldMatrix; } else { #if GrannyProductMinorVersion==4 int iBone = *boneIndices; #elif GrannyProductMinorVersion==11 || GrannyProductMinorVersion==9 || GrannyProductMinorVersion==8 || GrannyProductMinorVersion==7 const granny_int32x iBone = *boneIndices; #else #error "unknown granny version" #endif D3DXMATRIX matBoneTransform = boneMatrices[iBone]; D3DXVECTOR3 vTranslation(matBoneTransform._41, matBoneTransform._42, matBoneTransform._43); D3DXVec3Normalize((D3DXVECTOR3*)&matBoneTransform._11, (D3DXVECTOR3*)&matBoneTransform._11); D3DXVec3Normalize((D3DXVECTOR3*)&matBoneTransform._21, (D3DXVECTOR3*)&matBoneTransform._21); D3DXVec3Normalize((D3DXVECTOR3*)&matBoneTransform._31, (D3DXVECTOR3*)&matBoneTransform._31); matBoneTransform._41 = vTranslation.x; matBoneTransform._42 = vTranslation.y; matBoneTransform._43 = vTranslation.z; D3DXMatrixMultiply(&rWorldMatrix, &matBoneTransform, c_pWorldMatrix); } } #ifdef _TEST TEST_matWorld = *c_pWorldMatrix; #endif } void CActorInstance::UpdateAttachingInstances() { CEffectManager& rkEftMgr = CEffectManager::Instance(); std::list<TAttachingEffect>::iterator it; DWORD dwCurrentTime = CTimer::Instance().GetCurrentMillisecond(); for (it = m_AttachingEffectList.begin(); it != m_AttachingEffectList.end();) { if (EFFECT_LIFE_WITH_MOTION == it->iLifeType) { ++it; continue; } if ((EFFECT_LIFE_NORMAL == it->iLifeType && it->dwEndTime < dwCurrentTime) || !rkEftMgr.IsAliveEffect(it->dwEffectIndex)) { rkEftMgr.DestroyEffectInstance(it->dwEffectIndex); it = m_AttachingEffectList.erase(it); } else { if (it->isAttaching) { rkEftMgr.SelectEffectInstance(it->dwEffectIndex); if (it->iBoneIndex == -1) { D3DXMATRIX matTransform; matTransform = it->matTranslation; matTransform *= m_worldMatrix; rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform); } else { D3DXMATRIX* pBoneMat; if (GetBoneMatrix(it->dwModelIndex, it->iBoneIndex, &pBoneMat)) { D3DXMATRIX matTransform; matTransform = *pBoneMat; #ifdef FIX_WEAPON_UPSCALING D3DXVECTOR3 vTranslation(matTransform._41, matTransform._42, matTransform._43); D3DXMATRIX matTranslationOnly; D3DXMatrixTranslation(&matTranslationOnly, vTranslation.x, vTranslation.y, vTranslation.z); D3DXMATRIX matRotationOnly = matTransform; matRotationOnly._41 = 0.0f; matRotationOnly._42 = 0.0f; matRotationOnly._43 = 0.0f; matRotationOnly._44 = 1.0f; D3DXVECTOR3 vAxisX(matRotationOnly._11, matRotationOnly._12, matRotationOnly._13); float fScaleX = D3DXVec3Length(&vAxisX); if (fScaleX > 0.0001f) { matRotationOnly._11 /= fScaleX; matRotationOnly._12 /= fScaleX; matRotationOnly._13 /= fScaleX; } D3DXVECTOR3 vAxisY(matRotationOnly._21, matRotationOnly._22, matRotationOnly._23); float fScaleY = D3DXVec3Length(&vAxisY); if (fScaleY > 0.0001f) { matRotationOnly._21 /= fScaleY; matRotationOnly._22 /= fScaleY; matRotationOnly._23 /= fScaleY; } D3DXVECTOR3 vAxisZ(matRotationOnly._31, matRotationOnly._32, matRotationOnly._33); float fScaleZ = D3DXVec3Length(&vAxisZ); if (fScaleZ > 0.0001f) { matRotationOnly._31 /= fScaleZ; matRotationOnly._32 /= fScaleZ; matRotationOnly._33 /= fScaleZ; } matTransform = matRotationOnly * matTranslationOnly; #endif matTransform *= it->matTranslation; matTransform *= m_worldMatrix; rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform); } else { //TraceError("GetBoneMatrix(modelIndex(%d), boneIndex(%d)).NOT_FOUND_BONE", // it->dwModelIndex, it->iBoneIndex); } } } ++it; } } } if you have problems you can try fix this bug in this way (i can t ensure it will not broke some parts of your game, but atm i fixed in this way and i don t display any visual bug). [Hidden Content]
-
sorry delay, i think forgot to share the fix, i think it is enough, let me know if you see other issues, i think this fix will not break other parts of the game, but update me if you see any problem related to this fix. this fix works in directx9 o void CActorInstance::UpdateAttachingInstances() { CEffectManager& rkEftMgr=CEffectManager::Instance(); std::list<TAttachingEffect>::iterator it; DWORD dwCurrentTime = CTimer::Instance().GetCurrentMillisecond(); for (it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();) { if (EFFECT_LIFE_WITH_MOTION == it->iLifeType) { ++it; continue; } if ((EFFECT_LIFE_NORMAL == it->iLifeType && it->dwEndTime < dwCurrentTime) || !rkEftMgr.IsAliveEffect(it->dwEffectIndex)) { rkEftMgr.DestroyEffectInstance(it->dwEffectIndex); it = m_AttachingEffectList.erase(it); } else { if (it->isAttaching) { rkEftMgr.SelectEffectInstance(it->dwEffectIndex); if (it->iBoneIndex == -1) { D3DXMATRIX matTransform; matTransform = it->matTranslation; matTransform *= m_worldMatrix; rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform); } else { D3DXMATRIX* pBoneMat; if (GetBoneMatrix(it->dwModelIndex, it->iBoneIndex, &pBoneMat)) { D3DXMATRIX matTransform; matTransform = *pBoneMat; #ifdef FIX_WEAPON_UPSCALING #ifdef DIRECTX9 D3DXVECTOR3 vScale; D3DXQUATERNION qRotation; D3DXVECTOR3 vTranslation; D3DXMatrixDecompose(&vScale, &qRotation, &vTranslation, &matTransform); D3DXMATRIX matRotationOnly, matTranslationOnly; D3DXMatrixRotationQuaternion(&matRotationOnly, &qRotation); D3DXMatrixTranslation(&matTranslationOnly, vTranslation.x, vTranslation.y, vTranslation.z); matTransform = matRotationOnly * matTranslationOnly; #else D3DXVECTOR3 vTranslation(matTransform._41, matTransform._42, matTransform._43); D3DXMATRIX matTranslationOnly; D3DXMatrixTranslation(&matTranslationOnly, vTranslation.x, vTranslation.y, vTranslation.z); D3DXMATRIX matRotationOnly = matTransform; matRotationOnly._41 = 0.0f; matRotationOnly._42 = 0.0f; matRotationOnly._43 = 0.0f; matRotationOnly._44 = 1.0f; D3DXVECTOR3 vAxisX(matRotationOnly._11, matRotationOnly._12, matRotationOnly._13); float fScaleX = D3DXVec3Length(&vAxisX); if (fScaleX > 0.0001f) { matRotationOnly._11 /= fScaleX; matRotationOnly._12 /= fScaleX; matRotationOnly._13 /= fScaleX; } D3DXVECTOR3 vAxisY(matRotationOnly._21, matRotationOnly._22, matRotationOnly._23); float fScaleY = D3DXVec3Length(&vAxisY); if (fScaleY > 0.0001f) { matRotationOnly._21 /= fScaleY; matRotationOnly._22 /= fScaleY; matRotationOnly._23 /= fScaleY; } D3DXVECTOR3 vAxisZ(matRotationOnly._31, matRotationOnly._32, matRotationOnly._33); float fScaleZ = D3DXVec3Length(&vAxisZ); if (fScaleZ > 0.0001f) { matRotationOnly._31 /= fScaleZ; matRotationOnly._32 /= fScaleZ; matRotationOnly._33 /= fScaleZ; } matTransform = matRotationOnly * matTranslationOnly; #endif #endif matTransform *= it->matTranslation; matTransform *= m_worldMatrix; rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform); } else { //TraceError("GetBoneMatrix(modelIndex(%d), boneIndex(%d)).NOT_FOUND_BONE", // it->dwModelIndex, it->iBoneIndex); } } } ++it; } } } in simple terms the weapon attached to the hand bone inherited a matrix in which the scale of the bone was shrunk (probably to create an effect of gradual genesis of the skill starting from that bone, so that it did not appear out of nowhere too abruptly), consequently the weapon inheriting this matrix was shrunk, the fix consists simply in removing the information on the scale from the matrix. (remember to enable the macro FIX_WEAPON_UPSCALING and DIRECTX9 if you use this dx version)
-
void CSpeedTreeForestDirectX8::Render(unsigned long ulRenderBitVector) { ms_bRenderingToShadow = (ulRenderBitVector & Forest_RenderToShadow); if (m_pMainTreeMap.empty()) return; if (!(ulRenderBitVector & Forest_RenderToShadow) && !(ulRenderBitVector & Forest_RenderToMiniMap)) #ifdef DIN_SHADOW if (ms_bRenderingToShadow) UpdateCompundMatrix2(CCameraManager::Instance().GetCurrentCamera()->GetEye(), ms_matView, ms_matProj); else UpdateCompundMatrix2(CCameraManager::Instance().GetCurrentCamera()->GetEye(), ms_matView, ms_matProj); #else UpdateCompundMatrix(CCameraManager::Instance().GetCurrentCamera()->GetEye(), ms_matView, ms_matProj); #endif DWORD dwLightState = STATEMANAGER.GetRenderState(D3DRS_LIGHTING); DWORD dwColorVertexState = STATEMANAGER.GetRenderState(D3DRS_COLORVERTEX); DWORD dwFogVertexMode = STATEMANAGER.GetRenderState(D3DRS_FOGVERTEXMODE); STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, TRUE); UINT uiCount; TTreeMap::const_iterator itor = m_pMainTreeMap.begin(); while (itor != m_pMainTreeMap.end()) { SpeedTreeWrapperPtr pMainTree = (itor++)->second; std::list<CSpeedTreeForest::SpeedTreeWrapperWeakPtr> ppInstances = pMainTree->GetInstances(uiCount); for (auto it : ppInstances) { if (it.expired()) continue; auto pInstance = it.lock(); if (!pInstance->isShow()) continue; pInstance->Advance(); } } STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_Light, m_afLighting, 3); STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_Fog, m_afFog, 1); if (ulRenderBitVector & Forest_RenderToShadow) { STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); } else { STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); STATEMANAGER.SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); STATEMANAGER.SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC); STATEMANAGER.SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_ANISOTROPIC); STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); STATEMANAGER.SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); STATEMANAGER.SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); } STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_CW); if (STATEMANAGER.GetRenderState(D3DRS_FOGENABLE)) { STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); } STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); if (ulRenderBitVector & Forest_RenderLeaves) { STATEMANAGER.SetFVF(D3DFVF_SPEEDTREE_LEAF_VERTEX); STATEMANAGER.SetVertexShader(m_dwLeafVertexShader); if (STATEMANAGER.GetRenderState(D3DRS_FOGENABLE)) {} if (ulRenderBitVector & Forest_RenderToShadow || ulRenderBitVector & Forest_RenderToMiniMap) { STATEMANAGER.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000080); } itor = m_pMainTreeMap.begin(); while (itor != m_pMainTreeMap.end()) { SpeedTreeWrapperPtr pMainTree = (itor++)->second; std::list<CSpeedTreeForest::SpeedTreeWrapperWeakPtr> ppInstances = pMainTree->GetInstances(uiCount); pMainTree->SetupLeafForTreeType(); for (auto it : ppInstances) { if (it.expired()) continue; auto pInstance = it.lock(); if (!pInstance->isShow()) continue; pInstance->RenderLeaves(); } } if (ulRenderBitVector & Forest_RenderToShadow || ulRenderBitVector & Forest_RenderToMiniMap) { STATEMANAGER.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF); } // --- FIX 07/11/2025 (i displayed a bug on the leaves and grass, some parts of the environment were draw on the leaves/grass) STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); STATEMANAGER.SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); // --- END FIX --- } if (ulRenderBitVector & Forest_RenderFronds) { itor = m_pMainTreeMap.begin(); while (itor != m_pMainTreeMap.end()) { SpeedTreeWrapperPtr pMainTree = (itor++)->second; std::list<CSpeedTreeForest::SpeedTreeWrapperWeakPtr> ppInstances = pMainTree->GetInstances(uiCount); pMainTree->SetupFrondForTreeType(); for (auto it : ppInstances) { if (it.expired()) continue; auto pInstance = it.lock(); if (!pInstance->isShow()) continue; pInstance->RenderFronds(); } } } // --- FIX 07/11/2025 (i displayed a bug on the leaves and grass, some parts of the environment were draw on the leaves/grass) STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); STATEMANAGER.SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); // --- END FIX --- STATEMANAGER.SetFVF(D3DFVF_SPEEDTREE_BRANCH_VERTEX); STATEMANAGER.SetVertexShader(m_dwBranchVertexShader); if (ulRenderBitVector & Forest_RenderBranches) { itor = m_pMainTreeMap.begin(); while (itor != m_pMainTreeMap.end()) { SpeedTreeWrapperPtr pMainTree = (itor++)->second; std::list<CSpeedTreeForest::SpeedTreeWrapperWeakPtr> ppInstances = pMainTree->GetInstances(uiCount); pMainTree->SetupBranchForTreeType(); for (auto it : ppInstances) { if (it.expired()) continue; auto pInstance = it.lock(); if (!pInstance->isShow()) continue; pInstance->RenderBranches(); } } } // --- FIX 07/11/2025 (i displayed a bug on the leaves and grass, some parts of the environment were draw on the leaves/grass) STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); STATEMANAGER.SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); // --- END FIX --- if (ulRenderBitVector & Forest_RenderBillboards) { STATEMANAGER.SetVertexShader(NULL); STATEMANAGER.SetFVF(D3DFVF_SPEEDTREE_BILLBOARD_VERTEX); STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE); itor = m_pMainTreeMap.begin(); while (itor != m_pMainTreeMap.end()) { SpeedTreeWrapperPtr pMainTree = (itor++)->second; std::list<CSpeedTreeForest::SpeedTreeWrapperWeakPtr> ppInstances = pMainTree->GetInstances(uiCount); pMainTree->SetupBranchForTreeType(); for (auto it : ppInstances) { if (it.expired()) continue; auto pInstance = it.lock(); if (!pInstance->isShow()) continue; pInstance->RenderBillboards(); } } } STATEMANAGER.SetRenderState(D3DRS_LIGHTING, dwLightState); STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, dwColorVertexState); STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, dwFogVertexMode); if (!(ulRenderBitVector & Forest_RenderToShadow)) { STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); } STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); m_bIsRenderingToShadow = false; } Update, fixed a bug about the drawing of environment parts on the leaves in the moment that the camera were too much closer to these ones and so the alpha value were decreased
-
Hi everyone i m sharing this tool because tonight i made some changings into paked archives and i reached >4gb on it... but i forgot epack is 32bit.... so i wasn t able anymore unpack the archive, in short terms i had to compile lzomodule and etermanager in 64bit for solve this problem, and probably if anyone works on graphic upscaling will experiment this problem too, so there is the 64bit unpacker, i hope it can be usefull for anyone. Lemme know if you experiment some bugs or if i ve to change something.
- 2 replies
-
- 24
-
-
-
