Active Member ReFresh 2340 Posted May 29, 2022 Active Member Share Posted May 29, 2022 (edited) Hey guys, I'm trying to find a way how to change function below to check member pids on every map index, because it's checking party members count only on map where everyone of party is. I know, I could use this function: ForEachOnlineMember, but I need to check party members count when they're offline too. Why I need to do that? I need to remove party member from party when the party member change the empire. File: questlua_party.cpp Spoiler ALUA(party_get_member_pids) { CQuestManager & q = CQuestManager::instance(); LPCHARACTER ch = q.GetCurrentCharacterPtr(); LPPARTY pParty = ch->GetParty(); if (NULL == pParty) { return 0; } FPartyPIDCollector f; pParty->ForEachOnMapMember(f, ch->GetMapIndex()); for (std::vector <DWORD>::iterator it = f.vecPIDs.begin(); it != f.vecPIDs.end(); it++) { lua_pushnumber(L, *it); } return f.vecPIDs.size(); } Anyone know the solution? I'll be really really glad for that! Thanks for possible answers! Sincerely, ReFresh Edited May 29, 2022 by ReFresh I'll be always helpful! Link to comment Share on other sites More sharing options...
Braxy 618 Posted May 30, 2022 Share Posted May 30, 2022 Hi, why dont you just create a new party func that leaves the party? (Just be careful when you call the Quit party function, check if the group has two members left first and if that's true just Delete the party) As long as I'll be a threat for you , i will always be your target :3 Link to comment Share on other sites More sharing options...
Premium WeedHex 635 Posted May 30, 2022 Premium Share Posted May 30, 2022 party.cpp DWORD CParty::GetMemberCount() { return m_memberMap.size(); } Is not that what you want? Link to comment Share on other sites More sharing options...
Premium Syreldar 1875 Posted May 30, 2022 Premium Share Posted May 30, 2022 (edited) 2 hours ago, WeedHex said: party.cpp DWORD CParty::GetMemberCount() { return m_memberMap.size(); } Is not that what you want? party_get_member_count only returns the count of the members in your current map, and only if they're online, so no. What he needs is a way of determining whether or not the player's party exists, even if the player itself is in a different map/core/channel. It's doable in Lua without having to add anything sourceside, albeit definitely tricky. The suggestion to add a party.leave() function wouldn't work either, because the party instance from a different channel won't exist. So they could just change channel, change empire, and then return back to the original channel, pretty dirty. So it's better to prevent the empire change altogether instead. This solution is for sure not optimal, but it works, without any bugs, and doesn't require any source changes. So, let's start by making a simple quest: quest get_party_data begin state start begin when login or logout begin local qf_name = "last_channel"; local channel_id = pc.get_channel_id() -- We save the index of the last channel the player was in a party in. if (party.is_party() and pc.getqf(qf_name) == 0) then pc.setqf(qf_name, channel_id); -- if the player relogs back to the registered channel but with no party -- either it has been deleted or they got kicked, so we reset the qf. elseif (pc.getqf(qf_name) == channel_id and not party.is_party()) then pc.setqf(qf_name, 0); end -- if/elseif end -- when end -- state end -- quest Then, in our empire_change quest: .. .. -- add this somewhere within the main state.. function IsPlayerInParty() local idx, qf = "get_party_data", "last_channel" -- if the player's current channel is the registered one, but with no party.. -- ..it means the party was disbanded while the player was on the same channel.. -- ..in which they joined it. if (pc.getf(idx, qf) == pc.get_channel_id() and not party.is_party()) then pc.setf(idx, qf, 0); -- we reset the qf right now so they won't need to relog in this case. end -- if -- If the registered channel qf is still active.. -- ..it means the player has just changed core/ch, but the party still exists. return party.is_party() or pc.getf(idx, qf) > 0; end -- function -- ..and upon opening the empire change item, add this check: if (QUESTNAME.IsPlayerInParty()) then -- substitute QUESTNAME with the name of your empire change quest. return say_reward("Can't change empire, the player is in a party."); end -- if .. .. Overall, if we really gotta be picky, the only unoptimal factor is that if the party disbands/the player gets kicked while they were in a different channel, then they'll need to relog back to the channel from which they joined the party in order to let the game know the party was disbanded, which is not even a factor considering the nature of the problem, cause unless they're precisely trying to reproduce the bug @ ReFresh mentioned in this topic, they won't even notice this little thing, which itself is not a bug, and still prevents them from performing the bug anyway. Overall, it's not worth applying source changes to fix this little thing in my opinion, but anyone is welcome to propose a better solution. This one still works well and without bugs if you can't be arsed implementing C++ things. Edited May 30, 2022 by Syreldar 2 1 "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...
Active Member ReFresh 2340 Posted May 31, 2022 Author Active Member Share Posted May 31, 2022 (edited) @ SyreldarThanks for your answer. I wanted to do something like this: Spoiler function party_member_counting() local pids = {party.get_member_pids()} local player_count = 0 for i, pid in pids do player_count = player_count + 1 end return player_count end And then in empire change process: Spoiler if party.is_party() then local party_member_count = change_empire.party_member_counting() if party_member_count == 2 then party.delete_party() end if party_member_count >= 3 then if party.is_leader() then party.delete_party() elseif not party.is_leader() then party.leave_party() end end end But after you said, there are more things which can be passed by just a channel change, it will probably require many source changes. So in this case it's better use what you wrote, because I don't have a c++ knowledge to change things like this in source. So thanks anyway. But would be nice, if someone could provide us a c++ part to make this thing working like I wrote. Edited May 31, 2022 by ReFresh I'll be always helpful! Link to comment Share on other sites More sharing options...
Premium Syreldar 1875 Posted May 31, 2022 Premium Share Posted May 31, 2022 (edited) 10 minutes ago, ReFresh said: @ SyreldarThanks for your answer. I wanted to do something like this: Reveal hidden contents function party_member_counting() local pids = {party.get_member_pids()} local player_count = 0 for i, pid in pids do player_count = player_count + 1 end return player_count end And then in empire change process: Reveal hidden contents if party.is_party() then local party_member_count = change_empire.party_member_counting() if party_member_count == 2 then party.delete_party() end if party_member_count >= 3 then if party.is_leader() then party.delete_party() elseif not party.is_leader() then party.leave_party() end end end But after you said, there are more things which can be passed by just a channel change, it will probably require many source changes. So in this case it's better use what you wrote, because I don't have a c++ knowledge to change things like this in source. So thanks anyway. But would be nice, if someone could provide us a c++ part to make this thing working like I wrote. ? My quest works like you want. (Don't allow empire change if you're in a group, and supports different map/core/channel) Doesn't rly get better than this. C++ work would be pointless. Also the 'quest' you tried to write makes no sense whatsoever. Edited May 31, 2022 by Syreldar "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...
Active Member ReFresh 2340 Posted May 31, 2022 Author Active Member Share Posted May 31, 2022 @ Syreldar Yes, there is no better solution by Lua, but I was talking about the leaving the group or destroying group trough channels automatically, but it will be a little bit complicated to make something like that in C++. So I'll stay with what you wrote. I'll be always helpful! Link to comment Share on other sites More sharing options...
Forum Moderator VegaS™ 10275 Posted August 12, 2022 Forum Moderator Share Posted August 12, 2022 (edited) Guys, why are you always using quest flags? It's been 8 years since the source first appeared; we should avoid them because they're highly toxic; let's not use the database for everything when we already have everything in C++, it just needs to be properly accessed. This is the hidden content, please Sign In or Sign Up party.h This is the hidden content, please Sign In or Sign Up How-To-Use: if party.is_party() then local party_member_table = {party.party_get_all_member_pids()} local party_member_count = table.getn(party_member_table) -- Debug local party_member_string = table.concat(party_member_table, ", ") say(string.format("Party members: count(%d), pids(%s)", party_member_count, party_member_string)) end Edited August 12, 2022 by VegaS™ 16 1 2 Check my GitHub Profile Click to find all the threads started by me [TOOL] Text file loader + JSON Link to comment Share on other sites More sharing options...
Premium WeedHex 635 Posted August 12, 2022 Premium Share Posted August 12, 2022 3 hours ago, VegaS™ said: Guys, why are you always using quest flags? It's been 8 years since the source first appeared; we should avoid them because they're highly toxic; let's not use the database for everything when we already have everything in C++, it just needs to be properly accessed. This is the hidden content, please Sign In or Sign Up Hidden Content int party_get_all_member_pids(lua_State* L) { auto ch = CQuestManager::instance().GetCurrentCharacterPtr(); if (!ch) return 0; auto pParty = ch->GetParty(); if (!pParty) return 0; const auto& memberMap = pParty->GetPartyMembers(); for (const auto& it : memberMap) lua_pushnumber(L, it.first); return static_cast<int>(memberMap.size()); } { "party_get_all_member_pids", party_get_all_member_pids }, questlua_party.cpp party.h Hidden Content public: const TMemberMap& GetPartyMembers() const { return m_memberMap; } How-To-Use: if party.is_party() then local party_member_table = {party.party_get_all_member_pids()} local party_member_count = table.getn(party_member_table) -- Debug local party_member_string = table.concat(party_member_table, ", ") say(string.format("Party members: count(%d), pids(%s)", party_member_count, party_member_string)) end You can speak in the singular... Link to comment Share on other sites More sharing options...
Premium Syreldar 1875 Posted August 12, 2022 Premium Share Posted August 12, 2022 (edited) 8 hours ago, VegaS™ said: Guys, why are you always using quest flags? It's been 8 years since the source first appeared; we should avoid them because they're highly toxic; let's not use the database for everything when we already have everything in C++, it just needs to be properly accessed. This is the hidden content, please Sign In or Sign Up Hidden Content int party_get_all_member_pids(lua_State* L) { auto ch = CQuestManager::instance().GetCurrentCharacterPtr(); if (!ch) return 0; auto pParty = ch->GetParty(); if (!pParty) return 0; const auto& memberMap = pParty->GetPartyMembers(); for (const auto& it : memberMap) lua_pushnumber(L, it.first); return static_cast<int>(memberMap.size()); } { "party_get_all_member_pids", party_get_all_member_pids }, questlua_party.cpp party.h Hidden Content public: const TMemberMap& GetPartyMembers() const { return m_memberMap; } How-To-Use: if party.is_party() then local party_member_table = {party.party_get_all_member_pids()} local party_member_count = table.getn(party_member_table) -- Debug local party_member_string = table.concat(party_member_table, ", ") say(string.format("Party members: count(%d), pids(%s)", party_member_count, party_member_string)) end Good. That fixes the first part of the issue: The party member pids not being taken into account for characters in different cores/channels. However, that still won't do, it requires more work: Your solution assumes that the party stays valid through channels, but as I previously stated, when a group member logins in a different one they will be without a party in that channel, parties are channel-exclusive. Screenshots for reference: This means that they can just change channel, do whatever they want while eluding the party checks, then log back in the old one. With my solution they can't, because a flag stays valid between different channels. Also, I have already stated that my solution was suboptimal, I simply shared my own approach while being informative about it. That said, I believe your take towards questflags is a bit of a stretch: the game is built to handle hundreds of thousands of them active and get info on them at the same time with negligible impact on the server. Edited August 15, 2022 by Metin2 Dev Core X - External 2 Internal 1 "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 VegaS™ 10275 Posted August 12, 2022 Forum Moderator Share Posted August 12, 2022 23 minutes ago, Syreldar said: Good. That fixes the first part of the issue: The party member pids not being taken into account for characters in different cores/channels. However, that still won't do, it requires more work: Your solution assumes that the party stays valid through channels, but as I previously stated, when a group member logins in a different one they will be without a party in that channel, parties are channel-exclusive. I wrote that at 7 a.m., and I had mostly read the main post, which was about how he wanted that specific function; I had not considered the 'changing empire quest logic,' my mistake. 2 Check my GitHub Profile Click to find all the threads started by me [TOOL] Text file loader + JSON Link to comment Share on other sites More sharing options...
dotMatryx 10 Posted August 12, 2022 Share Posted August 12, 2022 (edited) 12 hours ago, VegaS™ said: Guys, why are you always using quest flags? It's been 8 years since the source first appeared; we should avoid them because they're highly toxic; let's not use the database for everything when we already have everything in C++, it just needs to be properly accessed. This is the hidden content, please Sign In or Sign Up Hidden Content int party_get_all_member_pids(lua_State* L) { auto ch = CQuestManager::instance().GetCurrentCharacterPtr(); if (!ch) return 0; auto pParty = ch->GetParty(); if (!pParty) return 0; const auto& memberMap = pParty->GetPartyMembers(); for (const auto& it : memberMap) lua_pushnumber(L, it.first); return static_cast<int>(memberMap.size()); } { "party_get_all_member_pids", party_get_all_member_pids }, questlua_party.cpp party.h Hidden Content public: const TMemberMap& GetPartyMembers() const { return m_memberMap; } How-To-Use: if party.is_party() then local party_member_table = {party.party_get_all_member_pids()} local party_member_count = table.getn(party_member_table) -- Debug local party_member_string = table.concat(party_member_table, ", ") say(string.format("Party members: count(%d), pids(%s)", party_member_count, party_member_string)) end What's auto& 's meaning exactly?I just read this.. automatically detects and assigns a data type to the variable with which it is used Why are you using the address symbol? & (I know only C that's why i am asking about address symbol) Edited August 12, 2022 by dotMatryx 1 Link to comment Share on other sites More sharing options...
Forum Moderator VegaS™ 10275 Posted August 12, 2022 Forum Moderator Share Posted August 12, 2022 (edited) 7 minutes ago, dotMatryx said: What's auto& 's meaning exactly?I just read this.. automatically detects and assigns a data type to the variable with which it is used Why are you using the address symbol? & (I know only C that's why i am asking about address symbol) https://stackoverflow.com/questions/26541920/is-it-a-good-practice-to-use-const-auto-in-a-range-for-to-process-the-element Edited August 12, 2022 by VegaS™ 1 Check my GitHub Profile Click to find all the threads started by me [TOOL] Text file loader + JSON Link to comment Share on other sites More sharing options...
dotMatryx 10 Posted August 12, 2022 Share Posted August 12, 2022 7 minutes ago, VegaS™ said: https://stackoverflow.com/questions/26541920/is-it-a-good-practice-to-use-const-auto-in-a-range-for-to-process-the-element This is the hidden content, please Sign In or Sign Up C++ is so cool xD 1 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now