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

327 lines
9.8 KiB
C++

#include "SunClientPrecompiledHeader.h"
#include "RiderContainer.h"
#include "Character.h"
#include "ObjectManager.h"
#include "SlotKeyGenerator.h"
#include "Rider.h"
#include "InterfaceManager.h"
#include "GlobalFunc.h"
#include "SCItemSlot.h"
#include "Hero.h"
#ifdef _NA_007732_20141024_RIDER_MOVESPEED_SYNC
#include "RidingInfoParser.h"
#include "SetItemOptionInfoParser.h"
#endif //_NA_007732_20141024_RIDER_MOVESPEED_SYNC
//----------------------------------------------------------------------------
/**
*/
WzID RiderContainer::m_wzId[RIDER_MAX] =
{
StrToWzID("B001"),//RIDER_SLOT_01(BODY)
StrToWzID("B002"),//RIDER_SLOT_02(BOOTS)
StrToWzID("B003"),//RIDER_SLOT_03(HELM)
StrToWzID("BT00"),//RIDER_BTN_LEFT
StrToWzID("BT01"),//RIDER_BTN_RIGHT
StrToWzID("B999"),//RIDER_BTN_EXIT
StrToWzID("T999"),//RIDER_BTN_TEXT
StrToWzID("PI00"),//RIDER_SLOT_VIEW
};
RiderContainer::RiderContainer()
{
m_dwOwnerKey = 0;
Init(MAX_RIDER_SLOT, SI_RIDER);
#ifdef _NA_007732_20141024_RIDER_MOVESPEED_SYNC
rider_speed_ = 0;
dwRiderCode = 0;
#endif //_NA_007732_20141024_RIDER_MOVESPEED_SYNC
}
RiderContainer::~RiderContainer()
{
Release();
}
//-------------------------------------------------------------------------------------------
/** 스트림을 통해서 슬롯을 재구축한다
라이더아이템(SCItemSlot)요하나에 변수식의로 3개의 라이더파츠가 포함되어있다.
요아이템을 넣어서 파츠정보를 끄집어 내야된다.
*/
DWORD RiderContainer::CopyItem(SCItemSlot& RiderSlot)
{
//파츠변경시 기존 컨테이너를 전부 날린다.
Clear();
#ifdef _NA_007732_20141024_RIDER_MOVESPEED_SYNC
// 헤더로 이동
#else
DWORD dwRiderCode = 0;
#endif //_NA_007732_20141024_RIDER_MOVESPEED_SYNC
Player *pPlayer = (Player *)g_ObjectManager.GetObject(m_dwOwnerKey);
if(!pPlayer)
{
return 0;
}
if(RiderSlot.IsRiderItem())
{
dwRiderCode = RiderSlot.GetItemInfo()->m_wSkillCode;
//eRIDER_PARTS_POS::StartIndex(91)부터 라이더Pos이다
for(int i=0;i<MAX_RIDER_SLOT;++i)
{
SCRiderPartsData parts_data;
memset(&parts_data,0,sizeof(parts_data));
eRIDER_PARTS_POS Position;
Position.value = Position.StartIndex+i;
SCItemSlot ItemSlot;
if(RiderSlot.GetRiderPartsItem(Position,&ItemSlot))
{
if(ItemSlot.IsContainValidItem())
{
this->InsertSlot( i, ItemSlot);
}
}
else
{
//assert(!"파츠아이템생성실패");
_asm nop;
}
}
}
else
{
assert(!"라이더 아이템이 아닙니다.");
}
return dwRiderCode;
}
//-------------------------------------------------------------------------------------------
/** 외형업데이트를해준다.
*/
void RiderContainer::RefreshApperance()
{
Player *pPlayer =(Player *)g_ObjectManager.GetObject(m_dwOwnerKey);
if(pPlayer)
{
for(int i=0;i<MAX_RIDER_SLOT;++i)
{
SCItemSlot &ItemSlot =(SCItemSlot &)GetSlot(i);
const BASE_ITEMINFO *pItemInfo = ItemSlot.GetItemInfo();
//슬롯에 먼가가 들어있네
if(pItemInfo && pItemInfo->IsRiderPartsItem())
{
pPlayer->AttachRiderPart(i,ItemSlot.GetItemInfo()->m_Code);
pPlayer->RiderSubtype(i,ItemSlot.GetEnchant());
}
else
{
pPlayer->DetachRiderPart(i);
}
}
}
}
//-------------------------------------------------------------------------------------------
/**
*/
void RiderContainer::Clear()
{
for ( POSTYPE pos = 0; pos < MAX_RIDER_SLOT; ++pos )
{
if ( !IsEmpty(pos) )
{
DeleteSlot(pos, NULL);
}
}
}
//-------------------------------------------------------------------------------------------
/**
*/
void
RiderContainer::Release()
{
Clear();
}
//----------------------------------------------------------------------------
/** 슬롯삽입
*/
RC::eSLOT_INSERT_RESULT
RiderContainer::InsertSlot(POSTYPE AtPos, SCSlot& rSlot)
{
//slot_safe_code:안전한 슬롯체크 구문(삽입)
if (ValidPos(AtPos) == false)
{
return RC::RC_INSERT_SLOT_FAILED;
}
// 슬롯에 넣음
RC::eSLOT_INSERT_RESULT eInsertSlotResult = SCSlotContainer::InsertSlot( AtPos, rSlot );
SCSlot &refSlot = GetSlot(AtPos);
refSlot.SetSerial(g_SlotKeyGenerator.GetKey());
return eInsertSlotResult;
}
//----------------------------------------------------------------------------
/** 슬롯제거
*/
BOOL
RiderContainer::DeleteSlot( POSTYPE AtPos, SCSlot * pSlotOut )
{
//slot_safe_code:안전한 슬롯체크 구문(삭제)
if ((ValidPos(AtPos) == false) ||
IsEmpty(AtPos))
{
return FALSE;
}
SCItemSlot & rItemSlot = (SCItemSlot & )GetSlot(AtPos);
g_SlotKeyGenerator.Restore((DWORD)rItemSlot.GetSerial());
SCSlotContainer::DeleteSlot(AtPos, pSlotOut );
return TRUE;
}
#ifdef _NA_007732_20141024_RIDER_MOVESPEED_SYNC
void RiderContainer::RefreshRiderSpeed() // 탈것 이동속도 갱신
{
rider_speed_ = 100; // 최종 결과
int base_speed = 0; // 기본 이속
int parts_speed = 0; // 파츠 이속
int setitem_increase = 0; // 풀세트옵션 증가량
// 기본 이속
const sRiderInfo* rider_info = RidingInfoParser::Instance()->GetInfo(dwRiderCode);
if (rider_info)
{
base_speed = rider_info->set_speed_;
}
// 파츠 이속
Player *player = static_cast<Player*>(g_ObjectManager.GetObject(m_dwOwnerKey));
if (player == NULL)
{
return;
}
int is_pcroom_player = !!(player->GetPCBangMode());
WORD setitem_group = 0;
BYTE setitem_count = 1;
for (int i = 0; i < MAX_RIDER_SLOT; ++i)
{
SCItemSlot& item_slot = (SCItemSlot&)GetSlot(i);
const BASE_ITEMINFO* item_info = item_slot.GetItemInfo();
//슬롯에 먼가가 들어있네
if (item_info && item_info->IsRiderPartsItem())
{
int loop_count = is_pcroom_player ? 2 : 1;
for (int loop = 0; loop < loop_count; ++loop)
{
const BASE_ITEMINFO::OptionIndexes* _option_indexs = \
(loop == 0) ? &item_info->m_wOptionIndex : &item_info->m_wPCOptionIndex;
const BASE_ITEMINFO::OptionTypes* _option_types = \
(loop == 0) ? &item_info->m_byOptionType : &item_info->m_byPCOptionType;
const BASE_ITEMINFO::OptionValues* _option_values = \
(loop == 0) ? &item_info->m_iOptionValue : &item_info->m_iPCOptionValue;
const BASE_ITEMINFO::OptionIndexes& option_indexs = *_option_indexs;
const BASE_ITEMINFO::OptionTypes& option_types = *_option_types;
const BASE_ITEMINFO::OptionValues& option_values = *_option_values;
for (int i = 0; i < BASE_ITEMINFO::_MAX_OPTION_NUM; ++i)
{
if ((option_indexs[i] == 0) ||
(option_values[i] == 0) ||
(option_indexs[i] >= _countof(g_ITEM_OPTION)))
{
continue;
}
const eATTR_TYPE attr_type = g_ITEM_OPTION[option_indexs[i]];
if (attr_type != eATTR_MOVE_SPEED)
{
continue;
}
if (option_types[i] != 1) // 고정수치값이 아니면 일단 패스
{
continue;
}
parts_speed += option_values[i];
}
}
//세트 아이템체크 (MAX_RIDER_SLOT가 3일 경우에만 로직이 맞음)
SUN_ASSERT(MAX_RIDER_SLOT==3);
for (int j = i+1; j < MAX_RIDER_SLOT; ++j)
{
SCItemSlot& item_slot2 = (SCItemSlot&)GetSlot(j);
const BASE_ITEMINFO* item_info2 = item_slot2.GetItemInfo();
//슬롯에 먼가가 들어있네
if (item_info2 && item_info2->IsRiderPartsItem())
{
if ((item_info->set_group_code == item_info2->set_group_code) &&
(1 == item_info->m_bySetOptionType) &&
(1 == item_info2->m_bySetOptionType))
{
// 같은 세트아이템이면
++setitem_count;
setitem_group = item_info->set_group_code;
}
}
}
}//if (item_info && item_info->IsRiderPartsItem())
}
//세트옵션 적용 (라이더 세트옵션은 풀세트 옵션만 적용. 그런가보네요?)
if (setitem_group != 0)
{
SETITEM_OPTION_INFO* option_info = SetItemOptionInfoParser::Instance()->Find(setitem_group);
if (option_info && (option_info->m_byActiveFullOptionNum <= setitem_count))
{
for (int i = 0; i < MAX_SETITEM_FULL_OPTION; ++i)
{
if ((option_info->m_FullOption[i].m_byOptionKind == 0) ||
(option_info->m_FullOption[i].m_nOption == 0) ||
(option_info->m_FullOption[i].m_byOptionKind >= _countof(g_ITEM_OPTION)))
{
continue;
}
const eATTR_TYPE attr_type = g_ITEM_OPTION[option_info->m_FullOption[i].m_byOptionKind];
if (attr_type != eATTR_MOVE_SPEED)
{
continue;
}
if (option_info->m_FullOption[i].m_byUseType != 1) // 고정수치값이 아니면 일단 패스
{
continue;
}
setitem_increase += option_info->m_FullOption[i].m_nOption;
}
}
}
// 최종 결과
rider_speed_ = base_speed + parts_speed + setitem_increase;
}
#endif //_NA_007732_20141024_RIDER_MOVESPEED_SYNC