forked from metin2/server
752 lines
16 KiB
C++
752 lines
16 KiB
C++
#include "stdafx.h"
|
|
#include "char.h"
|
|
#include "char_manager.h"
|
|
#include "sectree_manager.h"
|
|
#include "desc_client.h"
|
|
#include "p2p.h"
|
|
#include "wedding.h"
|
|
#include "config.h"
|
|
#include "utils.h"
|
|
#include "questmanager.h"
|
|
|
|
extern bool g_bShutdown;
|
|
|
|
namespace marriage
|
|
{
|
|
const int MAX_LOVE_GRADE = 4;
|
|
const int MAX_MARRIAGE_UNIQUE_ITEM = 6;
|
|
|
|
struct TMarriageItemBonusByGrade
|
|
{
|
|
DWORD dwVnum;
|
|
int value[MAX_LOVE_GRADE];
|
|
} g_ItemBonus[MAX_MARRIAGE_UNIQUE_ITEM] = {
|
|
{ 71069, { 4, 5, 6, 8, } }, // 관통 증가
|
|
{ 71070, { 10, 12, 15, 20, } }, // 경험치 증가
|
|
{ 71071, { 4, 5, 6, 8, } }, // 크리티컬 증가
|
|
{ 71072, { -4, -5, -6, -8, } }, // 상대방 공격력 감소
|
|
{ 71073, { 20, 25, 30, 40, } }, // 공격력 증가 (절대값)
|
|
{ 71074, { 12, 16, 20, 30, } }, // 방어력 증가 (절대값)
|
|
|
|
//{ 71069, 1, 2, 3, 6, 8, }, // 관통 증가
|
|
//{ 71070, 5, 7, 10, 15, 20, }, // 경험치 증가
|
|
//{ 71071, 1, 2, 3, 6, 8, }, // 크리티컬 증가
|
|
//{ 71072, 5, 10, 15, 20, 30, }, // 상대방이 입은 데미지를 나에게로
|
|
//{ 71073, 10, 15, 20, 25, 40, }, // 공격력 증가 (절대값)
|
|
//{ 71074, 5, 10, 15, 20, 30, }, // 방어력 증가 (절대값)
|
|
};
|
|
|
|
const int MARRIAGE_POINT_PER_DAY = 1;
|
|
const int MARRIAGE_POINT_PER_DAY_FAST = 2;
|
|
using namespace std;
|
|
|
|
void SendLoverInfo(LPCHARACTER ch, const string& lover_name, int love_point)
|
|
{
|
|
TPacketGCLoverInfo p;
|
|
|
|
p.header = HEADER_GC_LOVER_INFO;
|
|
strncpy(p.name, lover_name.c_str(), sizeof(p.name));
|
|
p.love_point = love_point;
|
|
ch->GetDesc()->Packet(&p, sizeof(p));
|
|
}
|
|
|
|
TMarriage::~TMarriage()
|
|
{
|
|
StopNearCheckEvent();
|
|
if (IsOnline())
|
|
{
|
|
ch1->ChatPacket(CHAT_TYPE_COMMAND, "lover_divorce");
|
|
ch2->ChatPacket(CHAT_TYPE_COMMAND, "lover_divorce");
|
|
}
|
|
M2_DELETE(pWeddingInfo);
|
|
pWeddingInfo = NULL;
|
|
}
|
|
|
|
int TMarriage::GetMarriageGrade()
|
|
{
|
|
int point = MINMAX(50, GetMarriagePoint(), 100);
|
|
if (point < 65)
|
|
return 0;
|
|
else if (point < 80)
|
|
return 1;
|
|
else if (point < 100)
|
|
return 2;
|
|
return 3;
|
|
}
|
|
|
|
int TMarriage::GetMarriagePoint()
|
|
{
|
|
if (test_server)
|
|
{
|
|
int value = quest::CQuestManager::instance().GetEventFlag("lovepoint");
|
|
if (value)
|
|
return MINMAX(0, value, 100);
|
|
}
|
|
|
|
int point_per_day = MARRIAGE_POINT_PER_DAY;
|
|
int max_limit = 30;
|
|
if (IsOnline())
|
|
{
|
|
if (ch1->GetPremiumRemainSeconds(PREMIUM_MARRIAGE_FAST) > 0 ||
|
|
ch2->GetPremiumRemainSeconds(PREMIUM_MARRIAGE_FAST) > 0)
|
|
{
|
|
point_per_day = MARRIAGE_POINT_PER_DAY_FAST;
|
|
max_limit = 40;
|
|
}
|
|
}
|
|
|
|
int days = (get_global_time() - marry_time);
|
|
if (test_server)
|
|
days /= 60;
|
|
else
|
|
days /= 86400;
|
|
|
|
// 기본 50%
|
|
|
|
// 원앙의 깃털 사용중일 때 :
|
|
// 날짜에 의한 영향 80% 하루당 8%
|
|
// 전투에 의한 영향 80%
|
|
// 토탈 100%
|
|
|
|
// 비사용중일 때 :
|
|
// 날짜에 의한 영향 60% 하루당 6%
|
|
// 전투에 의한 영향 60%
|
|
// 토탈 100%
|
|
return MIN(50 + MIN(days * point_per_day, max_limit) + MIN(love_point / 1000000, max_limit), 100);
|
|
}
|
|
|
|
bool TMarriage::IsNear()
|
|
{
|
|
if (!is_married)
|
|
return false;
|
|
if (!IsOnline())
|
|
return false;
|
|
|
|
return ch1->GetMapIndex() == ch2->GetMapIndex();
|
|
|
|
// 파티 체크가 사라졌음
|
|
/*if (!ch1->GetParty() || ch1->GetParty() != ch2->GetParty())
|
|
return false;*/
|
|
|
|
// 거리 체크가 사라졌음
|
|
/*const int DISTANCE = 5000;
|
|
|
|
if (labs(ch1->GetX() - ch2->GetX()) > DISTANCE)
|
|
return false;
|
|
|
|
if (labs(ch1->GetY() - ch2->GetY()) > DISTANCE)
|
|
return false;
|
|
|
|
return (DISTANCE_APPROX(ch1->GetX() - ch2->GetX(), ch1->GetY() - ch2->GetY()) < DISTANCE);*/
|
|
}
|
|
|
|
// 금슬 수치
|
|
int TMarriage::GetBonus(DWORD dwItemVnum, bool bShare, LPCHARACTER me)
|
|
{
|
|
if (!is_married)
|
|
return 0;
|
|
|
|
// 주변에 없을때는 자기 기능만 적용된다.
|
|
|
|
// 해당 아이템이 어떤 기능을 하는지 찾는다.
|
|
int iFindedBonusIndex=0;
|
|
{
|
|
for (iFindedBonusIndex = 0; iFindedBonusIndex < MAX_MARRIAGE_UNIQUE_ITEM; ++iFindedBonusIndex)
|
|
{
|
|
if (g_ItemBonus[iFindedBonusIndex].dwVnum == dwItemVnum)
|
|
break;
|
|
}
|
|
|
|
if (iFindedBonusIndex == MAX_MARRIAGE_UNIQUE_ITEM)
|
|
return 0;
|
|
}
|
|
|
|
if (bShare)
|
|
{
|
|
// 두명의 보너스를 합한다.
|
|
int count = 0;
|
|
if (NULL != ch1 && ch1->IsEquipUniqueItem(dwItemVnum))
|
|
count ++;
|
|
if (NULL != ch2 && ch2->IsEquipUniqueItem(dwItemVnum))
|
|
count ++;
|
|
|
|
const TMarriageItemBonusByGrade& rkBonus = g_ItemBonus[iFindedBonusIndex];
|
|
|
|
if (count>=1)
|
|
return rkBonus.value[GetMarriageGrade()];
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
// 상대방 것만 계산
|
|
int count = 0;
|
|
if (me != ch1 && NULL!= ch1 && ch1->IsEquipUniqueItem(dwItemVnum))
|
|
count ++;
|
|
if (me != ch2 && NULL!= ch2 && ch2->IsEquipUniqueItem(dwItemVnum))
|
|
count ++;
|
|
|
|
const TMarriageItemBonusByGrade& rkBonus = g_ItemBonus[iFindedBonusIndex];
|
|
|
|
if (count>=1)
|
|
return rkBonus.value[GetMarriageGrade()];
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void TMarriage::Login(LPCHARACTER ch)
|
|
{
|
|
if (ch->GetPlayerID() == m_pid1)
|
|
{
|
|
ch1 = ch;
|
|
if (is_married)
|
|
SendLoverInfo(ch1, name2, GetMarriagePoint());
|
|
}
|
|
else if (ch->GetPlayerID() == m_pid2)
|
|
{
|
|
ch2 = ch;
|
|
if (is_married)
|
|
SendLoverInfo(ch2, name1, GetMarriagePoint());
|
|
}
|
|
|
|
// 둘 다 이 프로세스에 로그인 중이면 포인터를 연결하고 이벤트 발생
|
|
if (IsOnline())
|
|
{
|
|
ch1->SetMarryPartner(ch2);
|
|
ch2->SetMarryPartner(ch1);
|
|
|
|
StartNearCheckEvent();
|
|
}
|
|
|
|
// 둘 다 로그인 되어 있다면 패킷을 보낸다.
|
|
if (is_married)
|
|
{
|
|
LPDESC d1, d2;
|
|
CCI * pkCCI;
|
|
|
|
d1 = ch1 ? ch1->GetDesc() : NULL;
|
|
|
|
if (!d1)
|
|
{
|
|
pkCCI = P2P_MANAGER::instance().FindByPID(m_pid1);
|
|
|
|
if (pkCCI)
|
|
{
|
|
d1 = pkCCI->pkDesc;
|
|
d1->SetRelay(pkCCI->szName);
|
|
}
|
|
}
|
|
|
|
d2 = ch2 ? ch2->GetDesc() : NULL;
|
|
|
|
if (!d2)
|
|
{
|
|
pkCCI = P2P_MANAGER::instance().FindByPID(m_pid2);
|
|
|
|
if (pkCCI)
|
|
{
|
|
d2 = pkCCI->pkDesc;
|
|
d2->SetRelay(pkCCI->szName);
|
|
}
|
|
}
|
|
|
|
if (d1 && d2)
|
|
{
|
|
d1->ChatPacket(CHAT_TYPE_COMMAND, "lover_login");
|
|
d2->ChatPacket(CHAT_TYPE_COMMAND, "lover_login");
|
|
sys_log(0, "lover_login %u %u", m_pid1, m_pid2);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TMarriage::Logout(DWORD pid)
|
|
{
|
|
if (pid == m_pid1)
|
|
ch1 = NULL;
|
|
else if (pid == m_pid2)
|
|
ch2 = NULL;
|
|
|
|
if (ch1 || ch2)
|
|
{
|
|
Save();
|
|
|
|
if (ch1)
|
|
ch1->SetMarryPartner(NULL);
|
|
|
|
if (ch2)
|
|
ch2->SetMarryPartner(NULL);
|
|
|
|
StopNearCheckEvent();
|
|
}
|
|
|
|
if (is_married)
|
|
{
|
|
LPDESC d1, d2;
|
|
CCI * pkCCI;
|
|
|
|
d1 = ch1 ? ch1->GetDesc() : NULL;
|
|
|
|
if (!d1)
|
|
{
|
|
pkCCI = P2P_MANAGER::instance().FindByPID(m_pid1);
|
|
|
|
if (pkCCI)
|
|
{
|
|
d1 = pkCCI->pkDesc;
|
|
d1->SetRelay(pkCCI->szName);
|
|
}
|
|
}
|
|
|
|
if (d1 && !g_bShutdown) {
|
|
d1->ChatPacket(CHAT_TYPE_COMMAND, "lover_logout");
|
|
}
|
|
|
|
d2 = ch2 ? ch2->GetDesc() : NULL;
|
|
|
|
if (!d2)
|
|
{
|
|
pkCCI = P2P_MANAGER::instance().FindByPID(m_pid2);
|
|
|
|
if (pkCCI)
|
|
{
|
|
d2 = pkCCI->pkDesc;
|
|
d2->SetRelay(pkCCI->szName);
|
|
}
|
|
}
|
|
|
|
if (d2 && !g_bShutdown) {
|
|
d2->ChatPacket(CHAT_TYPE_COMMAND, "lover_logout");
|
|
}
|
|
}
|
|
}
|
|
|
|
void TMarriage::NearCheck()
|
|
{
|
|
if (!is_married)
|
|
return;
|
|
|
|
if (!IsOnline())
|
|
{
|
|
StopNearCheckEvent();
|
|
return;
|
|
}
|
|
sys_log(0, "NearCheck %u %u %d %d %d", m_pid1, m_pid2, IsNear(), isLastNear, byLastLovePoint, GetMarriagePoint());
|
|
|
|
if (IsNear() && !isLastNear)
|
|
{
|
|
isLastNear = true;
|
|
ch1->ChatPacket(CHAT_TYPE_COMMAND, "lover_near");
|
|
ch2->ChatPacket(CHAT_TYPE_COMMAND, "lover_near");
|
|
}
|
|
else if (!IsNear() && isLastNear)
|
|
{
|
|
isLastNear = false;
|
|
ch1->ChatPacket(CHAT_TYPE_COMMAND, "lover_far");
|
|
ch2->ChatPacket(CHAT_TYPE_COMMAND, "lover_far");
|
|
}
|
|
|
|
if (byLastLovePoint != GetMarriagePoint())
|
|
{
|
|
byLastLovePoint = GetMarriagePoint();
|
|
TPacketGCLovePointUpdate p;
|
|
p.header = HEADER_GC_LOVE_POINT_UPDATE;
|
|
p.love_point = byLastLovePoint;
|
|
|
|
ch1->GetDesc()->Packet(&p, sizeof(p));
|
|
ch2->GetDesc()->Packet(&p, sizeof(p));
|
|
}
|
|
}
|
|
|
|
EVENTINFO(near_check_event_info)
|
|
{
|
|
TMarriage* pMarriage;
|
|
|
|
near_check_event_info()
|
|
: pMarriage( 0 )
|
|
{
|
|
}
|
|
};
|
|
|
|
EVENTFUNC(near_check_event)
|
|
{
|
|
near_check_event_info* info = dynamic_cast<near_check_event_info*>( event->info );
|
|
|
|
if ( info == NULL )
|
|
{
|
|
sys_err( "near_check_event> <Factor> Null pointer" );
|
|
return 0;
|
|
}
|
|
|
|
TMarriage* pMarriage = info->pMarriage;
|
|
pMarriage->NearCheck();
|
|
return PASSES_PER_SEC(5);
|
|
}
|
|
|
|
void TMarriage::StartNearCheckEvent()
|
|
{
|
|
StopNearCheckEvent();
|
|
|
|
near_check_event_info* info = AllocEventInfo<near_check_event_info>();
|
|
info->pMarriage = this;
|
|
eventNearCheck = event_create(near_check_event, info, 1);
|
|
}
|
|
|
|
void TMarriage::StopNearCheckEvent()
|
|
{
|
|
byLastLovePoint = 0;
|
|
isLastNear = false;
|
|
event_cancel(&eventNearCheck);
|
|
}
|
|
|
|
void TMarriage::Save()
|
|
{
|
|
sys_log(0, "TMarriage::Save() - RequestUpdate.bSave=%d", bSave);
|
|
if (bSave)
|
|
{
|
|
CManager::instance().RequestUpdate(m_pid1, m_pid2, love_point, is_married);
|
|
bSave = false;
|
|
}
|
|
}
|
|
|
|
void TMarriage::SetMarried()
|
|
{
|
|
is_married = 1;
|
|
bSave = true;
|
|
Save();
|
|
|
|
if (IsOnline())
|
|
{
|
|
SendLoverInfo(ch1, name2, GetMarriagePoint());
|
|
SendLoverInfo(ch2, name1, GetMarriagePoint());
|
|
|
|
ch1->ChatPacket(CHAT_TYPE_COMMAND, "lover_login");
|
|
ch2->ChatPacket(CHAT_TYPE_COMMAND, "lover_login");
|
|
}
|
|
}
|
|
|
|
void TMarriage::Update(DWORD point)
|
|
{
|
|
if (!IsOnline())
|
|
return;
|
|
|
|
if (point > 0 && is_married)
|
|
{
|
|
bSave = true;
|
|
love_point += point;
|
|
|
|
love_point = MIN( love_point, 2000000000 );
|
|
|
|
if (test_server)
|
|
{
|
|
LPCHARACTER ch;
|
|
ch = CHARACTER_MANAGER::instance().FindByPID(m_pid1);
|
|
if (ch)
|
|
ch->ChatPacket(CHAT_TYPE_PARTY, "lovepoint bykill %.3g total %d", love_point / 1000000., GetMarriagePoint());
|
|
ch = CHARACTER_MANAGER::instance().FindByPID(m_pid2);
|
|
if (ch)
|
|
ch->ChatPacket(CHAT_TYPE_PARTY, "lovepoint bykill %.3g total %d", love_point / 1000000., GetMarriagePoint());
|
|
}
|
|
}
|
|
}
|
|
|
|
void TMarriage::WarpToWeddingMap(DWORD dwPID)
|
|
{
|
|
if (!pWeddingInfo)
|
|
return;
|
|
|
|
LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(dwPID);
|
|
if (ch)
|
|
{
|
|
PIXEL_POSITION pos;
|
|
if (!SECTREE_MANAGER::instance().GetRecallPositionByEmpire(pWeddingInfo->dwMapIndex/10000, 0, pos))
|
|
{
|
|
sys_err("cannot get warp position");
|
|
return;
|
|
}
|
|
ch->SaveExitLocation();
|
|
ch->WarpSet(pos.x, pos.y, pWeddingInfo->dwMapIndex);
|
|
}
|
|
}
|
|
|
|
void TMarriage::RequestEndWedding()
|
|
{
|
|
if (!pWeddingInfo)
|
|
return;
|
|
CManager::instance().RequestEndWedding(m_pid1, m_pid2);
|
|
}
|
|
|
|
CManager::CManager()
|
|
{
|
|
}
|
|
|
|
CManager::~CManager()
|
|
{
|
|
}
|
|
|
|
bool CManager::IsMarriageUniqueItem(DWORD dwItemVnum)
|
|
{
|
|
for (int i = 0; i < MAX_MARRIAGE_UNIQUE_ITEM; i++)
|
|
{
|
|
if (g_ItemBonus[i].dwVnum == dwItemVnum)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CManager::IsMarried(DWORD dwPlayerID)
|
|
{
|
|
TMarriage* pkMarriageFinded=Get(dwPlayerID);
|
|
if (pkMarriageFinded && pkMarriageFinded->is_married)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CManager::IsEngaged(DWORD dwPlayerID)
|
|
{
|
|
TMarriage* pkMarriageFinded=Get(dwPlayerID);
|
|
if (pkMarriageFinded && !pkMarriageFinded->is_married)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CManager::IsEngagedOrMarried(DWORD dwPlayerID)
|
|
{
|
|
return Get(dwPlayerID) != NULL;
|
|
}
|
|
|
|
bool CManager::Initialize()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void CManager::Destroy()
|
|
{
|
|
}
|
|
|
|
void Align(DWORD& dwPID1, DWORD& dwPID2)
|
|
{
|
|
if (dwPID1 > dwPID2)
|
|
std::swap(dwPID1, dwPID2);
|
|
}
|
|
|
|
TMarriage* CManager::Get(DWORD dwPlayerID)
|
|
{
|
|
itertype(m_MarriageByPID) it = m_MarriageByPID.find(dwPlayerID);
|
|
|
|
if (it != m_MarriageByPID.end())
|
|
return it->second;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void CManager::RequestAdd(DWORD dwPID1, DWORD dwPID2, const char* szName1, const char* szName2)
|
|
{
|
|
if (dwPID1 > dwPID2)
|
|
{
|
|
std::swap(dwPID1, dwPID2);
|
|
std::swap(szName1, szName2);
|
|
}
|
|
|
|
TPacketMarriageAdd p;
|
|
|
|
p.dwPID1 = dwPID1;
|
|
p.dwPID2 = dwPID2;
|
|
strncpy(p.szName1, szName1, sizeof(p.szName1));
|
|
strncpy(p.szName2, szName2, sizeof(p.szName2));
|
|
db_clientdesc->DBPacket(HEADER_GD_MARRIAGE_ADD, 0, &p, sizeof(p));
|
|
}
|
|
|
|
void CManager::Add(DWORD dwPID1, DWORD dwPID2, time_t tMarryTime, const char* szName1, const char* szName2)
|
|
{
|
|
if (IsEngagedOrMarried(dwPID1) || IsEngagedOrMarried(dwPID2))
|
|
{
|
|
sys_err("cannot marry already married character. %d - %d", dwPID1, dwPID2);
|
|
return;
|
|
}
|
|
|
|
if (dwPID1 > dwPID2)
|
|
{
|
|
std::swap(dwPID1, dwPID2);
|
|
std::swap(szName1, szName2);
|
|
}
|
|
|
|
TMarriage* pMarriage = M2_NEW TMarriage(dwPID1, dwPID2, 0, tMarryTime, szName1, szName2);
|
|
m_Marriages.insert(pMarriage);
|
|
m_MarriageByPID.insert(make_pair(dwPID1, pMarriage));
|
|
m_MarriageByPID.insert(make_pair(dwPID2, pMarriage));
|
|
{
|
|
LPCHARACTER A = CHARACTER_MANAGER::instance().FindByPID(dwPID1);
|
|
LPCHARACTER B = CHARACTER_MANAGER::instance().FindByPID(dwPID2);
|
|
|
|
if (A && B)
|
|
{
|
|
// 웨딩 맵 요청을 보낸다
|
|
TPacketWeddingRequest p;
|
|
p.dwPID1 = dwPID1;
|
|
p.dwPID2 = dwPID2;
|
|
db_clientdesc->DBPacket(HEADER_GD_WEDDING_REQUEST, 0, &p, sizeof(p));
|
|
}
|
|
}
|
|
}
|
|
|
|
void CManager::RequestUpdate(DWORD dwPID1, DWORD dwPID2, int iUpdatePoint, BYTE byMarried)
|
|
{
|
|
Align(dwPID1, dwPID2);
|
|
|
|
TPacketMarriageUpdate p;
|
|
p.dwPID1 = dwPID1;
|
|
p.dwPID2 = dwPID2;
|
|
p.iLovePoint = iUpdatePoint;
|
|
p.byMarried = byMarried;
|
|
db_clientdesc->DBPacket(HEADER_GD_MARRIAGE_UPDATE, 0, &p, sizeof(p));
|
|
}
|
|
|
|
void CManager::Update(DWORD dwPID1, DWORD dwPID2, int lTotalPoint, BYTE byMarried)
|
|
{
|
|
TMarriage* pMarriage = Get(dwPID1);
|
|
|
|
if (!pMarriage || pMarriage->GetOther(dwPID1) != dwPID2)
|
|
{
|
|
sys_err("not under marriage : %u %u", dwPID1, dwPID2);
|
|
return;
|
|
}
|
|
|
|
pMarriage->love_point = lTotalPoint;
|
|
pMarriage->is_married = byMarried;
|
|
}
|
|
|
|
void CManager::RequestRemove(DWORD dwPID1, DWORD dwPID2)
|
|
{
|
|
Align(dwPID1, dwPID2);
|
|
|
|
TPacketMarriageRemove p;
|
|
p.dwPID1 = dwPID1;
|
|
p.dwPID2 = dwPID2;
|
|
db_clientdesc->DBPacket(HEADER_GD_MARRIAGE_REMOVE, 0, &p, sizeof(p));
|
|
}
|
|
|
|
void CManager::Remove(DWORD dwPID1, DWORD dwPID2)
|
|
{
|
|
TMarriage* pMarriage = Get(dwPID1);
|
|
if (!pMarriage || pMarriage->GetOther(dwPID1) != dwPID2)
|
|
{
|
|
sys_err("not under marriage : %u %u", dwPID1, dwPID2);
|
|
return;
|
|
}
|
|
|
|
m_Marriages.erase(pMarriage);
|
|
m_MarriageByPID.erase(dwPID1);
|
|
m_MarriageByPID.erase(dwPID2);
|
|
|
|
M2_DELETE(pMarriage);
|
|
}
|
|
|
|
void CManager::Login(LPCHARACTER ch)
|
|
{
|
|
DWORD pid = ch->GetPlayerID();
|
|
|
|
TMarriage* pMarriage = Get(pid);
|
|
if (!pMarriage)
|
|
return;
|
|
|
|
pMarriage->Login(ch);
|
|
}
|
|
|
|
void CManager::Logout(DWORD pid)
|
|
{
|
|
TMarriage * pMarriage = Get(pid);
|
|
|
|
if (!pMarriage)
|
|
return;
|
|
|
|
pMarriage->Logout(pid);
|
|
}
|
|
|
|
void CManager::Logout(LPCHARACTER ch)
|
|
{
|
|
Logout(ch->GetPlayerID());
|
|
}
|
|
|
|
void CManager::WeddingReady(DWORD dwPID1, DWORD dwPID2, DWORD dwMapIndex)
|
|
{
|
|
TMarriage* pMarriage = Get(dwPID1);
|
|
if (!pMarriage || pMarriage->GetOther(dwPID1) != dwPID2)
|
|
{
|
|
sys_err("wrong marriage %u, %u", dwPID1, dwPID2);
|
|
return;
|
|
}
|
|
|
|
TWeddingInfo* pwi;
|
|
if (pMarriage->pWeddingInfo)
|
|
pwi = pMarriage->pWeddingInfo;
|
|
else
|
|
{
|
|
pwi = M2_NEW TWeddingInfo;
|
|
pMarriage->pWeddingInfo = pwi;
|
|
}
|
|
|
|
pwi->dwMapIndex = dwMapIndex;
|
|
}
|
|
|
|
void CManager::WeddingStart(DWORD dwPID1, DWORD dwPID2)
|
|
{
|
|
TMarriage* pMarriage = Get(dwPID1);
|
|
if (!pMarriage || pMarriage->GetOther(dwPID1) != dwPID2)
|
|
{
|
|
sys_err("wrong marriage %u, %u", dwPID1, dwPID2);
|
|
return;
|
|
}
|
|
|
|
TWeddingInfo * pwi = pMarriage->pWeddingInfo;
|
|
|
|
if (!pwi)
|
|
return;
|
|
|
|
// 결혼자들을 워프시켜야함
|
|
pMarriage->WarpToWeddingMap(dwPID1);
|
|
pMarriage->WarpToWeddingMap(dwPID2);
|
|
|
|
// 등록해서 메뉴창에서 이름나와야함
|
|
m_setWedding.insert(make_pair(dwPID1, dwPID2));
|
|
}
|
|
|
|
void CManager::WeddingEnd(DWORD dwPID1, DWORD dwPID2)
|
|
{
|
|
TMarriage* pMarriage = Get(dwPID1);
|
|
if (!pMarriage || pMarriage->GetOther(dwPID1) != dwPID2)
|
|
{
|
|
sys_err("wrong marriage %u, %u", dwPID1, dwPID2);
|
|
return;
|
|
}
|
|
|
|
if (!pMarriage->pWeddingInfo)
|
|
{
|
|
sys_err("not under wedding %u, %u", dwPID1, dwPID2);
|
|
return;
|
|
}
|
|
|
|
// 맵에서 빼내야합니다
|
|
if (map_allow_find(WEDDING_MAP_INDEX))
|
|
if (!WeddingManager::instance().End(pMarriage->pWeddingInfo->dwMapIndex))
|
|
{
|
|
sys_err("wedding map error: map_index=%d", pMarriage->pWeddingInfo->dwMapIndex);
|
|
return;
|
|
}
|
|
|
|
M2_DELETE(pMarriage->pWeddingInfo);
|
|
pMarriage->pWeddingInfo = NULL;
|
|
|
|
m_setWedding.erase(make_pair(dwPID1, dwPID2));
|
|
}
|
|
|
|
void CManager::RequestEndWedding(DWORD dwPID1, DWORD dwPID2)
|
|
{
|
|
TPacketWeddingEnd p;
|
|
p.dwPID1 = dwPID1;
|
|
p.dwPID2 = dwPID2;
|
|
|
|
db_clientdesc->DBPacket(HEADER_GD_WEDDING_END, 0, &p, sizeof(p));
|
|
}
|
|
}
|