Honorable Member Owsap 9812 Posted August 30, 2022 Honorable Member Share Posted August 30, 2022 (edited) This is the hidden content, please Sign In or Sign Up Other Mirros This is the hidden content, please Sign In or Sign Up (GitHub) This is the hidden content, please Sign In or Sign Up (Mega) Ship Defense is a dungeon accessible only in groups (minimum 2 players, maximum 8) in which players set sail for the new continent defending the ship’s mast from increasingly stronger and more numerous monsters until they defeat all three heads of the Hydra boss. Once the mission is complete, the participants will receive some rewards (determined by chance). Information Spoiler Entry Requirements All these requirements can be disabled. The player must be present in a group. Only the Group Leader can request entry to the dungeon. All group members must have a Passage Ticket. The maximum number of participants is 8 and the minimum is 2. All group members must be on the same map. The use of mounts is not allowed. Entrance The Group Leader requests entry from the Fisherman NPC, located at Dragon Fire Chief, so all participants will be able to access the map. Requirements: have a Passage Ticket and do not use mounts of any kind. Objective The objective is to defend the mast, located on the deck of your ship, from sea monsters and the giant three-headed Hydra. A fight against the destruction of the ship’s mast: monsters attack the main sail in a targeted way to make the boat sink: it will have to be defended from waves of increasingly strong attacks. At the top right, under the mini-map, the HP bar of the ship’s Mast will appear. Battle The challenge will begin after the leader (only he can do it) has interacted with the NPC Rudder. All group members must be present in the ship, otherwise it will not be possible to start. From now on you will have 60 seconds to prepare before the ship sails. After these, the characters will have access to the deck of the ship and the first monsters will arrive. Stage 1 – Hold on for 120 seconds! The aim of the first phase is to resist the attack of the monsters for 120 seconds, defending the mast NPC. After the time has elapsed, there will be a 10 second pause before moving on to the next phase. Stage 2 – Destroy the first head! To complete the second phase it will be necessary to destroy the head of the Hydra, which will appear from the hole in the stern just below the rudder, while continuing to defend the Mast. In this phase, other types of monsters will appear. Defeat the first head, after 10 seconds, we will move on to the next phase. Certain monsters will attack with special attacks, the Brood of Hydra will be able to use a laser beam to heavily damage the tree, this beam can be interrupted by walking over a blue circle with an arrow. This can only be done once per every 10 seconds. Killing the Hydra Brood will spawn Wood for repair, a very weak stone type that if destroyed will drop a Wood for Repair (item) that will allow you to recharge the tree’s HP a little. Stage 3 – Destroy the second head! The third phase is identical to the previous one: it will end once the second head of the Hydra is destroyed. The waves of monsters will be more conspicuous and more resistant monsters will appear. More monsters will attack the Tree from a distance. At the end of the phase, after 10 seconds you will move on to the next one. Stage 4 – Destroy the last head! The last phase is a much more complicated version of the previous two, not only for the number, type and strength of the monsters, but also for the periodic activation of the Null Magic debuff (loss of all buffs, as for effect activated by the Ability Nullify Magic ) for 25 seconds that will be inflicted on all party members by the last head of the Hydra . Once this last phase is completed, the reward can be obtained. Possibility of failing The group may fail if: The Master Tree is destroyed by monsters All party members choose the Surrender button after dying (in this case you will be taken to Dragon Fire Chief) In case of Crash It is possible to reconnect to the dungeon at any time after a crash, the character will reappear directly inside the dungeon. You must log back into the same channel the dungeon was started in, otherwise you will be taken out to Dragon Fire Chief. It is however possible to re-enter the dungeon by reconnecting in the correct channel. In the event that all members of the party unplug / crash, it is still possible to re-enter the dungeon. Attention, even if there are no group members inside the dungeon, it will continue to function normally. For example, if all party members disconnect at the beginning of the dungeon (Phase 1), and then reconnect 3 minutes later, they will end up in Phase 2 of the dungeon, resulting in the loss of life of the Master Tree . Demonstration Spoiler Edited September 4, 2022 by Metin2 Dev Core X - External 2 Internal 320 3 6 2 1 2 1 2 1 1 2 1 87 1 21 160 https://owsap.dev/ / https://osf.owsap.dev/ Link to comment Share on other sites More sharing options...
Contributor Veltor88 5643 Posted August 30, 2022 Contributor Share Posted August 30, 2022 #HonorableOwsap 2 1 Link to comment Share on other sites More sharing options...
Management ɛʟ Ǥʟɑçѳи 🧊 7991 Posted August 30, 2022 Management Share Posted August 30, 2022 (edited) Edited September 4, 2022 by Metin2 Dev Core X - External 2 Internal 1 1 1 1 I don't respond to any private messages, except for messages regarding ad system issues... For everything else, please join the Discord server and open a ticket... Link to comment Share on other sites More sharing options...
Kafa 163 Posted August 30, 2022 Share Posted August 30, 2022 Exactly what i needed, i was about to buy it. But whats the music tho XD Link to comment Share on other sites More sharing options...
Artagnanxd 92 Posted August 30, 2022 Share Posted August 30, 2022 (edited) someone, something? ShipDefense.h:176:2: error: 'time_t' in namespace 'std' does not name a type std::time_t GetStartTime() const { return m_lStartTime; } ^ ShipDefense.h:206:2: error: 'time_t' in namespace 'std' does not name a type std::time_t m_lStartTime; solution: #include <ctime> Edited August 30, 2022 by Artagnanxd 6 1 Link to comment Share on other sites More sharing options...
Honorable Member Syreldar 2080 Posted August 31, 2022 Honorable Member Share Posted August 31, 2022 (edited) I'd like to share a message. Your story is kind of a complex one: you went through and had to deal with countless resellers, leakers and the betrayal of close friends, yet that never stopped you from doing what you loved. You once were a reseller yourself, but you proved everyone you didn't mean to hurt other people's work, you managed to work hard and redeem yourself. Back when I didn't know you, I wanted to join your project to see what it was all about and in time came to realize what a great person you are. You are now part of the Honorable members, the most esteemed people in the Metin2 community on a global level. I am truly proud of your redemption arc. You're an inspiration and in my opinion fully represent who people in this community should aim to be: A Fair, Square and Hard working person that learns from their mistakes. I didn't know you were aiming to release your latest work for free given how much time you spent on it, but thinking about it this truly is the hardest hitting thing you could've possibly done; to release such a dungeon for free really is a powerful act and deserves praise. Thank you again for never giving up. Edited August 31, 2022 by Syreldar 1 1 1 6 "Nothing's free in this life. Ignorant people have an obligation to make up for their ignorance by paying those who help them. Either you got the brains or cash, if you lack both you're useless." Syreldar Link to comment Share on other sites More sharing options...
Forum Moderator Gurgarath 2977 Posted August 31, 2022 Forum Moderator Share Posted August 31, 2022 Astonishing work from you, as well as an excellent asset for the community as a whole. Despite all the downside imaginable to willingly share something that cost you considerable time to complete and energy to fiddle for what is conceivably a limited appraise. Just as Distraught recently, or others before you (Mali, xP3NG3Rx and so on), I personally think you greatly deserve your place amongst the Honorable members of this community, for the quality as well as the will to make the community move forward and I believe everyone agrees with that, ASIKOO being the first. Thank you! 2 6 Gurgarath coming soon Link to comment Share on other sites More sharing options...
Trudix 47 Posted August 31, 2022 Share Posted August 31, 2022 (edited) Compiling error: Spoiler compiling main.cpp In file included from questlua_shipdefense_mgr.cpp:23: ShipDefense.h:176:7: error: 'time_t' in namespace 'std' does not name a type std::time_t GetStartTime() const { return m_lStartTime; } ^~~~~~ ShipDefense.h:176:2: note: suggested alternative: 'time_put' std::time_t GetStartTime() const { return m_lStartTime; } ^~~ time_put ShipDefense.h:206:7: error: 'time_t' in namespace 'std' does not name a type std::time_t m_lStartTime; ^~~~~~ ShipDefense.h:206:2: note: suggested alternative: 'time_put' std::time_t m_lStartTime; ^~~ time_put gmake: *** [Makefile:161: .obj/questlua_shipdefense_mgr.o] Error 1 gmake: *** Waiting for unfinished jobs.... In file included from ShipDefense.cpp:20: ShipDefense.h:176:7: error: 'time_t' in namespace 'std' does not name a type std::time_t GetStartTime() const { return m_lStartTime; } ^~~~~~ ShipDefense.h:176:2: note: suggested alternative: 'time_put' std::time_t GetStartTime() const { return m_lStartTime; } ^~~ time_put ShipDefense.h:206:7: error: 'time_t' in namespace 'std' does not name a type std::time_t m_lStartTime; ^~~~~~ ShipDefense.h:206:2: note: suggested alternative: 'time_put' std::time_t m_lStartTime; ^~~ time_put ShipDefense.cpp: In member function 'void SNotice::operator()(LPENTITY)': ShipDefense.cpp:269:58: error: 'class CHARACTER' has no member named 'GetLanguag e' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()) ^~~~~~~~~~~ ShipDefense.cpp:269:6: error: 'LC_MOB_NAME' was not declared in this scope LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()) ^~~~~~~~~~~ ShipDefense.cpp:269:6: note: suggested alternative: 'CMD_NAME' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()) ^~~~~~~~~~~ CMD_NAME ShipDefense.cpp:286:58: error: 'class CHARACTER' has no member named 'GetLanguag e' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ ShipDefense.cpp:286:6: error: 'LC_MOB_NAME' was not declared in this scope LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ ShipDefense.cpp:286:6: note: suggested alternative: 'CMD_NAME' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ CMD_NAME ShipDefense.cpp:287:55: error: 'class CHARACTER' has no member named 'GetLanguag e' LC_MOB_NAME(c_lpHydraChar->GetRaceNum(), lpChar->GetLanguage()) ^~~~~~~~~~~ ShipDefense.cpp:303:58: error: 'class CHARACTER' has no member named 'GetLanguag e' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ ShipDefense.cpp:303:6: error: 'LC_MOB_NAME' was not declared in this scope LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ ShipDefense.cpp:303:6: note: suggested alternative: 'CMD_NAME' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ CMD_NAME ShipDefense.cpp: In function 'long int LaserEffectEvent(LPEVENT, long int)': ShipDefense.cpp:483:8: error: 'random_device' is not a member of 'std' std::random_device RandomDevice; ^~~~~~~~~~~~~ ShipDefense.cpp:483:8: note: suggested alternative: 'ratio_divide' std::random_device RandomDevice; ^~~~~~~~~~~~~ ratio_divide ShipDefense.cpp:484:8: error: 'mt19937' is not a member of 'std' std::mt19937 Generate(RandomDevice()); ^~~~~~~ ShipDefense.cpp:485:8: error: 'uniform_real_distribution' is not a member of 'st d' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^~~~~~~~~~~~~~~~~~~~~~~~~ ShipDefense.cpp:485:8: note: suggested alternative: 'uniform_int_distribution' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^~~~~~~~~~~~~~~~~~~~~~~~~ uniform_int_distribution ShipDefense.cpp:485:34: error: expected primary-expression before '>' token std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^ ShipDefense.cpp:485:36: error: 'Distribute' was not declared in this scope std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^~~~~~~~~~ ShipDefense.cpp:485:36: note: suggested alternative: 'CAttribute' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^~~~~~~~~~ CAttribute ShipDefense.cpp:501:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= uiSpawnProbability) ^~~~~~~~ ShipDefense.cpp:501:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= uiSpawnProbability) ^~~~~~~~ rename ShipDefense.cpp: In function 'long int SpawnEvent(LPEVENT, long int)': ShipDefense.cpp:601:7: error: 'random_device' is not a member of 'std' std::random_device RandomDevice; ^~~~~~~~~~~~~ ShipDefense.cpp:601:7: note: suggested alternative: 'ratio_divide' std::random_device RandomDevice; ^~~~~~~~~~~~~ ratio_divide ShipDefense.cpp:602:7: error: 'mt19937' is not a member of 'std' std::mt19937 Generate(RandomDevice()); ^~~~~~~ ShipDefense.cpp:603:7: error: 'uniform_real_distribution' is not a member of 'st d' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^~~~~~~~~~~~~~~~~~~~~~~~~ ShipDefense.cpp:603:7: note: suggested alternative: 'uniform_int_distribution' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^~~~~~~~~~~~~~~~~~~~~~~~~ uniform_int_distribution ShipDefense.cpp:603:33: error: expected primary-expression before '>' token std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^ ShipDefense.cpp:603:35: error: 'Distribute' was not declared in this scope std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^~~~~~~~~~ ShipDefense.cpp:603:35: note: suggested alternative: 'CAttribute' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^~~~~~~~~~ CAttribute ShipDefense.cpp:635:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ ShipDefense.cpp:635:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ rename ShipDefense.cpp:638:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 30) // 3% ^~~~~~~~ ShipDefense.cpp:638:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 30) // 3% ^~~~~~~~ rename ShipDefense.cpp:664:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ ShipDefense.cpp:664:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ rename ShipDefense.cpp:667:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 40) // 4% ^~~~~~~~ ShipDefense.cpp:667:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 40) // 4% ^~~~~~~~ rename ShipDefense.cpp:693:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ ShipDefense.cpp:693:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ rename ShipDefense.cpp:696:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 50) // 5% ^~~~~~~~ ShipDefense.cpp:696:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 50) // 5% ^~~~~~~~ rename ShipDefense.cpp: In constructor 'CShipDefense::CShipDefense(long int, DWORD)': ShipDefense.cpp:738:2: error: 'm_lStartTime' was not declared in this scope m_lStartTime = 0; ^~~~~~~~~~~~ ShipDefense.cpp:738:2: note: suggested alternative: 'm_byState' m_lStartTime = 0; ^~~~~~~~~~~~ m_byState ShipDefense.cpp: In member function 'virtual void CShipDefense::Destroy()': ShipDefense.cpp:764:2: error: 'm_lStartTime' was not declared in this scope m_lStartTime = 0; ^~~~~~~~~~~~ ShipDefense.cpp:764:2: note: suggested alternative: 'm_byState' m_lStartTime = 0; ^~~~~~~~~~~~ m_byState ShipDefense.cpp: In member function 'void CShipDefense::Notice(LPCHARACTER, bool , const char*, ...)': ShipDefense.cpp:862:63: error: 'class CHARACTER' has no member named 'GetLanguag e' const char* c_pszLocaleText = LC_STRING(c_pszBuf, c_lpChar->GetLanguage()); ^~~~~~~~~~~ ShipDefense.cpp:862:33: error: 'LC_STRING' was not declared in this scope const char* c_pszLocaleText = LC_STRING(c_pszBuf, c_lpChar->GetLanguage()); ^~~~~~~~~ ShipDefense.cpp:862:33: note: suggested alternative: 'LC_TIME' const char* c_pszLocaleText = LC_STRING(c_pszBuf, c_lpChar->GetLanguage()); ^~~~~~~~~ LC_TIME ShipDefense.cpp: In member function 'void CShipDefense::Start()': ShipDefense.cpp:1057:2: error: 'm_lStartTime' was not declared in this scope m_lStartTime = std::time(nullptr); ^~~~~~~~~~~~ ShipDefense.cpp:1057:2: note: suggested alternative: 'm_byState' m_lStartTime = std::time(nullptr); ^~~~~~~~~~~~ m_byState ShipDefense.cpp: In member function 'bool CShipDefense::PrepareDeck()': ShipDefense.cpp:1094:3: error: 'm_lStartTime' was not declared in this scope m_lStartTime = std::time(nullptr); ^~~~~~~~~~~~ ShipDefense.cpp:1094:3: note: suggested alternative: 'm_byState' m_lStartTime = std::time(nullptr); ^~~~~~~~~~~~ m_byState gmake: *** [Makefile:161: .obj/ShipDefense.o] Error 1 Edited August 31, 2022 by Calypso2 Link to comment Share on other sites More sharing options...
Management ɛʟ Ǥʟɑçѳи 🧊 7991 Posted August 31, 2022 Management Share Posted August 31, 2022 3 minutes ago, Calypso2 said: Compiling error: Reveal hidden contents compiling main.cpp In file included from questlua_shipdefense_mgr.cpp:23: ShipDefense.h:176:7: error: 'time_t' in namespace 'std' does not name a type std::time_t GetStartTime() const { return m_lStartTime; } ^~~~~~ ShipDefense.h:176:2: note: suggested alternative: 'time_put' std::time_t GetStartTime() const { return m_lStartTime; } ^~~ time_put ShipDefense.h:206:7: error: 'time_t' in namespace 'std' does not name a type std::time_t m_lStartTime; ^~~~~~ ShipDefense.h:206:2: note: suggested alternative: 'time_put' std::time_t m_lStartTime; ^~~ time_put gmake: *** [Makefile:161: .obj/questlua_shipdefense_mgr.o] Error 1 gmake: *** Waiting for unfinished jobs.... In file included from ShipDefense.cpp:20: ShipDefense.h:176:7: error: 'time_t' in namespace 'std' does not name a type std::time_t GetStartTime() const { return m_lStartTime; } ^~~~~~ ShipDefense.h:176:2: note: suggested alternative: 'time_put' std::time_t GetStartTime() const { return m_lStartTime; } ^~~ time_put ShipDefense.h:206:7: error: 'time_t' in namespace 'std' does not name a type std::time_t m_lStartTime; ^~~~~~ ShipDefense.h:206:2: note: suggested alternative: 'time_put' std::time_t m_lStartTime; ^~~ time_put ShipDefense.cpp: In member function 'void SNotice::operator()(LPENTITY)': ShipDefense.cpp:269:58: error: 'class CHARACTER' has no member named 'GetLanguag e' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()) ^~~~~~~~~~~ ShipDefense.cpp:269:6: error: 'LC_MOB_NAME' was not declared in this scope LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()) ^~~~~~~~~~~ ShipDefense.cpp:269:6: note: suggested alternative: 'CMD_NAME' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()) ^~~~~~~~~~~ CMD_NAME ShipDefense.cpp:286:58: error: 'class CHARACTER' has no member named 'GetLanguag e' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ ShipDefense.cpp:286:6: error: 'LC_MOB_NAME' was not declared in this scope LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ ShipDefense.cpp:286:6: note: suggested alternative: 'CMD_NAME' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ CMD_NAME ShipDefense.cpp:287:55: error: 'class CHARACTER' has no member named 'GetLanguag e' LC_MOB_NAME(c_lpHydraChar->GetRaceNum(), lpChar->GetLanguage()) ^~~~~~~~~~~ ShipDefense.cpp:303:58: error: 'class CHARACTER' has no member named 'GetLanguag e' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ ShipDefense.cpp:303:6: error: 'LC_MOB_NAME' was not declared in this scope LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ ShipDefense.cpp:303:6: note: suggested alternative: 'CMD_NAME' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ CMD_NAME ShipDefense.cpp: In function 'long int LaserEffectEvent(LPEVENT, long int)': ShipDefense.cpp:483:8: error: 'random_device' is not a member of 'std' std::random_device RandomDevice; ^~~~~~~~~~~~~ ShipDefense.cpp:483:8: note: suggested alternative: 'ratio_divide' std::random_device RandomDevice; ^~~~~~~~~~~~~ ratio_divide ShipDefense.cpp:484:8: error: 'mt19937' is not a member of 'std' std::mt19937 Generate(RandomDevice()); ^~~~~~~ ShipDefense.cpp:485:8: error: 'uniform_real_distribution' is not a member of 'st d' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^~~~~~~~~~~~~~~~~~~~~~~~~ ShipDefense.cpp:485:8: note: suggested alternative: 'uniform_int_distribution' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^~~~~~~~~~~~~~~~~~~~~~~~~ uniform_int_distribution ShipDefense.cpp:485:34: error: expected primary-expression before '>' token std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^ ShipDefense.cpp:485:36: error: 'Distribute' was not declared in this scope std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^~~~~~~~~~ ShipDefense.cpp:485:36: note: suggested alternative: 'CAttribute' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^~~~~~~~~~ CAttribute ShipDefense.cpp:501:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= uiSpawnProbability) ^~~~~~~~ ShipDefense.cpp:501:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= uiSpawnProbability) ^~~~~~~~ rename ShipDefense.cpp: In function 'long int SpawnEvent(LPEVENT, long int)': ShipDefense.cpp:601:7: error: 'random_device' is not a member of 'std' std::random_device RandomDevice; ^~~~~~~~~~~~~ ShipDefense.cpp:601:7: note: suggested alternative: 'ratio_divide' std::random_device RandomDevice; ^~~~~~~~~~~~~ ratio_divide ShipDefense.cpp:602:7: error: 'mt19937' is not a member of 'std' std::mt19937 Generate(RandomDevice()); ^~~~~~~ ShipDefense.cpp:603:7: error: 'uniform_real_distribution' is not a member of 'st d' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^~~~~~~~~~~~~~~~~~~~~~~~~ ShipDefense.cpp:603:7: note: suggested alternative: 'uniform_int_distribution' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^~~~~~~~~~~~~~~~~~~~~~~~~ uniform_int_distribution ShipDefense.cpp:603:33: error: expected primary-expression before '>' token std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^ ShipDefense.cpp:603:35: error: 'Distribute' was not declared in this scope std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^~~~~~~~~~ ShipDefense.cpp:603:35: note: suggested alternative: 'CAttribute' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^~~~~~~~~~ CAttribute ShipDefense.cpp:635:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ ShipDefense.cpp:635:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ rename ShipDefense.cpp:638:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 30) // 3% ^~~~~~~~ ShipDefense.cpp:638:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 30) // 3% ^~~~~~~~ rename ShipDefense.cpp:664:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ ShipDefense.cpp:664:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ rename ShipDefense.cpp:667:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 40) // 4% ^~~~~~~~ ShipDefense.cpp:667:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 40) // 4% ^~~~~~~~ rename ShipDefense.cpp:693:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ ShipDefense.cpp:693:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ rename ShipDefense.cpp:696:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 50) // 5% ^~~~~~~~ ShipDefense.cpp:696:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 50) // 5% ^~~~~~~~ rename ShipDefense.cpp: In constructor 'CShipDefense::CShipDefense(long int, DWORD)': ShipDefense.cpp:738:2: error: 'm_lStartTime' was not declared in this scope m_lStartTime = 0; ^~~~~~~~~~~~ ShipDefense.cpp:738:2: note: suggested alternative: 'm_byState' m_lStartTime = 0; ^~~~~~~~~~~~ m_byState ShipDefense.cpp: In member function 'virtual void CShipDefense::Destroy()': ShipDefense.cpp:764:2: error: 'm_lStartTime' was not declared in this scope m_lStartTime = 0; ^~~~~~~~~~~~ ShipDefense.cpp:764:2: note: suggested alternative: 'm_byState' m_lStartTime = 0; ^~~~~~~~~~~~ m_byState ShipDefense.cpp: In member function 'void CShipDefense::Notice(LPCHARACTER, bool , const char*, ...)': ShipDefense.cpp:862:63: error: 'class CHARACTER' has no member named 'GetLanguag e' const char* c_pszLocaleText = LC_STRING(c_pszBuf, c_lpChar->GetLanguage()); ^~~~~~~~~~~ ShipDefense.cpp:862:33: error: 'LC_STRING' was not declared in this scope const char* c_pszLocaleText = LC_STRING(c_pszBuf, c_lpChar->GetLanguage()); ^~~~~~~~~ ShipDefense.cpp:862:33: note: suggested alternative: 'LC_TIME' const char* c_pszLocaleText = LC_STRING(c_pszBuf, c_lpChar->GetLanguage()); ^~~~~~~~~ LC_TIME ShipDefense.cpp: In member function 'void CShipDefense::Start()': ShipDefense.cpp:1057:2: error: 'm_lStartTime' was not declared in this scope m_lStartTime = std::time(nullptr); ^~~~~~~~~~~~ ShipDefense.cpp:1057:2: note: suggested alternative: 'm_byState' m_lStartTime = std::time(nullptr); ^~~~~~~~~~~~ m_byState ShipDefense.cpp: In member function 'bool CShipDefense::PrepareDeck()': ShipDefense.cpp:1094:3: error: 'm_lStartTime' was not declared in this scope m_lStartTime = std::time(nullptr); ^~~~~~~~~~~~ ShipDefense.cpp:1094:3: note: suggested alternative: 'm_byState' m_lStartTime = std::time(nullptr); ^~~~~~~~~~~~ m_byState gmake: *** [Makefile:161: .obj/ShipDefense.o] Error 1 Try this : 1 I don't respond to any private messages, except for messages regarding ad system issues... For everything else, please join the Discord server and open a ticket... Link to comment Share on other sites More sharing options...
Honorable Member martysama0134 7977 Posted August 31, 2022 Honorable Member Share Posted August 31, 2022 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. 1 1 2 1 2 Check out my GitHub Link to comment Share on other sites More sharing options...
Honorable Member Owsap 9812 Posted August 31, 2022 Author Honorable Member Share Posted August 31, 2022 @Calypso2, check the repository, it's been updated since yesterday and you can include <ctime> in your stdafx.h. Spoiler 46 minutes ago, Calypso2 said: Compiling error: Hide contents compiling main.cpp In file included from questlua_shipdefense_mgr.cpp:23: ShipDefense.h:176:7: error: 'time_t' in namespace 'std' does not name a type std::time_t GetStartTime() const { return m_lStartTime; } ^~~~~~ ShipDefense.h:176:2: note: suggested alternative: 'time_put' std::time_t GetStartTime() const { return m_lStartTime; } ^~~ time_put ShipDefense.h:206:7: error: 'time_t' in namespace 'std' does not name a type std::time_t m_lStartTime; ^~~~~~ ShipDefense.h:206:2: note: suggested alternative: 'time_put' std::time_t m_lStartTime; ^~~ time_put gmake: *** [Makefile:161: .obj/questlua_shipdefense_mgr.o] Error 1 gmake: *** Waiting for unfinished jobs.... In file included from ShipDefense.cpp:20: ShipDefense.h:176:7: error: 'time_t' in namespace 'std' does not name a type std::time_t GetStartTime() const { return m_lStartTime; } ^~~~~~ ShipDefense.h:176:2: note: suggested alternative: 'time_put' std::time_t GetStartTime() const { return m_lStartTime; } ^~~ time_put ShipDefense.h:206:7: error: 'time_t' in namespace 'std' does not name a type std::time_t m_lStartTime; ^~~~~~ ShipDefense.h:206:2: note: suggested alternative: 'time_put' std::time_t m_lStartTime; ^~~ time_put ShipDefense.cpp: In member function 'void SNotice::operator()(LPENTITY)': ShipDefense.cpp:269:58: error: 'class CHARACTER' has no member named 'GetLanguag e' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()) ^~~~~~~~~~~ ShipDefense.cpp:269:6: error: 'LC_MOB_NAME' was not declared in this scope LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()) ^~~~~~~~~~~ ShipDefense.cpp:269:6: note: suggested alternative: 'CMD_NAME' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()) ^~~~~~~~~~~ CMD_NAME ShipDefense.cpp:286:58: error: 'class CHARACTER' has no member named 'GetLanguag e' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ ShipDefense.cpp:286:6: error: 'LC_MOB_NAME' was not declared in this scope LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ ShipDefense.cpp:286:6: note: suggested alternative: 'CMD_NAME' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ CMD_NAME ShipDefense.cpp:287:55: error: 'class CHARACTER' has no member named 'GetLanguag e' LC_MOB_NAME(c_lpHydraChar->GetRaceNum(), lpChar->GetLanguage()) ^~~~~~~~~~~ ShipDefense.cpp:303:58: error: 'class CHARACTER' has no member named 'GetLanguag e' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ ShipDefense.cpp:303:6: error: 'LC_MOB_NAME' was not declared in this scope LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ ShipDefense.cpp:303:6: note: suggested alternative: 'CMD_NAME' LC_MOB_NAME(c_lpAllianceChar->GetRaceNum(), lpChar->GetLanguage()), ^~~~~~~~~~~ CMD_NAME ShipDefense.cpp: In function 'long int LaserEffectEvent(LPEVENT, long int)': ShipDefense.cpp:483:8: error: 'random_device' is not a member of 'std' std::random_device RandomDevice; ^~~~~~~~~~~~~ ShipDefense.cpp:483:8: note: suggested alternative: 'ratio_divide' std::random_device RandomDevice; ^~~~~~~~~~~~~ ratio_divide ShipDefense.cpp:484:8: error: 'mt19937' is not a member of 'std' std::mt19937 Generate(RandomDevice()); ^~~~~~~ ShipDefense.cpp:485:8: error: 'uniform_real_distribution' is not a member of 'st d' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^~~~~~~~~~~~~~~~~~~~~~~~~ ShipDefense.cpp:485:8: note: suggested alternative: 'uniform_int_distribution' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^~~~~~~~~~~~~~~~~~~~~~~~~ uniform_int_distribution ShipDefense.cpp:485:34: error: expected primary-expression before '>' token std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^ ShipDefense.cpp:485:36: error: 'Distribute' was not declared in this scope std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^~~~~~~~~~ ShipDefense.cpp:485:36: note: suggested alternative: 'CAttribute' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefens e::MAX_PROB); ^~~~~~~~~~ CAttribute ShipDefense.cpp:501:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= uiSpawnProbability) ^~~~~~~~ ShipDefense.cpp:501:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= uiSpawnProbability) ^~~~~~~~ rename ShipDefense.cpp: In function 'long int SpawnEvent(LPEVENT, long int)': ShipDefense.cpp:601:7: error: 'random_device' is not a member of 'std' std::random_device RandomDevice; ^~~~~~~~~~~~~ ShipDefense.cpp:601:7: note: suggested alternative: 'ratio_divide' std::random_device RandomDevice; ^~~~~~~~~~~~~ ratio_divide ShipDefense.cpp:602:7: error: 'mt19937' is not a member of 'std' std::mt19937 Generate(RandomDevice()); ^~~~~~~ ShipDefense.cpp:603:7: error: 'uniform_real_distribution' is not a member of 'st d' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^~~~~~~~~~~~~~~~~~~~~~~~~ ShipDefense.cpp:603:7: note: suggested alternative: 'uniform_int_distribution' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^~~~~~~~~~~~~~~~~~~~~~~~~ uniform_int_distribution ShipDefense.cpp:603:33: error: expected primary-expression before '>' token std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^ ShipDefense.cpp:603:35: error: 'Distribute' was not declared in this scope std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^~~~~~~~~~ ShipDefense.cpp:603:35: note: suggested alternative: 'CAttribute' std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense ::MAX_PROB); ^~~~~~~~~~ CAttribute ShipDefense.cpp:635:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ ShipDefense.cpp:635:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ rename ShipDefense.cpp:638:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 30) // 3% ^~~~~~~~ ShipDefense.cpp:638:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 30) // 3% ^~~~~~~~ rename ShipDefense.cpp:664:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ ShipDefense.cpp:664:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ rename ShipDefense.cpp:667:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 40) // 4% ^~~~~~~~ ShipDefense.cpp:667:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 40) // 4% ^~~~~~~~ rename ShipDefense.cpp:693:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ ShipDefense.cpp:693:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 10) // 1% ^~~~~~~~ rename ShipDefense.cpp:696:36: error: 'Generate' was not declared in this scope if (static_cast<UINT>(Distribute(Generate)) <= 50) // 5% ^~~~~~~~ ShipDefense.cpp:696:36: note: suggested alternative: 'rename' if (static_cast<UINT>(Distribute(Generate)) <= 50) // 5% ^~~~~~~~ rename ShipDefense.cpp: In constructor 'CShipDefense::CShipDefense(long int, DWORD)': ShipDefense.cpp:738:2: error: 'm_lStartTime' was not declared in this scope m_lStartTime = 0; ^~~~~~~~~~~~ ShipDefense.cpp:738:2: note: suggested alternative: 'm_byState' m_lStartTime = 0; ^~~~~~~~~~~~ m_byState ShipDefense.cpp: In member function 'virtual void CShipDefense::Destroy()': ShipDefense.cpp:764:2: error: 'm_lStartTime' was not declared in this scope m_lStartTime = 0; ^~~~~~~~~~~~ ShipDefense.cpp:764:2: note: suggested alternative: 'm_byState' m_lStartTime = 0; ^~~~~~~~~~~~ m_byState ShipDefense.cpp: In member function 'void CShipDefense::Notice(LPCHARACTER, bool , const char*, ...)': ShipDefense.cpp:862:63: error: 'class CHARACTER' has no member named 'GetLanguag e' const char* c_pszLocaleText = LC_STRING(c_pszBuf, c_lpChar->GetLanguage()); ^~~~~~~~~~~ ShipDefense.cpp:862:33: error: 'LC_STRING' was not declared in this scope const char* c_pszLocaleText = LC_STRING(c_pszBuf, c_lpChar->GetLanguage()); ^~~~~~~~~ ShipDefense.cpp:862:33: note: suggested alternative: 'LC_TIME' const char* c_pszLocaleText = LC_STRING(c_pszBuf, c_lpChar->GetLanguage()); ^~~~~~~~~ LC_TIME ShipDefense.cpp: In member function 'void CShipDefense::Start()': ShipDefense.cpp:1057:2: error: 'm_lStartTime' was not declared in this scope m_lStartTime = std::time(nullptr); ^~~~~~~~~~~~ ShipDefense.cpp:1057:2: note: suggested alternative: 'm_byState' m_lStartTime = std::time(nullptr); ^~~~~~~~~~~~ m_byState ShipDefense.cpp: In member function 'bool CShipDefense::PrepareDeck()': ShipDefense.cpp:1094:3: error: 'm_lStartTime' was not declared in this scope m_lStartTime = std::time(nullptr); ^~~~~~~~~~~~ ShipDefense.cpp:1094:3: note: suggested alternative: 'm_byState' m_lStartTime = std::time(nullptr); ^~~~~~~~~~~~ m_byState gmake: *** [Makefile:161: .obj/ShipDefense.o] Error 1 @ martysama0134, this is something that I tested over and over again, when any character is purged, deleted or killed the pointer is removed immediately from the map and cleared preventing the pointer to get dangled and additional checks where made to avoid this issue but I might consider changing the storage type if eventually there are future problems with it. Thanks for the reply. Spoiler 9 minutes ago, martysama0134 said: 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. https://owsap.dev/ / https://osf.owsap.dev/ Link to comment Share on other sites More sharing options...
Developer Ikarus_ 2711 Posted August 31, 2022 Developer Share Posted August 31, 2022 (edited) I leave here a few tips that could improve code readability, performance and safety. I also report you a serious issue that generates memory leaks. Clearly, even though there are things that I consider outdated (which I am sure you have seen in the ymir code written in the early 2000s), I still appreciate that you have released all this work for free. The Functor (struct with operator()) is a trick used in the past to work with temporary functions that can store data, in short, a very outdated "lambda". Since C++11, we can use lambdas to definitely replace Functors, which are clearer and more readable and probably much optimizable by the compiler. The serious issue I noticed is how you insert and remove data inside m_mapShipDefense. (ps. emplace is always preferable than insert) The raw use of new and delete is to be considered outdated, and really unsafe. Proof of this is the leak I am about to show. Looking on CShipDefenseManager::Remove method: void CShipDefenseManager::Remove(const DWORD c_dwLeaderPID) { ShipDefenseMap::iterator it = m_mapShipDefense.find(c_dwLeaderPID); if (it != m_mapShipDefense.end()) m_mapShipDefense.erase(it); //erased but not deleted? } and again looking on CShipDefenseManager::Destroy() method: void CShipDefenseManager::Destroy() { ShipDefenseMap::iterator it = m_mapShipDefense.begin(); for (; it != m_mapShipDefense.end(); ++it) { CShipDefense* pShipDefense = it->second; if (pShipDefense) { pShipDefense->Destroy(); //is this use safe if you check its value immediately below? if (pShipDefense) delete pShipDefense; } } m_mapShipDefense.clear(); } A good way to solve your issue would be the use of smart pointers which are much safer and do the dirty work for you. PS: Since C++98 you can use struct without encapsulating it in a typedef declaration. typedef struct SBroadcastAllianceHP { } TBroadcastAllianceHP; // can be changed to struct TBroadcastAllianceHP { }; I've only checked ShipDefense.cpp so far. If I get time, I'll check the rest ---- EDIT I think you have misunderstood the meaning of the return value of the c lua functions. You should return the number of pushed elements in the stack. Many of the functions I have seen in the code you shared have a wrong return. int ship_defense_mgr_land(lua_State* L) { const LPCHARACTER c_lpChar = CQuestManager::instance().GetCurrentCharacterPtr(); if (c_lpChar == nullptr) return 0; CShipDefenseManager& rkShipDefenseMgr = CShipDefenseManager::Instance(); rkShipDefenseMgr.Land(c_lpChar); return 1; // WRONG - NO PUSHED ELEMENTS SO WHY 1? } int ship_defense_mgr_is_created(lua_State* L) { const LPCHARACTER c_lpChar = CQuestManager::instance().GetCurrentCharacterPtr(); if (c_lpChar == nullptr) return 0; CShipDefenseManager& rkShipDefenseMgr = CShipDefenseManager::Instance(); lua_pushboolean(L, rkShipDefenseMgr.IsCreated(c_lpChar)); return 1; // CORRECT, YOU PUSHED 1 ELEMENT } ----- EDIT2 I would recommend to add some small check here to make the function skip all monsters dead outside the dungeon. This method CShipDefenseManager::OnKill get called 2 times (first inside CHARACTER::Dead, second inside CHARACTER_MANAGER::DestroyCharacter) anytime a monster die, anytime a monster die in the whole core.Not a good idea keep it loops throught `std::map` (which is really slow to get iterated) and perform the whole CShipDefense::DeadCharacter on each dungeon instance (which it again has a while loop iterating a `std::map`) method anytime a player kill a monster anywhere. All of this is preventable with a small check making the function skips 99.9% of the monsters killed/purged. bool CShipDefenseManager::OnKill(LPCHARACTER lpDeadChar, LPCHARACTER lpKillerChar) { if (lpDeadChar == nullptr) return false; if (m_mapShipDefense.empty()) return false; //TODO : Add here a check to skip 99.99% of the monsters which are not relevant in this method Edited September 1, 2022 by Ikarus_ 1 1 4 1 4 My youtube channel on which you can see my works here Link to comment Share on other sites More sharing options...
Honorable Member Owsap 9812 Posted September 1, 2022 Author Honorable Member Share Posted September 1, 2022 @ Ikarus_, thanks for the feedback and heads-up, I have updated the repository. About the struct usage, sometimes I add the typedef and sometimes I don't, It's personal preference but for good practice I removed it and about the lua returns, I honestly completely ignored and forgot them because I copied the first function from another questlua file and I continued to paste the same returns for the other functions. As for the destruction of the instance I have reviewed and fixed it. Finally, I add a check to the CShipDefenseManager::OnKill functuion that should be enough to prevent it beeing called from every destruction of characters. Quote 5 hours ago, Ikarus_ said: I leave here a few tips that could improve code readability, performance and safety. I also report you a serious issue that generates memory leaks. Clearly, even though there are things that I consider outdated (which I am sure you have seen in the ymir code written in the early 2000s), I still appreciate that you have released all this work for free. The Functor (struct with operator()) is a trick used in the past to work with temporary functions that can store data, in short, a very outdated "lambda". Since C++11, we can use lambdas to definitely replace Functors, which are clearer and more readable and probably much optimizable by the compiler. The serious issue I noticed is how you insert and remove data inside m_mapShipDefense. (ps. emplace is always preferable than insert) The raw use of new and delete is to be considered outdated, and really unsafe. Proof of this is the leak I am about to show. Looking on CShipDefenseManager::Remove method: void CShipDefenseManager::Remove(const DWORD c_dwLeaderPID) { ShipDefenseMap::iterator it = m_mapShipDefense.find(c_dwLeaderPID); if (it != m_mapShipDefense.end()) m_mapShipDefense.erase(it); //erased but not deleted? } and again looking on CShipDefenseManager::Destroy() method: void CShipDefenseManager::Destroy() { ShipDefenseMap::iterator it = m_mapShipDefense.begin(); for (; it != m_mapShipDefense.end(); ++it) { CShipDefense* pShipDefense = it->second; if (pShipDefense) { pShipDefense->Destroy(); //is this use safe if you check its value immediately below? if (pShipDefense) delete pShipDefense; } } m_mapShipDefense.clear(); } A good way to solve your issue would be the use of smart pointers which are much safer and do the dirty work for you. PS: Since C++98 you can use struct without encapsulating it in a typedef declaration. typedef struct SBroadcastAllianceHP { } TBroadcastAllianceHP; // can be changed to struct TBroadcastAllianceHP { }; I've only checked ShipDefense.cpp so far. If I get time, I'll check the rest ---- EDIT I think you have misunderstood the meaning of the return value of the c lua functions. You should return the number of pushed elements in the stack. Many of the functions I have seen in the code you shared have a wrong return. int ship_defense_mgr_land(lua_State* L) { const LPCHARACTER c_lpChar = CQuestManager::instance().GetCurrentCharacterPtr(); if (c_lpChar == nullptr) return 0; CShipDefenseManager& rkShipDefenseMgr = CShipDefenseManager::Instance(); rkShipDefenseMgr.Land(c_lpChar); return 1; // WRONG - NO PUSHED ELEMENTS SO WHY 1? } int ship_defense_mgr_is_created(lua_State* L) { const LPCHARACTER c_lpChar = CQuestManager::instance().GetCurrentCharacterPtr(); if (c_lpChar == nullptr) return 0; CShipDefenseManager& rkShipDefenseMgr = CShipDefenseManager::Instance(); lua_pushboolean(L, rkShipDefenseMgr.IsCreated(c_lpChar)); return 1; // CORRECT, YOU PUSHED 1 ELEMENT } ----- EDIT2 I would recommend to add some small check here to make the function skip all monsters dead outside the dungeon. This method CShipDefenseManager::OnKill get called 2 times (first inside CHARACTER::Dead, second inside CHARACTER_MANAGER::DestroyCharacter) anytime a monster die, anytime a monster die in the whole core.Not a good idea keep it loops throught `std::map` (which is really slow to get iterated) and perform the whole CShipDefense::DeadCharacter on each dungeon instance (which it again has a while loop iterating a `std::map`) method anytime a player kill a monster anywhere. All of this is preventable with a small check make the function skips 99.9% of the monsters killed/purged. bool CShipDefenseManager::OnKill(LPCHARACTER lpDeadChar, LPCHARACTER lpKillerChar) { if (lpDeadChar == nullptr) return false; if (m_mapShipDefense.empty()) return false; //TODO : Add here a check to skip 99.99% of the monsters which are not relevant in this method 3 3 https://owsap.dev/ / https://osf.owsap.dev/ Link to comment Share on other sites More sharing options...
Developer Ikarus_ 2711 Posted September 1, 2022 Developer Share Posted September 1, 2022 (edited) I ve also found a really slow piece of code which execute a syscall on every call that can be avoided just by declaring the variables as statics. Here is the piece of code i m talking about: // Generate random probability for spawning something. std::random_device RandomDevice; std::mt19937 Generate(RandomDevice()); std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense::MAX_PROB); And here the fix i would recommend: // Generate random probability for spawning something. static std::random_device RandomDevice; static std::mt19937 Generate(RandomDevice()); static std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense::MAX_PROB); Here is a small benchmark i made to better clarify what we are talking about. As you can see, we are talking about an improvement that reduces execution time by about 100,000 times, not a small amount I would say. https://godbolt.org/z/bGrqfvMna EDIT ----- I ve noticed right now that you got a failed check which should prevent numerical overflow but that actually it doesn't. //THIS EXPRESION RESULT TO BE ALWAYS FALSE DUE TO NUMERICAL OVERFLOW // Prevent second counter from overflowing. if (pSpawnEventInfo->uiCountSec > UINT_MAX) return 0; //CORRECT WAY OF PREVENTING NUMERICAL OVERFLOW // Prevent second counter from overflowing. if (static_cast<uint64_t>(pSpawnEventInfo->uiCountSec) + 1 > UINT_MAX) return 0; Edited September 1, 2022 by Ikarus_ 1 4 2 My youtube channel on which you can see my works here Link to comment Share on other sites More sharing options...
Premium Intel 816 Posted September 1, 2022 Premium Share Posted September 1, 2022 1 hour ago, Ikarus_ said: I ve also found a really slow piece of code which execute a syscall on every call that can be avoided just by declaring the variables as statics. Here is the piece of code i m talking about: // Generate random probability for spawning something. std::random_device RandomDevice; std::mt19937 Generate(RandomDevice()); std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense::MAX_PROB); And here the fix i would recommend: // Generate random probability for spawning something. static std::random_device RandomDevice; static std::mt19937 Generate(RandomDevice()); static std::uniform_real_distribution<> Distribute(ShipDefense::MIN_PROB, ShipDefense::MAX_PROB); Here is a small benchmark i made to better clarify what we are talking about. As you can see, we are talking about an improvement that reduces execution time by about 100,000 times, not a small amount I would say. https://godbolt.org/z/bGrqfvMna EDIT ----- I ve noticed right now that you got a failed check which should prevent numerical overflow but that actually it doesn't. //THIS EXEPRESION RESULT TO BE ALWAYS FALSE DUE TO NUMERICAL OVERFLOW // Prevent second counter from overflowing. if (pSpawnEventInfo->uiCountSec > UINT_MAX) return 0; //CORRECT WAY OF PREVENTING NUMERICAL OVERFLOW // Prevent second counter from overflowing. if (static_cast<uint64_t>(pSpawnEventInfo->uiCountSec) + 1 > UINT_MAX) return 0; That random thing is very interesting, I didn't know about such speed improvement (I replaced the number() function with STL implementations. Obviously in a test server environment it doesn't feel slow, but this is a big jump on speed nonetheless. Love it.) Link to comment Share on other sites More sharing options...
Developer Ikarus_ 2711 Posted September 1, 2022 Developer Share Posted September 1, 2022 (edited) 7 minutes ago, xXIntelXx said: That random thing is very interesting, I didn't know about such speed improvement (I replaced the number() function with STL implementations. Obviously in a test server environment it doesn't feel slow, but this is a big jump on speed nonetheless. Love it.) Don't forget that static variables aren't thread safe (m2 server is a single-threaded application so it is still safe). The `std::uniform_real_distribution<>` can be static only if min and max used to declare it are constant (as it is in the code i posted). Anyway moving to static storage only the two others (std::random_device, std::mt19937) still give most of the advantage in terms of execution time. Edited September 1, 2022 by Ikarus_ 2 1 My youtube channel on which you can see my works here Link to comment Share on other sites More sharing options...
Honorable Member Owsap 9812 Posted September 1, 2022 Author Honorable Member Share Posted September 1, 2022 (edited) Repository updated. Replaced "functors" (function objects) with lambda expressions. Optimized execution time of random generation by making them static and corrected numerical overflow check on second count. (Thanks @ Ikarus_) Edited September 1, 2022 by Owsap 21 1 1 3 4 https://owsap.dev/ / https://osf.owsap.dev/ Link to comment Share on other sites More sharing options...
Premium Mano 22 Posted September 2, 2022 Premium Share Posted September 2, 2022 (edited) Thanks for the amazing work you do and for publishing such system that cost you time and work There is a core crash problem tho, maybe you can check what's wrong https://metin2.download/picture/3RdcFkFv0mb07LtE3mIHW46Lk6YiYFfT/.png Thank you again Edited September 4, 2022 by Metin2 Dev Core X - External 2 Internal Link to comment Share on other sites More sharing options...
Developer Ikarus_ 2711 Posted September 2, 2022 Developer Share Posted September 2, 2022 (edited) 8 minutes ago, Mano said: Thanks for the amazing work you do and for publishing such system that cost you time and work There is a core crash problem tho, maybe you can check what's wrong https://metin2.download/picture/eKgq96f6A5lsfmpSwxNKw7PL2Y4sgG37/.png Thank you again It would be helpful to post char_battle.cpp or at least what it contains at line 2530 and around. Edited September 4, 2022 by Metin2 Dev Core X - External 2 Internal My youtube channel on which you can see my works here Link to comment Share on other sites More sharing options...
Premium Mano 22 Posted September 2, 2022 Premium Share Posted September 2, 2022 (edited) 12 minutes ago, Ikarus_ said: It would be helpful to post the char_battle.cpp file or at least what it contains at line 2530 and around. I'm running test server and i got that core downer because of this block Spoiler if (test_server) { int iTmpPercent = 0; // @fixme136 if (GetMaxHP() >= 0) iTmpPercent = (GetHP() * 100) / GetMaxHP(); if(pAttacker) { pAttacker->ChatPacket(CHAT_TYPE_INFO, "-> %s, DAM %d HP %d(%d%%) %s%s", GetName(), dam, GetHP(), iTmpPercent, IsCritical ? "crit " : "", IsPenetrate ? "pene " : "", IsDeathBlow ? "deathblow " : ""); } ChatPacket(CHAT_TYPE_PARTY, "<- %s, DAM %d HP %d(%d%%) %s%s", pAttacker ? pAttacker->GetName() : 0, dam, GetHP(), iTmpPercent, IsCritical ? "crit " : "", IsPenetrate ? "pene " : "", IsDeathBlow ? "deathblow " : ""); } This line exactly Spoiler iTmpPercent = (GetHP() * 100) / GetMaxHP(); Edit: if i deactivated test server it works and there is no core crash but the mast is destroyed right after counter timer ends https://metin2.download/picture/1e97P10iU39HjN9be33bqBsycEm2stuD/.png Edited September 4, 2022 by Metin2 Dev Core X - External 2 Internal Link to comment Share on other sites More sharing options...
Developer Ikarus_ 2711 Posted September 2, 2022 Developer Share Posted September 2, 2022 (edited) 1 hour ago, Mano said: I'm running test server and i got that core downer because of this block Hide contents if (test_server) { int iTmpPercent = 0; // @fixme136 if (GetMaxHP() >= 0) iTmpPercent = (GetHP() * 100) / GetMaxHP(); if(pAttacker) { pAttacker->ChatPacket(CHAT_TYPE_INFO, "-> %s, DAM %d HP %d(%d%%) %s%s", GetName(), dam, GetHP(), iTmpPercent, IsCritical ? "crit " : "", IsPenetrate ? "pene " : "", IsDeathBlow ? "deathblow " : ""); } ChatPacket(CHAT_TYPE_PARTY, "<- %s, DAM %d HP %d(%d%%) %s%s", pAttacker ? pAttacker->GetName() : 0, dam, GetHP(), iTmpPercent, IsCritical ? "crit " : "", IsPenetrate ? "pene " : "", IsDeathBlow ? "deathblow " : ""); } This line exactly Hide contents iTmpPercent = (GetHP() * 100) / GetMaxHP(); Edit: if i deactivated test server it works and there is no core crash but the mast is destroyed right after counter timer ends https://metin2.download/picture/1XiUAKWZEeCBM5XwxGy0Dri1Asb7v94h/.png I guess that GetMaxHP returned 0 for some reason, and that is why it crashed. You can solve it by simply checking that GetMaxHP is different from 0 in that if. Test this fix and report if it helped you: // replace this if (GetMaxHP() >= 0) iTmpPercent = (GetHP() * 100) / GetMaxHP(); //with this if (GetMaxHP() > 0) iTmpPercent = (GetHP() * 100) / GetMaxHP(); Edited September 4, 2022 by Metin2 Dev Core X - External 2 Internal 1 My youtube channel on which you can see my works here Link to comment Share on other sites More sharing options...
Premium Mano 22 Posted September 2, 2022 Premium Share Posted September 2, 2022 (edited) 31 minutes ago, Ikarus_ said: I guess that GetMaxHP returned 0 for some reason, and that is why it crashed. You can solve it by simply checking that GetMaxHP is different from 0 in that if. Test this fix and report if it helped you: // replace this if (GetMaxHP() >= 0) iTmpPercent = (GetHP() * 100) / GetMaxHP(); //with this if (GetMaxHP() > 0) iTmpPercent = (GetHP() * 100) / GetMaxHP(); Yeah that solved the problem, so somehow BroadcastAllianceHP is setting mast hp to 0 or idk why the mast is destroyed right after the timer ends Edit: Turns out mob_proto.txt data is the reason and max_hp field is missed up Edited September 2, 2022 by Mano Link to comment Share on other sites More sharing options...
sibermaster 2 Posted September 3, 2022 Share Posted September 3, 2022 Failed to create private map. why? Link to comment Share on other sites More sharing options...
Honorable Member Owsap 9812 Posted September 3, 2022 Author Honorable Member Share Posted September 3, 2022 (edited) 12 minutes ago, sibermaster said: Failed to create private map. why? You need to have the correct map indexes in the same CONFIG file. Make sure the metin2_map_capedragonhead (301), metin2_map_defensewave (358) and metin2_map_defensewave_port (359) are in the same CONFIG. 301 metin2_map_capedragonhead 358 metin2_map_defensewave 359 metin2_map_defensewave_port CONFIG MAP_INDEX: 301 358 359 Edited September 3, 2022 by Owsap https://owsap.dev/ / https://osf.owsap.dev/ Link to comment Share on other sites More sharing options...
sibermaster 2 Posted September 3, 2022 Share Posted September 3, 2022 24 minutes ago, Owsap said: You need to have the correct map indexes in the same CONFIG file. Make sure the metin2_map_capedragonhead (301), metin2_map_defensewave (358) and metin2_map_defensewave_port (359) are in the same CONFIG. 301 metin2_map_capedragonhead 358 metin2_map_defensewave 359 metin2_map_defensewave_port CONFIG MAP_INDEX: 301 358 359 Thanks for reply i will try. Link to comment Share on other sites More sharing options...
Recommended Posts