Files
2022-10-26 12:25:11 +08:00

365 lines
11 KiB
C++

#include "stdafx.h"
#ifdef _NA_008334_20150608_SONNENSCHEIN
#include "SonnenScheinManager.h"
#include "SonnenScheinRoom.h"
#include "DominationInfoParser.h"
#include "ChaosZoneInfoParser.h"
#include <ChaosZoneSystem/PacketStruct_ChaosZoneSystem.h>
#include <ChaosZoneSystem/BattleGroundManager.h>
#include <Zone/InstanceDungeon.h>
#include <Zone/ZoneManager.h>
#include "ServerOptionParserEx.h"
#include "AgentServer.h"
//_NA_008801_20160429_ADD_GUILDMISSION_TIMEINFO_SCRIPT
#include "ChaosZoneSystem/OneDaysGuildMissioninfoParser.h"
VOID SonnenScheinManager::Init()
{
sonnenschein_mapcode_ = ChaosZoneInfoParser::Instance()->GetSonnenScheinMapCode();
room_map_.clear();
}
MAPCODE SonnenScheinManager::GetSonnenScheinMapCode()
{
if (sonnenschein_mapcode_ == 0)
{
//맵코드가 0일 경우
//solarauth로 스크립트를 로드할 경우 스크립트가 뒤늦게 읽혀져서 0일 수 있다.
sonnenschein_mapcode_ = ChaosZoneInfoParser::Instance()->GetSonnenScheinMapCode();
}
return sonnenschein_mapcode_;
}
VOID SonnenScheinManager::ProcessPacket_CG( User* user, MSG_BASE* packet, WORD size )
{
handler_cg_sonnenschein_.OnCG_ProcessPacket(user, packet, size);
}
VOID SonnenScheinManager::ProcessPacket_AG( GameServerSession* server_session, MSG_BASE* packet, WORD size )
{
handler_ag_sonnenschein_.OnAG_ProcessPacket(server_session, packet, size);
}
RC::eSONNENSCHEIN_RESULT SonnenScheinManager::CreateSonnenScheinRoom(User* user, BOOL is_gm_cmd /*= FALSE*/)
{
// 유저가 생성 가능한 상태인지 검사
RC::eSONNENSCHEIN_RESULT check_result = CanUserCreateSonnenSchein(user, is_gm_cmd);
if (check_result != RC::RC_SONNENSCHEIN_SUCCESS) {
return check_result;
}
//sonnenschein의 맵코드
const MAPCODE map_code = GetSonnenScheinMapCode();
user->BeginTransaction(TR_CREATE_INSTANCE_DUNGEON);
// Instance Dungeon 생성
InstanceDungeon* dungeon = NULL;
const RC::eROOM_RESULT result =
g_ZoneManager.CreateInstanceDungeon(user->GetZoneKey(), user, map_code, (InstanceDungeon*&)dungeon,
INDUN_KIND_CHAOS_ZONE, FALSE);
if (dungeon == NULL || result != RC::RC_ROOM_SUCCESS)
{
//instance_dungeon생성실패
user->EndTransaction();
return RC::RC_SONNENSCHEIN_ROOM_CREATE_FAILED;
}
dungeon->SetRoomState(eROOMSTATE_GENERNAL);
// SonnenScheinRoom 생성
KEYTYPE room_key = dungeon->GetKey();
SonnenScheinRoom* new_room = new SonnenScheinRoom(room_key, user->GetSelectedCharGuildGuid());
//Map에 Room 등록
room_map_[room_key] = new_room;
user->EndTransaction();
return RC::RC_SONNENSCHEIN_SUCCESS;
}
SonnenScheinRoom* SonnenScheinManager::FindRoomUsingGuildGuid( GUILDGUID guild_guid )
{
SONNENSCHEIN_ROOM_MAP::iterator itr = room_map_.begin();
for (itr; itr != room_map_.end(); ++itr)
{
SonnenScheinRoom* target = itr->second;
if (target == NULL) {
continue;
}
if (guild_guid == target->GetGuildGuid()) {
return target;
}
}
return NULL;
}
RC::eSONNENSCHEIN_RESULT SonnenScheinManager::CanUserCreateSonnenSchein( User* user, BOOL is_gm_cmd /*= FALSE*/ )
{
// GM명령에 의한 생성이 아닐 경우 추가 검사
// 방생성조건: EventState가 Wait 혹은 Start이어야 한다
if (is_gm_cmd == FALSE)
{
eSONNENSCHEIN_EVENT_STATE cur_state = _GetCurEventState();
if (cur_state != SONNENSCHEIN_EVENT_STATE_START) {
return RC::RC_SONNENSCHEIN_STATE_NOT_READY;
}
}
RC::eSONNENSCHEIN_RESULT enter_result = _CheckUserProcessSonnenSchein(user);
if ( enter_result != RC::RC_SONNENSCHEIN_SUCCESS) {
return enter_result;
}
//이미 해당 길드의 방이 생성되어 있음
SonnenScheinRoom* room =SonnenScheinManager::Instance()->FindRoomUsingGuildGuid(user->GetSelectedCharGuildGuid());
if (room != NULL) {
return RC::RC_SONNENSCHEIN_ALEADY_CREATED;
}
return RC::RC_SONNENSCHEIN_SUCCESS;
}
RC::eSONNENSCHEIN_RESULT SonnenScheinManager::CheckUserEnterSonnenSchein( User* user, BOOL is_gm_cmd /*= FALSE*/ )
{
GUILDGUID user_guild_guid = user->GetSelectedCharGuildGuid();
SonnenScheinRoom* room = FindRoomUsingGuildGuid(user_guild_guid);
if (room == NULL) {
SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] SonnenScheinRoom is NULL! [guild:%d]", user_guild_guid);
return RC::RC_SONNENSCHEIN_ROOM_NO_EXIST;
}
//이미 입장한 플레이어인가?
if (room->FindUser(user->GetPlayerKey()) != NULL) {
return RC::RC_SONNENSCHEIN_ALREADY_ENTERED;
}
// 각인이 완료되지 않은상태여야 한다
if (room->IsStampComplete() == TRUE) {
return RC::RC_SONNENSCHEIN_STATE_END;
}
// GM명령에 의한 생성이 아닐 경우 추가 검사
if (is_gm_cmd == FALSE)
{
// 방입장 조건: 시간이 'Start'가 된 이후여야 한다
if (_GetCurEventState() != SONNENSCHEIN_EVENT_STATE_START) {
return RC::RC_SONNENSCHEIN_STATE_NOT_READY;
}
}
RC::eSONNENSCHEIN_RESULT result = _CheckUserProcessSonnenSchein(user);
if (result != RC::RC_SONNENSCHEIN_SUCCESS) {
return result;
}
return RC::RC_SONNENSCHEIN_SUCCESS;
}
SonnenScheinRoom* SonnenScheinManager::FindRoomUsingRoomKey( KEYTYPE room_key )
{
SONNENSCHEIN_ROOM_MAP::iterator itr = room_map_.find(room_key);
if(itr != room_map_.end()) {
return itr->second;
}
return NULL;
}
KEYTYPE SonnenScheinManager::GetZoneKeyUsingGuildGuid( GUILDGUID guild_guid )
{
SonnenScheinRoom* room = FindRoomUsingGuildGuid(guild_guid);
if (room == NULL) {
return 0;
}
return room->GetZoneKey();
}
//모든 room의 플레이어들 내보내기, SonnenSchein종료시 사용
VOID SonnenScheinManager::KickAllPlayers()
{
SONNENSCHEIN_ROOM_MAP::iterator itr = room_map_.begin();
for (itr; itr != room_map_.end(); ++itr)
{
SonnenScheinRoom* room = itr->second;
room->KickAllUsers();
}
}
//특정 Room 내 모든 플레이어 내보내기
VOID SonnenScheinManager::KickRoomPlayers( KEYTYPE zone_key )
{
if (zone_key == 0) {
//zone_key가 0일 경우 들어오는 함수는 여기가 아니다
return;
}
SONNENSCHEIN_ROOM_MAP::iterator itr = room_map_.find(zone_key);
if (itr != room_map_.end())
{
SonnenScheinRoom* room = itr->second;
room->KickAllUsers();
}
}
RC::eSONNENSCHEIN_RESULT SonnenScheinManager::_CheckUserProcessSonnenSchein( User* user )
{
//점령전 채널에서만 가능
AgentServer* pAgentServer = AgentServer::GetInstance();
SERVER_KEY rKey(pAgentServer->GetKey());
SERVER_COMMON_OPTION& server_option = ServerOptionParserEx::Instance()->GetServerOption();
if ( rKey.GetChannelID() != server_option.m_byDominationChannel )
{
return RC::RC_SONNENSCHEIN_NOT_DOMINATION_CHANNEL;
}
// 다른행동중이면 (거래/상점) 실패
if (user->GetBehaveState() != PLAYER_BEHAVE_IDLE_STATE) {
return RC::RC_SONNENSCHEIN_FAIL_TRANSACTION;
}
//전장 예약상태
BattleGroundManager* const battle_ground_manager = BattleGroundManager::Instance();
if (battle_ground_manager)
{
if (battle_ground_manager->IsValidReservationMember(user->GetUserKey())) {
return RC::RC_SONNENSCHEIN_BATTLEGROUND_RESERVATION_STATE;
}
}
//트랜잭션상태
if (user->IsBeginTransaction()) {
return RC::RC_SONNENSCHEIN_FAIL_TRANSACTION;
}
return RC::RC_SONNENSCHEIN_SUCCESS;
}
VOID SonnenScheinManager::DestroyRoom(KEYTYPE zone_key)
{
SONNENSCHEIN_ROOM_MAP::iterator itr = room_map_.find(zone_key);
if (itr != room_map_.end())
{
SonnenScheinRoom* room = itr->second;
room_map_.erase(itr);
SAFE_DELETE(room);
}
}
VOID SonnenScheinManager::DestroyRoom( GUILDGUID guild_guid )
{
KEYTYPE zone_key = GetZoneKeyUsingGuildGuid(guild_guid);
if (zone_key != 0) {
DestroyRoom(zone_key);
}
}
eSONNENSCHEIN_EVENT_STATE SonnenScheinManager::_GetCurEventState()
{
DWORD cur_time = 0; //현재시간
const WORD day_of_week = util::GetDateTime_Week_HHMMSS(cur_time);
//_NA_008801_20160429_ADD_GUILDMISSION_TIMEINFO_SCRIPT
MAPCODE map_code = GetSonnenScheinMapCode();
const GuildMissionTimeInfo* const event_info = OneDaysGuildMissionInfoParser::Instance()->FindGuildMissionTimeInfo(map_code);
//요일체크
if (day_of_week != event_info->day_of_week) {
// 소넨샤인 진행 요일이 아니다
return SONNENSCHEIN_EVENT_STATE_NONE;
}
DWORD wait_start_time = event_info->wait_time;
DWORD battle_start_time = event_info->starting_time;
DWORD battle_end_time = event_info->end_time;
if (Between(cur_time, wait_start_time, battle_start_time) == TRUE) {
return SONNENSCHEIN_EVENT_STATE_WAIT;
}
else if (Between(cur_time, battle_start_time, battle_end_time) == TRUE) {
return SONNENSCHEIN_EVENT_STATE_START;
}
else if (cur_time >= battle_end_time) {
return SONNENSCHEIN_EVENT_STATE_END;
}
}
VOID SonnenScheinManager::StampComplete( KEYTYPE zone_key )
{
SonnenScheinRoom* room = FindRoomUsingRoomKey(zone_key);
room->StampComplete();
}
BOOL SonnenScheinManager::GetEnterPlayerList_CharGuid( GUILDGUID guild_guid, CHARGUID* list OUT, INT* player_count OUT)
{
SonnenScheinRoom* room = FindRoomUsingGuildGuid(guild_guid);
if (room == NULL) {
return FALSE;
}
*player_count = room->GetPlayerList_CharGuid(list);
return TRUE;
}
BOOL SonnenScheinManager::MoveToSonnenScheinRoom(User* user, BOOL is_gm_cmd /*= FALSE*/)
{
GUILDGUID user_guild_guid = user->GetSelectedCharGuildGuid();
if (user_guild_guid == 0) {
return FALSE;
}
RC::eSONNENSCHEIN_RESULT enter_result = CheckUserEnterSonnenSchein(user, is_gm_cmd);
if (enter_result != RC::RC_SONNENSCHEIN_SUCCESS) {
SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"][GM]SonnenSchein Enter Failed!");
return FALSE;
}
KEYTYPE zone_key = GetZoneKeyUsingGuildGuid(user_guild_guid);
// 이동하려는 곳의 instance_dungeon
InstanceDungeon* const target_dungeon = \
static_cast<InstanceDungeon*>(g_ZoneManager.FindZone(zone_key));
if (target_dungeon == NULL) {
return FALSE;
}
//현재 위치한 Zone
ZoneInterface* current_zone = g_ZoneManager.FindZone(user->GetZoneKey());
if (current_zone == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__ " : Not found zone : %d", user->GetUserGUID());
return FALSE;
}
user->BeginTransaction(TR_LEAVE_FIELD_FOR_INSTANCE);
user->SetTRRoomKey(zone_key);
CheckMoveZonePolicy* const check_move_zone_policy =
MoveZonePolicy<MZTF_STATIC_TO_ROOM_FOR_UCUSER>::AlignInfo(user,
user->GetZoneType(), target_dungeon->GetType(),
user->GetZoneKey(), target_dungeon->GetKey());
RoomArgument argument(eZONEPUBLIC_PUBLIC, NULL);
RC::eROOM_RESULT rt = g_ZoneManager.MoveZone(check_move_zone_policy, RoomArgument::GetEmpty());
if (rt != RC::RC_ROOM_SUCCESS) {
user->EndTransaction();
SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] SonnenSchein Zone Move Failed!");
return FALSE;
}
return TRUE;
}
#endif //_NA_008334_20150608_SONNENSCHEIN