forked from metin2/server
749 lines
18 KiB
C++
749 lines
18 KiB
C++
#include "stdafx.h"
|
|
#include "constants.h"
|
|
#include "utils.h"
|
|
#include "config.h"
|
|
#include "log.h"
|
|
#include "char.h"
|
|
#include "packet.h"
|
|
#include "desc_client.h"
|
|
#include "buffer_manager.h"
|
|
#include "char_manager.h"
|
|
#include "db.h"
|
|
#include "affect.h"
|
|
#include "p2p.h"
|
|
#include "war_map.h"
|
|
#include "questmanager.h"
|
|
#include "sectree_manager.h"
|
|
#include "locale_service.h"
|
|
#include "guild_manager.h"
|
|
|
|
enum
|
|
{
|
|
GUILD_WAR_WAIT_START_DURATION = 10*60
|
|
};
|
|
|
|
//
|
|
// Packet
|
|
//
|
|
void CGuild::GuildWarPacket(DWORD dwOppGID, BYTE bWarType, BYTE bWarState)
|
|
{
|
|
TPacketGCGuild pack;
|
|
TPacketGCGuildWar pack2;
|
|
|
|
pack.header = HEADER_GC_GUILD;
|
|
pack.subheader = GUILD_SUBHEADER_GC_WAR;
|
|
pack.size = sizeof(pack) + sizeof(pack2);
|
|
pack2.dwGuildSelf = GetID();
|
|
pack2.dwGuildOpp = dwOppGID;
|
|
pack2.bWarState = bWarState;
|
|
pack2.bType = bWarType;
|
|
|
|
for (itertype(m_memberOnline) it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
|
|
{
|
|
LPCHARACTER ch = *it;
|
|
|
|
if (bWarState == GUILD_WAR_ON_WAR)
|
|
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 길드전중에는 사냥에 따른 이익이 없습니다."));
|
|
|
|
LPDESC d = ch->GetDesc();
|
|
|
|
if (d)
|
|
{
|
|
ch->SendGuildName( dwOppGID );
|
|
|
|
d->RawPacket(&pack, sizeof(pack));
|
|
d->Packet(&pack2, sizeof(pack2));
|
|
}
|
|
}
|
|
}
|
|
|
|
void CGuild::SendEnemyGuild(LPCHARACTER ch)
|
|
{
|
|
LPDESC d = ch->GetDesc();
|
|
|
|
if (!d)
|
|
return;
|
|
|
|
TPacketGCGuild pack;
|
|
TPacketGCGuildWar pack2;
|
|
pack.header = HEADER_GC_GUILD;
|
|
pack.subheader = GUILD_SUBHEADER_GC_WAR;
|
|
pack.size = sizeof(pack) + sizeof(pack2);
|
|
pack2.dwGuildSelf = GetID();
|
|
|
|
TPacketGCGuild p;
|
|
p.header = HEADER_GC_GUILD;
|
|
p.subheader = GUILD_SUBHEADER_GC_WAR_SCORE;
|
|
p.size = sizeof(p) + sizeof(DWORD) + sizeof(DWORD) + sizeof(int);
|
|
|
|
for (itertype(m_EnemyGuild) it = m_EnemyGuild.begin(); it != m_EnemyGuild.end(); ++it)
|
|
{
|
|
ch->SendGuildName( it->first );
|
|
|
|
pack2.dwGuildOpp = it->first;
|
|
pack2.bType = it->second.type;
|
|
pack2.bWarState = it->second.state;
|
|
|
|
d->RawPacket(&pack, sizeof(pack));
|
|
d->Packet(&pack2, sizeof(pack2));
|
|
|
|
if (it->second.state == GUILD_WAR_ON_WAR)
|
|
{
|
|
int lScore;
|
|
|
|
lScore = GetWarScoreAgainstTo(pack2.dwGuildOpp);
|
|
|
|
d->RawPacket(&p, sizeof(p));
|
|
d->RawPacket(&pack2.dwGuildSelf, sizeof(DWORD));
|
|
d->RawPacket(&pack2.dwGuildOpp, sizeof(DWORD));
|
|
d->Packet(&lScore, sizeof(int));
|
|
|
|
lScore = CGuildManager::instance().TouchGuild(pack2.dwGuildOpp)->GetWarScoreAgainstTo(pack2.dwGuildSelf);
|
|
|
|
d->RawPacket(&p, sizeof(p));
|
|
d->RawPacket(&pack2.dwGuildOpp, sizeof(DWORD));
|
|
d->RawPacket(&pack2.dwGuildSelf, sizeof(DWORD));
|
|
d->Packet(&lScore, sizeof(int));
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// War Login
|
|
//
|
|
int CGuild::GetGuildWarState(DWORD dwOppGID)
|
|
{
|
|
if (dwOppGID == GetID())
|
|
return GUILD_WAR_NONE;
|
|
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
return (it != m_EnemyGuild.end()) ? (it->second.state) : GUILD_WAR_NONE;
|
|
}
|
|
|
|
int CGuild::GetGuildWarType(DWORD dwOppGID)
|
|
{
|
|
itertype(m_EnemyGuild) git = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (git == m_EnemyGuild.end())
|
|
return GUILD_WAR_TYPE_FIELD;
|
|
|
|
return git->second.type;
|
|
}
|
|
|
|
DWORD CGuild::GetGuildWarMapIndex(DWORD dwOppGID)
|
|
{
|
|
itertype(m_EnemyGuild) git = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (git == m_EnemyGuild.end())
|
|
return 0;
|
|
|
|
return git->second.map_index;
|
|
}
|
|
|
|
bool CGuild::CanStartWar(BYTE bGuildWarType) // 타입에 따라 다른 조건이 생길 수도 있음
|
|
{
|
|
if (bGuildWarType >= GUILD_WAR_TYPE_MAX_NUM)
|
|
return false;
|
|
|
|
// 테스트시에는 인원수를 확인하지 않는다.
|
|
if (test_server || quest::CQuestManager::instance().GetEventFlag("guild_war_test") != 0)
|
|
return GetLadderPoint() > 0;
|
|
|
|
return GetLadderPoint() > 0 && GetMemberCount() >= GUILD_WAR_MIN_MEMBER_COUNT;
|
|
}
|
|
|
|
bool CGuild::UnderWar(DWORD dwOppGID)
|
|
{
|
|
if (dwOppGID == GetID())
|
|
return false;
|
|
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
return (it != m_EnemyGuild.end()) && (it->second.IsWarBegin());
|
|
}
|
|
|
|
DWORD CGuild::UnderAnyWar(BYTE bType)
|
|
{
|
|
for (itertype(m_EnemyGuild) it = m_EnemyGuild.begin(); it != m_EnemyGuild.end(); ++it)
|
|
{
|
|
if (bType < GUILD_WAR_TYPE_MAX_NUM)
|
|
if (it->second.type != bType)
|
|
continue;
|
|
|
|
if (it->second.IsWarBegin())
|
|
return it->first;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CGuild::SetWarScoreAgainstTo(DWORD dwOppGID, int iScore)
|
|
{
|
|
DWORD dwSelfGID = GetID();
|
|
|
|
sys_log(0, "GuildWarScore Set %u from %u %d", dwSelfGID, dwOppGID, iScore);
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (it != m_EnemyGuild.end())
|
|
{
|
|
it->second.score = iScore;
|
|
|
|
if (it->second.type != GUILD_WAR_TYPE_FIELD)
|
|
{
|
|
CGuild * gOpp = CGuildManager::instance().TouchGuild(dwOppGID);
|
|
CWarMap * pMap = CWarMapManager::instance().Find(it->second.map_index);
|
|
|
|
if (pMap)
|
|
pMap->UpdateScore(dwSelfGID, iScore, dwOppGID, gOpp->GetWarScoreAgainstTo(dwSelfGID));
|
|
}
|
|
else
|
|
{
|
|
TPacketGCGuild p;
|
|
|
|
p.header = HEADER_GC_GUILD;
|
|
p.subheader = GUILD_SUBHEADER_GC_WAR_SCORE;
|
|
p.size = sizeof(p) + sizeof(DWORD) + sizeof(DWORD) + sizeof(int);
|
|
|
|
TEMP_BUFFER buf;
|
|
buf.write(&p, sizeof(p));
|
|
|
|
buf.write(&dwSelfGID, sizeof(DWORD));
|
|
buf.write(&dwOppGID, sizeof(DWORD));
|
|
buf.write(&iScore, sizeof(int));
|
|
|
|
Packet(buf.read_peek(), buf.size());
|
|
|
|
CGuild * gOpp = CGuildManager::instance().TouchGuild(dwOppGID);
|
|
|
|
if (gOpp)
|
|
gOpp->Packet(buf.read_peek(), buf.size());
|
|
}
|
|
}
|
|
}
|
|
|
|
int CGuild::GetWarScoreAgainstTo(DWORD dwOppGID)
|
|
{
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (it != m_EnemyGuild.end())
|
|
{
|
|
sys_log(0, "GuildWarScore Get %u from %u %d", GetID(), dwOppGID, it->second.score);
|
|
return it->second.score;
|
|
}
|
|
|
|
sys_log(0, "GuildWarScore Get %u from %u No data", GetID(), dwOppGID);
|
|
return 0;
|
|
}
|
|
|
|
DWORD CGuild::GetWarStartTime(DWORD dwOppGID)
|
|
{
|
|
if (dwOppGID == GetID())
|
|
return 0;
|
|
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (it == m_EnemyGuild.end())
|
|
return 0;
|
|
|
|
return it->second.war_start_time;
|
|
}
|
|
|
|
const TGuildWarInfo& GuildWar_GetTypeInfo(unsigned type)
|
|
{
|
|
return KOR_aGuildWarInfo[type];
|
|
}
|
|
|
|
unsigned GuildWar_GetTypeMapIndex(unsigned type)
|
|
{
|
|
return GuildWar_GetTypeInfo(type).lMapIndex;
|
|
}
|
|
|
|
bool GuildWar_IsWarMap(unsigned type)
|
|
{
|
|
if (type == GUILD_WAR_TYPE_FIELD)
|
|
return true;
|
|
|
|
unsigned mapIndex = GuildWar_GetTypeMapIndex(type);
|
|
|
|
if (SECTREE_MANAGER::instance().GetMapRegion(mapIndex))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
void CGuild::NotifyGuildMaster(const char* msg)
|
|
{
|
|
LPCHARACTER ch = GetMasterCharacter();
|
|
if (ch)
|
|
ch->ChatPacket(CHAT_TYPE_INFO, msg);
|
|
}
|
|
|
|
extern void map_allow_log();
|
|
|
|
//
|
|
// War State Relative
|
|
//
|
|
//
|
|
// A Declare -> B Refuse
|
|
// -> B Declare -> StartWar -> EndWar
|
|
//
|
|
// A Declare -> B Refuse
|
|
// -> B Declare -> WaitStart -> Fail
|
|
// -> StartWar -> EndWar
|
|
//
|
|
void CGuild::RequestDeclareWar(DWORD dwOppGID, BYTE type)
|
|
{
|
|
if (dwOppGID == GetID())
|
|
{
|
|
sys_log(0, "GuildWar.DeclareWar.DECLARE_WAR_SELF id(%d -> %d), type(%d)", GetID(), dwOppGID, type);
|
|
return;
|
|
}
|
|
|
|
if (type >= GUILD_WAR_TYPE_MAX_NUM)
|
|
{
|
|
sys_log(0, "GuildWar.DeclareWar.UNKNOWN_WAR_TYPE id(%d -> %d), type(%d)", GetID(), dwOppGID, type);
|
|
return;
|
|
}
|
|
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
if (it == m_EnemyGuild.end())
|
|
{
|
|
if (!GuildWar_IsWarMap(type))
|
|
{
|
|
sys_err("GuildWar.DeclareWar.NOT_EXIST_MAP id(%d -> %d), type(%d), map(%d)",
|
|
GetID(), dwOppGID, type, GuildWar_GetTypeMapIndex(type));
|
|
|
|
map_allow_log();
|
|
NotifyGuildMaster(LC_TEXT("전쟁 서버가 열려있지 않아 길드전을 시작할 수 없습니다."));
|
|
return;
|
|
}
|
|
|
|
// 패킷 보내기 to another server
|
|
TPacketGuildWar p;
|
|
p.bType = type;
|
|
p.bWar = GUILD_WAR_SEND_DECLARE;
|
|
p.dwGuildFrom = GetID();
|
|
p.dwGuildTo = dwOppGID;
|
|
db_clientdesc->DBPacket(HEADER_GD_GUILD_WAR, 0, &p, sizeof(p));
|
|
sys_log(0, "GuildWar.DeclareWar id(%d -> %d), type(%d)", GetID(), dwOppGID, type);
|
|
return;
|
|
}
|
|
|
|
switch (it->second.state)
|
|
{
|
|
case GUILD_WAR_RECV_DECLARE:
|
|
{
|
|
const unsigned saved_type = it->second.type;
|
|
|
|
if (saved_type == GUILD_WAR_TYPE_FIELD)
|
|
{
|
|
// 선전포고 한것을 받아들였다.
|
|
TPacketGuildWar p;
|
|
p.bType = saved_type;
|
|
p.bWar = GUILD_WAR_ON_WAR;
|
|
p.dwGuildFrom = GetID();
|
|
p.dwGuildTo = dwOppGID;
|
|
db_clientdesc->DBPacket(HEADER_GD_GUILD_WAR, 0, &p, sizeof(p));
|
|
sys_log(0, "GuildWar.AcceptWar id(%d -> %d), type(%d)", GetID(), dwOppGID, saved_type);
|
|
return;
|
|
}
|
|
|
|
if (!GuildWar_IsWarMap(saved_type))
|
|
{
|
|
sys_err("GuildWar.AcceptWar.NOT_EXIST_MAP id(%d -> %d), type(%d), map(%d)",
|
|
GetID(), dwOppGID, type, GuildWar_GetTypeMapIndex(type));
|
|
|
|
map_allow_log();
|
|
NotifyGuildMaster(LC_TEXT("전쟁 서버가 열려있지 않아 길드전을 시작할 수 없습니다."));
|
|
return;
|
|
}
|
|
|
|
const TGuildWarInfo& guildWarInfo = GuildWar_GetTypeInfo(saved_type);
|
|
|
|
TPacketGuildWar p;
|
|
p.bType = saved_type;
|
|
p.bWar = GUILD_WAR_WAIT_START;
|
|
p.dwGuildFrom = GetID();
|
|
p.dwGuildTo = dwOppGID;
|
|
p.lWarPrice = guildWarInfo.iWarPrice;
|
|
p.lInitialScore = guildWarInfo.iInitialScore;
|
|
|
|
if (test_server)
|
|
p.lInitialScore /= 10;
|
|
|
|
db_clientdesc->DBPacket(HEADER_GD_GUILD_WAR, 0, &p, sizeof(p));
|
|
|
|
sys_log(0, "GuildWar.WaitStartSendToDB id(%d vs %d), type(%d), bet(%d), map_index(%d)",
|
|
GetID(), dwOppGID, saved_type, guildWarInfo.iWarPrice, guildWarInfo.lMapIndex);
|
|
|
|
}
|
|
break;
|
|
case GUILD_WAR_SEND_DECLARE:
|
|
{
|
|
NotifyGuildMaster(LC_TEXT("이미 선전포고 중인 길드입니다."));
|
|
}
|
|
break;
|
|
default:
|
|
sys_err("GuildWar.DeclareWar.UNKNOWN_STATE[%d]: id(%d vs %d), type(%d), guild(%s:%u)",
|
|
it->second.state, GetID(), dwOppGID, type, GetName(), GetID());
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool CGuild::DeclareWar(DWORD dwOppGID, BYTE type, BYTE state)
|
|
{
|
|
if (m_EnemyGuild.find(dwOppGID) != m_EnemyGuild.end())
|
|
return false;
|
|
|
|
TGuildWar gw(type);
|
|
gw.state = state;
|
|
|
|
m_EnemyGuild.insert(std::make_pair(dwOppGID, gw));
|
|
|
|
GuildWarPacket(dwOppGID, type, state);
|
|
return true;
|
|
}
|
|
|
|
bool CGuild::CheckStartWar(DWORD dwOppGID)
|
|
{
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (it == m_EnemyGuild.end())
|
|
return false;
|
|
|
|
TGuildWar & gw(it->second);
|
|
|
|
if (gw.state == GUILD_WAR_ON_WAR)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void CGuild::StartWar(DWORD dwOppGID)
|
|
{
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (it == m_EnemyGuild.end())
|
|
return;
|
|
|
|
TGuildWar & gw(it->second);
|
|
|
|
if (gw.state == GUILD_WAR_ON_WAR)
|
|
return;
|
|
|
|
gw.state = GUILD_WAR_ON_WAR;
|
|
gw.war_start_time = get_global_time();
|
|
|
|
GuildWarPacket(dwOppGID, gw.type, GUILD_WAR_ON_WAR);
|
|
|
|
if (gw.type != GUILD_WAR_TYPE_FIELD)
|
|
GuildWarEntryAsk(dwOppGID);
|
|
}
|
|
|
|
bool CGuild::WaitStartWar(DWORD dwOppGID)
|
|
{
|
|
//자기자신이면
|
|
if (dwOppGID == GetID())
|
|
{
|
|
sys_log(0 ,"GuildWar.WaitStartWar.DECLARE_WAR_SELF id(%u -> %u)", GetID(), dwOppGID);
|
|
return false;
|
|
}
|
|
|
|
//상대방 길드 TGuildWar 를 얻어온다.
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
if (it == m_EnemyGuild.end())
|
|
{
|
|
sys_log(0 ,"GuildWar.WaitStartWar.UNKNOWN_ENEMY id(%u -> %u)", GetID(), dwOppGID);
|
|
return false;
|
|
}
|
|
|
|
//레퍼런스에 등록하고
|
|
TGuildWar & gw(it->second);
|
|
|
|
if (gw.state == GUILD_WAR_WAIT_START)
|
|
{
|
|
sys_log(0 ,"GuildWar.WaitStartWar.UNKNOWN_STATE id(%u -> %u), state(%d)", GetID(), dwOppGID, gw.state);
|
|
return false;
|
|
}
|
|
|
|
//상태를 저장한다.
|
|
gw.state = GUILD_WAR_WAIT_START;
|
|
|
|
//상대편의 길드 클래스 포인터를 얻어오고
|
|
CGuild* g = CGuildManager::instance().FindGuild(dwOppGID);
|
|
if (!g)
|
|
{
|
|
sys_log(0 ,"GuildWar.WaitStartWar.NOT_EXIST_GUILD id(%u -> %u)", GetID(), dwOppGID);
|
|
return false;
|
|
}
|
|
|
|
// GUILDWAR_INFO
|
|
const TGuildWarInfo& rkGuildWarInfo = GuildWar_GetTypeInfo(gw.type);
|
|
// END_OF_GUILDWAR_INFO
|
|
|
|
|
|
// 필드형이면 맵생성 안함
|
|
if (gw.type == GUILD_WAR_TYPE_FIELD)
|
|
{
|
|
sys_log(0 ,"GuildWar.WaitStartWar.FIELD_TYPE id(%u -> %u)", GetID(), dwOppGID);
|
|
return true;
|
|
}
|
|
|
|
// 전쟁 서버 인지 확인
|
|
sys_log(0 ,"GuildWar.WaitStartWar.CheckWarServer id(%u -> %u), type(%d), map(%d)",
|
|
GetID(), dwOppGID, gw.type, rkGuildWarInfo.lMapIndex);
|
|
|
|
if (!map_allow_find(rkGuildWarInfo.lMapIndex))
|
|
{
|
|
sys_log(0 ,"GuildWar.WaitStartWar.SKIP_WAR_MAP id(%u -> %u)", GetID(), dwOppGID);
|
|
return true;
|
|
}
|
|
|
|
|
|
DWORD id1 = GetID();
|
|
DWORD id2 = dwOppGID;
|
|
|
|
if (id1 > id2)
|
|
std::swap(id1, id2);
|
|
|
|
//워프 맵을 생성
|
|
DWORD lMapIndex = CWarMapManager::instance().CreateWarMap(rkGuildWarInfo, id1, id2);
|
|
if (!lMapIndex)
|
|
{
|
|
sys_err("GuildWar.WaitStartWar.CREATE_WARMAP_ERROR id(%u vs %u), type(%u), map(%d)", id1, id2, gw.type, rkGuildWarInfo.lMapIndex);
|
|
CGuildManager::instance().RequestEndWar(GetID(), dwOppGID);
|
|
return false;
|
|
}
|
|
|
|
sys_log(0, "GuildWar.WaitStartWar.CreateMap id(%u vs %u), type(%u), map(%d) -> map_inst(%u)", id1, id2, gw.type, rkGuildWarInfo.lMapIndex, lMapIndex);
|
|
|
|
//길드전 정보에 맵인덱스를 세팅
|
|
gw.map_index = lMapIndex;
|
|
|
|
//양쪽에 등록(?)
|
|
SetGuildWarMapIndex(dwOppGID, lMapIndex);
|
|
g->SetGuildWarMapIndex(GetID(), lMapIndex);
|
|
|
|
///////////////////////////////////////////////////////
|
|
TPacketGGGuildWarMapIndex p;
|
|
|
|
p.bHeader = HEADER_GG_GUILD_WAR_ZONE_MAP_INDEX;
|
|
p.dwGuildID1 = id1;
|
|
p.dwGuildID2 = id2;
|
|
p.lMapIndex = lMapIndex;
|
|
|
|
P2P_MANAGER::instance().Send(&p, sizeof(p));
|
|
///////////////////////////////////////////////////////
|
|
|
|
return true;
|
|
}
|
|
|
|
void CGuild::RequestRefuseWar(DWORD dwOppGID)
|
|
{
|
|
if (dwOppGID == GetID())
|
|
return;
|
|
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (it != m_EnemyGuild.end() && it->second.state == GUILD_WAR_RECV_DECLARE)
|
|
{
|
|
// 선전포고를 거절했다.
|
|
TPacketGuildWar p;
|
|
p.bWar = GUILD_WAR_REFUSE;
|
|
p.dwGuildFrom = GetID();
|
|
p.dwGuildTo = dwOppGID;
|
|
|
|
db_clientdesc->DBPacket(HEADER_GD_GUILD_WAR, 0, &p, sizeof(p));
|
|
}
|
|
}
|
|
|
|
void CGuild::RefuseWar(DWORD dwOppGID)
|
|
{
|
|
if (dwOppGID == GetID())
|
|
return;
|
|
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (it != m_EnemyGuild.end() && (it->second.state == GUILD_WAR_SEND_DECLARE || it->second.state == GUILD_WAR_RECV_DECLARE))
|
|
{
|
|
BYTE type = it->second.type;
|
|
m_EnemyGuild.erase(dwOppGID);
|
|
|
|
GuildWarPacket(dwOppGID, type, GUILD_WAR_END);
|
|
}
|
|
}
|
|
|
|
void CGuild::ReserveWar(DWORD dwOppGID, BYTE type)
|
|
{
|
|
if (dwOppGID == GetID())
|
|
return;
|
|
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (it == m_EnemyGuild.end())
|
|
{
|
|
TGuildWar gw(type);
|
|
gw.state = GUILD_WAR_RESERVE;
|
|
m_EnemyGuild.insert(std::make_pair(dwOppGID, gw));
|
|
}
|
|
else
|
|
it->second.state = GUILD_WAR_RESERVE;
|
|
|
|
sys_log(0, "Guild::ReserveWar %u", dwOppGID);
|
|
}
|
|
|
|
void CGuild::EndWar(DWORD dwOppGID)
|
|
{
|
|
if (dwOppGID == GetID())
|
|
return;
|
|
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (it != m_EnemyGuild.end())
|
|
{
|
|
CWarMap * pMap = CWarMapManager::instance().Find(it->second.map_index);
|
|
|
|
if (pMap)
|
|
pMap->SetEnded();
|
|
|
|
GuildWarPacket(dwOppGID, it->second.type, GUILD_WAR_END);
|
|
m_EnemyGuild.erase(it);
|
|
|
|
if (!UnderAnyWar())
|
|
{
|
|
for (itertype(m_memberOnline) it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
|
|
{
|
|
LPCHARACTER ch = *it;
|
|
ch->RemoveAffect(GUILD_SKILL_BLOOD);
|
|
ch->RemoveAffect(GUILD_SKILL_BLESS);
|
|
ch->RemoveAffect(GUILD_SKILL_SEONGHWI);
|
|
ch->RemoveAffect(GUILD_SKILL_ACCEL);
|
|
ch->RemoveAffect(GUILD_SKILL_BUNNO);
|
|
ch->RemoveAffect(GUILD_SKILL_JUMUN);
|
|
|
|
ch->RemoveBadAffect();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CGuild::SetGuildWarMapIndex(DWORD dwOppGID, int lMapIndex)
|
|
{
|
|
itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (it == m_EnemyGuild.end())
|
|
return;
|
|
|
|
it->second.map_index = lMapIndex;
|
|
sys_log(0, "GuildWar.SetGuildWarMapIndex id(%d -> %d), map(%d)", GetID(), dwOppGID, lMapIndex);
|
|
}
|
|
|
|
void CGuild::GuildWarEntryAccept(DWORD dwOppGID, LPCHARACTER ch)
|
|
{
|
|
itertype(m_EnemyGuild) git = m_EnemyGuild.find(dwOppGID);
|
|
|
|
if (git == m_EnemyGuild.end())
|
|
return;
|
|
|
|
TGuildWar & gw(git->second);
|
|
|
|
if (gw.type == GUILD_WAR_TYPE_FIELD)
|
|
return;
|
|
|
|
if (gw.state != GUILD_WAR_ON_WAR)
|
|
{
|
|
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이미 전쟁이 끝났습니다."));
|
|
return;
|
|
}
|
|
|
|
if (!gw.map_index)
|
|
return;
|
|
|
|
PIXEL_POSITION pos;
|
|
|
|
if (!CWarMapManager::instance().GetStartPosition(gw.map_index, GetID() < dwOppGID ? 0 : 1, pos))
|
|
return;
|
|
|
|
quest::PC * pPC = quest::CQuestManager::instance().GetPC(ch->GetPlayerID());
|
|
pPC->SetFlag("war.is_war_member", 1);
|
|
|
|
ch->SaveExitLocation();
|
|
ch->WarpSet(pos.x, pos.y, gw.map_index);
|
|
}
|
|
|
|
void CGuild::GuildWarEntryAsk(DWORD dwOppGID)
|
|
{
|
|
itertype(m_EnemyGuild) git = m_EnemyGuild.find(dwOppGID);
|
|
if (git == m_EnemyGuild.end())
|
|
{
|
|
sys_err("GuildWar.GuildWarEntryAsk.UNKNOWN_ENEMY(%d)", dwOppGID);
|
|
return;
|
|
}
|
|
|
|
TGuildWar & gw(git->second);
|
|
|
|
sys_log(0, "GuildWar.GuildWarEntryAsk id(%d vs %d), map(%d)", GetID(), dwOppGID, gw.map_index);
|
|
if (!gw.map_index)
|
|
{
|
|
sys_err("GuildWar.GuildWarEntryAsk.NOT_EXIST_MAP id(%d vs %d)", GetID(), dwOppGID);
|
|
return;
|
|
}
|
|
|
|
PIXEL_POSITION pos;
|
|
if (!CWarMapManager::instance().GetStartPosition(gw.map_index, GetID() < dwOppGID ? 0 : 1, pos))
|
|
{
|
|
sys_err("GuildWar.GuildWarEntryAsk.START_POSITION_ERROR id(%d vs %d), pos(%d, %d)", GetID(), dwOppGID, pos.x, pos.y);
|
|
return;
|
|
}
|
|
|
|
sys_log(0, "GuildWar.GuildWarEntryAsk.OnlineMemberCount(%d)", m_memberOnline.size());
|
|
|
|
itertype(m_memberOnline) it = m_memberOnline.begin();
|
|
|
|
while (it != m_memberOnline.end())
|
|
{
|
|
LPCHARACTER ch = *it++;
|
|
|
|
using namespace quest;
|
|
unsigned int questIndex=CQuestManager::instance().GetQuestIndexByName("guild_war_join");
|
|
if (questIndex)
|
|
{
|
|
sys_log(0, "GuildWar.GuildWarEntryAsk.SendLetterToMember pid(%d), qid(%d)", ch->GetPlayerID(), questIndex);
|
|
CQuestManager::instance().Letter(ch->GetPlayerID(), questIndex, 0);
|
|
}
|
|
else
|
|
{
|
|
sys_err("GuildWar.GuildWarEntryAsk.SendLetterToMember.QUEST_ERROR pid(%d), quest_name('guild_war_join.quest')",
|
|
ch->GetPlayerID(), questIndex);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// LADDER POINT
|
|
//
|
|
void CGuild::SetLadderPoint(int point)
|
|
{
|
|
if (m_data.ladder_point != point)
|
|
{
|
|
char buf[256];
|
|
snprintf(buf, sizeof(buf), LC_TEXT("<길드> 래더 점수가 %d 점이 되었습니다"), point);
|
|
for (itertype(m_memberOnline) it = m_memberOnline.begin(); it!=m_memberOnline.end();++it)
|
|
{
|
|
LPCHARACTER ch = (*it);
|
|
ch->ChatPacket(CHAT_TYPE_INFO, buf);
|
|
}
|
|
}
|
|
m_data.ladder_point = point;
|
|
}
|
|
|
|
void CGuild::ChangeLadderPoint(int iChange)
|
|
{
|
|
TPacketGuildLadderPoint p;
|
|
p.dwGuild = GetID();
|
|
p.lChange = iChange;
|
|
db_clientdesc->DBPacket(HEADER_GD_GUILD_CHANGE_LADDER_POINT, 0, &p, sizeof(p));
|
|
}
|
|
|
|
|