-
Posts
613 -
Joined
-
Last visited
-
Days Won
96 -
Feedback
100%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Everything posted by martysama0134
-
official Ship Defense (Hydra Dungeon)
martysama0134 replied to Owsap's topic in Features & Metin2 Systems
I haven't tested the system, but there's something that you should always avoid if possible: using UniqueCharacterMap = std::map<UNIQUE_CHAR_POSITION, LPCHARACTER>; UniqueCharacterMap m_mapUniqueCharacter; 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: LPCHARACTER FindValidCharacter(const VID & vid) { if (!vid.GetID()) return nullptr; const auto ch = CHARACTER_MANAGER::instance().Find(vid.GetID()); return (ch && !ch->IsDead()) ? ch : nullptr; } Thanks for sharing. -
The M2 Download Center may not include the last changes I've committed: [Hidden Content] 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".
- 143 replies
-
- 39
-
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
-
fix Fix horse skills after changing horse riding position
martysama0134 replied to filipw1's topic in Bug Fixes
Yes, if you want. -
fix Fix horse skills after changing horse riding position
martysama0134 replied to filipw1's topic in Bug Fixes
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. -
@ VegaS™from the latest episode of the orville
-
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. Yes
-
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)
-
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 [Hidden Content] 0.7f
-
I've created a Roadmap for the WE Remix: [Hidden Content] Let me know of any possible feature / bug that can be added in there.
-
Try the latest version. If I remember correctly, it should fix it even without the external dpi manifest fix.
-
Like automatic Guild rooms in the Discord server
-
DungeonBlock and LightMap: set Gr2 Model for .prd
martysama0134 replied to Toki.San's topic in Guides & HowTo
One of the most important tutorials for developing outstanding indoor dungeons. -
You probably got a warning in that line, but the solution is even simpler: m_pointsInstant = {};
-
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.
- 34 replies
-
- 16
-
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; You're missing if (d) { ... } brackets. if you were to get a nullptr d, you'd end up with a core crash there.
-
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;
-
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 [Hidden Content] 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); }
- 29 replies
-
- 31
-
8px is too much. I see 1px in the other monitor. I suggest you -7.
-
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.
-
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.
-
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)
- 40 replies
-
- 132