Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include "constants.h"
- #include "pvp.h"
- #include "crc32.h"
- #include "packet.h"
- #include "desc.h"
- #include "desc_manager.h"
- #include "char.h"
- #include "char_manager.h"
- #include "config.h"
- #include "sectree_manager.h"
- #include "buffer_manager.h"
- #include "locale_service.h"
- using namespace std;
- CPVP::CPVP(DWORD dwPID1, DWORD dwPID2)
- {
- if (dwPID1 > dwPID2)
- {
- m_players[0].dwPID = dwPID1;
- m_players[1].dwPID = dwPID2;
- m_players[0].bAgree = true;
- }
- else
- {
- m_players[0].dwPID = dwPID2;
- m_players[1].dwPID = dwPID1;
- m_players[1].bAgree = true;
- }
- DWORD adwID[2];
- adwID[0] = m_players[0].dwPID;
- adwID[1] = m_players[1].dwPID;
- m_dwCRC = GetFastHash((const char *) &adwID, 8);
- m_bRevenge = false;
- SetLastFightTime();
- }
- CPVP::CPVP(CPVP & k)
- {
- m_players[0] = k.m_players[0];
- m_players[1] = k.m_players[1];
- m_dwCRC = k.m_dwCRC;
- m_bRevenge = k.m_bRevenge;
- SetLastFightTime();
- }
- CPVP::~CPVP()
- {
- }
- void CPVP::Packet(bool bDelete)
- {
- if (!m_players[0].dwVID || !m_players[1].dwVID)
- {
- if (bDelete)
- sys_err("null vid when removing %u %u", m_players[0].dwVID, m_players[0].dwVID);
- return;
- }
- TPacketGCPVP pack;
- pack.bHeader = HEADER_GC_PVP;
- if (bDelete)
- {
- pack.bMode = PVP_MODE_NONE;
- pack.dwVIDSrc = m_players[0].dwVID;
- pack.dwVIDDst = m_players[1].dwVID;
- }
- else if (IsFight())
- {
- pack.bMode = PVP_MODE_FIGHT;
- pack.dwVIDSrc = m_players[0].dwVID;
- pack.dwVIDDst = m_players[1].dwVID;
- }
- else
- {
- pack.bMode = m_bRevenge ? PVP_MODE_REVENGE : PVP_MODE_AGREE;
- if (m_players[0].bAgree)
- {
- pack.dwVIDSrc = m_players[0].dwVID;
- pack.dwVIDDst = m_players[1].dwVID;
- }
- else
- {
- pack.dwVIDSrc = m_players[1].dwVID;
- pack.dwVIDDst = m_players[0].dwVID;
- }
- }
- const DESC_MANAGER::DESC_SET & c_rSet = DESC_MANAGER::instance().GetClientSet();
- DESC_MANAGER::DESC_SET::const_iterator it = c_rSet.begin();
- while (it != c_rSet.end())
- {
- LPDESC d = *it++;
- if (d->IsPhase(PHASE_GAME) || d->IsPhase(PHASE_DEAD))
- d->Packet(&pack, sizeof(pack));
- }
- }
- bool CPVP::Agree(DWORD dwPID)
- {
- m_players[m_players[0].dwPID != dwPID ? 1 : 0].bAgree = true;
- if (IsFight())
- {
- Packet();
- return true;
- }
- return false;
- }
- bool CPVP::IsFight()
- {
- return (m_players[0].bAgree == m_players[1].bAgree) && m_players[0].bAgree;
- }
- void CPVP::Win(DWORD dwPID)
- {
- int iSlot = m_players[0].dwPID != dwPID ? 1 : 0;
- m_bRevenge = true;
- m_players[iSlot].bAgree = true; // ŔÚµżŔ¸·Î µżŔÇ
- m_players[!iSlot].bCanRevenge = true;
- m_players[!iSlot].bAgree = false;
- Packet();
- }
- bool CPVP::CanRevenge(DWORD dwPID)
- {
- return m_players[m_players[0].dwPID != dwPID ? 1 : 0].bCanRevenge;
- }
- void CPVP::SetVID(DWORD dwPID, DWORD dwVID)
- {
- if (m_players[0].dwPID == dwPID)
- m_players[0].dwVID = dwVID;
- else
- m_players[1].dwVID = dwVID;
- }
- void CPVP::SetLastFightTime()
- {
- m_dwLastFightTime = get_dword_time();
- }
- DWORD CPVP::GetLastFightTime()
- {
- return m_dwLastFightTime;
- }
- CPVPManager::CPVPManager()
- {
- }
- CPVPManager::~CPVPManager()
- {
- }
- void CPVPManager::Insert(LPCHARACTER pkChr, LPCHARACTER pkVictim)
- {
- if (pkChr->IsDead() || pkVictim->IsDead())
- return;
- CPVP kPVP(pkChr->GetPlayerID(), pkVictim->GetPlayerID());
- CPVP * pkPVP;
- if ((pkPVP = Find(kPVP.m_dwCRC)))
- {
- // şąĽöÇŇ Ľö ŔÖŔ¸¸é ąŮ·Î ˝Îżň!
- if (pkPVP->Agree(pkChr->GetPlayerID()))
- {
- pkVictim->ChatPacket(CHAT_TYPE_INFO, "[LS;730;%s]", pkChr->GetName());
- pkChr->ChatPacket(CHAT_TYPE_INFO, "[LS;730;%s]", pkVictim->GetName());
- }
- return;
- }
- pkPVP = M2_NEW CPVP(kPVP);
- pkPVP->SetVID(pkChr->GetPlayerID(), pkChr->GetVID());
- pkPVP->SetVID(pkVictim->GetPlayerID(), pkVictim->GetVID());
- m_map_pkPVP.insert(map<DWORD, CPVP *>::value_type(pkPVP->m_dwCRC, pkPVP));
- m_map_pkPVPSetByID[pkChr->GetPlayerID()].insert(pkPVP);
- m_map_pkPVPSetByID[pkVictim->GetPlayerID()].insert(pkPVP);
- pkPVP->Packet();
- char msg[CHAT_MAX_LEN + 1];
- snprintf(msg, sizeof(msg), "[LS;732;%s]", pkChr->GetName());
- pkVictim->ChatPacket(CHAT_TYPE_INFO, msg);
- pkChr->ChatPacket(CHAT_TYPE_INFO, "[LS;731;%s]", pkVictim->GetName());
- // NOTIFY_PVP_MESSAGE
- LPDESC pkVictimDesc = pkVictim->GetDesc();
- if (pkVictimDesc)
- {
- TPacketGCWhisper pack;
- int len = MIN(CHAT_MAX_LEN, strlen(msg) + 1);
- pack.bHeader = HEADER_GC_WHISPER;
- pack.wSize = sizeof(TPacketGCWhisper) + strlen(msg) + 1;
- pack.bType = WHISPER_TYPE_SYSTEM;
- pack.bCanFormat = true;
- strlcpy(pack.szNameFrom, pkChr->GetName(), sizeof(pack.szNameFrom));
- TEMP_BUFFER buf;
- buf.write(&pack, sizeof(TPacketGCWhisper));
- buf.write(msg, strlen(msg) + 1);
- pkVictimDesc->Packet(buf.read_peek(), buf.size());
- }
- }
- void CPVPManager::ConnectEx(LPCHARACTER pkChr, bool bDisconnect)
- {
- CPVPSetMap::iterator it = m_map_pkPVPSetByID.find(pkChr->GetPlayerID());
- if (it == m_map_pkPVPSetByID.end())
- return;
- DWORD dwVID = bDisconnect ? 0 : pkChr->GetVID();
- std::unordered_set<CPVP*>::iterator it2 = it->second.begin();
- while (it2 != it->second.end())
- {
- CPVP * pkPVP = *it2++;
- pkPVP->SetVID(pkChr->GetPlayerID(), dwVID);
- }
- }
- void CPVPManager::Connect(LPCHARACTER pkChr)
- {
- ConnectEx(pkChr, false);
- }
- void CPVPManager::Disconnect(LPCHARACTER playerCharacter)
- {
- auto pvpSetIterator = m_map_pkPVPSetByID.find(playerCharacter->GetPlayerID());
- if (pvpSetIterator == m_map_pkPVPSetByID.end())
- {
- return;
- }
- for (auto* pvpInstance : pvpSetIterator->second)
- {
- if (pvpInstance->m_players[0].dwPID == playerCharacter->GetPlayerID() || pvpInstance->m_players[1].dwPID == playerCharacter->GetPlayerID())
- {
- pvpInstance->SetVID(playerCharacter->GetPlayerID(), 0);
- pvpInstance->Packet(true);
- Delete(pvpInstance);
- }
- }
- }
- void CPVPManager::GiveUp(LPCHARACTER pkChr, DWORD dwKillerPID) // This method is calling from no where yet.
- {
- CPVPSetMap::iterator it = m_map_pkPVPSetByID.find(pkChr->GetPlayerID());
- if (it == m_map_pkPVPSetByID.end())
- return;
- sys_log(1, "PVPManager::Dead %d", pkChr->GetPlayerID());
- std::unordered_set<CPVP*>::iterator it2 = it->second.begin();
- while (it2 != it->second.end())
- {
- CPVP * pkPVP = *it2++;
- DWORD dwCompanionPID;
- if (pkPVP->m_players[0].dwPID == pkChr->GetPlayerID())
- dwCompanionPID = pkPVP->m_players[1].dwPID;
- else
- dwCompanionPID = pkPVP->m_players[0].dwPID;
- if (dwCompanionPID != dwKillerPID)
- continue;
- pkPVP->SetVID(pkChr->GetPlayerID(), 0);
- m_map_pkPVPSetByID.erase(dwCompanionPID);
- it->second.erase(pkPVP);
- if (it->second.empty())
- m_map_pkPVPSetByID.erase(it);
- m_map_pkPVP.erase(pkPVP->m_dwCRC);
- pkPVP->Packet(true);
- M2_DELETE(pkPVP);
- break;
- }
- }
- // ¸®ĹϰŞ: 0 = PK, 1 = PVP
- // PVP¸¦ ¸®ĹĎÇĎ¸é °ćÇčġłŞ ľĆŔĚĹŰŔ» ¶ł±¸°í PK¸é ¶ł±¸Áö ľĘ´Â´Ů.
- bool CPVPManager::Dead(LPCHARACTER pkChr, DWORD dwKillerPID)
- {
- CPVPSetMap::iterator it = m_map_pkPVPSetByID.find(pkChr->GetPlayerID());
- if (it == m_map_pkPVPSetByID.end())
- return false;
- bool found = false;
- sys_log(1, "PVPManager::Dead %d", pkChr->GetPlayerID());
- std::unordered_set<CPVP*>::iterator it2 = it->second.begin();
- while (it2 != it->second.end())
- {
- CPVP * pkPVP = *it2++;
- DWORD dwCompanionPID;
- if (pkPVP->m_players[0].dwPID == pkChr->GetPlayerID())
- dwCompanionPID = pkPVP->m_players[1].dwPID;
- else
- dwCompanionPID = pkPVP->m_players[0].dwPID;
- if (dwCompanionPID == dwKillerPID)
- {
- if (pkPVP->IsFight())
- {
- pkPVP->SetLastFightTime();
- pkPVP->Win(dwKillerPID);
- found = true;
- break;
- }
- else if (get_dword_time() - pkPVP->GetLastFightTime() <= 15000)
- {
- found = true;
- break;
- }
- }
- }
- return found;
- }
- bool CPVPManager::CanAttack(LPCHARACTER pkChr, LPCHARACTER pkVictim)
- {
- switch (pkVictim->GetCharType())
- {
- case CHAR_TYPE_NPC:
- case CHAR_TYPE_WARP:
- case CHAR_TYPE_GOTO:
- return false;
- }
- if (pkChr == pkVictim)
- return false;
- if (pkVictim->IsNPC() && pkChr->IsNPC() && !pkChr->IsGuardNPC())
- return false;
- if( true == pkChr->IsHorseRiding() )
- {
- if( pkChr->GetHorseLevel() > 0 && 1 == pkChr->GetHorseGrade() )
- return false;
- }
- else
- {
- switch( pkChr->GetMountVnum() )
- {
- case 0:
- case 20030:
- case 20110: //mount test for metin2.dev
- case 20111:
- case 20112:
- case 20113:
- case 20114:
- case 20115:
- case 20116:
- case 20117:
- case 20118:
- case 20119:
- case 20120:
- case 20121:
- case 20122:
- case 20123:
- case 20124:
- case 20125:
- case 20126:
- case 20127:
- case 20128:
- case 20201:
- case 20202:
- case 20203:
- case 20204:
- case 20205:
- case 20206:
- case 20207:
- case 20208:
- case 20209:
- case 20210:
- case 20211:
- case 20212:
- case 20213:
- case 20214:
- case 20215:
- case 20216:
- case 20217:
- case 20218:
- case 20219:
- case 20220:
- case 20221:
- case 20222:
- break;
- default:
- return false;
- }
- }
- if (pkVictim->IsNPC() || pkChr->IsNPC())
- {
- return true;
- }
- if (pkVictim->IsObserverMode() || pkChr->IsObserverMode())
- return false;
- {
- BYTE bMapEmpire = SECTREE_MANAGER::instance().GetEmpireFromMapIndex(pkChr->GetMapIndex());
- if ( pkChr->GetPKMode() == PK_MODE_PROTECT && pkChr->GetEmpire() == bMapEmpire ||
- pkVictim->GetPKMode() == PK_MODE_PROTECT && pkVictim->GetEmpire() == bMapEmpire )
- {
- return false;
- }
- }
- if (pkChr->GetEmpire() != pkVictim->GetEmpire())
- {
- if ( LC_IsYMIR() == true || LC_IsKorea() == true )
- {
- if ( pkChr->GetPKMode() == PK_MODE_PROTECT || pkVictim->GetPKMode() == PK_MODE_PROTECT )
- {
- return false;
- }
- }
- return true;
- }
- bool beKillerMode = false;
- if (pkVictim->GetParty() && pkVictim->GetParty() == pkChr->GetParty())
- {
- return false;
- // Cannot attack same party on any pvp model
- }
- else
- {
- if (pkVictim->IsKillerMode())
- {
- return true;
- }
- if (pkChr->GetAlignment() < 0 && pkVictim->GetAlignment() >= 0)
- {
- if (g_protectNormalPlayer)
- {
- // ąüąýŔÚ´Â ĆňȸđµĺŔÎ ÂřÇŃ»ç¶÷Ŕ» °ř°ÝÇŇ Ľö ľř´Ů.
- if (PK_MODE_PEACE == pkVictim->GetPKMode())
- return false;
- }
- }
- switch (pkChr->GetPKMode())
- {
- case PK_MODE_PEACE:
- case PK_MODE_REVENGE:
- // Cannot attack same guild
- if (pkVictim->GetGuild() && pkVictim->GetGuild() == pkChr->GetGuild())
- break;
- if (pkChr->GetPKMode() == PK_MODE_REVENGE)
- {
- //if (!g_iUseLocale)
- if (1)
- {
- if (pkChr->GetAlignment() < 0 && pkVictim->GetAlignment() >= 0)
- {
- pkChr->SetKillerMode(true);
- return true;
- }
- else if (pkChr->GetAlignment() >= 0 && pkVictim->GetAlignment() < 0)
- return true;
- }
- else
- {
- if (pkChr->GetAlignment() < 0 && pkVictim->GetAlignment() < 0)
- break;
- else if (pkChr->GetAlignment() >= 0 && pkVictim->GetAlignment() >= 0)
- break;
- beKillerMode = true;
- }
- }
- break;
- case PK_MODE_GUILD:
- // Same implementation from PK_MODE_FREE except for attacking same guild
- if (!pkChr->GetGuild() || (pkVictim->GetGuild() != pkChr->GetGuild()))
- {
- if (1)
- //if (!g_iUseLocale)
- {
- if (pkVictim->GetAlignment() >= 0)
- pkChr->SetKillerMode(true);
- else if (pkChr->GetAlignment() < 0 && pkVictim->GetAlignment() < 0)
- pkChr->SetKillerMode(true);
- return true;
- }
- else
- beKillerMode = true;
- }
- break;
- case PK_MODE_FREE:
- //if (!g_iUseLocale)
- if (1)
- {
- if (pkVictim->GetAlignment() >= 0)
- pkChr->SetKillerMode(true);
- else if (pkChr->GetAlignment() < 0 && pkVictim->GetAlignment() < 0)
- pkChr->SetKillerMode(true);
- return true;
- }
- else
- beKillerMode = true;
- break;
- }
- }
- CPVP kPVP(pkChr->GetPlayerID(), pkVictim->GetPlayerID());
- CPVP * pkPVP = Find(kPVP.m_dwCRC);
- if (!pkPVP || !pkPVP->IsFight())
- {
- if (beKillerMode)
- pkChr->SetKillerMode(true);
- return (beKillerMode);
- }
- pkPVP->SetLastFightTime();
- return true;
- }
- CPVP * CPVPManager::Find(DWORD dwCRC)
- {
- map<DWORD, CPVP *>::iterator it = m_map_pkPVP.find(dwCRC);
- if (it == m_map_pkPVP.end())
- return NULL;
- return it->second;
- }
- void CPVPManager::Delete(CPVP * pkPVP)
- {
- map<DWORD, CPVP *>::iterator it = m_map_pkPVP.find(pkPVP->m_dwCRC);
- if (it == m_map_pkPVP.end())
- return;
- m_map_pkPVP.erase(it);
- m_map_pkPVPSetByID[pkPVP->m_players[0].dwPID].erase(pkPVP);
- m_map_pkPVPSetByID[pkPVP->m_players[1].dwPID].erase(pkPVP);
- M2_DELETE(pkPVP);
- }
- void CPVPManager::SendList(LPDESC d)
- {
- map<DWORD, CPVP *>::iterator it = m_map_pkPVP.begin();
- DWORD dwVID = d->GetCharacter()->GetVID();
- TPacketGCPVP pack;
- pack.bHeader = HEADER_GC_PVP;
- while (it != m_map_pkPVP.end())
- {
- CPVP * pkPVP = (it++)->second;
- if (!pkPVP->m_players[0].dwVID || !pkPVP->m_players[1].dwVID)
- continue;
- // VID°ˇ µŃ´Ů ŔÖŔ» °ćżěżˇ¸¸ ş¸ł˝´Ů.
- if (pkPVP->IsFight())
- {
- pack.bMode = PVP_MODE_FIGHT;
- pack.dwVIDSrc = pkPVP->m_players[0].dwVID;
- pack.dwVIDDst = pkPVP->m_players[1].dwVID;
- }
- else
- {
- pack.bMode = pkPVP->m_bRevenge ? PVP_MODE_REVENGE : PVP_MODE_AGREE;
- if (pkPVP->m_players[0].bAgree)
- {
- pack.dwVIDSrc = pkPVP->m_players[0].dwVID;
- pack.dwVIDDst = pkPVP->m_players[1].dwVID;
- }
- else
- {
- pack.dwVIDSrc = pkPVP->m_players[1].dwVID;
- pack.dwVIDDst = pkPVP->m_players[0].dwVID;
- }
- }
- d->Packet(&pack, sizeof(pack));
- sys_log(1, "PVPManager::SendList %d %d", pack.dwVIDSrc, pack.dwVIDDst);
- if (pkPVP->m_players[0].dwVID == dwVID)
- {
- LPCHARACTER ch = CHARACTER_MANAGER::instance().Find(pkPVP->m_players[1].dwVID);
- if (ch && ch->GetDesc())
- {
- LPDESC d = ch->GetDesc();
- d->Packet(&pack, sizeof(pack));
- }
- }
- else if (pkPVP->m_players[1].dwVID == dwVID)
- {
- LPCHARACTER ch = CHARACTER_MANAGER::instance().Find(pkPVP->m_players[0].dwVID);
- if (ch && ch->GetDesc())
- {
- LPDESC d = ch->GetDesc();
- d->Packet(&pack, sizeof(pack));
- }
- }
- }
- }
- void CPVPManager::Process()
- {
- map<DWORD, CPVP *>::iterator it = m_map_pkPVP.begin();
- while (it != m_map_pkPVP.end())
- {
- CPVP * pvp = (it++)->second;
- if (get_dword_time() - pvp->GetLastFightTime() > 600000) // 10şĐ ŔĚ»ó ˝ÎżňŔĚ ľřľúŔ¸¸é
- {
- pvp->Packet(true);
- Delete(pvp);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment