forked from metin2/server
658 lines
13 KiB
C++
658 lines
13 KiB
C++
|
#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; // <20>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
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)))
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٷ<EFBFBD> <20>ο<EFBFBD>!
|
|||
|
if (pkPVP->Agree(pkChr->GetPlayerID()))
|
|||
|
{
|
|||
|
pkVictim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s<><EFBFBD><D4B0><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>!"), pkChr->GetName());
|
|||
|
pkChr->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s<><EFBFBD><D4B0><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>!"), 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), LC_TEXT("%s<><73><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB> <20>߽<EFBFBD><DFBD>ϴ<EFBFBD>. <20>³<EFBFBD><C2B3>Ϸ<EFBFBD><CFB7><EFBFBD> <20><><EFBFBD>ᵿ<EFBFBD>Ǹ<EFBFBD> <20>ϼ<EFBFBD><CFBC><EFBFBD>."), pkChr->GetName());
|
|||
|
|
|||
|
pkVictim->ChatPacket(CHAT_TYPE_INFO, msg);
|
|||
|
pkChr->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s<><73><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB> <20>߽<EFBFBD><DFBD>ϴ<EFBFBD>."), 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) + len;
|
|||
|
pack.bType = WHISPER_TYPE_SYSTEM;
|
|||
|
strlcpy(pack.szNameFrom, pkChr->GetName(), sizeof(pack.szNameFrom));
|
|||
|
|
|||
|
TEMP_BUFFER buf;
|
|||
|
|
|||
|
buf.write(&pack, sizeof(TPacketGCWhisper));
|
|||
|
buf.write(msg, len);
|
|||
|
|
|||
|
pkVictimDesc->Packet(buf.read_peek(), buf.size());
|
|||
|
}
|
|||
|
// END_OF_NOTIFY_PVP_MESSAGE
|
|||
|
}
|
|||
|
|
|||
|
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();
|
|||
|
|
|||
|
TR1_NS::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 pkChr)
|
|||
|
{
|
|||
|
//ConnectEx(pkChr, true);
|
|||
|
}
|
|||
|
|
|||
|
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());
|
|||
|
TR1_NS::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;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD>ϰ<EFBFBD>: 0 = PK, 1 = PVP
|
|||
|
// PVP<56><50> <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> <20><><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> PK<50><4B> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
|
|||
|
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());
|
|||
|
TR1_NS::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) // <20><><EFBFBD><EFBFBD> <20><> ĥ<><C4A5><EFBFBD><EFBFBD> <20>ϳ<EFBFBD> -_-
|
|||
|
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:
|
|||
|
case 20111:
|
|||
|
case 20112:
|
|||
|
case 20113:
|
|||
|
case 20114:
|
|||
|
case 20115:
|
|||
|
case 20116:
|
|||
|
case 20117:
|
|||
|
case 20118:
|
|||
|
//<2F>ű<EFBFBD> Ż<><C5BB> <20><><EFBFBD><EFBFBD>
|
|||
|
case 20205:
|
|||
|
case 20206:
|
|||
|
case 20207:
|
|||
|
case 20208:
|
|||
|
case 20209:
|
|||
|
case 20210:
|
|||
|
case 20211:
|
|||
|
case 20212:
|
|||
|
case 20119: // <20><EFBFBD> <20>渶
|
|||
|
case 20219: // <20><EFBFBD> <20>渶 Ŭ<><C5AC> (<28>ҷ<EFBFBD><D2B7><EFBFBD><EFBFBD><EFBFBD>)
|
|||
|
case 20220: // ũ<><C5A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ż<><C5BB>
|
|||
|
case 20221: // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
case 20222: // <20><><EFBFBD><EFBFBD> <20>Ҵ<EFBFBD>
|
|||
|
case 20120:
|
|||
|
case 20121:
|
|||
|
case 20122:
|
|||
|
case 20123:
|
|||
|
case 20124:
|
|||
|
case 20125:
|
|||
|
case 20214: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
case 20215: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
case 20217: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD><CFBC><EFBFBD>
|
|||
|
case 20218: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD><CFBC><EFBFBD>
|
|||
|
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)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD> <20><>ȭ<EFBFBD><C8AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ѻ<EFBFBD><D1BB><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>.
|
|||
|
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<49><44> <20>Ѵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|||
|
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<31><30> <20>̻<EFBFBD> <20>ο<EFBFBD><CEBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
pvp->Packet(true);
|
|||
|
Delete(pvp);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|