-
Posts
613 -
Joined
-
Last visited
-
Days Won
96 -
Feedback
100%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Posts posted by martysama0134
-
-
The M2 Download Center may not include the last changes I've committed:
In the last commit, I've added a post-build event that "touches" system.c. (in v2.1 it touches _RESERVED)
If you're asking why I've done this: visual studio has a known bug of not triggering the pre-build events after a "rebuild".
- 25
- 3
- 3
- 8
-
23 minutes ago, Jimmermania said:
Hello guys,i installed mailbox from @ Mali, but when i try to log in i have this error:
0725 13:30:07144 :: networkmodule.py(line:211) networkmodule.MainStream.SetSelectCharacterPhase (C:\Users\George\Desktop\WoM2\Binary\Client\CRootLib\Workplace\RootLib\cyTemp\networkmodule.c:3901) system.py(line:169) system.__hybrid_import (C:\Users\George\Desktop\WoM2\Binary\Client\CRootLib\Workplace\RootLib\cyTemp\system.c:3889) introselect.py(line:32) init introselect (C:\Users\George\Desktop\WoM2\Binary\Client\CRootLib\Workplace\RootLib\cyTemp\introselect.c:30467) system.py(line:169) system.__hybrid_import (C:\Users\George\Desktop\WoM2\Binary\Client\CRootLib\Workplace\RootLib\cyTemp\system.c:3889) interfacemodule.py(line:52) init interfacemodule (C:\Users\George\Desktop\WoM2\Binary\Client\CRootLib\Workplace\RootLib\cyTemp\interfacemodule.c:58471) system.py(line:190) system.__hybrid_import (C:\Users\George\Desktop\WoM2\Binary\Client\CRootLib\Workplace\RootLib\cyTemp\system.c:4312) networkmodule.SetSelectCharacterPhase - <type 'exceptions.ImportError'>:No module named uimailbox 0725 13:30:07144 :: ============================================================================================================ 0725 13:30:07144 :: Abort!!!!
I added uimailbox at PythonrootlibManager.cpp, but when i compile .exe i have this error:
Severity Code Description Project File Line Suppression State Error LNK2001 unresolved external symbol _inituimailbox UserInterface
Any ideas?
1) You should add the uimailbox.c file in the cythonrootlib project.
2) You should add the {"uimailbox",inituimailbox} import in the pythonrootlibmanager.cpp file.
3) You have to be sure that the file is called&imported as uimailbox.py, and not differently. It's case sensitive, so uiMailBox may not work if the file isn't called uiMailBox.py
-
5 minutes ago, ReFresh said:
So, if I'm not mistaken, we can do that like the @martysama0134 said and we can add the DWORD GetHorseSkillSlotIndex() to PythonPlayer.h to make the function shared in CPythonPlayer class.
Yes, if you want.
-
This is what I did some time ago:
DWORD GetHorseSkillSlotIndex() { constexpr auto HorseSkillIndex = 130; static DWORD RequireSkillSlotIndex = 0; if (!RequireSkillSlotIndex) CPythonPlayer::Instance().FindSkillSlotIndexBySkillIndex(HorseSkillIndex, &RequireSkillSlotIndex); return RequireSkillSlotIndex; } bool CPythonPlayer::__CanUseSkill() { CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); if (!pkInstMain) return false; if (IsObserverMode()) return false; // Terrible skill slot index managament if (pkInstMain->IsMountingHorse() && (GetSkillGrade(GetHorseSkillSlotIndex()) < 1 && GetSkillLevel(GetHorseSkillSlotIndex()) < 20)) return false; return pkInstMain->CanUseSkill(); } bool CPythonPlayer::__CanAttack() { if (__IsProcessingEmotion()) return false; if (IsOpenPrivateShop()) return false; if (IsObserverMode()) return false; CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); if (!pkInstMain) return false; // Terrible skill slot index managament if (pkInstMain->IsMountingHorse() && pkInstMain->IsNewMount() && (GetSkillGrade(GetHorseSkillSlotIndex()) < 1 && GetSkillLevel(GetHorseSkillSlotIndex()) < 11)) return false; return pkInstMain->CanAttack(); }
I haven't tested your solution, but using GetSkillSlotIndex should be better than FindSkillSlotIndexBySkillIndex.
- 2
- 1
-
- 1
- 6
-
12 minutes ago, ReFresh said:
it's a global fix for all default sources?
Yes, every source is affected. For the other registered effects (not fly), you should search for each GetCaseCRC32 call (a dozen) and fix the input with StringPath.
12 minutes ago, ReFresh said:Did I do it right?
Yes
- 1
- 1
-
On 1/29/2020 at 6:10 PM, Karbust said:
I have a couple of bugs:
- Normal arrows don't have any effect
- Skills don't have any effect (only the skill "warmup" before shooting) while shooting, neither normal arrows nor the quiver
On Debug Target, the fly effects are not registered.
You also need to check whether the GetCaseCRC32(filename) is getting mismatches due to UpPeRcAse!=lowercase and backslashes \\\ vs slashes /// or not. (most of the new boss effects are not displayed because of this)
like this: (GameLib\RaceMotionDataEvent.h)
StringPath(strFlyFileName); //@fixme030 dwFlyIndex = GetCaseCRC32(strFlyFileName.c_str(), strFlyFileName.length()); // Register Fly CFlyingManager::Instance().RegisterFlyingData(strFlyFileName.c_str());
and also this one: (GameLib\FlyingInstance.cpp)
- 1
- 2
- 4
-
3 hours ago, Syreldar said:
But based on what I see here, it means the target will also be pushed way farther than intended while usually targets with Immunity to Fall (mental warriors) get pushed way less.
To solve this, I've tried to reduce the push by 20%:
// VICTIM_COLLISION_TEST const D3DXVECTOR3& kVictimPos = rVictim.GetPosition(); auto externalForceRatio = 1.0f; if (rVictim.IsResistFallen()) externalForceRatio = 0.8f; // reduce external force almost like before rVictim.m_PhysicsObject.IncreaseExternalForce(kVictimPos, c_rAttackData.fExternalForce * externalForceRatio); // VICTIM_COLLISION_TEST_END
ActorInstanceBattle.cpp CActorInstance::__ProcessDataAttackSuccess
https://metin2.download/video/vMrt47r4elg57lFB6ym3v765UoC6q2MI/.mp4
0.7f- 1
- 2
- 1
-
4 hours ago, WeedHex said:
Hmmm, it's not properly a bug. It's happening because you are not making any movement in the victim.
Anyway thanks to this thread, after some check, I figured out that may be this the problem:
File ActorInstanceSync.cpp:
Replace the function
void CActorInstance::__Push(int x, int y) { const D3DXVECTOR3& c_rv3Src=GetPosition(); const D3DXVECTOR3 c_v3Dst=D3DXVECTOR3(x, -y, c_rv3Src.z); const D3DXVECTOR3 c_v3Delta=c_v3Dst-c_rv3Src; const auto LoopValue = 100; const D3DXVECTOR3 inc = c_v3Delta / LoopValue; D3DXVECTOR3 v3Movement(0.0f, 0.0f, 0.0f); IPhysicsWorld* pWorld = IPhysicsWorld::GetPhysicsWorld(); if (!pWorld) return; for (int i = 0; i < LoopValue; ++i) { if (pWorld->isPhysicalCollision(c_rv3Src + v3Movement)) { ResetBlendingPosition(); return; } v3Movement += inc; } SetBlendingPosition(c_v3Dst); if (IsResistFallen()) return; if (!IsUsingSkill()) { const int len = sqrt(c_v3Delta.x*c_v3Delta.x+c_v3Delta.y*c_v3Delta.y); if (len > 150.0f) { InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING); PushOnceMotion(CRaceMotionData::NAME_STAND_UP); } } }
Yep, as you can see I just moved the order of execution of a statement. I leave the theory to you.
This solves the issue client-side, but not server-side. When you respawn, you restart from where the one-sided fight started:
I'm gonna check it further more.
After relogin:
- 1
- 1
- 1
-
12 hours ago, VegaS™ said:
UPDATE
Alright, after some debugging:
Here is a fast fix and should work fine, I didn't test it so well.
- UserInterface\PythonApplicationProcedure.cpp
Hidden ContentLRESULT CPythonApplication::WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) { if (wParam == 0xF100) return 1; [...] }
I've tested it and it seems fine. Gonna test it further more.
I just prefer it like this:
case WM_SYSCOMMAND: if (wParam == SC_KEYMENU) return 0; break;
Edit: I've changed the return 1L to return 0. Even (TRUE) should be fine (which is 1).
https://docs.microsoft.com/en-us/windows/win32/menurc/wm-syscommand
- 1
- 2
- 1
-
I've created a Roadmap for the WE Remix: https://trello.com/b/SWZ7gxkh/worldeditor-remix
Let me know of any possible feature / bug that can be added in there.
- 1
- 1
-
On 5/31/2022 at 4:38 AM, Shizer said:
Hello, I ran into a problem and I don't know how to solve it, namely my 24 inch monitor broke down recently, and I bought a new 28 inch, and part of the side panel is cut off in the world editor, how can I fix it? changing the resolution does not help, in the current one is 150 recommended, everywhere in other programs it works properly, and with world editor I have a problem unfortunately, can someone help me with it?
https://metin2.download/picture/EbYmB3mGSKV2ddrA2ytVIEYw4K50nsDz/.png
Try the latest version. If I remember correctly, it should fix it even without the external dpi manifest fix.
- 1
- 1
-
5 hours ago, ASIKOO said:
it gives me ideas!
Like automatic Guild rooms in the Discord server
Spoilerevery guild member will have the relative GUILDNAME role; if kicked in game, the member will lose the role automatically on discord too
- 2
- 4
-
I don't suggest freebsd 11.4 because it reached the end-of-life support. You should use either freebsd 13.0 or 12.2 (when 12.3 will be out, 12.2 will be trashed away)
-
One of the most important tutorials for developing outstanding indoor dungeons.
- 1
-
1 hour ago, sxvoyz said:
void CHARACTER::Initialize() { memset(&m_pointsInstant, 0, sizeof(m_pointsInstant)); }
That's why somebody got crash. Try define map/unordered_map outside this structure then everything will be alright.
You probably got a warning in that line, but the solution is even simpler:
m_pointsInstant = {};
- 1
- 1
-
There are far better solutions than using std::map or std::unordered_map (which still takes a lot of ram for no reason for each mob):
(I included the most important parts)
You also forgot the CubeItems, and we could probably fit the quickslot too.
Spoiler- 2
- 7
- 7
-
The problem is not related to "some serverfiles", but to the servers' network.
In theory, after you close the client (via "quit" cmdchat) the connection should be interrupted, but on some occasions they remained stucked, and that's the bug. The stucked character will probably remain online for 300s until the server will kick it.
case SCMD_QUIT: ch->ChatPacket(CHAT_TYPE_COMMAND, "quit"); if (d) d->SetPhase(PHASE_CLOSE); break;
I would try like this first, otherwise I'll stick with DelayedDisconnect(1) instead of SetPhase like:
case SCMD_QUIT: ch->ChatPacket(CHAT_TYPE_COMMAND, "quit"); if (d) d->DelayedDisconnect(1); break;
2 hours ago, Draveniou1 said:Its 100% fix without game.core or another problems
case SCMD_QUIT: if (d) d->DelayedDisconnect(2); d->ChatPacket(CHAT_TYPE_COMMAND, "quit"); break;
You're missing if (d) { ... } brackets. if you were to get a nullptr d, you'd end up with a core crash there.
- 2
- 3
- 2
-
1 hour ago, xifati said:
I cut it in order to see the whole client in 1920x1080 res (otherwise the Windows taskbar will eat up some pixels), Set titlebarSize to 0, otherwise set titlebarSize to 0 only if m_pySystem.GetHeight() >= 1000.
auto titlebarSize = (m_pySystem.GetHeight() >= 1000) ? 10 : 0;
- 3
- 1
-
7 hours ago, Abel(Tiger) said:
Those ~5px are for the shadows if I'm not mistaken.
Also the ideea made by Ymir to open the client in two diferent position is stupid.
I consider opening the windowed client on the center it's the best solution:
if (Windowed) { m_isWindowed = true; RECT rc; GetClientRect(&rc); int windowWidth = rc.right - rc.left; int windowHeight = (rc.bottom - rc.top); // 80 is the gap for the taskbar, you can increase it CMSApplication::SetPosition((GetScreenWidth() - windowWidth) / 2, (GetScreenHeight() - windowHeight - 80) / 2); } else { m_isWindowed = false; SetPosition(0, 0); }
I used GetWindowRect to calculate the dropshadow area automatically:
AdjustSize(m_pySystem.GetWidth(), m_pySystem.GetHeight()); if (Windowed) { m_isWindowed = true; RECT rc{}; GetClientRect(&rc); auto windowWidth = rc.right - rc.left; auto windowHeight = (rc.bottom - rc.top); //TraceError("windowWidth %d == %d windowHeight %d == %d", windowWidth, m_pySystem.GetWidth(), windowHeight, m_pySystem.GetHeight()); RECT rc2{}; GetWindowRect(&rc2); auto windowWidth2 = rc2.right - rc2.left; auto windowHeight2 = (rc2.bottom - rc2.top); //TraceError("windowWidth2 %d windowHeight2 %d", windowWidth2, windowHeight2); auto windowWidthDiff = windowWidth2 - windowWidth; auto windowHeightDiff = windowHeight2 - windowHeight; //TraceError("windowWidthDiff %d windowHeightDiff %d", windowWidthDiff, windowHeightDiff); //TraceError("GetLastError %d", ::GetLastError()); constexpr auto taskbarSize = 80; auto dropshadowSize = (windowWidthDiff / 2 != 0) ? (windowWidthDiff / 2 - 1) : 0; CMSApplication::SetPosition(((GetScreenWidth() - windowWidth) / 2) - dropshadowSize, (GetScreenHeight() - windowHeight - taskbarSize) / 2); } else { m_isWindowed = false; SetPosition(0, 0); }
This one is for 1920x1080 res
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowrect
Old way with second window:
AdjustSize(m_pySystem.GetWidth(), m_pySystem.GetHeight()); if (Windowed) { m_isWindowed = true; RECT rc{}; GetClientRect(&rc); auto windowWidth = rc.right - rc.left; auto windowHeight = (rc.bottom - rc.top); //TraceError("windowWidth %d == %d windowHeight %d == %d", windowWidth, m_pySystem.GetWidth(), windowHeight, m_pySystem.GetHeight()); RECT rc2{}; GetWindowRect(&rc2); auto windowWidth2 = rc2.right - rc2.left; auto windowHeight2 = (rc2.bottom - rc2.top); //TraceError("windowWidth2 %d windowHeight2 %d", windowWidth2, windowHeight2); auto windowWidthDiff = windowWidth2 - windowWidth; auto windowHeightDiff = windowHeight2 - windowHeight; //TraceError("windowWidthDiff %d windowHeightDiff %d", windowWidthDiff, windowHeightDiff); //TraceError("GetLastError %d", ::GetLastError()); auto dropshadowSize = (windowWidthDiff / 2 != 0) ? (windowWidthDiff / 2 - 1) : 0; #ifdef ENABLE_CENTERED_CLIENT_WINDOW constexpr auto taskbarSize = 80; CMSApplication::SetPosition(((GetScreenWidth() - windowWidth) / 2) - dropshadowSize, (GetScreenHeight() - windowHeight - taskbarSize) / 2); #else constexpr auto taskbarSize = 73; constexpr auto titlebarSize = 10; if (bAnotherWindow) CMSApplication::SetPosition(GetScreenWidth() - windowWidth - dropshadowSize, GetScreenHeight() - windowHeight - taskbarSize); else SetPosition(-dropshadowSize, -titlebarSize); #endif } else { m_isWindowed = false; SetPosition(0, 0); }
- 18
- 6
- 7
-
8px is too much. I see 1px in the other monitor. I suggest you -7.
- 1
- 1
-
On 9/18/2021 at 2:23 AM, Helia01 said:
I'm not saying that this is an ideal solution. If you have any ideas, please write comments.
If m_DamageQueue' size() is bigger than 20 elements, you can just pop() the old one. Just 2 lines of code required.
I suggest you to change its type from std::list to std::queue.
- 4
-
On 9/16/2021 at 2:34 PM, Distraught said:
The effects you use on your maps are not managed by EffectManager. They are managed by the Area itself.
I've checked them, and they don't stack up. The loaded effects will keep being played as a loop until you move outside of the closed 2x2 area.
In here there was only one element inside m_EffectInstanceMap, and rkEftMgr.DestroyUnsafeEffectInstance has never being called.
I initially thought to move the CArea::__UpdateEffectList call inside CPythonBackground::Update, but we probably don't even need to do so if there are no temporary effects in the maps.
- 2
- 3
-
The black screen was mostly caused by two major bugs:
-
The granny controller freezing the process for n seconds until you get dc'd from the game
- You can test it by:
- Spawning tons of monsters
- Minimize the client for 30 - 40 minutes
- Maximizing the window again (it will freeze exactly at this point)
-
The EffectManager not destroying the expired effects while the window was minimized, which caused all the executed effects to stack up and be run all at once after maximizing the window again
- You can test this bug very easily:
-
Spawn tons Flame Ghosts and minimize the window
- /ma "Flame Ghost" 100
- /cannot_dead
I wasn't sure how to solve the 1st one, but for the 2nd one you can fix it in one of these ways:
1st Way) refresh only once every 256 frames = 4-6 seconds depending on the lag
2nd Way) effect manager refresh for every frame
3rd Way) move the update from RenderGame to UpdateGame (it may not be called if skipFrame=true on ::Process)
- 62
- 1
- 3
- 1
- 1
- 27
- 9
- 28
-
The granny controller freezing the process for n seconds until you get dc'd from the game
Ship Defense (Hydra Dungeon)
in Features & Metin2 Systems
Posted
I haven't tested the system, but there's something that you should always avoid if possible:
You are directly storing the character ptr into the map, and, later on, calling GetUniqueCharacter to get the ptr back. There's a very good possibility of getting a dangling pointer.
Purged monsters expire immediately, dead monsters in few seconds. One of the common issues of writing dungeons in c++ is actually this one.
To be sure you're not getting a dangling pointer, you should store the VID of the monster instead of the ptr. This little change slightly affects performance though.
This function should be enough to check the validity of a vid:
Thanks for sharing.