#include "StdAfx.h" #include "DropFormulaCore.h" #include "DropItemRatioCalc.h" #include #include #include DropFormulaCore::DropFormulaCore(void) { m_pItemDropRatio = new DropItemRatioCalc; } DropFormulaCore::~DropFormulaCore(void) { SAFE_RELEASENDELETE(m_pItemDropRatio); } VOID DropFormulaCore::_InitRatio() { BOOL rt = FALSE; // µå¶ø È®·ü ¼±Åñâ for( int Grade = eNPC_GENERAL ; Grade < eNPC_GRADE_MAX ; ++Grade ) { for( int num = 1 ; num < MAX_PARTYMEMBER_NUM+1 ; ++num ) { m_DropRatioSelecter[Grade][num].Clear(); for( int Step = 0 ; Step < MAX_DROP_ITEM_STEP_NUM ; ++Step ) { DROP_ITEM_RATIO * pInfo = m_ItemDropParser.GetDropItemRatio( (eNPC_GRADE)Grade, Step ); DWORD StandardAmount = pInfo->m_DropStandardAmount; DWORD Amount = pInfo->m_DropAmount[num]; if( 0 == StandardAmount || 0 == Amount ) continue; ASSERT( pInfo->m_Index <= DROP_ITEM_10 ); rt = m_DropRatioSelecter[Grade][num].AddRatio( pInfo->m_Index, Amount, StandardAmount ); ASSERT(rt); } rt = m_DropRatioSelecter[Grade][num].AddRatio( DROP_RARE_ITEM, 100000, 1000000 ); ASSERT(rt); } } // ·¹¾î ¾ÆÀÌÅÛ È®·ü ¼±Åñâ // °¡Á¤ m_bPrior == 0 ÀΰÍÀº key°¡ 0À̾î¾ß ÇÑ´Ù. // ·¹º§»çÀÌÀÇ °£°ÝÀÌ ºó°÷ÀÌ ¾ø¾î¾ß ÇÑ´Ù. memset( m_Section, 0, sizeof(BYTE)*MAX_LEVEL_STEP_NUM ); for( int LVStep = 0 ; LVStep < MAX_LEVEL_STEP_NUM ; ++LVStep ) { RAREITEM_DROP_INFO * pTmpInfo = m_RareItemDropParser.GetRareItemDropInfo(LVStep, (eNPC_GRADE)1, 1); m_Section[LVStep] = pTmpInfo->m_MaxLV; for( int Grade = eNPC_GENERAL ; Grade < eNPC_GRADE_MAX ; ++Grade ) { for( int num = 1 ; num < MAX_PARTYMEMBER_NUM+1 ; ++num ) { m_RareItemDropRatioSelecter[LVStep][Grade][num].Clear(); for( int ele = 1 ; ele < MAX_ELEMENT_PER_LEVEL_NUM ; ++ele ) { RAREITEM_DROP_INFO * pInfo = m_RareItemDropParser.GetRareItemDropInfo(LVStep, (eNPC_GRADE)Grade, ele); ASSERT(pInfo); if( !pInfo ) continue; if( 0 == pInfo->m_StandardAmount || 0 == pInfo->m_ItemCode || 0 == pInfo->m_Amount[num] ) continue; ASSERT( pInfo->m_bPrior ); BOOL rt = m_RareItemDropRatioSelecter[LVStep][Grade][num].AddRatio( ele, pInfo->m_Amount[num], pInfo->m_StandardAmount ); ASSERT(rt); } } } } /* SUNLOG( eFULL_LOG, ""); for( int i = 0 ; i < 40 ; ++i ) { for( int i = 0 ; i < 20 ; ++i ) { INT Index = m_RareItemDropRatioSelecter[1][eNPC_GENERAL][1].RandomizedKey(); RAREITEM_DROP_INFO * pInfo = m_RareItemDropParser.GetRareItemDropInfo( 1, eNPC_GENERAL, Index ); if( !pInfo ) continue; SLOTCODE Code = pInfo->m_ItemCode; SUNLOG( eFULL_LOG, "%d\t", Code); } SUNLOG( eFULL_LOG, ""); } */ } VOID DropFormulaCore::Reload() { m_ItemDropParser.Reload(); m_RareItemDropParser.Reload(); m_pItemDropRatio->Reload(); _InitRatio(); m_fPlusScriptPercent = FormulaRatioParser::Instance()->GetFormulaRatio(RATIO_TYPE_DROP)->m_fRatio; } // ItemDropPerGrade.txt, VOID DropFormulaCore::Init( TCHAR * tszItemDropPerGradeFile, TCHAR * tszItemDropInfoFile, TCHAR * tszRareItemDropInfoFile ) { BOOL rt = m_ItemDropParser.Load( tszItemDropInfoFile ); ASSERT(rt); rt = m_RareItemDropParser.Load( tszRareItemDropInfoFile ); ASSERT(rt); m_pItemDropRatio->Init(tszItemDropPerGradeFile); _InitRatio(); m_fPlusScriptPercent = FormulaRatioParser::Instance()->GetFormulaRatio(RATIO_TYPE_DROP)->m_fRatio; } BOOL DropFormulaCore::Drop( DWORD PlayerNum, eNPC_GRADE MonsterGrade, LEVELTYPE MonsterDisplayLV, FLOAT fBonusPercent, LEVELTYPE LVAverage, eDROP_TYPE & OUT DropTypeOut, MONEY & OUT rDroppedMoneyOut, SCItemSlot & OUT rDroppedItemSlotOut ) { DropTypeOut = (eDROP_TYPE)m_DropRatioSelecter[MonsterGrade][PlayerNum].RandomizedKey(); switch(DropTypeOut) { case DROP_MONEY_1: case DROP_MONEY_40: case DROP_MONEY_400: return DropMoneyFunc( fBonusPercent, LVAverage, DropTypeOut, MonsterGrade, MonsterDisplayLV, rDroppedMoneyOut ); case DROP_ITEM_0: case DROP_ITEM_1: case DROP_ITEM_2: case DROP_ITEM_3: case DROP_ITEM_4: case DROP_ITEM_5: case DROP_ITEM_6: case DROP_ITEM_7: case DROP_ITEM_8: case DROP_ITEM_9: case DROP_ITEM_10: return DropItemFunc( DropTypeOut, MonsterDisplayLV, rDroppedItemSlotOut ); case DROP_RARE_ITEM: return DropRareItemFunc( PlayerNum, MonsterGrade, MonsterDisplayLV, rDroppedItemSlotOut ); } return FALSE; } BOOL DropFormulaCore::AdditionalItemDrop( BOOL IsItemDrop, INT MaxArrayNum, WORD * pDropItemRate, WORD * pDropItemCode, SCItemSlot & OUT rDroppedItemSlotOut ) { // Ãß°¡ÀûÀÎ »óÀ§ ¸ó½ºÅÍ ¾ÆÀÌÅÛ µå¶ø if( IsItemDrop ) { return DropHigherMonsterItemFunc( MaxArrayNum, pDropItemRate, pDropItemCode, rDroppedItemSlotOut ); } return FALSE; } //--------------------------------------------------------------------------------------------------------------------------------- // µ· µå¶ø //--------------------------------------------------------------------------------------------------------------------------------- BOOL DropFormulaCore::DropMoneyFunc( FLOAT fBonusPercent, LEVELTYPE LVAverage, eDROP_TYPE DropType, eNPC_GRADE MonsterGrade, LEVELTYPE MonsterDisplayLV, MONEY & OUT rDropMoney ) { // Ãß°¡ ¹èÀ² FLOAT PlusScriptPercent = m_fPlusScriptPercent; FLOAT PlusBonusPercent = 1.0f; FLOAT PlusGradePercent = 1.0f; // µî±Þ¿¡ µû¸¥ °¡ÁßÄ¡ switch(MonsterGrade) { case eNPC_GENERAL: PlusGradePercent = 1.0f; break; case eNPC_LEADER: PlusGradePercent = 1.1f; break; case eNPC_ELITE: PlusGradePercent = 1.3f; break; case eNPC_MIDDLEBOSS: PlusGradePercent = 1.5f; break; case eNPC_BOSS: PlusGradePercent = 2.0f; break; default: { /*SASSERT( NULL, "À߸øµÈ ¸ó½ºÅÍ µî±ÞÀÔ´Ï´Ù." );*/ return FALSE; } } // µ· ¾×¼ö °è»ê MONEY SeedMoney = (MONEY)(MonsterDisplayLV*MonsterDisplayLV*6/LVAverage*PlusGradePercent*PlusBonusPercent*PlusScriptPercent); MONEY Seed = SeedMoney/4; MONEY MinSeed = SeedMoney - Seed; if(MinSeed == 0) return FALSE; MONEY MaxSeed = SeedMoney + Seed; MONEY RealMoney = (MONEY)dRandom( MinSeed, MaxSeed ); if(RealMoney == 0) return FALSE; // ¾¾µå ¹è¼ö¿¡ µû¸¥ DROP WORD SeedMultiple = 0; switch(DropType) { case DROP_MONEY_1: SeedMultiple = random(1,3); break; case DROP_MONEY_40: SeedMultiple = random(40,60); break; case DROP_MONEY_400: SeedMultiple = random(400,600); break; default: { // SUNLOG( eFULL_LOG, "[DropFormulaCore::DropMoneyFunc] À߸øµÈ DROPTYPE ÀÌ ³Ñ¾î¿Ô´Ù!" ); return FALSE; } } RealMoney *= SeedMultiple; rDropMoney = RealMoney; return TRUE; } //--------------------------------------------------------------------------------------------------------------------------------- // ±âº» ¸ó½ºÅÍ ¾ÆÀÌÅÛ µå¶ø //--------------------------------------------------------------------------------------------------------------------------------- BOOL DropFormulaCore::DropItemFunc( eDROP_TYPE DropType, LEVELTYPE MonsterDisplayLV, SCItemSlot & OUT rDropItemSlot ) { // -5 <= LVInterval <= 5 // DROP_ITEM_0 ~ DROP_ITEM_11 : ¾ÈÁÁÀº ¾ÆÀÌÅÛ ~ ÁÁÀº ¾ÆÀÌÅÛ INT LVInterval = DropType - DROP_ITEM_0 - 5; INT DropItemLV = MonsterDisplayLV + LVInterval; // ¶³¾î ¶ß¸®Áö ¾Ê´Â´Ù. if( DropItemLV <= 0 ) return FALSE; if( DropItemLV >= MAX_LEVEL ) { //SUNLOG( eFULL_LOG, "[DropFormulaCore::DropItemFunc] MAX Drop LevelÀ» ³Ñ¾î¼¹´Ù." ); return FALSE; } DropItemInfo * rDropItem = m_pItemDropRatio->PopRandomDropItemForLevel( (LEVELTYPE)DropItemLV ); if( !rDropItem ) return FALSE; rDropItemSlot.Clear(); rDropItemSlot.SetCode( rDropItem->GetCode() ); rDropItemSlot.SetEnchant( rDropItem->GetEnchant() ); rDropItemSlot.SetRank( rDropItem->GetRank() ); rDropItemSlot.SetSet( rDropItem->GetSet() ); // TEMP : ³»±¸µµ ÀÓ½Ã!!!!! if( rDropItemSlot.IsOverlap() ) rDropItemSlot.SetDura(1); else rDropItemSlot.SetDura(0); return TRUE; } //--------------------------------------------------------------------------------------------------------------------------------- // ·¹¾î ¾ÆÀÌÅÛ µå¶ø //--------------------------------------------------------------------------------------------------------------------------------- BOOL DropFormulaCore::DropRareItemFunc( DWORD PlayerNum, eNPC_GRADE MonsterGrade, LEVELTYPE MonsterDisplayLV, SCItemSlot & OUT rDropItemSlot ) { ASSERT( MonsterDisplayLV > 0 ); ASSERT( PlayerNum <= MAX_PARTYMEMBER_NUM ); // ·¹º§º° ±¸°£ ¼±Åà INT FromPercent = 0; INT ToPercent = 0; LEVELTYPE LVStep = 0; for( LEVELTYPE i = 0 ; i < MAX_LEVEL_STEP_NUM ; ++i ) { FromPercent = ToPercent; ToPercent += m_Section[i]; if(FromPercent <= MonsterDisplayLV && MonsterDisplayLV < ToPercent) { LVStep = i; break; } } // ±¸°£¾È¿¡¼­ È®·ü ¼±Åà INT Index = m_RareItemDropRatioSelecter[LVStep][MonsterGrade][PlayerNum].RandomizedKey(); RAREITEM_DROP_INFO * pInfo = m_RareItemDropParser.GetRareItemDropInfo( LVStep, MonsterGrade, Index ); if( !pInfo ) return FALSE; DEBUG_CODE( if(Index==0) ASSERT( pInfo->m_bPrior == FALSE ); ); rDropItemSlot.Clear(); rDropItemSlot.SetCode( pInfo->m_ItemCode ); if( rDropItemSlot.IsOverlap() ) rDropItemSlot.SetDura(1); else rDropItemSlot.SetDura(0); return TRUE; } //--------------------------------------------------------------------------------------------------------------------------------- // »óÀ§ ¸ó½ºÅÍ ¾ÆÀÌÅÛ µå¶ø //--------------------------------------------------------------------------------------------------------------------------------- BOOL DropFormulaCore::DropHigherMonsterItemFunc( INT MaxArrayNum, WORD * pDropItemRate, WORD * pDropItemCode, SCItemSlot & OUT rDropItemSlot ) { if( MaxArrayNum <= 0) return FALSE; if( !pDropItemRate || !pDropItemCode ) return FALSE; ASSERT( !IsBadReadPtr( pDropItemRate, sizeof(WORD)*MaxArrayNum ) ); ASSERT( !IsBadReadPtr( pDropItemCode, sizeof(WORD)*MaxArrayNum ) ); BOOL bDrop = FALSE; INT FromPercent = 0; INT ToPercent = 0; INT seed = random( 0, MAX_HIGHER_MONSTER_ITEM_DROP_UNIT ); for( INT i = 0 ; i < MaxArrayNum ; ++i ) { FromPercent = ToPercent; ToPercent += pDropItemRate[i]; if(FromPercent <= seed && seed < ToPercent) { bDrop = TRUE; break; } } if( bDrop ) { rDropItemSlot.Clear(); rDropItemSlot.SetCode( pDropItemCode[i] ); if( rDropItemSlot.IsOverlap() ) rDropItemSlot.SetDura(1); else rDropItemSlot.SetDura(0); } return bDrop; }