// EquipmentSlotContainer.cpp: implementation of the CEquipmentSlotContainer class. // //================================================================================================== #include "stdafx.h" #include "EquipmentSlotContainer.h" //================================================================================================== #if !defined(_NA_002289_20110322_EQUIPMENTS_CALCULATOR_CHANGES_FOR_IMPROVEMENT) //================================================================================================== #include "Player.h" #include "GameField.h" #include #include #include #include "ItemAttrCalculator.h" #include "SkillSlotManager.h" #include #include #include "QuickManager.h" #include "QuickSlotContainer.h" #include #include "ItemManager.h" #include "StatusManager.h" #include #include #include //================================================================================================== // Construction/Destruction CEquipmentSlotContainer::CEquipmentSlotContainer() : m_pPlayer(NULL) { Init(MAX_EQUIPMENT_SLOT_NUM, SI_EQUIPMENT); ZeroMemory(m_bRealEquip, sizeof(m_bRealEquip)); } CEquipmentSlotContainer::~CEquipmentSlotContainer() { } void CEquipmentSlotContainer::ClearAll() { SCItemSlotContainer::ClearAll(); m_mapEquipCount.clear(); m_mapEquipTypeCount.clear(); m_mapEquipGroupCount.clear(); ZeroMemory(m_bRealEquip, sizeof(m_bRealEquip)); } RC::eSLOT_INSERT_RESULT CEquipmentSlotContainer::InsertSlot(POSTYPE at_pos, SCSlot& IN rSlot) { SASSERT(m_pPlayer != NULL, "[CEquipmentSlotContainer::InsertSlot] m_pPlayer == NULL"); if(CanEquip(at_pos, rSlot) == 0) return RC::RC_INSERT_SLOT_CAN_NOT_EQUIP; RC::eSLOT_INSERT_RESULT rt = SCSlotContainer::InsertSlot(at_pos, rSlot); if(rt != RC::RC_INSERT_SLOT_SUCCESS) return rt; SCItemSlot& rCurSlot = static_cast(GetSlot(at_pos)); if(rCurSlot.OnEquip()) { GAMELOG->LogItem(ITEM_CHARGE_FIRST_EQUIP, m_pPlayer, &rCurSlot); } SCQuickSlotContainer* quick_slot_container = m_pPlayer->GetQuickManager()->GetQuickSlotContainer(); quick_slot_container->UpdateQuickSlot(rSlot.GetSlotIdx(), rSlot.GetPos(), rCurSlot.GetItemCode(), SI_EQUIPMENT, at_pos, rCurSlot.GetItemCode()); // m_pPlayer->GetQuickManager()->GetQuickSlotContainer()->UpdateQuickSlot(rCurSlot.GetSlotIdx(), rCurSlot.GetPos(), rCurSlot.GetItemCode(), // SI_EQUIPMENT, at_pos, rCurSlot.GetItemCode()); //ÀåÂøÇßÀ¸¹Ç·Î ºñȰ¼ºÈ­À̸é Ȱ¼ºÈ­·Î ¼öÁ¤ÇØÁÖÀÚ. if(m_bRealEquip[at_pos] == false) { m_bRealEquip[at_pos] = true; } // Equip AttrChange ItemAttrCalculator itemCalc(m_pPlayer->GetPlayerAttr(), *this); BOOL bChangeFullOption = false; itemCalc.Equip(rCurSlot, m_pPlayer->CanApplyPCBangBenefit(true), true, bChangeFullOption); // ¹«±â°¡ º¯°æµÇ¾úÀ» °æ¿ì ½ºÅ¸ÀÏ ¼ÂÆÃ°ú ÆÐ½Ãºê Àû¿ëÀÌ ´Þ¶óÁø´Ù. if(at_pos == eEQUIPCONTAINER_WEAPON) { m_pPlayer->GetSkillSlotManager()->AddWeapon(rCurSlot.GetItemCode()); } if(m_pPlayer->IsRenderEquipItem(at_pos)) { // ÀÚ½ÅÀ» Á¦¿ÜÇÑ ¸ðµç »ç¶÷¿¡°Ô ³¯¸°´Ù. MSG_CG_CHARINFO_APPREARANCE_BRD msg; msg.m_PlayerKey = (PLAYERKEY)m_pPlayer->GetObjectKey(); msg.m_EquipPos = at_pos; rCurSlot.CopyOut(msg.m_OptItemStream); m_pPlayer->SendPacketAround(&msg, sizeof(msg), false); } if (nsSlot::ItemManagerUpdateImpl* const item_updater_impl = m_pPlayer->GetItemManager()->GetUpdaterImpl()) { item_updater_impl->AddSerialCode(eSERIAL_EQUIPMENT, GetSlotIdx(), rCurSlot.GetPos(), rCurSlot.GetWorldSerial()); } static_cast(m_pPlayer->GetAttr()).Display(); return rt; } BOOL CEquipmentSlotContainer::DeleteSlot(POSTYPE at_pos, SCSlot* pSlotOut) { SASSERT(m_pPlayer != NULL, "[CEquipmentSlotContainer::DeleteSlot] m_pPlayer == NULL"); BOOL bChangeFullOption = false; SCSlot& at_pos_slot = GetSlot(at_pos); if(CanUnEquip(at_pos, at_pos_slot) == 0) return false; SCItemSlot temp_delete_item_slot; if(SCSlotContainer::DeleteSlot(at_pos, &temp_delete_item_slot) == 0) return false; if(pSlotOut) { static_cast(pSlotOut)->Copy(temp_delete_item_slot); } temp_delete_item_slot.OnUnEquip(); SASSERT(pSlotOut != NULL, "[CEquipmentSlotContainer::DeleteSlot] pSlotOut == NULL"); // UnEquip AttrChange ItemAttrCalculator itemCalc(m_pPlayer->GetPlayerAttr(), *this); //Ȱ¼ºÈ­ À̸é Unequip if(m_bRealEquip[at_pos] != false) { BOOLEAN apply_pc_benefit = m_pPlayer->CanApplyPCBangBenefit(true); itemCalc.UnEquip(&temp_delete_item_slot, apply_pc_benefit, true, bChangeFullOption); } // ¹«±â°¡ º¯°æµÇ¾úÀ» °æ¿ì ½ºÅ¸ÀÏ ¼ÂÆÃ°ú ÆÐ½Ãºê Àû¿ëÀÌ ´Þ¶óÁø´Ù. if(at_pos == eEQUIPCONTAINER_WEAPON) m_pPlayer->GetSkillSlotManager()->DelWeapon(); if(m_pPlayer->IsRenderEquipItem(at_pos)) { MSG_CG_CHARINFO_DISAPPREARANCE_BRD msg; msg.m_PlayerKey = (PLAYERKEY)m_pPlayer->GetObjectKey(); msg.m_EquipPos = at_pos; m_pPlayer->SendPacketAround(&msg, sizeof(msg), false); } if (nsSlot::ItemManagerUpdateImpl* const item_updater_impl = m_pPlayer->GetItemManager()->GetUpdaterImpl()) { item_updater_impl->RemoveSerialCode(GetSlotIdx(), at_pos, temp_delete_item_slot.GetWorldSerial()); }; static_cast(m_pPlayer->GetAttr()).Display(); //¹þÀº ¾ÆÀÌÅÛÀÌ ¹öÇÁÀ̺¥Æ® ¾ÆÀÌÅÛÀÏ °æ¿ì¸é BYTE byEventCode = temp_delete_item_slot.GetItemInfo()->m_byEventCode; if(byEventCode != 0) { //°°Àº Á¾·ùÀÇ À̺¥Æ® ¾ÆÀÌÅÛÀ» ÀÔ°í ÀÖÁö ¾Ê´Ù¸é »óÅÂ ÇØÁ¦ if(!IsEquipEventItem(byEventCode)) { m_pPlayer->GetStatusManager()->RemoveEventStatus(byEventCode); } } return true; } BOOL CEquipmentSlotContainer::ValidState() { // ¿¹) PK½Ã µå¶øµÇ´Â ITEMÀÌ ÀåºñÀÏ °æ¿ì... CanUnEquip¿¡¼­ »ç¿ëÇÏ¸é ¾ÈµÈ´Ù. // ÆÐŶ¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇÏÀÚ. // (BUGFIX) (091202) (WOPS:5334) Àκ¥Àá±Ý »óÅ¿¡¼­ ¾ÆÀÌÅÛ Á¦°Å °¡´ÉÇÑ Æ¯¼ö ó¸®(PKµå¶ø) ItemManager::TransactionClosure::value_type transaction = m_pPlayer->GetItemManager()->GetCurrentTransactionAction(); if(transaction == ItemManager::TransactionClosure::eTransType_None) { ProtectorInventory& rPROTECT = m_pPlayer->GetWarehouseInventoryProtector().INVENTORY(); if(!rPROTECT.IsUsable()) return false; } return SCItemSlotContainer::ValidState(); } BOOL CEquipmentSlotContainer::CanUnEquip(POSTYPE at_pos, SCSlot& IN rSlotIn) { //ºñȰ¼ºÈ­ ¾ÆÀÌÅÛÀ̸é UnEquip°¡´É if (m_bRealEquip[at_pos] == false) return true; ItemAttrCalculator itemCalc(m_pPlayer->GetPlayerAttr(), *this); itemCalc.Clear(); m_pPlayer->GetItemManager()->UpdateAttrInventory(); itemCalc.SetCalcTypeSetItemCount(true); BOOL bFullOption = false; m_mapEquipCount.clear(); m_mapEquipTypeCount.clear(); m_mapEquipGroupCount.clear(); // (CHANGES) ...ÃʱâÈ­ °ü·Ã const BOOLEAN need_apply_pc_benefit = m_pPlayer->CanApplyPCBangBenefit(true); BOOL bEquipTable[MAX_EQUIPMENT_SLOT_NUM] = { 0, }; const POSTYPE maxSlotNum = GetMaxSlotNum(); POSTYPE itr_pos = 0; //POSTYPE stacked_inc = 0; //POSTYPE stacked_equip[MAX_EQUIPMENT_SLOT_NUM]; //memset(stacked_equip, -1, sizeof(stacked_equip)); while(itr_pos < maxSlotNum) { //ÇöÀç ÀåÂøÇϰí ÀÖ´Â ¾ÆÀÌÅÛÁß ÀåÂø °¡´ÉÇÑ ¾ÆÀÌÅÛÀÇ ´É·ÂÄ¡¸¦ ¸ðµÎ Àû¿ë ½ÃŲ´Ù. //ÇöÀç ¹þÀ» ¾ÆÀÌÅÛ¶§¹®¿¡ ÀåÂø ¸øÇÏ´Â ¾ÆÀÌÅÛÀº bEquipTable[itr_pos] ·Î ±¸ºÐÇÑ´Ù. if(bEquipTable[itr_pos] || itr_pos == at_pos || m_bRealEquip[itr_pos] == false || IsEmpty(itr_pos)) // (CHANGES) change check condition sequence : more cheap { ++itr_pos; continue; } SCItemSlot& itr_slot = static_cast(GetSlot(itr_pos)); if(CanEquip(itr_pos, itr_slot, false)) { bEquipTable[itr_pos] = true; //stacked_equip[stacked_inc++] = itr_pos; itemCalc.Equip(itr_slot, need_apply_pc_benefit, true, bFullOption); itr_pos = 0; continue; } ++itr_pos; } BOOL rt = true; for(POSTYPE itr_pos = 0; itr_pos < maxSlotNum ; ++itr_pos) { if(IsEmpty(itr_pos)) continue; SCItemSlot& itr_slot = static_cast(GetSlot(itr_pos)); IncEquipCount(itr_slot.GetItemCode()); //ÇöÀç ¹þÀ»·Á´Â ¾ÆÀÌÅÛ À̰ųª, Âø¿ëÇÏÁö ¾ÊÀº ¾ÆÀÌÅÛÀ̰ųª, ºñȰ¼ºÈ­ µÈ ¾ÆÀÌÅÛÀÌ¸é ½ºÅµ if(itr_pos == at_pos || m_bRealEquip[itr_pos] == false) continue; if(bEquipTable[itr_pos] == false) { // ¿©±â¿¡ ¿À´Â °æ¿ì´Â ÇöÀç ÀåÂøÀº Çϰí ÀÖÀ¸³ª, // ÇöÀç ¹þÀº ¾ÆÀÌÅÛ ¶§¹®¿¡ ´Ù½Ã EquipÇÏÁö ¸øÇÏ´Â ¾ÆÀÌÅÛÀÎ °æ¿ìÀÌ´Ù. // À̰æ¿ì false ¶óµµ ´Ù½Ã ´Ù ÀÔÇô¾ß Çϱ⠶§¹®¿¡ break ÇÏ¸é ¾ÈµÊ itemCalc.Equip(itr_slot, need_apply_pc_benefit, false, bFullOption); rt = false; } } itemCalc.Equip(rSlotIn, need_apply_pc_benefit, false, bFullOption); return rt; } BOOL CEquipmentSlotContainer::CanEquip(POSTYPE at_pos, SCSlot& IN rSlotIn, BOOL bCheckEquipState) { if(bCheckEquipState != false) { // µå·¡°ï º¯½Å»óÅ¿¡¼­´Â ÀåÂø½½·ÔÀ» ÀÌ¿ëÇÒ ¼ö ¾ø´Ù. if(m_pPlayer->GetStatusManager()->Status.IsDragonTransforming()) { return false; } } SCItemSlot& item_slot = static_cast(rSlotIn); const BASE_ITEMINFO* item_info = item_slot.GetItemInfo(); // (CHANGES) use BASE_ITEMINFO interface| // ref eITEM_MATERIAL_TYPE + for rider info if (item_slot.CanEquip() == false) { return false; } // Áߺ¹ÀåÂø °³¼ö üũ(0ÀÌ¸é ¹«Á¦ÇÑ) if(item_info->m_byDupEquipNum) { int iCount = GetEquipCount(item_slot.GetItemCode()); if(iCount >= item_info->m_byDupEquipNum) return false; } // Áߺ¹Å¸ÀÔ ÀåÂø °³¼ö üũ //³ªÁß¿¡ ½ºÅ©¸³Æ®·Î »©¾ßÁö!!! if(item_info->m_byDupEquipTypeNum) { int iCount = GetEquipTypeCount((eITEMTYPE)item_info->m_wType); if(iCount >= 1) return false; } // ¾ÆÀÌÅÛ ±×·ìº° °³¼ö Á¦ÇÑ Ã¼Å© if(item_info->m_byDupEquipGroup) { int iCount = GetEquipGroupCount(item_info->m_byDupEquipGroup); if(iCount >= item_info->m_byDupEquipGroupNum) return false; } #ifdef _NA_002050_20110216_ADD_GENDER // ÀåÂø °¡´ÉÇÑ ¼ºº°ÀÎÁö °Ë»çÇÑ´Ù. if (item_info->IsCanUseGender((m_pPlayer->GetCharInfo())->gender) == false) { return false; } #endif // classº° ÀåÂø ¿©ºÎ switch(m_pPlayer->GetCharType()) { case eCHAR_BERSERKER : if(0 == item_info->m_wEqClass1) return false; break; case eCHAR_DRAGON : if(0 == item_info->m_wEqClass2) return false; break; case eCHAR_SHADOW : if(0 == item_info->m_wEqClass3) return false; break; case eCHAR_VALKYRIE : if(0 == item_info->m_wEqClass4) return false; break; case eCHAR_ELEMENTALIST : if(0 == item_info->m_wEqClass5) return false; break; // _NA_004965_20120613_NEW_CHARACTER_MYSTIC case eCHAR_MYSTIC: : if (item_info->can_equip_class6 == false) return false; break; // _NA_000000_20130812_NEW_CHARACTER_HELLROID case eCHAR_HELLROID : if(item_info->can_equip_class7 == false) return false; break; #ifdef _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE case eCHAR_WITCHBLADE : if(item_info->can_equip_class8 == false) return false; break; #endif //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE default: SUNLOG(eCRITICAL_LOG, "[CEquipmentSlotContainer::CanEquip] Wrong Char_Type in CanEquip()"); return false; } switch(item_info->m_wEqPos) { case eEQUIPCONTAINER_RING1: case eEQUIPCONTAINER_RING2: if(at_pos != eEQUIPCONTAINER_RING1 && at_pos != eEQUIPCONTAINER_RING2) { return false; } break; case eEQUIPCONTAINER_SACCESSORY1: case eEQUIPCONTAINER_SACCESSORY2: case eEQUIPCONTAINER_SACCESSORY3: if(at_pos != eEQUIPCONTAINER_SACCESSORY1 && at_pos != eEQUIPCONTAINER_SACCESSORY2 && at_pos != eEQUIPCONTAINER_SACCESSORY3) { return false; } #ifdef _NA001955_110210_WING_COSTUME_ACCESSORY_EXTENTION #else if((at_pos == eEQUIPCONTAINER_SACCESSORY2 || at_pos == eEQUIPCONTAINER_SACCESSORY3) && m_pPlayer->GetCharType() != eCHAR_ELEMENTALIST) { return false; } #endif break; case eEQUIPCONTAINER_CHARGE1: case eEQUIPCONTAINER_CHARGE2: case eEQUIPCONTAINER_CHARGE3: case eEQUIPCONTAINER_CHARGE4: case eEQUIPCONTAINER_CHARGE5: if(at_pos != eEQUIPCONTAINER_CHARGE1 && at_pos != eEQUIPCONTAINER_CHARGE2 && at_pos != eEQUIPCONTAINER_CHARGE3 && at_pos != eEQUIPCONTAINER_CHARGE4 && at_pos != eEQUIPCONTAINER_CHARGE5) { return false; } if(at_pos == eEQUIPCONTAINER_CHARGE4 && m_pPlayer->GetCharInfo()->m_ExtraEquipCashSlotCount < 1) { return false; } if(at_pos == eEQUIPCONTAINER_CHARGE5 && m_pPlayer->GetCharInfo()->m_ExtraEquipCashSlotCount < 2) { return false; } break; case eEQUIPCONTAINER_PC_ROOM1: case eEQUIPCONTAINER_PC_ROOM2: case eEQUIPCONTAINER_PC_ROOM3: if(at_pos != eEQUIPCONTAINER_PC_ROOM1 && at_pos != eEQUIPCONTAINER_PC_ROOM2 && at_pos != eEQUIPCONTAINER_PC_ROOM3) { return false; } if(m_pPlayer->CanApplyPCBangBenefit(true) == false) return false; break; default: if(item_info->m_wEqPos != at_pos) return false; break; } if(!ValidLimitStr(item_slot)) return false; if(!ValidLimitDex(item_slot)) return false; if(!ValidLimitVit(item_slot)) return false; if(!ValidLimitInt(item_slot)) return false; if(!ValidLimitSpr(item_slot)) return false; if(!ValidLimitLevel(item_slot)) return false; if(!ValidLimitSKill1(item_slot)) return false; if(!ValidLimitSKill2(item_slot)) return false; if(item_slot.IsFateItem()) { if(!(item_slot.GetFateIdentify())) return false; } if(item_slot.IsPossessionItem() && item_slot.GetIdentifyPossession() == 0) { return false; } if(item_slot.IsDestroyItem()) return false; return true; } //-------------------------------------------------------------------------------------------------- // internal function inline BOOL CEquipmentSlotContainer::ValidLimitAll(short player_limit, short item_limit) { // ½ºÅÈ Á¦ÇÑ short decrease_limit_stat = m_pPlayer->GetDecreaseLimitStat(); if(player_limit + decrease_limit_stat < item_limit) return false; return true; } // ½ºÅ©¸³Æ®¿¡¼­ Âø¿ë ¿ä±¸Ä¡ Á¶Á¤°ª Àû¿ë(CalcLimitStatWeapon/Armor·¡ÇÎ) WORD CEquipmentSlotContainer::CalcLimitStat(WORD ItemLimitStr, SCItemSlot& item_slot, BOOL is_weapon, BOOL is_armor) { WORD (*CalcLimitStatRouteFunc)(WORD,BYTE,eRANK,LEVELTYPE,float); if(is_weapon) { CalcLimitStatRouteFunc = CalcLimitStatWeapon; } else if(is_armor) { CalcLimitStatRouteFunc = CalcLimitStatArmor; } else { DEBUG_CODE(if(ItemLimitStr!=0) SUNLOG(eFULL_LOG, "[CEquipmentSlotContainer::CalcLimitStat] ½ºÅ©¸³Æ®¿À·ù!Àåºñ(%s)°¡¾Æ´Ñµ¥0À̾ƴϴÙ", item_slot.GetItemInfo()->m_pszName);); return ItemLimitStr; } BYTE byEnchant = item_slot.GetEnchant(); LEVELTYPE lv = item_slot.GetItemInfo()->m_LV; float fLimitRatio = EnchantParser::Instance()->GetLimitRatio(lv, byEnchant, is_weapon, item_slot.IsLimited()); return (WORD)CalcLimitStatRouteFunc(ItemLimitStr,byEnchant,item_slot.GetRank(),lv,fLimitRatio); } BOOL CEquipmentSlotContainer::ValidLimitStr(SCItemSlot& item_slot) { BASE_ITEMINFO* pInfo = item_slot.GetItemInfo(); WORD LimitStr = pInfo->m_wLimitStr; if(0 == LimitStr) return true; //µð¹ÙÀÎ? if(item_slot.IsDivine()) { //LimitStr = CalcLimitStrForDivineWeapon(LimitStr, m_pPlayer->GetCharType(), (eITEMTYPE)pInfo->m_wType); LimitStr = pInfo->m_wDivLimitStr; } //¸®¹ÌƼµå? if(item_slot.IsLimited()) { INT Ratio = 0; Ratio = item_slot.GetLimitValueRatio(); float fValue = 0; if(Ratio >= 0) fValue = 0.5f + 0.001f;//FLT_EPSILON; else fValue = -0.5f - 0.001f;//FLT_EPSILON; fValue = LimitStr + ((float)Ratio * (float)LimitStr) / 100.0f + fValue; LimitStr = (WORD)fValue; } LimitStr = CalcLimitStat(LimitStr, item_slot, pInfo->IsWeapon(), pInfo->IsArmor()); // ½ºÅÈ Á¦ÇÑ return ValidLimitAll(m_pPlayer->GetLimitStrength(), LimitStr); } BOOL CEquipmentSlotContainer::ValidLimitDex(SCItemSlot& item_slot) { const BASE_ITEMINFO* pInfo = item_slot.GetItemInfo(); WORD LimitDex = pInfo->m_wLimitDex; if(0 == LimitDex) return true; //µð¹ÙÀÎ? if(item_slot.IsDivine()) { //LimitDex = CalcLimitDexForDivineWeapon(LimitDex, m_pPlayer->GetCharType(), (eITEMTYPE)pInfo->m_wType); LimitDex = pInfo->m_wDivLimitDex; } //¸®¹ÌƼµå? if(item_slot.IsLimited()) { INT Ratio = 0; Ratio = item_slot.GetLimitValueRatio(); float fValue = 0; if(Ratio >= 0) fValue = 0.5f + 0.001f;//FLT_EPSILON; else fValue = -0.5f - 0.001f;//FLT_EPSILON; fValue = LimitDex + ((float)Ratio * (float)LimitDex) / 100.0f + fValue; LimitDex = (WORD)fValue; } LimitDex = CalcLimitStat(LimitDex, item_slot, pInfo->IsWeapon(), pInfo->IsArmor()); // ½ºÅÈ Á¦ÇÑ return ValidLimitAll(m_pPlayer->GetLimitDexterity(), LimitDex); //if(m_pPlayer->GetLimitDexterity() < LimitDex) return false; //return true; } BOOL CEquipmentSlotContainer::ValidLimitVit(SCItemSlot& item_slot) { const BASE_ITEMINFO* pInfo = item_slot.GetItemInfo(); WORD LimitVit = pInfo->m_wLimitVit; if(0 == LimitVit) return true; //µð¹ÙÀÎ? if(item_slot.IsDivine()) { //LimitInt = CalcLimitIntForDivineWeapon(LimitVit, m_pPlayer->GetCharType(), (eITEMTYPE)pInfo->m_wType); LimitVit = pInfo->m_wDivLimitVit; } //¸®¹ÌƼµå? if(item_slot.IsLimited()) { INT Ratio = 0; Ratio = item_slot.GetLimitValueRatio(); float fValue = 0; if(Ratio >= 0) fValue = 0.5f + 0.001f;//FLT_EPSILON; else fValue = -0.5f - 0.001f;//FLT_EPSILON; fValue = LimitVit + ((float)Ratio * (float)LimitVit) / 100.0f + fValue; LimitVit = (WORD)fValue; } LimitVit = CalcLimitStat(LimitVit, item_slot, pInfo->IsWeapon(), pInfo->IsArmor()); // ½ºÅÈ Á¦ÇÑ return ValidLimitAll(m_pPlayer->GetLimitVitality(), LimitVit); //if(m_pPlayer->GetLimitVitality() < LimitVit) return false; //return true; } BOOL CEquipmentSlotContainer::ValidLimitInt(SCItemSlot& item_slot) { const BASE_ITEMINFO* pInfo = item_slot.GetItemInfo(); WORD LimitInt = pInfo->m_wLimitInt; if(0 == LimitInt) return true; //µð¹ÙÀÎ? if(item_slot.IsDivine()) { //LimitInt = CalcLimitIntForDivineWeapon(LimitInt, m_pPlayer->GetCharType(), (eITEMTYPE)pInfo->m_wType); LimitInt = pInfo->m_wDivLimitInt; } //¸®¹ÌƼµå? if(item_slot.IsLimited()) { INT Ratio = 0; Ratio = item_slot.GetLimitValueRatio(); float fValue = 0; if(Ratio >= 0) fValue = 0.5f + 0.001f;//FLT_EPSILON; else fValue = -0.5f - 0.001f;//FLT_EPSILON; fValue = LimitInt + ((float)Ratio * (float)LimitInt) / 100.0f + fValue; LimitInt = (WORD)fValue; } LimitInt = CalcLimitStat(LimitInt, item_slot, pInfo->IsWeapon(), pInfo->IsArmor()); // ½ºÅÈ Á¦ÇÑ return ValidLimitAll(m_pPlayer->GetLimitInteligence(), LimitInt); //if(m_pPlayer->GetLimitInteligence() < LimitInt) return false; //return true; } BOOL CEquipmentSlotContainer::ValidLimitSpr(SCItemSlot& item_slot) { BASE_ITEMINFO* pInfo = item_slot.GetItemInfo(); WORD LimitSpr = pInfo->m_wLimitSpr; if(0 == LimitSpr) return true; //µð¹ÙÀÎ? if(item_slot.IsDivine()) { //LimitSpr = CalcLimitIntForDivineWeapon(LimitSpr, m_pPlayer->GetCharType(), (eITEMTYPE)pInfo->m_wType); LimitSpr = pInfo->m_wDivLimitSpr; } //¸®¹ÌƼµå? if(item_slot.IsLimited()) { INT Ratio = 0; Ratio = item_slot.GetLimitValueRatio(); float fValue = 0; if(Ratio >= 0) fValue = 0.5f + 0.001f;//FLT_EPSILON; else fValue = -0.5f - 0.001f;//FLT_EPSILON; fValue = LimitSpr + ((float)Ratio * (float)LimitSpr) / 100.0f + fValue; LimitSpr = (WORD)fValue; } LimitSpr = CalcLimitStat(LimitSpr, item_slot, pInfo->IsWeapon(), pInfo->IsArmor()); // ½ºÅÈ Á¦ÇÑ return ValidLimitAll(m_pPlayer->GetLimitSpirit(), LimitSpr); //if(m_pPlayer->GetLimitSpirit() < LimitSpr) return false; //return true; } BOOL CEquipmentSlotContainer::ValidLimitLevel(SCItemSlot& item_slot) { BASE_ITEMINFO* pInfo = item_slot.GetItemInfo(); WORD LimitLV = pInfo->m_LimitEqLevel; if(0 == LimitLV) return true; //if(item_slot.GetItemInfo()->IsAccessory()) //{ // LimitLV = CalcLimitLVAccessory(LimitLV, item_slot.GetRank()); //} if(item_slot.IsLimited()) { INT Ratio = 0; Ratio = item_slot.GetLimitValueRatio(); float fValue = 0; if(Ratio >= 0) fValue = 0.5f + 0.001f;//FLT_EPSILON; else fValue = -0.5f - 0.001f;//FLT_EPSILON; fValue = LimitLV + ((float)Ratio * (float)LimitLV) / 100.0f + fValue; LimitLV = (WORD)fValue; } // ·¹º§ Á¦ÇÑ if(m_pPlayer->GetLevel() < LimitLV) return false; return true; } BOOL CEquipmentSlotContainer::ValidLimitSKill1(SCItemSlot& item_slot) { BASE_ITEMINFO* pInfo = item_slot.GetItemInfo(); WORD LimitSkill = pInfo->m_wLimitSkil1; if(0 == LimitSkill) return true; //µð¹ÙÀÎ? if(item_slot.IsDivine()) { LimitSkill = pInfo->m_wDivLimitSkill1; } //¸®¹ÌƼµå? if(item_slot.IsLimited()) { INT Ratio = 0; Ratio = item_slot.GetLimitValueRatio(); float fValue = 0; if(Ratio >= 0) fValue = 0.5f + 0.001f;//FLT_EPSILON; else fValue = -0.5f - 0.001f;//FLT_EPSILON; fValue = LimitSkill + ((float)Ratio * (float)LimitSkill) / 100.0f + fValue; LimitSkill = (WORD)fValue; } LimitSkill = CalcLimitStat(LimitSkill, item_slot, pInfo->IsWeapon(), pInfo->IsArmor()); // ½ºÅÈ Á¦ÇÑ return ValidLimitAll(m_pPlayer->GetLimitExperty1(), LimitSkill); //if(m_pPlayer->GetLimitExperty1() < LimitSkill) return false; //return true; } BOOL CEquipmentSlotContainer::ValidLimitSKill2(SCItemSlot& item_slot) { BASE_ITEMINFO* pInfo = item_slot.GetItemInfo(); WORD LimitSkill = pInfo->m_wLimitSkil2; if(0 == LimitSkill) return true; //µð¹ÙÀÎ? if(item_slot.IsDivine()) { LimitSkill = pInfo->m_wDivLimitSkill2; } //¸®¹ÌƼµå? if(item_slot.IsLimited()) { INT Ratio = 0; Ratio = item_slot.GetLimitValueRatio(); float fValue = 0; if(Ratio >= 0) fValue = 0.5f + 0.001f;//FLT_EPSILON; else fValue = -0.5f - 0.001f;//FLT_EPSILON; fValue = LimitSkill + ((float)Ratio * (float)LimitSkill) / 100.0f + fValue; LimitSkill = (WORD)fValue; } LimitSkill = CalcLimitStat(LimitSkill, item_slot, pInfo->IsWeapon(), pInfo->IsArmor()); // ½ºÅÈ Á¦ÇÑ return ValidLimitAll(m_pPlayer->GetLimitExperty2(), LimitSkill); //if(m_pPlayer->GetLimitExperty2() < LimitSkill) return false; //return true; } VOID CEquipmentSlotContainer::CheckupActiveEquipItemAll() { // (CHANGES) initalized ZeroMemory(m_bRealEquip, sizeof(m_bRealEquip)); ItemAttrCalculator itemCalc(m_pPlayer->GetPlayerAttr(), *this); itemCalc.Clear(); m_pPlayer->GetItemManager()->UpdateAttrInventory(); itemCalc.SetCalcTypeSetItemCount(true); m_mapEquipCount.clear(); m_mapEquipTypeCount.clear(); m_mapEquipGroupCount.clear(); BOOLEAN need_apply_pc_benefit = m_pPlayer->CanApplyPCBangBenefit(true); POSTYPE itr_pos = 0; const POSTYPE maxSlotNum = GetMaxSlotNum(); while(itr_pos < maxSlotNum) { if(m_bRealEquip[itr_pos] || IsEmpty(itr_pos)) { ++itr_pos; continue; } SCItemSlot& itr_slot = static_cast(GetSlot(itr_pos)); // ½ÇÁ¦ Âø¿ëÇϰí ÀÖÀ¸¸é¼­ ´É·ÂÄ¡µµ Àû¿ëµÇ´Â ³ð if(CanEquip(itr_pos, itr_slot, false)) { m_bRealEquip[itr_pos] = true; BOOL bFullOption = false; itemCalc.Equip(itr_slot, need_apply_pc_benefit, true, bFullOption); itr_pos = 0; continue; } ++itr_pos; } // ½ÇÁ¦ Âø¿ëÀº Çϰí ÀÖÀ¸³ª ´É·ÂÄ¡´Â Àû¿ë ¾ÈµÇ´Â ³ð for(POSTYPE itr_pos = 0; itr_pos < maxSlotNum; ++itr_pos) { if(!IsEmpty(itr_pos)) { SCItemSlot& itr_slot = static_cast(GetSlot(itr_pos)); IncEquipCount(itr_slot.GetItemCode()); } } } void CEquipmentSlotContainer::OnInsert(SCSlot& IN rSlot) { if (nsSlot::ItemManagerUpdateImpl* const item_updater_impl = m_pPlayer->GetItemManager()->GetUpdaterImpl()) { item_updater_impl->AddExpirationItem(static_cast(rSlot)); } // ÀåÂø °³¼ö Áõ°¡ IncEquipCount(static_cast(rSlot).GetItemCode()); } void CEquipmentSlotContainer::OnDelete(SCSlot& IN rSlot) { if (nsSlot::ItemManagerUpdateImpl* const item_updater_impl = m_pPlayer->GetItemManager()->GetUpdaterImpl()) { item_updater_impl->RemoveExpirationItem(static_cast(rSlot)); } // ÀåÂø °³¼ö °¨¼Ò DecEquipCount(static_cast(rSlot).GetItemCode()); } int CEquipmentSlotContainer::GetEquipCount(SLOTCODE item_code) { HASHMAP_EQUIP_COUNT_ITR it = m_mapEquipCount.find(item_code); if(it != m_mapEquipCount.end()) return it->second; return 0; } VOID CEquipmentSlotContainer::IncEquipCount(SLOTCODE item_code) { HASHMAP_EQUIP_COUNT_ITR it = m_mapEquipCount.find(item_code); if(it != m_mapEquipCount.end()) { it->second += 1; } else { m_mapEquipCount.insert(HASHMAP_EQUIP_COUNT_PAIR(item_code, 1)); } const BASE_ITEMINFO* pItemInfo = ItemInfoParser::Instance()->GetItemInfo(item_code); if(pItemInfo == NULL) { ASSERT(false); return; } IncEquipTypeCount((eITEMTYPE)pItemInfo->m_wType); IncEquipGroupCount((eITEMTYPE)pItemInfo->m_byDupEquipGroup); } VOID CEquipmentSlotContainer::DecEquipCount(SLOTCODE item_code) { HASHMAP_EQUIP_COUNT_ITR it = m_mapEquipCount.find(item_code); if(it != m_mapEquipCount.end()) { if(it->second <= 1) m_mapEquipCount.erase(item_code); else it->second -= 1; } else { SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] item_code[%d] Can't Remove EquipCount", item_code); } const BASE_ITEMINFO* pItemInfo = ItemInfoParser::Instance()->GetItemInfo(item_code); if(pItemInfo == NULL) { ASSERT(false); return; } DecEquipTypeCount((eITEMTYPE)pItemInfo->m_wType); DecEquipGroupCount((eITEMTYPE)pItemInfo->m_byDupEquipGroup); } int CEquipmentSlotContainer::GetEquipTypeCount(eITEMTYPE item_type) { HASHMAP_EQUIP_TYPE_COUNT_ITR it = m_mapEquipTypeCount.find(item_type); if(it != m_mapEquipTypeCount.end()) return it->second; return 0; } VOID CEquipmentSlotContainer::IncEquipTypeCount(eITEMTYPE item_type) { HASHMAP_EQUIP_TYPE_COUNT_ITR itr = m_mapEquipTypeCount.find(item_type); if(itr != m_mapEquipTypeCount.end()) { itr->second += 1; } else { m_mapEquipTypeCount.insert(HASHMAP_EQUIP_TYPE_COUNT_PAIR(item_type, 1)); } } VOID CEquipmentSlotContainer::DecEquipTypeCount(eITEMTYPE item_type) { HASHMAP_EQUIP_TYPE_COUNT_ITR itr = m_mapEquipTypeCount.find(item_type); if(itr != m_mapEquipTypeCount.end()) { if(itr->second <= 1) m_mapEquipTypeCount.erase(item_type); else itr->second -= 1; } else { SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] item_code[%d] Can't Remove EquipTypeCount", item_type); } } //±×·ìº° ÀåÂø °³¼ö Á¦ÇÑ °ü¸® // (NOTE) it has not the usage case at this point in time (100505) int CEquipmentSlotContainer::GetEquipGroupCount(BYTE byEquipGroup) { EQUIP_GROUP_COUNT_MAP_ITER it = m_mapEquipGroupCount.find(byEquipGroup); if(it != m_mapEquipGroupCount.end()) return it->second; return 0; } VOID CEquipmentSlotContainer::IncEquipGroupCount(BYTE byEquipGroup) { EQUIP_GROUP_COUNT_MAP_ITER itr = m_mapEquipGroupCount.find(byEquipGroup); if(itr != m_mapEquipGroupCount.end()) { itr->second += 1; } else { m_mapEquipGroupCount.insert(std::make_pair(byEquipGroup, 1)); } } VOID CEquipmentSlotContainer::DecEquipGroupCount(BYTE byEquipGroup) { EQUIP_GROUP_COUNT_MAP_ITER itr = m_mapEquipGroupCount.find(byEquipGroup); if(itr != m_mapEquipGroupCount.end()) { if(itr->second <= 1) m_mapEquipGroupCount.erase(byEquipGroup); else itr->second -= 1; } else { SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] GroupCode[%d] Can't Remove EquipGroupCount", byEquipGroup); } } VOID CEquipmentSlotContainer::SendSetItemBrd(BOOL bFullOption) { if(!m_pPlayer) return; MSG_CG_ITEM_SETITEM_CHANGE_BRD Brd; Brd.m_PlayerKey = (PLAYERKEY)m_pPlayer->GetObjectKey(); Brd.m_bFull = bFullOption; m_pPlayer->SendPacketAround(&Brd, sizeof(Brd), false); } //_NA_0_20100722_AUTO_SYSTEM POSTYPE CEquipmentSlotContainer::GetPosEquipByItemType(eITEMTYPE type, POSTYPE start, POSTYPE end) { ASSERT(start < end); ASSERT(end <= eEQUIPCONTAINER_MAX); const POSTYPE maxSlotNum = GetMaxSlotNum(); for(POSTYPE itr_pos = start; itr_pos < end ; ++itr_pos) { if(!IsEmpty(itr_pos)) { SCItemSlot& item_slot = static_cast(GetSlot(itr_pos)); if (type == item_slot.GetItemInfo()->m_wType) return itr_pos; } } return eEQUIPCONTAINER_INVALID; } BOOL CEquipmentSlotContainer::IsEquipEventItem(BYTE byEventCode) { const POSTYPE maxSlotNum = GetMaxSlotNum(); for(POSTYPE itr_pos = 0; itr_pos < maxSlotNum ; ++itr_pos) { if(!IsEmpty(itr_pos)) { SCItemSlot& item_slot = static_cast(GetSlot(itr_pos)); if(byEventCode == item_slot.GetItemInfo()->m_byEventCode) return TRUE; } } return FALSE; } //================================================================================================== // CHANGES: f110420.5L, constant information is added whether this item is renderable equipment. bool CEquipmentSlotContainer::IsDefaultRenderableEquipItem(POSTYPE pos) { switch (pos) { case eEQUIPCONTAINER_WEAPON: case eEQUIPCONTAINER_ARMOR: case eEQUIPCONTAINER_PROTECTOR: //< ¿¤¸®Æ® ¾ÆÀÌÅÛ Ç®¼ÂÀÏ °æ¿ì È¿°ú Ãß°¡ (2007.08.03 - ±èâÇö, Àüº¸È¯) case eEQUIPCONTAINER_HELMET: case eEQUIPCONTAINER_PANTS: case eEQUIPCONTAINER_BOOTS: case eEQUIPCONTAINER_GLOVE: case eEQUIPCONTAINER_SACCESSORY1: case eEQUIPCONTAINER_SACCESSORY2: case eEQUIPCONTAINER_SACCESSORY3: case eEQUIPCONTAINER_BELT: //< ¿¤¸®Æ® ¾ÆÀÌÅÛ Ç®¼ÂÀÏ °æ¿ì È¿°ú Ãß°¡ case eEQUIPCONTAINER_SHIRTS: //< ¿¤¸®Æ® ¾ÆÀÌÅÛ Ç®¼ÂÀÏ °æ¿ì È¿°ú Ãß°¡ //case eEQUIPCONTAINER_CAPE: //< ÇöÀç Ãß°¡ ¾ÈµÊ case eEQUIPCONTAINER_CHARGE1: case eEQUIPCONTAINER_CHARGE2: case eEQUIPCONTAINER_CHARGE3: case eEQUIPCONTAINER_CHARGE4: case eEQUIPCONTAINER_CHARGE5: return true; //case eEQUIPCONTAINER_PROTECTOR: //case eEQUIPCONTAINER_BELT: //case eEQUIPCONTAINER_SHIRTS: case eEQUIPCONTAINER_RING1: case eEQUIPCONTAINER_RING2: case eEQUIPCONTAINER_NECKLACE: case eEQUIPCONTAINER_PC_ROOM1: case eEQUIPCONTAINER_PC_ROOM2: case eEQUIPCONTAINER_PC_ROOM3: return false; }; return false; } //================================================================================================== #endif //_NA_002289_20110322_EQUIPMENTS_CALCULATOR_CHANGES_FOR_IMPROVEMENT