-
Posts
22 -
Joined
-
Last visited
-
Feedback
0%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Posts posted by Hysteria
-
-
phenomenal
-
day after day, we see the retirement of the best people in the metin2 community This is very sad. I hope you come back soon
- 1
-
Welcome back Bro keep Going posting stuff like this
-
i don't why i'm answering for old topic but nevemind
the fix for this is go to interfacemodule.pyon def close(self): ## search for if self.wndCharacter: self.wndCharacter.Destroy() ##and add self.wndCharacter.Hide() ## make it look like this if self.wndCharacter: self.wndCharacter.Hide() self.wndCharacter.Destroy()
-
this is the best fix if someone need it
void CQuestManager::CancelServerTimers(DWORD arg) { itertype(m_mapServerTimer) it = m_mapServerTimer.begin(); for (; it != m_mapServerTimer.end(); ) { if (it->first.second == arg) { LPEVENT event = it->second; event_cancel(&event); m_mapServerTimer.erase(it++); } else ++it; } }
- 1
-
fix highlight system : find
AutoGiveItem(getitem->GetVnum(), getitem->GetCount(), -1, false); M2_DESTROY_ITEM(getitem); } else AutoGiveItem(getitem);
change with
#ifdef ENABLE_HIGHLIGHT_SYSTEM AutoGiveItem(getitem->GetVnum(), getitem->GetCount(), -1, false, false); M2_DESTROY_ITEM(getitem); #else AutoGiveItem(getitem->GetVnum(), getitem->GetCount(), -1, false); M2_DESTROY_ITEM(getitem); #endif } else #ifdef ENABLE_HIGHLIGHT_SYSTEM AutoGiveItem(getitem, false, false); #else AutoGiveItem(getitem, false); #endif
not tested
-
char szLevel[256]; _snprintf(szLevel, sizeof(szLevel), "(Lv: %u)", CPythonPlayer::Instance().GetStatus(POINT_LEVEL));
get level by different way
- 1
-
2 hours ago, blaxis said:
Does everyone have it? o.O
yeah everyone
-
ah its normal that happen in every server file
-
this just in skill icon or on any button ?
-
in InstanceBase.cpp somebody disable return; thats why this bug is coming out
- 1
-
make sure you put the right .dds file for the skill in ETC/d/ymir work/ui
-
-
fix online/offline problem
fix in " void CParty::SendPartyJoinAllToOne " and " void CParty::SendPartyUnlinkOneToAll " and " void CParty::SendPartyLinkOneToAll " and " void CParty::UpdateOnlineState " and " void CParty::UpdateOfflineState " function compare the file between yours and good luck
party.cpp
Spoiler#include "stdafx.h" #include "utils.h" #include "char.h" #include "party.h" #include "char_manager.h" #include "config.h" #include "p2p.h" #include "desc_client.h" #include "dungeon.h" #include "unique_item.h" #ifdef ENABLE_12ZI #include "zodiac_temple.h" #endif CPartyManager::CPartyManager() { Initialize(); } CPartyManager::~CPartyManager() { } void CPartyManager::Initialize() { m_bEnablePCParty = false; } void CPartyManager::DeleteAllParty() { TPCPartySet::iterator it = m_set_pkPCParty.begin(); while (it != m_set_pkPCParty.end()) { DeleteParty(*it); it = m_set_pkPCParty.begin(); } } bool CPartyManager::SetParty(LPCHARACTER ch) // PC¸¸ »ç؟ëاط¾ك ار´ظ!! { TPartyMap::iterator it = m_map_pkParty.find(ch->GetPlayerID()); if (it == m_map_pkParty.end()) return false; LPPARTY pParty = it->second; pParty->Link(ch); return true; } #ifdef ENABLE_PARTY_UPDATE void CPartyManager::P2PLogin(DWORD pid, const char* name, long mapIdx, long channel) #else void CPartyManager::P2PLogin(DWORD pid, const char* name) #endif { TPartyMap::iterator it = m_map_pkParty.find(pid); if (it == m_map_pkParty.end()) return; #ifdef ENABLE_PARTY_UPDATE it->second->UpdateOnlineState(pid, name, mapIdx, channel); #else it->second->UpdateOnlineState(pid, name); #endif } void CPartyManager::P2PLogout(DWORD pid) { TPartyMap::iterator it = m_map_pkParty.find(pid); if (it == m_map_pkParty.end()) return; it->second->UpdateOfflineState(pid); } void CPartyManager::P2PJoinParty(DWORD leader, DWORD pid, BYTE role) { TPartyMap::iterator it = m_map_pkParty.find(leader); if (it != m_map_pkParty.end()) { it->second->P2PJoin(pid); if (role >= PARTY_ROLE_MAX_NUM) role = PARTY_ROLE_NORMAL; it->second->SetRole(pid, role, true); } else { sys_err("No such party with leader [%d]", leader); } } void CPartyManager::P2PQuitParty(DWORD pid) { TPartyMap::iterator it = m_map_pkParty.find(pid); if (it != m_map_pkParty.end()) { it->second->P2PQuit(pid); } else { sys_err("No such party with member [%d]", pid); } } LPPARTY CPartyManager::P2PCreateParty(DWORD pid) { TPartyMap::iterator it = m_map_pkParty.find(pid); if (it != m_map_pkParty.end()) return it->second; LPPARTY pParty = M2_NEW CParty; m_set_pkPCParty.insert(pParty); SetPartyMember(pid, pParty); pParty->SetPCParty(true); pParty->P2PJoin(pid); return pParty; } void CPartyManager::P2PDeleteParty(DWORD pid) { TPartyMap::iterator it = m_map_pkParty.find(pid); if (it != m_map_pkParty.end()) { m_set_pkPCParty.erase(it->second); M2_DELETE(it->second); } else sys_err("PARTY P2PDeleteParty Cannot find party [%u]", pid); } LPPARTY CPartyManager::CreateParty(LPCHARACTER pLeader) { if (pLeader->GetParty()) return pLeader->GetParty(); LPPARTY pParty = M2_NEW CParty; if (pLeader->IsPC()) { //TPacketGGParty p; //p.header = HEADER_GG_PARTY; //p.subheader = PARTY_SUBHEADER_GG_CREATE; //p.pid = pLeader->GetPlayerID(); //P2P_MANAGER::instance().Send(&p, sizeof(p)); TPacketPartyCreate p; p.dwLeaderPID = pLeader->GetPlayerID(); db_clientdesc->DBPacket(HEADER_GD_PARTY_CREATE, 0, &p, sizeof(TPacketPartyCreate)); sys_log(0, "PARTY: Create %s pid %u", pLeader->GetName(), pLeader->GetPlayerID()); pParty->SetPCParty(true); pParty->Join(pLeader->GetPlayerID()); m_set_pkPCParty.insert(pParty); } else { pParty->SetPCParty(false); pParty->Join(pLeader->GetVID()); } pParty->Link(pLeader); return (pParty); } void CPartyManager::DeleteParty(LPPARTY pParty) { //TPacketGGParty p; //p.header = HEADER_GG_PARTY; //p.subheader = PARTY_SUBHEADER_GG_DESTROY; //p.pid = pParty->GetLeaderPID(); //P2P_MANAGER::instance().Send(&p, sizeof(p)); TPacketPartyDelete p; p.dwLeaderPID = pParty->GetLeaderPID(); db_clientdesc->DBPacket(HEADER_GD_PARTY_DELETE, 0, &p, sizeof(TPacketPartyDelete)); m_set_pkPCParty.erase(pParty); M2_DELETE(pParty); } void CPartyManager::SetPartyMember(DWORD dwPID, LPPARTY pParty) { TPartyMap::iterator it = m_map_pkParty.find(dwPID); if (pParty == NULL) { if (it != m_map_pkParty.end()) m_map_pkParty.erase(it); } else { if (it != m_map_pkParty.end()) { if (it->second != pParty) { it->second->Quit(dwPID); it->second = pParty; } } else m_map_pkParty.insert(TPartyMap::value_type(dwPID, pParty)); } } EVENTINFO(party_update_event_info) { DWORD pid; party_update_event_info() : pid( 0 ) { } }; ///////////////////////////////////////////////////////////////////////////// // // CParty begin! // ///////////////////////////////////////////////////////////////////////////// EVENTFUNC(party_update_event) { party_update_event_info* info = dynamic_cast<party_update_event_info*>( event->info ); if ( info == NULL ) { sys_err( "party_update_event> <Factor> Null pointer" ); return 0; } DWORD pid = info->pid; LPCHARACTER leader = CHARACTER_MANAGER::instance().FindByPID(pid); if (leader && leader->GetDesc()) { LPPARTY pParty = leader->GetParty(); if (pParty) pParty->Update(); } return PASSES_PER_SEC(3); } CParty::CParty() { Initialize(); } CParty::~CParty() { Destroy(); } void CParty::Initialize() { sys_log(2, "Party::Initialize"); m_iExpDistributionMode = PARTY_EXP_DISTRIBUTION_NON_PARITY; m_pkChrExpCentralize = NULL; m_dwLeaderPID = 0; m_eventUpdate = NULL; memset(&m_anRoleCount, 0, sizeof(m_anRoleCount)); memset(&m_anMaxRole, 0, sizeof(m_anMaxRole)); m_anMaxRole[PARTY_ROLE_LEADER] = 1; m_anMaxRole[PARTY_ROLE_NORMAL] = 32; m_dwPartyStartTime = get_dword_time(); m_iLongTimeExpBonus = 0; m_dwPartyHealTime = get_dword_time(); m_bPartyHealReady = false; m_bCanUsePartyHeal = false; m_iLeadership = 0; m_iExpBonus = 0; m_iAttBonus = 0; m_iDefBonus = 0; m_itNextOwner = m_memberMap.begin(); m_iCountNearPartyMember = 0; m_pkChrLeader = NULL; m_bPCParty = false; m_pkDungeon = NULL; m_pkDungeon_for_Only_party = NULL; #ifdef ENABLE_12ZI m_pkZodiac = NULL; m_pkZodiac_for_Only_party = NULL; #endif } void CParty::Destroy() { sys_log(2, "Party::Destroy"); // PC°، ¸¸µç ئؤئ¼¸é ئؤئ¼¸إ´دہْ؟، ¸ت؟،¼ PID¸¦ »èء¦اط¾ك ار´ظ. if (m_bPCParty) { for (TMemberMap::iterator it = m_memberMap.begin(); it != m_memberMap.end(); ++it) CPartyManager::instance().SetPartyMember(it->first, NULL); } event_cancel(&m_eventUpdate); RemoveBonus(); TMemberMap::iterator it = m_memberMap.begin(); DWORD dwTime = get_dword_time(); while (it != m_memberMap.end()) { TMember & rMember = it->second; ++it; if (rMember.pCharacter) { if (rMember.pCharacter->GetDesc()) { TPacketGCPartyRemove p; p.header = HEADER_GC_PARTY_REMOVE; p.pid = rMember.pCharacter->GetPlayerID(); rMember.pCharacter->GetDesc()->Packet(&p, sizeof(p)); rMember.pCharacter->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ئؤئ¼> ئؤئ¼°، اط»ê µا¾ْ½ہ´د´ظ.")); } else { // NPCہد °و؟ى ہدء¤ ½أ°£ بؤ ہüإُ ءكہج ¾ئ´ز ¶§ »ç¶َءِ°ش اد´آ ہج؛¥ئ®¸¦ ½أہغ½أإ²´ظ. rMember.pCharacter->SetLastAttacked(dwTime); rMember.pCharacter->StartDestroyWhenIdleEvent(); } rMember.pCharacter->SetParty(NULL); } } m_memberMap.clear(); m_itNextOwner = m_memberMap.begin(); if (m_pkDungeon_for_Only_party != NULL) { m_pkDungeon_for_Only_party->SetPartyNull(); m_pkDungeon_for_Only_party = NULL; } #ifdef ENABLE_12ZI if (m_pkZodiac_for_Only_party != NULL) { m_pkZodiac_for_Only_party->SetPartyNull(); m_pkZodiac_for_Only_party = NULL; } #endif } void CParty::ChatPacketToAllMember(BYTE type, const char* format, ...) { char chatbuf[CHAT_MAX_LEN + 1]; va_list args; va_start(args, format); vsnprintf(chatbuf, sizeof(chatbuf), format, args); va_end(args); TMemberMap::iterator it; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { TMember & rMember = it->second; if (rMember.pCharacter) { if (rMember.pCharacter->GetDesc()) { rMember.pCharacter->ChatPacket(type, "%s", chatbuf); } } } } DWORD CParty::GetLeaderPID() { return m_dwLeaderPID; } DWORD CParty::GetMemberCount() { return m_memberMap.size(); } void CParty::P2PJoin(DWORD dwPID) { TMemberMap::iterator it = m_memberMap.find(dwPID); if (it == m_memberMap.end()) { TMember Member; Member.pCharacter = NULL; Member.bNear = false; if (m_memberMap.empty()) { Member.bRole = PARTY_ROLE_LEADER; m_dwLeaderPID = dwPID; } else Member.bRole = PARTY_ROLE_NORMAL; if (m_bPCParty) { LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(dwPID); if (ch) { sys_log(0, "PARTY: Join %s pid %u leader %u", ch->GetName(), dwPID, m_dwLeaderPID); Member.strName = ch->GetName(); if (Member.bRole == PARTY_ROLE_LEADER) m_iLeadership = ch->GetLeadershipSkillLevel(); #ifdef ENABLE_PARTY_UPDATE Member.mapIdx = ch->GetMapIndex(); Member.channel = g_bChannel; #endif } else { CCI * pcci = P2P_MANAGER::instance().FindByPID(dwPID); if (!pcci); else if (pcci->bChannel == g_bChannel) { Member.strName = pcci->szName; #ifdef ENABLE_PARTY_UPDATE Member.mapIdx = pcci->lMapIndex; Member.channel = pcci->bChannel; #endif } else sys_err("member is not in same channel PID: %u channel %d, this channel %d", dwPID, pcci->bChannel, g_bChannel); } } sys_log(2, "PARTY[%d] MemberCountChange %d -> %d", GetLeaderPID(), GetMemberCount(), GetMemberCount()+1); m_memberMap.insert(TMemberMap::value_type(dwPID, Member)); if (m_memberMap.size() == 1) m_itNextOwner = m_memberMap.begin(); if (m_bPCParty) { CPartyManager::instance().SetPartyMember(dwPID, this); SendPartyJoinOneToAll(dwPID); LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(dwPID); if (ch) SendParameter(ch); } } if (m_pkDungeon) { m_pkDungeon->QuitParty(this); } #ifdef ENABLE_12ZI if (m_pkZodiac) { m_pkZodiac->QuitParty(this); } #endif } void CParty::Join(DWORD dwPID) { P2PJoin(dwPID); if (m_bPCParty) { TPacketPartyAdd p; p.dwLeaderPID = GetLeaderPID(); p.dwPID = dwPID; p.bState = PARTY_ROLE_NORMAL; // #0000790: [M2EU] CZ إ©·،½¬ ءُ°،: أت±âب ءك؟ن! db_clientdesc->DBPacket(HEADER_GD_PARTY_ADD, 0, &p, sizeof(p)); } } void CParty::P2PQuit(DWORD dwPID) { TMemberMap::iterator it = m_memberMap.find(dwPID); if (it == m_memberMap.end()) return; if (m_bPCParty) SendPartyRemoveOneToAll(dwPID); if (it == m_itNextOwner) IncreaseOwnership(); if (m_bPCParty) RemoveBonusForOne(dwPID); LPCHARACTER ch = it->second.pCharacter; BYTE bRole = it->second.bRole; m_memberMap.erase(it); sys_log(2, "PARTY[%d] MemberCountChange %d -> %d", GetLeaderPID(), GetMemberCount(), GetMemberCount() - 1); if (bRole < PARTY_ROLE_MAX_NUM) { --m_anRoleCount[bRole]; } else { sys_err("ROLE_COUNT_QUIT_ERROR: INDEX(%d) > MAX(%d)", bRole, PARTY_ROLE_MAX_NUM); } if (ch) { ch->SetParty(NULL); ComputeRolePoint(ch, bRole, false); } if (m_bPCParty) CPartyManager::instance().SetPartyMember(dwPID, NULL); // ¸®´ُ°، ³ھ°،¸é ئؤئ¼´آ اط»êµا¾î¾ك ار´ظ. if (bRole == PARTY_ROLE_LEADER) CPartyManager::instance().DeleteParty(this); // ہج ¾ئ·،´آ ؤعµه¸¦ أك°،ادءِ ¸» °ح!!! ہ§ DeleteParty اد¸é this´آ ¾ّ´ظ. } void CParty::Quit(DWORD dwPID) { // Always PC P2PQuit(dwPID); if (m_bPCParty && dwPID != GetLeaderPID()) { //TPacketGGParty p; //p.header = HEADER_GG_PARTY; //p.subheader = PARTY_SUBHEADER_GG_QUIT; //p.pid = dwPID; //p.leaderpid = GetLeaderPID(); //P2P_MANAGER::instance().Send(&p, sizeof(p)); TPacketPartyRemove p; p.dwPID = dwPID; p.dwLeaderPID = GetLeaderPID(); db_clientdesc->DBPacket(HEADER_GD_PARTY_REMOVE, 0, &p, sizeof(p)); } } void CParty::Link(LPCHARACTER pkChr) { TMemberMap::iterator it; if (pkChr->IsPC()) it = m_memberMap.find(pkChr->GetPlayerID()); else it = m_memberMap.find(pkChr->GetVID()); if (it == m_memberMap.end()) { sys_err("%s is not member of this party", pkChr->GetName()); return; } // اأ·¹ہج¾î ئؤئ¼ہد °و؟ى ¾÷µ¥ہجئ® ہج؛¥ئ® »¼؛ if (m_bPCParty && !m_eventUpdate) { party_update_event_info* info = AllocEventInfo<party_update_event_info>(); info->pid = m_dwLeaderPID; m_eventUpdate = event_create(party_update_event, info, PASSES_PER_SEC(3)); } if (it->second.bRole == PARTY_ROLE_LEADER) m_pkChrLeader = pkChr; sys_log(2, "PARTY[%d] %s linked to party", GetLeaderPID(), pkChr->GetName()); it->second.pCharacter = pkChr; pkChr->SetParty(this); if (pkChr->IsPC()) { if (it->second.strName.empty()) { it->second.strName = pkChr->GetName(); } SendPartyJoinOneToAll(pkChr->GetPlayerID()); SendPartyJoinAllToOne(pkChr); SendPartyLinkOneToAll(pkChr); SendPartyLinkAllToOne(pkChr); SendPartyInfoAllToOne(pkChr); SendPartyInfoOneToAll(pkChr); SendParameter(pkChr); if (GetDungeon() && GetDungeon()->GetMapIndex() == pkChr->GetMapIndex()) { pkChr->SetDungeon(GetDungeon()); } #ifdef ENABLE_12ZI if (GetZodiac() && GetZodiac()->GetMapIndex() == pkChr->GetMapIndex()) { pkChr->SetZodiac(GetZodiac()); } #endif RequestSetMemberLevel(pkChr->GetPlayerID(), pkChr->GetLevel()); #ifdef ENABLE_PARTY_UPDATE RequestSetMemberMapIndex(pkChr->GetPlayerID(), pkChr->GetMapIndex()); RequestSetMemberChannel(pkChr->GetPlayerID(), g_bChannel); #endif } } void CParty::RequestSetMemberLevel(DWORD pid, BYTE level) { TPacketPartySetMemberLevel p; p.dwLeaderPID = GetLeaderPID(); p.dwPID = pid; p.bLevel = level; db_clientdesc->DBPacket(HEADER_GD_PARTY_SET_MEMBER_LEVEL, 0, &p, sizeof(TPacketPartySetMemberLevel)); } void CParty::P2PSetMemberLevel(DWORD pid, BYTE level) { if (!m_bPCParty) return; TMemberMap::iterator it; sys_log(0, "PARTY P2PSetMemberLevel leader %d pid %d level %d", GetLeaderPID(), pid, level); it = m_memberMap.find(pid); if (it != m_memberMap.end()) { it->second.bLevel = level; } } #ifdef ENABLE_PARTY_UPDATE void CParty::RequestSetMemberMapIndex(DWORD pid, long mapIdx) { TPacketPartySetMemberMapIndex p; p.dwLeaderPID = GetLeaderPID(); p.dwPID = pid; p.mapIdx = mapIdx; db_clientdesc->DBPacket(HEADER_GD_PARTY_SET_MEMBER_MAP_INDEX, 0, &p, sizeof(TPacketPartySetMemberMapIndex)); } void CParty::P2PSetMemberMapIndex(DWORD pid, long mapIdx) { if (!m_bPCParty) return; TMemberMap::iterator it; sys_log(0, "PARTY P2PSetMemberMapIndex leader %d pid %d mapIdx %d", GetLeaderPID(), pid, mapIdx); it = m_memberMap.find(pid); if (it != m_memberMap.end()) { it->second.mapIdx = mapIdx; } } void CParty::RequestSetMemberChannel(DWORD pid, long channel) { TPacketPartySetMemberChannel p; p.dwLeaderPID = GetLeaderPID(); p.dwPID = pid; p.channel = channel; db_clientdesc->DBPacket(HEADER_GD_PARTY_SET_MEMBER_CHANNEL, 0, &p, sizeof(TPacketPartySetMemberChannel)); } void CParty::P2PSetMemberChannel(DWORD pid, long channel) { if (!m_bPCParty) return; TMemberMap::iterator it; sys_log(0, "PARTY P2PSetMemberChannel leader %d pid %d ch %d", GetLeaderPID(), pid, channel); it = m_memberMap.find(pid); if (it != m_memberMap.end()) { it->second.channel = channel; } } #endif namespace { struct FExitDungeon { void operator()(LPCHARACTER ch) { ch->ExitToSavedLocation(); } }; } void CParty::Unlink(LPCHARACTER pkChr) { TMemberMap::iterator it; if (pkChr->IsPC()) it = m_memberMap.find(pkChr->GetPlayerID()); else it = m_memberMap.find(pkChr->GetVID()); if (it == m_memberMap.end()) { sys_err("%s is not member of this party", pkChr->GetName()); return; } if (pkChr->IsPC()) { SendPartyUnlinkOneToAll(pkChr); if (it->second.bRole == PARTY_ROLE_LEADER) { RemoveBonus(); #ifdef ENABLE_12ZI if (it->second.pCharacter->GetDungeon() || it->second.pCharacter->GetZodiac()) #else if (it->second.pCharacter->GetDungeon()) #endif { FExitDungeon f; ForEachNearMember(f); } } } if (it->second.bRole == PARTY_ROLE_LEADER) m_pkChrLeader = NULL; it->second.pCharacter = NULL; pkChr->SetParty(NULL); } void CParty::SendPartyRemoveOneToAll(DWORD pid) { TMemberMap::iterator it; TPacketGCPartyRemove p; p.header = HEADER_GC_PARTY_REMOVE; p.pid = pid; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { if (it->second.pCharacter && it->second.pCharacter->GetDesc()) it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); } } void CParty::SendPartyJoinOneToAll(DWORD pid) { const TMember& r = m_memberMap[pid]; TPacketGCPartyAdd p; p.header = HEADER_GC_PARTY_ADD; p.pid = pid; strlcpy(p.name, r.strName.c_str(), sizeof(p.name)); #ifdef ENABLE_PARTY_UPDATE p.mapIdx = r.mapIdx; p.channel = r.channel; #endif for (TMemberMap::iterator it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { if (it->second.pCharacter && it->second.pCharacter->GetDesc()) it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); } } void CParty::SendPartyJoinAllToOne(LPCHARACTER ch) { if (!ch->GetDesc()) return; for (TMemberMap::iterator it = m_memberMap.begin();it!= m_memberMap.end(); ++it) { CCI *pCCI = P2P_MANAGER::instance().Find(it->second.strName.c_str()); if (it->second.pCharacter || pCCI) UpdateOnlineState(it->first, it->second.strName.c_str(), it->second.channel, it->second.mapIdx); else UpdateOfflineState(it->first); } } void CParty::SendPartyUnlinkOneToAll(LPCHARACTER ch) { if (!ch->GetDesc()) return; TMemberMap::iterator it; TPacketGCPartyLink p; p.header = HEADER_GC_PARTY_UNLINK; p.pid = ch->GetPlayerID(); p.vid = (DWORD)ch->GetVID(); for (it = m_memberMap.begin();it!= m_memberMap.end(); ++it) { #ifdef ENABLE_PARTY_UPDATE CCI *pCCI = P2P_MANAGER::instance().Find(it->second.strName.c_str()); if (it->second.pCharacter && it->second.pCharacter->GetDesc()) it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); else if (pCCI) pCCI->pkDesc->Packet(&p, sizeof(p)); #else if (it->second.pCharacter && it->second.pCharacter->GetDesc()) it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); #endif } } void CParty::SendPartyLinkOneToAll(LPCHARACTER ch) { if (!ch->GetDesc()) return; TMemberMap::iterator it; TPacketGCPartyLink p; p.header = HEADER_GC_PARTY_LINK; p.vid = ch->GetVID(); p.pid = ch->GetPlayerID(); #ifdef ENABLE_PARTY_UPDATE p.mapIdx = ch->GetMapIndex(); p.channel = g_bChannel; #endif for (it = m_memberMap.begin();it!= m_memberMap.end(); ++it) { #ifdef ENABLE_PARTY_UPDATE CCI *pCCI = P2P_MANAGER::instance().Find(it->second.strName.c_str()); if (it->second.pCharacter && it->second.pCharacter->GetDesc()) it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); else if (pCCI) pCCI->pkDesc->Packet(&p, sizeof(p)); #else if (it->second.pCharacter && it->second.pCharacter->GetDesc()) it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); #endif } } void CParty::SendPartyLinkAllToOne(LPCHARACTER ch) { if (!ch->GetDesc()) return; TMemberMap::iterator it; TPacketGCPartyLink p; p.header = HEADER_GC_PARTY_LINK; for (it = m_memberMap.begin();it!= m_memberMap.end(); ++it) { if (it->second.pCharacter) { p.vid = it->second.pCharacter->GetVID(); p.pid = it->second.pCharacter->GetPlayerID(); #ifdef ENABLE_PARTY_UPDATE p.mapIdx = it->second.pCharacter->GetMapIndex(); p.channel = g_bChannel; #endif ch->GetDesc()->Packet(&p, sizeof(p)); } } } void CParty::SendPartyInfoOneToAll(DWORD pid) { TMemberMap::iterator it = m_memberMap.find(pid); if (it == m_memberMap.end()) return; if (it->second.pCharacter) { SendPartyInfoOneToAll(it->second.pCharacter); return; } // Data Building TPacketGCPartyUpdate p; memset(&p, 0, sizeof(p)); p.header = HEADER_GC_PARTY_UPDATE; p.pid = pid; p.percent_hp = 255; p.role = it->second.bRole; for (it = m_memberMap.begin();it!= m_memberMap.end(); ++it) { if ((it->second.pCharacter) && (it->second.pCharacter->GetDesc())) { //sys_log(2, "PARTY send info %s[%d] to %s[%d]", ch->GetName(), (DWORD)ch->GetVID(), it->second.pCharacter->GetName(), (DWORD)it->second.pCharacter->GetVID()); it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); } } } void CParty::SendPartyInfoOneToAll(LPCHARACTER ch) { if (!ch->GetDesc()) return; TMemberMap::iterator it; // Data Building TPacketGCPartyUpdate p; ch->BuildUpdatePartyPacket(p); for (it = m_memberMap.begin();it!= m_memberMap.end(); ++it) { if ((it->second.pCharacter) && (it->second.pCharacter->GetDesc())) { sys_log(2, "PARTY send info %s[%d] to %s[%d]", ch->GetName(), (DWORD)ch->GetVID(), it->second.pCharacter->GetName(), (DWORD)it->second.pCharacter->GetVID()); it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); } } } void CParty::SendPartyInfoAllToOne(LPCHARACTER ch) { TMemberMap::iterator it; TPacketGCPartyUpdate p; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { if (!it->second.pCharacter) { DWORD pid = it->first; memset(&p, 0, sizeof(p)); p.header = HEADER_GC_PARTY_UPDATE; p.pid = pid; p.percent_hp = 255; p.role = it->second.bRole; ch->GetDesc()->Packet(&p, sizeof(p)); continue; } it->second.pCharacter->BuildUpdatePartyPacket(p); sys_log(2, "PARTY send info %s[%d] to %s[%d]", it->second.pCharacter->GetName(), (DWORD)it->second.pCharacter->GetVID(), ch->GetName(), (DWORD)ch->GetVID()); ch->GetDesc()->Packet(&p, sizeof(p)); } } void CParty::SendMessage(LPCHARACTER ch, BYTE bMsg, DWORD dwArg1, DWORD dwArg2) { if (ch->GetParty() != this) { sys_err("%s is not member of this party %p", ch->GetName(), this); return; } switch (bMsg) { case PM_ATTACK: break; case PM_RETURN: { TMemberMap::iterator it = m_memberMap.begin(); while (it != m_memberMap.end()) { TMember & rMember = it->second; ++it; LPCHARACTER pkChr; if ((pkChr = rMember.pCharacter) && ch != pkChr) { DWORD x = dwArg1 + number(-500, 500); DWORD y = dwArg2 + number(-500, 500); pkChr->SetVictim(NULL); pkChr->SetRotationToXY(x, y); if (pkChr->Goto(x, y)) { LPCHARACTER victim = pkChr->GetVictim(); sys_log(0, "%s %p RETURN victim %p", pkChr->GetName(), get_pointer(pkChr), get_pointer(victim)); pkChr->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0); } } } } break; case PM_ATTACKED_BY: // °ّ°ف ¹ق¾زہ½, ¸®´ُ؟،°ش µµ؟ٍہ» ؟نأ» { // ¸®´ُ°، ¾ّہ» ¶§ LPCHARACTER pkChrVictim = ch->GetVictim(); if (!pkChrVictim) return; TMemberMap::iterator it = m_memberMap.begin(); while (it != m_memberMap.end()) { TMember & rMember = it->second; ++it; LPCHARACTER pkChr; if ((pkChr = rMember.pCharacter) && ch != pkChr) { if (pkChr->CanBeginFight()) pkChr->BeginFight(pkChrVictim); } } } break; case PM_AGGRO_INCREASE: { LPCHARACTER victim = CHARACTER_MANAGER::instance().Find(dwArg2); if (!victim) return; TMemberMap::iterator it = m_memberMap.begin(); while (it != m_memberMap.end()) { TMember & rMember = it->second; ++it; LPCHARACTER pkChr; if ((pkChr = rMember.pCharacter) && ch != pkChr) { pkChr->UpdateAggrPoint(victim, DAMAGE_TYPE_SPECIAL, dwArg1); } } } break; } } LPCHARACTER CParty::GetLeaderCharacter() { return m_memberMap[GetLeaderPID()].pCharacter; } bool CParty::SetRole(DWORD dwPID, BYTE bRole, bool bSet) { TMemberMap::iterator it = m_memberMap.find(dwPID); if (it == m_memberMap.end()) { return false; } LPCHARACTER ch = it->second.pCharacter; if (bSet) { if (m_anRoleCount[bRole] >= m_anMaxRole[bRole]) return false; if (it->second.bRole != PARTY_ROLE_NORMAL) return false; it->second.bRole = bRole; if (ch && GetLeader()) ComputeRolePoint(ch, bRole, true); if (bRole < PARTY_ROLE_MAX_NUM) { ++m_anRoleCount[bRole]; } else { sys_err("ROLE_COUNT_INC_ERROR: INDEX(%d) > MAX(%d)", bRole, PARTY_ROLE_MAX_NUM); } } else { if (it->second.bRole == PARTY_ROLE_LEADER) return false; if (it->second.bRole == PARTY_ROLE_NORMAL) return false; it->second.bRole = PARTY_ROLE_NORMAL; if (ch && GetLeader()) ComputeRolePoint(ch, PARTY_ROLE_NORMAL, false); if (bRole < PARTY_ROLE_MAX_NUM) { --m_anRoleCount[bRole]; } else { sys_err("ROLE_COUNT_DEC_ERROR: INDEX(%d) > MAX(%d)", bRole, PARTY_ROLE_MAX_NUM); } } SendPartyInfoOneToAll(dwPID); return true; } BYTE CParty::GetRole(DWORD pid) { TMemberMap::iterator it = m_memberMap.find(pid); if (it == m_memberMap.end()) return PARTY_ROLE_NORMAL; else return it->second.bRole; } bool CParty::IsRole(DWORD pid, BYTE bRole) { TMemberMap::iterator it = m_memberMap.find(pid); if (it == m_memberMap.end()) return false; return it->second.bRole == bRole; } void CParty::RemoveBonus() { TMemberMap::iterator it; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { LPCHARACTER ch; if ((ch = it->second.pCharacter)) { ComputeRolePoint(ch, it->second.bRole, false); } it->second.bNear = false; } } void CParty::RemoveBonusForOne(DWORD pid) { TMemberMap::iterator it = m_memberMap.find(pid); if (it == m_memberMap.end()) return; LPCHARACTER ch; if ((ch = it->second.pCharacter)) ComputeRolePoint(ch, it->second.bRole, false); } void CParty::HealParty() { // XXX DELETEME إ¬¶َہج¾ًئ® ؟د·لµة¶§±îءِ { return; } if (!m_bPartyHealReady) return; TMemberMap::iterator it; LPCHARACTER l = GetLeaderCharacter(); for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { if (!it->second.pCharacter) continue; LPCHARACTER ch = it->second.pCharacter; if (DISTANCE_APPROX(l->GetX()-ch->GetX(), l->GetY()-ch->GetY()) < PARTY_DEFAULT_RANGE) { ch->PointChange(POINT_HP, ch->GetMaxHP()-ch->GetHP()); ch->PointChange(POINT_SP, ch->GetMaxSP()-ch->GetSP()); } } m_bPartyHealReady = false; m_dwPartyHealTime = get_dword_time(); } void CParty::SummonToLeader(DWORD pid) { int xy[12][2] = { { 250, 0 }, { 216, 125 }, { 125, 216 }, { 0, 250 }, { -125, 216 }, { -216, 125 }, { -250, 0 }, { -216, -125 }, { -125, -216 }, { 0, -250 }, { 125, -216 }, { 216, -125 }, }; int n = 0; int x[12], y[12]; SECTREE_MANAGER & s = SECTREE_MANAGER::instance(); LPCHARACTER l = GetLeaderCharacter(); if (m_memberMap.find(pid) == m_memberMap.end()) { l->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ئؤئ¼> ¼زب¯اد·ء´آ ´ë»َہ» أ£ہ» ¼ِ ¾ّ½ہ´د´ظ.")); return; } LPCHARACTER ch = m_memberMap[pid].pCharacter; if (!ch) { l->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ئؤئ¼> ¼زب¯اد·ء´آ ´ë»َہ» أ£ہ» ¼ِ ¾ّ½ہ´د´ظ.")); return; } if (ch->IsDead()) { l->ChatPacket(CHAT_TYPE_INFO, " <مجموعة> لا تستطيع سحب شخص ميت "); return; } if (!ch->CanSummon(m_iLeadership)) { l->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ئؤئ¼> ´ë»َہ» ¼زب¯از ¼ِ ¾ّ½ہ´د´ظ.")); return; } for (int i = 0; i < 12; ++i) { PIXEL_POSITION p; if (s.GetMovablePosition(l->GetMapIndex(), l->GetX() + xy [i][0], l->GetY() + xy[i][1], p)) { x[n] = p.x; y[n] = p.y; n++; } } if (n == 0) l->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ئؤئ¼> ئؤئ¼؟ّہ» اِہç ہ§ؤ،·خ ¼زب¯از ¼ِ ¾ّ½ہ´د´ظ.")); else { int i = number(0, n - 1); ch->Show(l->GetMapIndex(), x[i], y[i]); ch->Stop(); } } void CParty::IncreaseOwnership() { if (m_memberMap.empty()) { m_itNextOwner = m_memberMap.begin(); return; } if (m_itNextOwner == m_memberMap.end()) m_itNextOwner = m_memberMap.begin(); else { m_itNextOwner++; if (m_itNextOwner == m_memberMap.end()) m_itNextOwner = m_memberMap.begin(); } } LPCHARACTER CParty::GetNextOwnership(LPCHARACTER ch, long x, long y) { if (m_itNextOwner == m_memberMap.end()) return ch; int size = m_memberMap.size(); while (size-- > 0) { LPCHARACTER pkMember = m_itNextOwner->second.pCharacter; if (pkMember && DISTANCE_APPROX(pkMember->GetX() - x, pkMember->GetY() - y) < 3000) { IncreaseOwnership(); return pkMember; } IncreaseOwnership(); } return ch; } void CParty::ComputeRolePoint(LPCHARACTER ch, BYTE bRole, bool bAdd) { if (!bAdd) { bool state = false; const DWORD Bonuslar[] = { POINT_PARTY_ATTACKER_BONUS, POINT_PARTY_TANKER_BONUS, POINT_PARTY_BUFFER_BONUS, POINT_PARTY_SKILL_MASTER_BONUS, POINT_PARTY_DEFENDER_BONUS, POINT_PARTY_HASTE_BONUS }; for (size_t i = 0; i < sizeof(Bonuslar) / sizeof(DWORD); ++i) { if (ch->GetPoint(Bonuslar[i])) { ch->PointChange(Bonuslar[i], -ch->GetPoint(Bonuslar[i])); state = true; } } if (state) { ch->ComputeBattlePoints(); ch->ComputePoints(); } return; } float k = (float) ch->GetSkillPowerByLevel( MIN(SKILL_MAX_LEVEL, m_iLeadership ) )/ 100.0f; switch (bRole) { case PARTY_ROLE_ATTACKER: { int iBonus = (int) (10 + 60 * k); if (ch->GetPoint(POINT_PARTY_ATTACKER_BONUS) != iBonus) { ch->PointChange(POINT_PARTY_ATTACKER_BONUS, iBonus - ch->GetPoint(POINT_PARTY_ATTACKER_BONUS)); ch->ComputePoints(); } } break; case PARTY_ROLE_TANKER: { int iBonus = (int) (50 + 1450 * k); if (ch->GetPoint(POINT_PARTY_TANKER_BONUS) != iBonus) { ch->PointChange(POINT_PARTY_TANKER_BONUS, iBonus - ch->GetPoint(POINT_PARTY_TANKER_BONUS)); ch->ComputePoints(); } } break; case PARTY_ROLE_BUFFER: { int iBonus = (int) (5 + 45 * k); if (ch->GetPoint(POINT_PARTY_BUFFER_BONUS) != iBonus) { ch->PointChange(POINT_PARTY_BUFFER_BONUS, iBonus - ch->GetPoint(POINT_PARTY_BUFFER_BONUS)); } } break; case PARTY_ROLE_SKILL_MASTER: { int iBonus = (int) (25 + 600 * k); if (ch->GetPoint(POINT_PARTY_SKILL_MASTER_BONUS) != iBonus) { ch->PointChange(POINT_PARTY_SKILL_MASTER_BONUS, iBonus - ch->GetPoint(POINT_PARTY_SKILL_MASTER_BONUS)); ch->ComputePoints(); } } break; case PARTY_ROLE_HASTE: { int iBonus = (int) (1+5*k); if (ch->GetPoint(POINT_PARTY_HASTE_BONUS) != iBonus) { ch->PointChange(POINT_PARTY_HASTE_BONUS, iBonus - ch->GetPoint(POINT_PARTY_HASTE_BONUS)); ch->ComputePoints(); } } break; case PARTY_ROLE_DEFENDER: { int iBonus = (int) (5+30*k); if (ch->GetPoint(POINT_PARTY_DEFENDER_BONUS) != iBonus) { ch->PointChange(POINT_PARTY_DEFENDER_BONUS, iBonus - ch->GetPoint(POINT_PARTY_DEFENDER_BONUS)); ch->ComputePoints(); } } break; } } void CParty::Update() { sys_log(1, "PARTY::Update"); LPCHARACTER l = GetLeaderCharacter(); if (!l) return; TMemberMap::iterator it; int iNearMember = 0; bool bResendAll = false; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { LPCHARACTER ch = it->second.pCharacter; it->second.bNear = false; if (!ch) continue; if (l->GetDungeon()) it->second.bNear = l->GetDungeon() == ch->GetDungeon(); #ifdef ENABLE_12ZI else if (l->GetZodiac()) it->second.bNear = l->GetZodiac() == ch->GetZodiac(); #endif else it->second.bNear = (DISTANCE_APPROX(l->GetX()-ch->GetX(), l->GetY()-ch->GetY()) < PARTY_DEFAULT_RANGE); if (it->second.bNear) { ++iNearMember; } } if (iNearMember <= 1 && !l->GetDungeon()) { for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) it->second.bNear = false; iNearMember = 0; } #ifdef ENABLE_12ZI if (iNearMember <= 1 && !l->GetZodiac()) { for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) it->second.bNear = false; iNearMember = 0; } #endif if (iNearMember != m_iCountNearPartyMember) { m_iCountNearPartyMember = iNearMember; bResendAll = true; } m_iLeadership = l->GetLeadershipSkillLevel(); int iNewExpBonus = ComputePartyBonusExpPercent(); m_iAttBonus = ComputePartyBonusAttackGrade(); m_iDefBonus = ComputePartyBonusDefenseGrade(); if (m_iExpBonus != iNewExpBonus) { bResendAll = true; m_iExpBonus = iNewExpBonus; } bool bLongTimeExpBonusChanged = false; // ئؤئ¼ °ل¼؛ بؤ أو؛ذار ½أ°£ہج ءِ³ھ¸é °واèؤ، ؛¸³ت½؛¸¦ ¹ق´آ´ظ. if (!m_iLongTimeExpBonus && (get_dword_time() - m_dwPartyStartTime > PARTY_ENOUGH_MINUTE_FOR_EXP_BONUS * 60 * 1000 / (g_iUseLocale?1:2))) { bLongTimeExpBonusChanged = true; m_iLongTimeExpBonus = 5; bResendAll = true; } for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { LPCHARACTER ch = it->second.pCharacter; if (!ch) continue; if (bLongTimeExpBonusChanged && ch->GetDesc()) ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ئؤئ¼ہا اùµ؟·آہج ³ô¾ئء® ءِ±ف؛خإح أك°، °واèؤ، ؛¸³ت½؛¸¦ ¹ق½ہ´د´ظ.")); bool bNear = it->second.bNear; ComputeRolePoint(ch, it->second.bRole, bNear); if (bNear) { if (!bResendAll) SendPartyInfoOneToAll(ch); } } // PARTY_ROLE_LIMIT_LEVEL_BUG_FIX m_anMaxRole[PARTY_ROLE_ATTACKER] = m_iLeadership >= 10 ? 1 : 0; m_anMaxRole[PARTY_ROLE_HASTE] = m_iLeadership >= 20 ? 1 : 0; m_anMaxRole[PARTY_ROLE_TANKER] = m_iLeadership >= 20 ? 1 : 0; m_anMaxRole[PARTY_ROLE_BUFFER] = m_iLeadership >= 25 ? 1 : 0; m_anMaxRole[PARTY_ROLE_SKILL_MASTER] = m_iLeadership >= 35 ? 1 : 0; m_anMaxRole[PARTY_ROLE_DEFENDER] = m_iLeadership >= 40 ? 1 : 0; m_anMaxRole[PARTY_ROLE_ATTACKER] += m_iLeadership >= 40 ? 1 : 0; // END_OF_PARTY_ROLE_LIMIT_LEVEL_BUG_FIX // Party Heal Update if (!m_bPartyHealReady) { if (!m_bCanUsePartyHeal && m_iLeadership >= 18) m_dwPartyHealTime = get_dword_time(); m_bCanUsePartyHeal = m_iLeadership >= 18; // إë¼ض·آ 18 ہج»َہ؛ بْہ» »ç؟ëاز ¼ِ ہضہ½. // إë¼ض·آ 40ہج»َہ؛ ئؤئ¼ بْ ؤًإ¸ہسہج ہû´ظ. DWORD PartyHealCoolTime = (m_iLeadership >= 40) ? PARTY_HEAL_COOLTIME_SHORT * 60 * 1000 : PARTY_HEAL_COOLTIME_LONG * 60 * 1000; if (m_bCanUsePartyHeal) { if (get_dword_time() > m_dwPartyHealTime + PartyHealCoolTime) { m_bPartyHealReady = true; // send heal ready if (0) // XXX DELETEME إ¬¶َہج¾ًئ® ؟د·لµة¶§±îءِ if (GetLeaderCharacter()) GetLeaderCharacter()->ChatPacket(CHAT_TYPE_COMMAND, "PartyHealReady"); } } } if (bResendAll) { for (TMemberMap::iterator it = m_memberMap.begin(); it != m_memberMap.end(); ++it) if (it->second.pCharacter) SendPartyInfoOneToAll(it->second.pCharacter); } } #ifdef ENABLE_PARTY_UPDATE void CParty::UpdateOnlineState(DWORD dwPID, const char* name, long mapIdx, long channel) #else void CParty::UpdateOnlineState(DWORD dwPID, const char* name) #endif { TMember& r = m_memberMap[dwPID]; TPacketGCPartyAdd p; p.header = HEADER_GC_PARTY_ADD; p.pid = dwPID; r.strName = name; strlcpy(p.name, name, sizeof(p.name)); #ifdef ENABLE_PARTY_UPDATE p.mapIdx = mapIdx; p.channel = channel; #endif for (TMemberMap::iterator it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { #ifdef ENABLE_PARTY_UPDATE CCI *pCCI = P2P_MANAGER::instance().Find(it->second.strName.c_str()); if (it->second.pCharacter && it->second.pCharacter->GetDesc()) it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); else if (pCCI) pCCI->pkDesc->Packet(&p, sizeof(p)); #else if (it->second.pCharacter && it->second.pCharacter->GetDesc()) it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); #endif } } void CParty::UpdateOfflineState(DWORD dwPID) { //const TMember& r = m_memberMap[dwPID]; TPacketGCPartyAdd p; p.header = HEADER_GC_PARTY_ADD; p.pid = dwPID; memset(p.name, 0, CHARACTER_NAME_MAX_LEN+1); #ifdef ENABLE_PARTY_UPDATE p.mapIdx = 0; p.channel = 0; #endif for (TMemberMap::iterator it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { #ifdef ENABLE_PARTY_UPDATE CCI *pCCI = P2P_MANAGER::instance().Find(it->second.strName.c_str()); if (it->second.pCharacter && it->second.pCharacter->GetDesc()) it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); else if (pCCI) pCCI->pkDesc->Packet(&p, sizeof(p)); #else if (it->second.pCharacter && it->second.pCharacter->GetDesc()) it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); #endif } } int CParty::GetFlag(const std::string& name) { TFlagMap::iterator it = m_map_iFlag.find(name); if (it != m_map_iFlag.end()) { //sys_log(0,"PARTY GetFlag %s %d", name.c_str(), it->second); return it->second; } //sys_log(0,"PARTY GetFlag %s 0", name.c_str()); return 0; } void CParty::SetFlag(const std::string& name, int value) { TFlagMap::iterator it = m_map_iFlag.find(name); //sys_log(0,"PARTY SetFlag %s %d", name.c_str(), value); if (it == m_map_iFlag.end()) { m_map_iFlag.insert(make_pair(name, value)); } else if (it->second != value) { it->second = value; } } void CParty::SetDungeon(LPDUNGEON pDungeon) { m_pkDungeon = pDungeon; m_map_iFlag.clear(); } LPDUNGEON CParty::GetDungeon() { return m_pkDungeon; } void CParty::SetDungeon_for_Only_party(LPDUNGEON pDungeon) { m_pkDungeon_for_Only_party = pDungeon; } LPDUNGEON CParty::GetDungeon_for_Only_party() { return m_pkDungeon_for_Only_party; } #ifdef ENABLE_12ZI void CParty::SetZodiac(LPZODIAC pZodiac) { m_pkZodiac = pZodiac; m_map_iFlag.clear(); } LPZODIAC CParty::GetZodiac() { return m_pkZodiac; } void CParty::SetZodiac_for_Only_party(LPZODIAC pZodiac) { m_pkZodiac_for_Only_party = pZodiac; } LPZODIAC CParty::GetZodiac_for_Only_party() { return m_pkZodiac_for_Only_party; } #endif bool CParty::IsPositionNearLeader(LPCHARACTER ch) { if (!m_pkChrLeader) return false; if (DISTANCE_APPROX(ch->GetX() - m_pkChrLeader->GetX(), ch->GetY() - m_pkChrLeader->GetY()) >= PARTY_DEFAULT_RANGE) return false; return true; } int CParty::GetExpBonusPercent() { if (GetNearMemberCount() <= 1) return 0; return m_iExpBonus + m_iLongTimeExpBonus; } bool CParty::IsNearLeader(DWORD pid) { TMemberMap::iterator it = m_memberMap.find(pid); if (it == m_memberMap.end()) return false; return it->second.bNear; } BYTE CParty::CountMemberByVnum(DWORD dwVnum) { if (m_bPCParty) return 0; LPCHARACTER tch; BYTE bCount = 0; TMemberMap::iterator it; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { if (!(tch = it->second.pCharacter)) continue; if (tch->IsPC()) continue; if (tch->GetMobTable().dwVnum == dwVnum) ++bCount; } return bCount; } void CParty::SendParameter(LPCHARACTER ch) { TPacketGCPartyParameter p; p.bHeader = HEADER_GC_PARTY_PARAMETER; p.bDistributeMode = m_iExpDistributionMode; LPDESC d = ch->GetDesc(); if (d) { d->Packet(&p, sizeof(TPacketGCPartyParameter)); } } void CParty::SendParameterToAll() { if (!m_bPCParty) return; TMemberMap::iterator it; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) if (it->second.pCharacter) SendParameter(it->second.pCharacter); } void CParty::SetParameter(int iMode) { if (iMode >= PARTY_EXP_DISTRIBUTION_MAX_NUM) { sys_err("Invalid exp distribution mode %d", iMode); return; } m_iExpDistributionMode = iMode; SendParameterToAll(); } int CParty::GetExpDistributionMode() { return m_iExpDistributionMode; } void CParty::SetExpCentralizeCharacter(DWORD dwPID) { TMemberMap::iterator it = m_memberMap.find(dwPID); if (it == m_memberMap.end()) return; m_pkChrExpCentralize = it->second.pCharacter; } LPCHARACTER CParty::GetExpCentralizeCharacter() { return m_pkChrExpCentralize; } BYTE CParty::GetMemberMaxLevel() { BYTE bMax = 0; itertype(m_memberMap) it = m_memberMap.begin(); while (it!=m_memberMap.end()) { if (!it->second.bLevel) { ++it; continue; } if (!bMax) bMax = it->second.bLevel; else if (it->second.bLevel) bMax = MAX(bMax, it->second.bLevel); ++it; } return bMax; } BYTE CParty::GetMemberMinLevel() { BYTE bMin = PLAYER_MAX_LEVEL_CONST; itertype(m_memberMap) it = m_memberMap.begin(); while (it!=m_memberMap.end()) { if (!it->second.bLevel) { ++it; continue; } if (!bMin) bMin = it->second.bLevel; else if (it->second.bLevel) bMin = MIN(bMin, it->second.bLevel); ++it; } return bMin; } int CParty::ComputePartyBonusExpPercent() { if (GetNearMemberCount() <= 1) return 0; LPCHARACTER leader = GetLeaderCharacter(); int iBonusPartyExpFromItem = 0; // UPGRADE_PARTY_BONUS int iMemberCount=MIN(8, GetNearMemberCount()); if (leader && (leader->IsEquipUniqueItem(UNIQUE_ITEM_PARTY_BONUS_EXP) || leader->IsEquipUniqueItem(UNIQUE_ITEM_PARTY_BONUS_EXP_MALL) || leader->IsEquipUniqueItem(UNIQUE_ITEM_PARTY_BONUS_EXP_GIFT) || leader->IsEquipUniqueGroup(10010))) { // ءك±¹أّ ہ°µµ ہû؟ëہ» ب®ہخاط¾كار´ظ. if (g_iUseLocale) { iBonusPartyExpFromItem = 30; } else { iBonusPartyExpFromItem = KOR_aiUniqueItemPartyBonusExpPercentByMemberCount[iMemberCount]; } } if (g_iUseLocale) return iBonusPartyExpFromItem + CHN_aiPartyBonusExpPercentByMemberCount[iMemberCount]; else return iBonusPartyExpFromItem + KOR_aiPartyBonusExpPercentByMemberCount[iMemberCount]; // END_OF_UPGRADE_PARTY_BONUS }
party.h
Spoiler#ifndef __INC_METIN_II_GAME_PARTY_H__ #define __INC_METIN_II_GAME_PARTY_H__ #include "char.h" enum // unit : minute { PARTY_ENOUGH_MINUTE_FOR_EXP_BONUS = 60, // ئؤئ¼ °ل¼؛ بؤ 60؛ذ بؤ ؛خإح أك°، °واèؤ، ؛¸³ت½؛ PARTY_HEAL_COOLTIME_LONG = 60, PARTY_HEAL_COOLTIME_SHORT = 30, PARTY_MAX_MEMBER = 8, PARTY_DEFAULT_RANGE = 5000, }; enum EPartyRole { PARTY_ROLE_NORMAL, PARTY_ROLE_LEADER, PARTY_ROLE_ATTACKER, PARTY_ROLE_TANKER, PARTY_ROLE_BUFFER, PARTY_ROLE_SKILL_MASTER, PARTY_ROLE_HASTE, PARTY_ROLE_DEFENDER, PARTY_ROLE_MAX_NUM, }; enum EPartyExpDistributionModes { PARTY_EXP_DISTRIBUTION_NON_PARITY, PARTY_EXP_DISTRIBUTION_PARITY, PARTY_EXP_DISTRIBUTION_MAX_NUM }; class CParty; class CDungeon; #ifdef ENABLE_12ZI class CZodiac; #endif class CPartyManager : public singleton<CPartyManager> { public: typedef std::map<DWORD, LPPARTY> TPartyMap; typedef std::set<LPPARTY> TPCPartySet; public: CPartyManager(); virtual ~CPartyManager(); void Initialize(); //void SendPartyToDB(); void EnablePCParty() { m_bEnablePCParty = true; sys_log(0,"PARTY Enable"); } void DisablePCParty() { m_bEnablePCParty = false; sys_log(0,"PARTY Disable"); } bool IsEnablePCParty() { return m_bEnablePCParty; } LPPARTY CreateParty(LPCHARACTER pkLeader); void DeleteParty(LPPARTY pParty); void DeleteAllParty(); bool SetParty(LPCHARACTER pkChr); void SetPartyMember(DWORD dwPID, LPPARTY pParty); #ifdef ENABLE_PARTY_UPDATE void P2PLogin(DWORD pid, const char* name, long mapIdx, long channel); #else void P2PLogin(DWORD pid, const char* name); #endif void P2PLogout(DWORD pid); LPPARTY P2PCreateParty(DWORD pid); void P2PDeleteParty(DWORD pid); void P2PJoinParty(DWORD leader, DWORD pid, BYTE role = 0); void P2PQuitParty(DWORD pid); private: TPartyMap m_map_pkParty; // PID·خ ¾î´ہ ئؤئ¼؟، ہض³ھ °ث»ِاد±â ہ§ار ؤءإ×ہج³ت TPartyMap m_map_pkMobParty; // Mob ئؤئ¼´آ PID ´ë½إ VID ·خ µû·خ °ü¸®ار´ظ. TPCPartySet m_set_pkPCParty; // »ç¶÷µéہا ئؤئ¼ ہüأ¼ ءاص bool m_bEnablePCParty; // µً؛ٌ°، ؤرء®ہضءِ ¾تہ¸¸é »ç¶÷µéہا ئؤئ¼ »َإآ°، ؛¯°و؛ز°، }; enum EPartyMessages { PM_ATTACK, // Attack him PM_RETURN, // Return back to position PM_ATTACKED_BY, // I was attacked by someone PM_AGGRO_INCREASE, // My aggro is increased }; class CParty { public: typedef struct SMember { LPCHARACTER pCharacter; bool bNear; BYTE bRole; BYTE bLevel; std::string strName; #ifdef ENABLE_PARTY_UPDATE long mapIdx; long channel; #endif } TMember; typedef std::map<DWORD, TMember> TMemberMap; typedef std::map<std::string, int> TFlagMap; public: CParty(); virtual ~CParty(); void P2PJoin(DWORD dwPID); void P2PQuit(DWORD dwPID); virtual void Join(DWORD dwPID); void Quit(DWORD dwPID); void Link(LPCHARACTER pkChr); void Unlink(LPCHARACTER pkChr); void ChatPacketToAllMember(BYTE type, const char* format, ...); #ifdef ENABLE_PARTY_UPDATE void UpdateOnlineState(DWORD dwPID, const char* name, long mapIdx, long channel); #else void UpdateOnlineState(DWORD dwPID, const char* name); #endif void UpdateOfflineState(DWORD dwPID); DWORD GetLeaderPID(); LPCHARACTER GetLeaderCharacter(); LPCHARACTER GetLeader() { return m_pkChrLeader; } DWORD GetMemberCount(); DWORD GetNearMemberCount() { return m_iCountNearPartyMember; } bool IsMember(DWORD pid) { return m_memberMap.find(pid) != m_memberMap.end(); } bool IsNearLeader(DWORD pid); bool IsPositionNearLeader(LPCHARACTER ch); void SendMessage(LPCHARACTER ch, BYTE bMsg, DWORD dwArg1, DWORD dwArg2); void SendPartyJoinOneToAll(DWORD dwPID); void SendPartyJoinAllToOne(LPCHARACTER ch); void SendPartyRemoveOneToAll(DWORD dwPID); void SendPartyInfoOneToAll(DWORD pid); void SendPartyInfoOneToAll(LPCHARACTER ch); void SendPartyInfoAllToOne(LPCHARACTER ch); void SendPartyLinkOneToAll(LPCHARACTER ch); void SendPartyLinkAllToOne(LPCHARACTER ch); void SendPartyUnlinkOneToAll(LPCHARACTER ch); int GetPartyBonusExpPercent() { return m_iExpBonus; } int GetPartyBonusAttackGrade() { return m_iAttBonus; } int GetPartyBonusDefenseGrade() { return m_iDefBonus; } int ComputePartyBonusExpPercent(); inline int ComputePartyBonusAttackGrade(); inline int ComputePartyBonusDefenseGrade(); template <class Func> void ForEachMember(Func & f); template <class Func> void ForEachMemberPtr(Func & f); template <class Func> void ForEachOnlineMember(Func & f); template <class Func> void ForEachNearMember(Func & f); template <class Func> void ForEachOnMapMember (Func & f, long lMapIndex); template <class Func> bool ForEachOnMapMemberBool (Func & f, long lMapIndex); void Update(); int GetExpBonusPercent(); bool SetRole(DWORD pid, BYTE bRole, bool on); BYTE GetRole(DWORD pid); bool IsRole(DWORD pid, BYTE bRole); BYTE GetMemberMaxLevel(); BYTE GetMemberMinLevel(); void ComputeRolePoint(LPCHARACTER ch, BYTE bRole, bool bAdd); void HealParty(); void SummonToLeader(DWORD pid); void SetPCParty(bool b) { m_bPCParty = b; } LPCHARACTER GetNextOwnership(LPCHARACTER ch, long x, long y); void SetFlag(const std::string& name, int value); int GetFlag(const std::string& name); void SetDungeon(LPDUNGEON pDungeon); LPDUNGEON GetDungeon(); #ifdef ENABLE_12ZI void SetZodiac(LPZODIAC pZodiac); LPZODIAC GetZodiac(); #endif BYTE CountMemberByVnum(DWORD dwVnum); void SetParameter(int iMode); int GetExpDistributionMode(); void SetExpCentralizeCharacter(DWORD pid); LPCHARACTER GetExpCentralizeCharacter(); void RequestSetMemberLevel(DWORD pid, BYTE level); void P2PSetMemberLevel(DWORD pid, BYTE level); #ifdef ENABLE_PARTY_UPDATE void RequestSetMemberMapIndex(DWORD pid, long mapIdx); void P2PSetMemberMapIndex(DWORD pid, long mapIdx); void RequestSetMemberChannel(DWORD pid, long channel); void P2PSetMemberChannel(DWORD pid, long channel); #endif protected: void IncreaseOwnership(); virtual void Initialize(); void Destroy(); void RemovePartyBonus(); void RemoveBonus(); void RemoveBonusForOne(DWORD pid); void SendParameter(LPCHARACTER ch); void SendParameterToAll(); TMemberMap m_memberMap; DWORD m_dwLeaderPID; LPCHARACTER m_pkChrLeader; LPEVENT m_eventUpdate; TMemberMap::iterator m_itNextOwner; private: int m_iExpDistributionMode; LPCHARACTER m_pkChrExpCentralize; DWORD m_dwPartyStartTime; DWORD m_dwPartyHealTime; bool m_bPartyHealReady; bool m_bCanUsePartyHeal; int m_anRoleCount[PARTY_ROLE_MAX_NUM]; int m_anMaxRole[PARTY_ROLE_MAX_NUM]; int m_iLongTimeExpBonus; // used in Update int m_iLeadership; int m_iExpBonus; int m_iAttBonus; int m_iDefBonus; int m_iCountNearPartyMember; bool m_bPCParty; TFlagMap m_map_iFlag; LPDUNGEON m_pkDungeon; LPDUNGEON m_pkDungeon_for_Only_party; #ifdef ENABLE_12ZI LPZODIAC m_pkZodiac; LPZODIAC m_pkZodiac_for_Only_party; #endif public: void SetDungeon_for_Only_party(LPDUNGEON pDungeon); LPDUNGEON GetDungeon_for_Only_party(); #ifdef ENABLE_12ZI void SetZodiac_for_Only_party(LPZODIAC pZodiac); LPZODIAC GetZodiac_for_Only_party(); #endif }; template <class Func> void CParty::ForEachMember(Func & f) { TMemberMap::iterator it; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) f(it->first); } template <class Func> void CParty::ForEachMemberPtr(Func & f) { TMemberMap::iterator it; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) f(it->second.pCharacter); } template <class Func> void CParty::ForEachOnlineMember(Func & f) { TMemberMap::iterator it; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) if (it->second.pCharacter) f(it->second.pCharacter); } template <class Func> void CParty::ForEachNearMember(Func & f) { TMemberMap::iterator it; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) if (it->second.pCharacter && it->second.bNear) f(it->second.pCharacter); } template <class Func> void CParty::ForEachOnMapMember (Func & f, long lMapIndex) { TMemberMap::iterator it; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { LPCHARACTER ch = it->second.pCharacter; if (ch) { if (ch->GetMapIndex () == lMapIndex) f(ch); } } } template <class Func> bool CParty::ForEachOnMapMemberBool(Func & f, long lMapIndex) { TMemberMap::iterator it; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { LPCHARACTER ch = it->second.pCharacter; if (ch) { if (ch->GetMapIndex () == lMapIndex) { if(f(ch) == false) { return false; } } } } return true; } inline int CParty::ComputePartyBonusAttackGrade() { /* if (GetNearMemberCount() <= 1) return 0; int leadership = GetLeaderCharacter()->GetLeadershipSkillLevel(); int n = GetNearMemberCount(); if (n >= 3 && leadership >= 10) return 2; if (n >= 2 && leadership >= 4) return 1; */ return 0; } inline int CParty::ComputePartyBonusDefenseGrade() { /* if (GetNearMemberCount() <= 1) return 0; int leadership = GetLeaderCharacter()->GetLeadershipSkillLevel(); int n = GetNearMemberCount(); if (n >= 5 && leadership >= 24) return 2; if (n >= 4 && leadership >= 16) return 1; */ return 0; } #endif #ifdef ENABLE_ENABLE_DICE_SYSTEM #include "item.h" struct FPartyDropDiceRoll { const LPITEM m_itemDrop; LPCHARACTER m_itemOwner; int m_lastNumber; FPartyDropDiceRoll(const LPITEM itemDrop, LPCHARACTER itemOwner) : m_itemDrop(itemDrop), m_itemOwner(itemOwner), m_lastNumber(0) { }; void Process(const LPCHARACTER mobVictim) { if ((!mobVictim || (mobVictim->GetMobRank() >= MOB_RANK_BOSS && mobVictim->GetMobRank() <= MOB_RANK_KING)) && m_itemOwner->GetParty() && m_itemOwner->GetParty()->GetNearMemberCount() > 1) { LPPARTY pParty = m_itemOwner->GetParty(); pParty->ChatPacketToAllMember(CHAT_TYPE_DICE_INFO, LC_TEXT("*** Rolling for the following item: %16s ***"), m_itemDrop->GetName()); pParty->ForEachNearMember(*this); if (m_itemOwner) { m_itemDrop->SetOwnership(m_itemOwner); pParty->ChatPacketToAllMember(CHAT_TYPE_DICE_INFO, LC_TEXT("*** Rolling of %s: %16s ***"), m_itemDrop->GetName(), m_itemOwner->GetName()); } } else m_itemDrop->SetOwnership(m_itemOwner); } LPCHARACTER GetItemOwner() { return m_itemOwner; } const LPITEM GetItemDrop() { return m_itemDrop; } void operator () (LPCHARACTER ch) { if (!ch) return; LPPARTY pParty = ch->GetParty(); if (!pParty) return; while (true) { int pickedNumber = number(10000, 99999); if (pickedNumber > m_lastNumber) { m_lastNumber = pickedNumber; m_itemOwner = ch; } else if (pickedNumber == m_lastNumber) { continue; } else // if (pickedNumber < m_lastNumber) { } pParty->ChatPacketToAllMember(CHAT_TYPE_DICE_INFO, LC_TEXT("*** -> %16s - Dice score: %05d ***"), ch->GetName(), pickedNumber); break; } } }; #endif
- 1
- 1
- 1
- 2
-
-
Someone who knows this bug or telling me where to look
i think it is contrivedhttps://metin2.download/video/K7gaz3Y1LFkN2xs0qQ8GdJ8t2L0PS4d2/.mp4
- 1
-
this bug is public just googling
-
-
-
skill by ganara
Official Lucky Box(Fortune Chest)
in Features & Metin2 Systems
Posted
the enemy of GF brilliant as usual