server.pg/game/src/wedding.cpp
2022-03-05 12:44:06 +02:00

387 lines
8.4 KiB
C++

#include "stdafx.h"
#include "desc_client.h"
#include "desc_manager.h"
#include "char_manager.h"
#include "sectree_manager.h"
#include "config.h"
#include "char.h"
#include "wedding.h"
#include "regen.h"
#include "locale_service.h"
namespace marriage
{
using namespace std;
EVENTINFO(wedding_map_info)
{
WeddingMap * pWeddingMap;
int iStep;
wedding_map_info()
: pWeddingMap( 0 )
, iStep( 0 )
{
}
};
EVENTFUNC(wedding_end_event)
{
wedding_map_info* info = dynamic_cast<wedding_map_info*>( event->info );
if ( info == NULL )
{
sys_err( "wedding_end_event> <Factor> Null pointer" );
return 0;
}
WeddingMap* pMap = info->pWeddingMap;
if (info->iStep == 0)
{
++info->iStep;
pMap->WarpAll();
return PASSES_PER_SEC(15);
}
WeddingManager::instance().DestroyWeddingMap(pMap);
return 0;
}
// Map instance
WeddingMap::WeddingMap(DWORD dwMapIndex, DWORD dwPID1, DWORD dwPID2) :
m_dwMapIndex(dwMapIndex),
m_pEndEvent(NULL),
m_isDark(false),
m_isSnow(false),
m_isMusic(false),
dwPID1(dwPID1),
dwPID2(dwPID2)
{
}
WeddingMap::~WeddingMap()
{
event_cancel(&m_pEndEvent);
}
void WeddingMap::SetEnded()
{
if (m_pEndEvent)
{
sys_err("WeddingMap::SetEnded - ALREADY EndEvent(m_pEndEvent=%x)", get_pointer(m_pEndEvent));
return;
}
wedding_map_info* info = AllocEventInfo<wedding_map_info>();
info->pWeddingMap = this;
m_pEndEvent = event_create(wedding_end_event, info, PASSES_PER_SEC(5));
Notice(LC_TEXT("결혼식이 종료됩니다."));
Notice(LC_TEXT("자동으로 나가게됩니다."));
for (itertype(m_set_pkChr) it = m_set_pkChr.begin(); it != m_set_pkChr.end(); ++it)
{
LPCHARACTER ch = *it;
if (ch->GetPlayerID() == dwPID1 || ch->GetPlayerID() == dwPID2)
continue;
if (ch->GetLevel() < 10) // 10 레벨이하는 주지않는다.
continue;
//ch->AutoGiveItem(27003, 5);
ch->AutoGiveItem(27002, 5);
}
}
struct FNotice
{
FNotice(const char * psz) :
m_psz(psz)
{
}
void operator() (LPCHARACTER ch)
{
ch->ChatPacket(CHAT_TYPE_NOTICE, "%s", m_psz);
}
const char * m_psz;
};
void WeddingMap::Notice(const char * psz)
{
FNotice f(psz);
for_each(m_set_pkChr.begin(), m_set_pkChr.end(), f);
}
struct FWarpEveryone
{
void operator() (LPCHARACTER ch)
{
if (ch->IsPC())
{
// ExitToSavedLocation은 WarpSet을 부르는데 이 함수에서
// Sectree가 NULL이 된다. 추 후 SectreeManager로 부터는
// 이 캐릭터를 찾을 수 없으므로 아래 DestroyAll에서 별도 처리함
ch->ExitToSavedLocation();
}
}
};
void WeddingMap::WarpAll()
{
FWarpEveryone f;
for_each(m_set_pkChr.begin(), m_set_pkChr.end(), f);
}
struct FDestroyEveryone
{
void operator() (LPCHARACTER ch)
{
sys_log(0, "WeddingMap::DestroyAll: %s", ch->GetName());
if (ch->GetDesc())
DESC_MANAGER::instance().DestroyDesc(ch->GetDesc());
else
M2_DESTROY_CHARACTER(ch);
}
};
void WeddingMap::DestroyAll()
{
sys_log(0, "WeddingMap::DestroyAll: m_set_pkChr size %zu", m_set_pkChr.size());
FDestroyEveryone f;
for (charset_t::iterator it = m_set_pkChr.begin(); it != m_set_pkChr.end(); it = m_set_pkChr.begin())
f(*it);
}
void WeddingMap::IncMember(LPCHARACTER ch)
{
if (IsMember(ch) == true)
return;
//sys_log(0, "WeddingMap: IncMember %s", ch->GetName());
m_set_pkChr.insert(ch);
SendLocalEvent(ch);
if (ch->GetLevel() < 10)
{
ch->SetObserverMode(true);
}
}
void WeddingMap::DecMember(LPCHARACTER ch)
{
if (IsMember(ch) == false)
return;
//sys_log(0, "WeddingMap: DecMember %s", ch->GetName());
m_set_pkChr.erase(ch);
if (ch->GetLevel() < 10)
{
ch->SetObserverMode(false);
}
}
bool WeddingMap::IsMember(LPCHARACTER ch)
{
if (m_set_pkChr.size() <= 0)
return false;
return m_set_pkChr.find(ch) != m_set_pkChr.end();
}
void WeddingMap::ShoutInMap(BYTE type, const char* msg)
{
for (itertype(m_set_pkChr) it = m_set_pkChr.begin(); it != m_set_pkChr.end(); ++it)
{
LPCHARACTER ch = *it;
ch->ChatPacket(CHAT_TYPE_COMMAND, msg);
}
}
void WeddingMap::SetMusic(bool bSet, const char* musicFileName)
{
if (m_isMusic != bSet)
{
m_isMusic = bSet;
m_stMusicFileName = musicFileName;
char szCommand[256];
if (m_isMusic)
{
ShoutInMap(CHAT_TYPE_COMMAND, __BuildCommandPlayMusic(szCommand, sizeof(szCommand), 1, m_stMusicFileName.c_str()));
}
else
{
ShoutInMap(CHAT_TYPE_COMMAND, __BuildCommandPlayMusic(szCommand, sizeof(szCommand), 0, "default"));
}
}
}
void WeddingMap::SetDark(bool bSet)
{
if (m_isDark != bSet)
{
m_isDark = bSet;
if (m_isDark)
ShoutInMap(CHAT_TYPE_COMMAND, "DayMode dark");
else
ShoutInMap(CHAT_TYPE_COMMAND, "DayMode light");
}
}
void WeddingMap::SetSnow(bool bSet)
{
if (m_isSnow != bSet)
{
m_isSnow = bSet;
if (m_isSnow)
ShoutInMap(CHAT_TYPE_COMMAND, "xmas_snow 1");
else
ShoutInMap(CHAT_TYPE_COMMAND, "xmas_snow 0");
}
}
bool WeddingMap::IsPlayingMusic()
{
return m_isMusic;
}
void WeddingMap::SendLocalEvent(LPCHARACTER ch)
{
char szCommand[256];
if (m_isDark)
ch->ChatPacket(CHAT_TYPE_COMMAND, "DayMode dark");
if (m_isSnow)
ch->ChatPacket(CHAT_TYPE_COMMAND, "xmas_snow 1");
if (m_isMusic)
ch->ChatPacket(CHAT_TYPE_COMMAND, __BuildCommandPlayMusic(szCommand, sizeof(szCommand), 1, m_stMusicFileName.c_str()));
}
const char* WeddingMap::__BuildCommandPlayMusic(char* szCommand, size_t nCmdLen, BYTE bSet, const char* c_szMusicFileName)
{
if (nCmdLen < 1)
{
szCommand[0] = '\0';
return "PlayMusic 0 CommandLengthError";
}
snprintf(szCommand, nCmdLen, "PlayMusic %d %s", bSet, c_szMusicFileName);
return szCommand;
}
// Manager
WeddingManager::WeddingManager()
{
}
WeddingManager::~WeddingManager()
{
}
bool WeddingManager::IsWeddingMap(DWORD dwMapIndex)
{
return (dwMapIndex == WEDDING_MAP_INDEX || dwMapIndex / 10000 == WEDDING_MAP_INDEX);
}
WeddingMap* WeddingManager::Find(DWORD dwMapIndex)
{
itertype(m_mapWedding) it = m_mapWedding.find(dwMapIndex);
if (it == m_mapWedding.end())
return NULL;
return it->second;
}
DWORD WeddingManager::__CreateWeddingMap(DWORD dwPID1, DWORD dwPID2)
{
SECTREE_MANAGER& rkSecTreeMgr = SECTREE_MANAGER::instance();
DWORD dwMapIndex = rkSecTreeMgr.CreatePrivateMap(WEDDING_MAP_INDEX);
if (!dwMapIndex)
{
sys_err("CreateWeddingMap(pid1=%d, pid2=%d) / CreatePrivateMap(%d) FAILED", dwPID1, dwPID2, WEDDING_MAP_INDEX);
return 0;
}
m_mapWedding.insert(make_pair(dwMapIndex, M2_NEW WeddingMap(dwMapIndex, dwPID1, dwPID2)));
// LOCALE_SERVICE
LPSECTREE_MAP pkSectreeMap = rkSecTreeMgr.GetMap(dwMapIndex);
if (pkSectreeMap == NULL) {
return 0;
}
string st_weddingMapRegenFileName;
st_weddingMapRegenFileName.reserve(64);
st_weddingMapRegenFileName = LocaleService_GetMapPath();
st_weddingMapRegenFileName += "/metin2_map_wedding_01/npc.txt";
if (!regen_do(st_weddingMapRegenFileName.c_str(), dwMapIndex, pkSectreeMap->m_setting.iBaseX, pkSectreeMap->m_setting.iBaseY, NULL, true))
{
sys_err("CreateWeddingMap(pid1=%d, pid2=%d) / regen_do(fileName=%s, mapIndex=%d, basePos=(%d, %d)) FAILED", dwPID1, dwPID2, st_weddingMapRegenFileName.c_str(), dwMapIndex, pkSectreeMap->m_setting.iBaseX, pkSectreeMap->m_setting.iBaseY);
}
else
{
sys_log(0, "CreateWeddingMap(pid1=%d, pid2=%d) / regen_do(fileName=%s, mapIndex=%d, basePos=(%d, %d)) ok", dwPID1, dwPID2, st_weddingMapRegenFileName.c_str(), dwMapIndex, pkSectreeMap->m_setting.iBaseX, pkSectreeMap->m_setting.iBaseY);
}
// END_OF_LOCALE_SERVICE
return dwMapIndex;
}
void WeddingManager::DestroyWeddingMap(WeddingMap* pMap)
{
sys_log(0, "DestroyWeddingMap(index=%u)", pMap->GetMapIndex());
pMap->DestroyAll();
m_mapWedding.erase(pMap->GetMapIndex());
SECTREE_MANAGER::instance().DestroyPrivateMap(pMap->GetMapIndex());
M2_DELETE(pMap);
}
bool WeddingManager::End(DWORD dwMapIndex)
{
itertype(m_mapWedding) it = m_mapWedding.find(dwMapIndex);
if (it == m_mapWedding.end())
return false;
it->second->SetEnded();
return true;
}
void WeddingManager::Request(DWORD dwPID1, DWORD dwPID2)
{
if (map_allow_find(WEDDING_MAP_INDEX))
{
DWORD dwMapIndex = __CreateWeddingMap(dwPID1, dwPID2);
if (!dwMapIndex)
{
sys_err("cannot create wedding map for %u, %u", dwPID1, dwPID2);
return;
}
TPacketWeddingReady p;
p.dwPID1 = dwPID1;
p.dwPID2 = dwPID2;
p.dwMapIndex = dwMapIndex;
db_clientdesc->DBPacket(HEADER_GD_WEDDING_READY, 0, &p, sizeof(p));
}
}
}