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

348 lines
11 KiB
C++

#include "stdafx.h"
//==================================================================================================
#include "MissionRoom.h"
//==================================================================================================
#include <PacketStruct_AG.h>
#include <PacketStruct_AW.h>
#include <MapInfoParser.h>
//==================================================================================================
#include <Zone/ZoneManager.h>
#include <ServerSessions/ServerSessionManager.h>
#include <ServerSessions/ServerSessionEx.h>
#include <UserSessions/User.h>
#include <AgentParty/AgentPartyManager.h>
//_NA_20110630_BATTLE_ZONE_RENEWAL
#include "MapPartialLoadingParser.h"
#include <AgentParty/AgentParty.h>
#include "Party/PartyRoom.h"
#ifdef _NA_007156_20140703_TOP_OF_TRIAL_LIGHT
#include "BattleOpenTimeManager.h"
#endif // _NA_007156_20140703_TOP_OF_TRIAL_LIGHT
_IMPL_POOL(MissionRoom)
MissionRoom::MissionRoom(void)
{
}
MissionRoom::~MissionRoom(void)
{
}
RC::eROOM_RESULT MissionRoom::Migrate(KEYTYPE key, RoomInterface* pPreviousRoom, ServerSession* pServerSession)
{
if(pPreviousRoom->GetType() != eZONETYPE_MISSION && pPreviousRoom->GetType() != eZONETYPE_LOBBY)
return RC::RC_ROOM_INVALIDROOMTYPE;
RoomInterface::Migrate(key, pPreviousRoom, pServerSession);
On_create();
// 릴레이 유저 등록
RelayUser(pPreviousRoom);
//pPreviousRoom->SetReusedKey(TRUE);
g_ZoneManager.ChangeBattlePlayersCount(this, GetNumberOfExpectedPlayers());
return RC::RC_ROOM_SUCCESS;
}
//_NA_20110630_BATTLE_ZONE_RENEWAL
RC::eROOM_RESULT
MissionRoom::_SetBaseRoomInfo(User* user, BASE_ROOMINFO& base_room_info, MAPCODE map_code)
{
const sMAPINFO* map_info = MapInfoParser::Instance()->FindMapInfo(map_code);
if (map_info == NULL)
{
return RC::RC_ROOM_INVALID_MAPCODE;
}
if(map_info->byMKind != eZONETYPE_MISSION)
{
return RC::RC_ROOM_INVALID_MAPCODE;
}
base_room_info.m_ClassLimit = map_info->byClass;
base_room_info.m_MinLV = static_cast<BYTE>(map_info->minLV);
base_room_info.m_MaxLV = static_cast<BYTE>(map_info->maxLV);
if (user->CanApplyPCBangBenefit(TRUE))
{
base_room_info.m_SpecialType = eROOM_SPECIAL_PCBANG_SUPER_ROOM;
}
else if (user->GetItemOwnFlag().FindItemInfo(eITEMTYPE_SUPERMASTER))
{
base_room_info.m_SpecialType = eROOM_SPECIAL_ITEM1_SUPER_ROOM;
}
return RC::RC_ROOM_SUCCESS;
}
RC::eROOM_RESULT
MissionRoom::Create(User* user, MAPCODE map_code, KEYTYPE mission_key, ServerSession* server_session)
{
BASE_ROOMINFO base_room_info;
RC::eROOM_RESULT result_code = _SetBaseRoomInfo(user, base_room_info, map_code);
if (result_code != RC::RC_ROOM_SUCCESS)
{
return result_code;
}
SetMaster(user);
LinkParty(user->GetPartyState().GetPartyKey());
result_code = _CanCreate(user, map_code, base_room_info, eZONETYPE_MISSION);
if (result_code != RC::RC_ROOM_SUCCESS)
{
return result_code;
}
#ifdef _NA_007156_20140703_TOP_OF_TRIAL_LIGHT
AgentPartyManager* const party_manager = AgentPartyManager::Instance();
const PartyRoom* party_room = party_manager->FindPartyRoom(GetLinkParty());
if(party_room)
{
PartyZoneType party_zone_type = party_room->GetPartyRoomType();
if (party_zone_type == PartyOfTopOfTrialLight_cash ||
party_zone_type == PartyOfTopOfTrialLight_normal)
{
WORD partyKey = user->GetPartyState().GetPartyKey();
result_code = AgentPartyManager::Instance()->TopOfTrialCheck(partyKey);
if (result_code != RC::RC_ROOM_SUCCESS) {
return result_code;
}
}
if (party_zone_type == PartyOfTopOfTrialLight_normal)
{
const sMAPINFO* map_info = MapInfoParser::Instance()->FindMapInfo(map_code);
if (map_info == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found map info parser : %d", map_code);
return RC::RC_ROOM_FAILED;
}
if (!(g_BattleOpenTimeMng.IsOpenDungeon(map_info->wTimeLimit))) {
return RC::RC_ROOM_FAILED;
}
}
}
#endif //_NA_007156_20140703_TOP_OF_TRIAL_LIGHT
RoomInterface::Create(user, mission_key, map_code, eZONEPUBLIC_PUBLIC,
"", "", base_room_info, server_session);
On_create();
return result_code;
}
RC::eROOM_RESULT
MissionRoom::_CanCreate(User* user, MAPCODE map_code,
const BASE_ROOMINFO& base_room_info, eZONETYPE zone_type)
{
if (GetRoomState() != eROOMSTATE_DESTROY)
{
return RC::RC_ROOM_INVALIDPREVLOBBY;
}
const sMAPINFO* map_info = MapInfoParser::Instance()->FindMapInfo(map_code);
if (map_info == NULL)
{
return RC::RC_ROOM_INVALID_MAPCODE;
}
if (map_info->GetZoneType4SharedCode() != zone_type)
{
return RC::RC_ROOM_INVALID_MAPCODE;
}
MAP_PARTIAL_LOADING* loading_info = NULL;
loading_info = MapPartialLoadingParser::Instance()->FindMapInfo(map_info->MapKind);
if (loading_info && !(loading_info->m_bLoading))
{
return RC::RC_ROOM_INVALID_MAPCODE;
}
if (base_room_info.m_SpecialType == eROOM_SPECIAL_PCBANG_SUPER_ROOM)
{
if (user->CanApplyPCBangBenefit(TRUE) == FALSE)
{
return RC::RC_ROOM_ISNOT_PCBANG_USER;
}
}
else if (base_room_info.m_SpecialType == eROOM_SPECIAL_ITEM1_SUPER_ROOM)
{
if (user->GetItemOwnFlag().FindItemInfo(eITEMTYPE_SUPERMASTER) == FALSE)
{
return RC::RC_ROOM_NOT_HAVE_SUPER_MASTER_ITEM;
}
}
bool is_valid_limit_level = (base_room_info.m_MinLV <= base_room_info.m_MaxLV) &&
(map_info->minLV <= base_room_info.m_MinLV) &&
(base_room_info.m_MaxLV <= map_info->maxLV);
if (is_valid_limit_level == false)
{
return RC::RC_ROOM_INVALID_LIMITLEVEL;
}
LEVELTYPE user_level = user->GetSelectedCharLV();
is_valid_limit_level = base_room_info.m_MinLV <= user_level &&
user_level <= base_room_info.m_MaxLV;
if (is_valid_limit_level == false)
{
return RC::RC_ROOM_INVALID_LIMITLEVEL;
}
for(int i = 0; i < eCHAR_TYPE_MAX - 1; ++i)
{
if((map_info->byClass & (eCLASS_BERSERKER << i)) == 0)
{
if(base_room_info.m_ClassLimit & (eCLASS_BERSERKER << i))
{
return RC::RC_ROOM_INVALID_LIMITCLASS;
}
}
}
return RC::RC_ROOM_SUCCESS;
}
RC::eROOM_RESULT
MissionRoom::MigratePortalUserFirstEnter(KEYTYPE key,
const RoomArgumentForRoomSetup& rRoomArgument,
User* pUser,
ServerSession* pServerSession)
{
const sMAPINFO* pMapInfo = rRoomArgument.m_pMapInfo;
const eZONETYPE enterZoneType = eZONETYPE(pMapInfo->byMKind);
if(enterZoneType != eZONETYPE_MISSION)
return RC::RC_ROOM_INVALIDROOMTYPE;
//RoomInterface::Create(pUser, key, pMapInfo->MapCode,
RoomInterface::MigratePortalUserFirstEnter(key, rRoomArgument, pUser, pServerSession);
// Portal정보를 참조해서 방장정보를 확인해야 한다. 일단 최초 유저를 마스터로 설정한 뒤
// 실제 마스터 입장시 ChangeMaster를 수행하자.
// <- 기획 확인 결과 현 시점 계획 없음. (방장 바뀌어도 별 상관 없다는 의미인데...
// 일단 수퍼 방장과 같은 문제는 충분히 거론될 수 있을 거라 생각됨. 방장 기준 미션 생성후
// 방장이 탈퇴해도 수퍼방이 될 수 있기도 하고...
// TODO(WAVERIX)
//VestUserWithMaster(pUser);
//VestUserWithMaster(pPreviousRoom->GetMaster());
On_create();
AgentPartyManager* pPartyManager = AgentPartyManager::Instance();
{
WORD partyKey = pUser->GetPartyState().GetPartyKey();
BYTE number_of_expected_players = partyKey != 0
? (BYTE)pPartyManager->GetMemberNum(partyKey) //pre-checked
: 1;
SetNumberOfExpectedPlayers(number_of_expected_players);
g_ZoneManager.ChangeBattlePlayersCount(this, number_of_expected_players);
}
return RC::RC_ROOM_SUCCESS;
}
VOID MissionRoom::On_create()
{
RoomInterface::On_create();
MSG_AG_ZONE_MISSION_CREATE_CMD msg;
msg.m_dwKey = GetMaster()->GetUserKey();
msg.m_MapCode = GetMapCode();
msg.m_RoomKey = GetKey();
// (WAVERIX) (NOTE) 매번 맵코드에 기반한 sMAPINFO찾는 것 대단히 귀찮다. 객체 맴버로 등록하자.
// 일단 시간상 찾는 걸로 한다.
if(RoomPolicyment.FIELD & RoomPolicyment.QUEST_PORTAL_CONTROL)
{
const sMAPINFO* pMapInfo = MapInfoParser::Instance()->FindMapInfo(GetMapCode());
const eZONE_RULESET& rRuleSet = pMapInfo->Ruleset;
msg.m_Rules = eZONE_RULESET::eRules(rRuleSet.rules | rRuleSet.ZONE_RULE_OPTION_ROOM_BY_PORTAL);
}
else
{
msg.m_Rules = eZONE_RULESET::ZONE_RULE_EMPTY;
}
memcpy(msg.m_pszRoomTitle, GetRoomTitle(), _countof(msg.m_pszRoomTitle)*sizeof(msg.m_pszRoomTitle[0]));
memcpy(msg.m_pszRoomPWD, GetRoomPWD(), _countof(msg.m_pszRoomPWD)*sizeof(msg.m_pszRoomPWD[0]));
msg.m_RoomInfo = *(GetRoomInfo());//생성할 방 정보
#ifdef _NA_003649_20111115_BATTLE_ZONE_HARDMODE
AgentPartyManager* const party_manager = AgentPartyManager::Instance();
const PartyRoom* party_room = party_manager->FindPartyRoom(GetLinkParty());
if(party_room) {
msg.party_zone_type = party_room->GetPartyRoomType();
}
#endif //_NA_003649_20111115_BATTLE_ZONE_HARDMODE
SendToLinkedServer(&msg, sizeof(msg));
}
VOID MissionRoom::On_destroy()
{
if(!IsReusedServerSession())
ServerSessionManager::Instance()->Decr_LOF_BattleServer(GetLinkedServer()->GetSessionIndex());
RoomInterface::On_destroy();
}
VOID MissionRoom::On_readyuser(User* pUser)
{
RoomInterface::On_readyuser(pUser);
pUser->SetZoneState(ePRS_BEFORE_ENTER_MISSION);
pUser->SetZoneKey(GetKey());
pUser->SetZoneType(eZONETYPE_MISSION);
}
VOID MissionRoom::On_enteruser(User* pUser)
{
RoomInterface::On_enteruser(pUser);
pUser->SetZoneState(ePRS_AT_MISSION);
}
VOID MissionRoom::On_leaveuser(User* user)
{
BOOL is_master = GetMaster() == user;
RoomInterface::On_leaveuser(user);
//_NA_20110630_BATTLE_ZONE_RENEWAL
if(is_master)
{
AgentPartyManager* const party_manager = AgentPartyManager::Instance();
const AgentParty* party =
static_cast<const AgentParty*>(party_manager->FindParty(GetLinkParty()));
if (party)
{
if (party->GetType() != ePARTY_ROOM)
{
User* next_master = RoomInterface::ChangeSpecialType(false, user);
if (next_master)
{
party_manager->ChangeMaster(next_master->GetPartyState().GetPartyKey(),
next_master->GetPlayerKey());
}
}
}
else
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party : %d", GetLinkParty());
}
}
}
RC::eROOM_RESULT MissionRoom::_CanJoinEach(User* pUser, eZONEPUBLIC RoomPublic, TCHAR* pszRoomPWD)
{
// 카오상태 체크
if(!GetServerOptChaoStateUseZone(GetType()) && pUser->IsChaoState())
{
return RC::RC_ROOM_UNABLE_FUNCTION_FOR_CHAOSTATE;
}
return RC::RC_ROOM_SUCCESS;
}