コード例 #1
0
bool CDropManager::dropItem(CPC* _pPC, CNPC* _pNPC, CDropItemData * _pDropItem, bool _bPreferenceIndex)
{
	CItem* pItem = gserver->m_itemProtoList.CreateItem(
					   _pDropItem->getIndex(), -1 , _pDropItem->getPlus(), _pDropItem->getFlag(), _pDropItem->getCount() );

	if (!pItem)
	{
		GAMELOG << init("DROP_SYSTEM ITEM DROP FAILD", _pPC)
				<< _pDropItem->getIndex()	<< delim
				<< _pDropItem->getPlus()		<< delim
				<< _pDropItem->getFlag()		<< delim
				<< _pDropItem->getCount()
				<< end;
		return false;
	}

	if( _bPreferenceIndex )
		pItem->m_preferenceIndex = _pPC->m_index;

	if( _pDropItem && _pDropItem->getIndex() == NAS_ITEM_DB_INDEX)
	{
		//돈일 경우 돈 메시지 전송
		GoldType_t moneyCount = _pDropItem->getCount();

		_pPC->m_inventory.increaseMoney(moneyCount);
		GAMELOG << init("DROP_SYSTEM ITEM NAS INPUT SUCC", _pPC) << moneyCount << end;
	}
	else
	{
		CNetMsg::SP rmsg(new CNetMsg);
		_pNPC->m_pArea->DropItem(pItem, (CCharacter*)_pNPC);
		ItemDropMsg(rmsg, (CCharacter*)_pNPC, pItem);
		pItem->m_pArea->SendToCell(rmsg, GET_YLAYER(pItem), pItem->m_cellX, pItem->m_cellZ);
		GAMELOG << init("DROP_SYSTEM ITEM DROP SUCC", _pPC) << itemlog(pItem) << end;
	}
	return true;
}
コード例 #2
0
void do_GMItemDrop(CPC *a1, char *a2)
{
    COptionProto *j; // [sp+4Ch] [bp-2Ch]@33
    CItem *v28; // [sp+54h] [bp-24h]@15
    int *v29; // [sp+58h] [bp-20h]@1
    int *v30; // [sp+5Ch] [bp-1Ch]@1
    int v31; // [sp+60h] [bp-18h]@1
    long long v32; // [sp+64h] [bp-14h]@13
    int v33; // [sp+6Ch] [bp-Ch]@10
    int v34; // [sp+70h] [bp-8h]@7
    int v35; // [sp+74h] [bp-4h]@4
    char *v36; // [sp+84h] [bp+Ch]@4
    char *v37; // [sp+84h] [bp+Ch]@7
    char *v38; // [sp+84h] [bp+Ch]@10
    char *v39; // [sp+84h] [bp+Ch]@13
    char *v40; // [sp+84h] [bp+Ch]@18
    char *v41; // [sp+84h] [bp+Ch]@25

    v31 = 0;
    v30 = 0;
    v29 = 0;
    if(a2)
    {
        if(*a2)
        {
            v36 = AnyOneArg(a2, g_buf, 0);
            v35 = atoi(g_buf);
            if(v36)
            {
                if(*v36)
                {
                    v37 = AnyOneArg(v36, g_buf, 0);
                    v34 = atoi(g_buf);
                    if(v37)
                    {
                        if(*v37)
                        {
                            v38 = AnyOneArg(v37, g_buf, 0);
                            v33 = atoi(g_buf);
                            if(v38)
                            {
                                if(*v38)
                                {
                                    v39 = AnyOneArg(v38, g_buf, 0);
                                    v32 = atoll(g_buf);

                                    if(!v32)
                                        v32 = 1;

                                    v28 = a1->Unk412->DropItem(v35, a1, v34, v33, v32, 0);
                                    if(v28)
                                    {
                                        if(v39)
                                        {
                                            if(*v39)
                                            {
                                                v40 = AnyOneArg(v39, g_buf, 0);
                                                v31 = atoi(g_buf);
                                                if(v31 > 0 || v31 <= 5)
                                                {
                                                    v30 = (int *)malloc(4 * v31);
                                                    v29 = (int *)malloc(4 * v31);

                                                    for(int i = 0; i < v31; ++i)
                                                    {
                                                        if(!v40 || !*v40 || (v41 = AnyOneArg(v40, g_buf, 0), v30[i] = atoi(g_buf), !v41) || !*v41)
                                                            return;

                                                        v40 = AnyOneArg(v41, g_buf, 0);
                                                        v29[i] = atoi(g_buf);

                                                        if(v30[i] >= 0 && v30[i] <= 35 && v29[i] > 0 && v29[i] <= 6)
                                                        {
                                                            j = gserver.Unk452236.FindProto(v30[i]);
                                                            if(j)
                                                            {
                                                                v28->Unk68[i].Unk0  = j;
                                                                v28->Unk68[i].Unk4  = v30[i];
                                                                v28->Unk68[i].Unk8  = v29[i];
                                                                v28->Unk68[i].Unk12 = j->Unk8[v29[i]-1];
                                                                v28->Unk68[i].SetDBValue();

                                                                ++v28->Unk168;
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        CNetMsg v25;

                                        ItemDropMsg(v25, a1, v28);
                                        a1->Unk412->SendToCell(v25, a1, 1, 4);

                                        g_gamelogbuffer.__ls(init("ITEM_LOAD", a1->Unk8));
                                        g_gamelogbuffer.__ls(v28->Unk28);
                                        g_gamelogbuffer.__ls(delim);
                                        g_gamelogbuffer.__ls(v28->Unk44);
                                        g_gamelogbuffer.__ls(delim);
                                        g_gamelogbuffer.__ls(v28->Unk36);
                                        g_gamelogbuffer.__ls(delim);
                                        g_gamelogbuffer.__ls(v28->Unk40);
                                        g_gamelogbuffer.__ls(delim);
                                        g_gamelogbuffer.__ls(v28->Count());
                                        g_gamelogbuffer.__ls(delim);
                                        g_gamelogbuffer.__ls(v28->Unk168);

                                        for(int j_1 = 0; j_1 < v31; j_1++)
                                        {
                                            g_gamelogbuffer.__ls(delim);
                                            g_gamelogbuffer.__ls(v30[j_1]);
                                            g_gamelogbuffer.__ls(delim);
                                            g_gamelogbuffer.__ls(v29[j_1]);
                                        }

                                        g_gamelogbuffer.__ls(end);

                                        if(v30 && v30)
                                            delete v30;

                                        if(v29 && v29)
                                            delete v29;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
コード例 #3
0
void ProcDropItemAfterBattle(CNPC* df, CPC* opc, CPC* tpc, int level)
{
	if(df->m_pZone->IsComboZone())
	{
		DropComboGiftMob(df, opc, tpc, level);
		return ;
	}

#ifdef SYSTEM_TREASURE_MAP
	if( df->m_idNum == TREASURE_BOX_NPC_INDEX ) // npc 일경우 보물 상자만 드랍 한다.
	{
		DropTreasureBoxNpc(df, opc, tpc, level);
		return;
	}

	// 보물 지도는 필드에서만 드랍된다.
	if( df->m_pZone->CheckTreasureDropFlag() && df->m_pZone->IsFieldZone() )
	{
		DropTreasureMap(df, opc, tpc, level);
	}
#endif

	// 아이템 드롭율 증폭제 검사
	bool hcSepDrop = false;
	bool hcDropPlus_S360 = false;
	bool hcPlatinumDrop = false;

	if (opc && tpc == opc)
	{
		if (opc->m_assist.m_avAddition.hcSepDrop)
		{
			opc->m_assist.CureByItemIndex(884);	// 아이템
			hcSepDrop = true;
			CNetMsg::SP rmsg(new CNetMsg);
			EventErrorMsg(rmsg, MSG_EVENT_ERROR_SEPTEMBER_DROP);
			SEND_Q(rmsg, opc->m_desc);
		}

		if (opc->m_assist.m_avAddition.hcSepDrop_Cash)
		{
			opc->m_assist.CureByItemIndex(6096);	// 아이템
			hcSepDrop = true;
			CNetMsg::SP rmsg(new CNetMsg);
			EventErrorMsg(rmsg, MSG_EVENT_ERROR_SEPTEMBER_DROP);
			SEND_Q(rmsg, opc->m_desc);
		}

		// 추천서버포션 드롭율 상승
		else if (opc->m_assist.m_avAddition.hcDropPlus_S360)
		{
			opc->m_assist.CureBySkillIndex(360);
			hcDropPlus_S360 = true;
		}
		else if(opc->m_assist.m_avAddition.hcPlatinumDrop)
		{
			opc->m_assist.CureByItemIndex(2855);	// 아이템
			hcPlatinumDrop = true;
		}
	} // 아이템 드롭율 증폭제 검사

	// 아이템 드롭
	int loopcount;
	bool IsNotDropInCube = true;
#ifdef EXTREME_CUBE
	if(df->m_bCubeRegen)
		IsNotDropInCube = false;
#endif // EXTREME_CUBE]

	int itemDropLoop = MAX_NPC_DROPITEM_LOOP;
#ifdef EVENT_WORLDCUP_2010
	if( df->m_proto->m_index == 1105 )
		itemDropLoop = 1;
#endif // #ifdef EVENT_WORLDCUP_2010

	for (loopcount = 0; loopcount < itemDropLoop; loopcount++)
	{
		// 5레벨보다 크면 아이템 드롭 없음
		// 1. 드롭할 수 있는 수 범위에서 아이템 선정
		// 2. 그 아이팀의 드롭확률로 드롭여부 결정
		// 3. 드롭
#ifdef EVENT_WORLDCUP_2010 // 트라이앵글 볼(1105) 일경우 무조건 아이템을 드랍 한다
		if( ( df->m_proto->m_itemCount > 0 &&  ((level != -1 && level - df->m_level <= 5) ||  !IsNotDropInCube) )
			|| df->m_proto->m_index == 1105)
#else
		if (df->m_proto->m_itemCount > 0 &&  ((level != -1 && level - df->m_level <= 5) ||  !IsNotDropInCube) )
#endif
		{
			CItem* dropItem = NULL;
			int tableindex;
#ifdef EVENT_WORLDCUP_2010
			if( df->m_proto->m_index == 1105 )
			{
				// npc툴 드랍 테이블1,2번에 각각 축국공, 황금 축구공이  100%g확률로 들어가 있어야 한다.
				tableindex = GetRandom(1, 10000); // 0. 95%확률로 축구공. 1. 5% 확률 황금 축구공 2. 꽝
				if( tableindex <= 9000 )
					tableindex = 0;
				else if( tableindex <= 9500)
					tableindex = 1;
				else
					tableindex = 2;
			}
			else
#endif
				tableindex = GetRandom(0, MAX_NPC_DROPITEM - 1);
			int dropprob = df->m_proto->m_itemPercent[tableindex];

			dropprob = dropprob * gserver->m_itemDropProb / 100;

			if (tpc)
			{
				// 자두
				if (tpc->m_assist.m_avAddition.hcDropPlus_838)
					dropprob *= 2;

				// 행운의스크롤, 5080강운의 스크롤과 변수를 같이 사용한다.
				if (tpc->m_assist.m_avAddition.hcScrollDrop)
					dropprob *= 2;

				if (tpc->m_assist.m_avAddition.hcScrollDrop_5081)
					dropprob *= 4;

				// 행운 주문서
				if (tpc->m_assist.m_avAddition.hcDropPlus_2141)
				{
					if (GetRandom(1, 10000) <= 2000 ) // 20 %
					{
						dropprob *= 2;
					}
				}

				// 플래티늄 행운의 스크롤
				if(tpc->m_assist.m_avAddition.hcPlatinumScroll)
				{
					dropprob *= 4;
				}
			}

			// BS 수정 : 아이템 드롭 이벤트
			dropprob = dropprob * gserver->m_nItemDropEventRate / 100;

			// 드롭율 상승 %단위 누적
			if (opc && tpc == opc && opc->m_assist.m_avAddition.hcDropPlusPer100 > 0)
				dropprob += dropprob * opc->m_assist.m_avAddition.hcDropPlusPer100 / 100;

#ifdef DOUBLE_ITEM_DROP
			if ( gserver->m_bDoubleItemEvent )
				dropprob += dropprob * gserver->m_bDoubleItemPercent / 100;
#endif // DOUBLE_ITEM_DROP

			// 9월 이벤트 드롭율 10배
			if (hcSepDrop)
				dropprob = dropprob * 10;

			// 추천서버포션 드롭율 상승
			else if (hcDropPlus_S360)
				dropprob = dropprob * 10;

			else if (hcPlatinumDrop)
				dropprob = dropprob * 20;

			if( opc && opc->m_assist.m_avAddition.hcRandomDropUp > 0  && GetRandom(0,100) <= opc->m_assist.m_avAddition.hcRandomDropUp )
			{
				dropprob = dropprob * 10;
				CNetMsg::SP rmsg(new CNetMsg);
				EffectEtcMsg(rmsg, opc, MSG_EFFECT_ETC_RANDOM_DROP);
				opc->m_pArea->SendToCell(rmsg, opc, true);
			}

			if( tpc )
			{
				if( gserver->isActiveEvent( A_EVENT_XMAS) )
				{
					if ( tpc->m_assist.m_avAddition.hcDropPlus_Xmas2007 > 0)
						dropprob += df->m_proto->m_itemPercent[tableindex] * tpc->m_assist.m_avAddition.hcDropPlus_Xmas2007;
				}
			}

#ifdef IMP_SPEED_SERVER
			// Zone Drop 률 적용
			if( gserver->m_bSpeedServer && tpc && tpc->m_pZone )
			{
				dropprob = dropprob * tpc->m_pZone->GetZoneDrop() / 100;
			}
#endif //IMP_SPEED_SERVER

			if (df->m_proto->m_item[tableindex] != -1 && GetRandom(1, 10000) <= dropprob)
			{
				if (df->m_proto->m_item[tableindex] == 84)
				{
					dropItem = df->m_pArea->DropItem(df->m_proto->m_item[tableindex], df, 0, df->m_level, 1);
				}
#if defined (LC_USA) || defined(LC_BILA)
				// 대만과 말레이시아는 중소형 체력약이 소형으로 떨어진다
				else if( df->m_proto->m_item[tableindex] == 44
						 || df->m_proto->m_item[tableindex] == 45 )
				{
					dropItem = df->m_pArea->DropItem(43, df, 0, 0, 1);
				}
				// 대만과 말레이시아는 중형 마나 회복 물약이 드롭되지 않는다.
				else if ( df->m_proto->m_item[tableindex] == 485 )
				{
					dropItem = NULL;
				}
#endif // #if defined (LC_USA) || defined(LC_BILA)
#if defined (LC_USA) || defined(LC_BILA)
				// 대형 힐링포션 제작서, 대형 마나, 중형 마나 메뉴얼 드롭 금지
				else if ( df->m_proto->m_item[tableindex] == 1066
						  || df->m_proto->m_item[tableindex] == 1067
						  || df->m_proto->m_item[tableindex] == 1068
						  || df->m_proto->m_item[tableindex] == 489)
				{
					dropItem = NULL;
				}
#endif // #if defined (LC_USA) || defined (LC_BILA)
				else
				{
					// 61레벨 무기류 및 65레벨 방어구 드롭 금지 제작서 드롭 금지
					switch (df->m_proto->m_item[tableindex])
					{
					case -1:	// 지우지 말것
						dropItem = NULL;
						break;

					default:
						{
							bool bAvailableDrop = true;
							if (bAvailableDrop)
								dropItem = df->m_pArea->DropItem(df->m_proto->m_item[tableindex], df, 0, 0, 1, true);
							else
								dropItem = NULL;
						}
						break;
					} // switch (df->m_proto->m_item[tableindex])
				}
			} // if (df->m_proto->m_item[tableindex] != -1 && GetRandom(1, 10000) <= dropprob)

			if (dropItem)
			{
// 050303 : bs : 몬스터에게서 plus 붙은 아이템 만들기
				if (df->m_proto->m_minplus >= 0 && df->m_proto->m_maxplus >= df->m_proto->m_minplus && df->m_proto->m_probplus > 0 && dropItem->CanUpgrade())
				{
					if (GetRandom(1, 10000) <= df->m_proto->m_probplus)
					{
						dropItem->setPlus(GetRandom(df->m_proto->m_minplus, df->m_proto->m_maxplus));
					}
				}

				// Drop Msg 보내기
				// 아이템 우선권 셋팅 (같은 데미지 고려, 선공 고려)
				if (tpc)
					dropItem->m_preferenceIndex = tpc->m_index;
				else
					dropItem->m_preferenceIndex = -1;

				{
					CNetMsg::SP rmsg(new CNetMsg);
					ItemDropMsg(rmsg, df, dropItem);
					df->m_pArea->SendToCell(rmsg, GET_YLAYER(dropItem), dropItem->m_cellX, dropItem->m_cellZ);
				}

				if (df->m_proto->CheckFlag(NPC_BOSS | NPC_MBOSS))
				{
					GAMELOG << init("MOB DROP ITEM")
							<< "NPC INDEX" << delim
							<< df->m_proto->m_index << delim
							<< "NPC NAME" << delim
							<< df->m_name << delim
							<< "ITEM" << delim
							<< itemlog(dropItem)
							<< end;
				}
			}
		}
	} // // 아이템 드롭

	// opc 공격 캐릭터, tpc 우선권 캐릭터
	int job = -1;

	if(tpc)
		job = (int)tpc->m_job;
	else if(opc)
		job = (int)opc->m_job;

	if(job >= 0 && job < JOBCOUNT)
	{
		if(level != -1 && level - df->m_level <= 5)
		{
			if(df->m_proto->m_jobdropitem[job] > 0 && df->m_proto->m_jobdropitemprob[job] > 0)
			{
				int dropprob = df->m_proto->m_jobdropitemprob[job];
				if(GetRandom(1, 10000) <= dropprob)
				{
					CItem* dropItem = NULL;
					dropItem = gserver->m_itemProtoList.CreateItem(df->m_proto->m_jobdropitem[job], -1, 0, 0, 1);
					if(dropItem)
					{
						df->m_pArea->DropItem(dropItem, df);
						CNetMsg::SP rmsg(new CNetMsg);
						ItemDropMsg(rmsg, df, dropItem);
						df->m_pArea->SendToCell(rmsg, df, true);
						GAMELOG << init("MOB DROP ITEM")
								<< "NPC INDEX" << delim
								<< df->m_proto->m_index << delim
								<< "NPC NAME" << delim
								<< df->m_name << delim
								<< "ITEM" << delim
								<< itemlog(dropItem)
								<< end;
					}
				}
			}
		}
	}

	// 이 아이템은 레벨제한 없이 무조건 떨어트린다.
	int loopi = 0;
	for(loopi = 0; loopi < MAX_NPC_DROPITEM; loopi++)
	{
		if(df->m_proto->m_dropallitem[loopi] < 1)
			continue ;

		int dropprob = df->m_proto->m_dropallitemprob[loopi];
		if(GetRandom(1, 10000) <= dropprob)
		{
			CItem* pItem = NULL;

			pItem = gserver->m_itemProtoList.CreateItem(df->m_proto->m_dropallitem[loopi], -1, 0, 0, 1);
			if(pItem)
			{
				if (tpc)
					pItem->m_preferenceIndex = tpc->m_index;
				else
					pItem->m_preferenceIndex = -1;

				df->m_pArea->DropItem(pItem, df);
				CNetMsg::SP rmsg(new CNetMsg);
				ItemDropMsg(rmsg, df, pItem);
				df->m_pArea->SendToCell(rmsg, df, true);
				GAMELOG << init("MOB DROP ALL ITEM")
						<< "NPC INDEX" << delim
						<< df->m_proto->m_index << delim
						<< "NPC NAME" << delim
						<< df->m_name << delim
						<< "ITEM" << delim
						<< itemlog(pItem)
						<< end;
			}
		}
	}
	// 보석 드롭
	for (loopcount = 0; loopcount < MAX_NPC_DROPITEM_LOOP; loopcount++)
	{
		// 5레벨보다 크면 아이템 드롭 없음
		// 1. 드롭할 수 있는 수 범위에서 아이템 선정
		// 2. 그 아이팀의 드롭확률로 드롭여부 결정
		// 3. 드롭
		if (df->m_proto->m_jewelCount > 0 &&  ((level != -1 && level - df->m_level <= 5) ||  !IsNotDropInCube)  )
		{
			CItem* dropItem = NULL;
			int tableindex = GetRandom(0, MAX_NPC_DROPJEWEL - 1);
			int dropprob = df->m_proto->m_jewelPercent[tableindex];

			if (df->m_proto->m_jewel[tableindex] != -1 && GetRandom(1, 10000) <= dropprob)
			{
				switch (df->m_proto->m_jewel[tableindex])
				{
				case -1:	// 지우지 말것
					dropItem = NULL;
					break;

				default:
					{
						dropItem = df->m_pArea->DropItem(df->m_proto->m_jewel[tableindex], df, 0, 0, 1, true);
					}
					break;
				}
			}

			if (dropItem)
			{
				// Drop Msg 보내기
				// 아이템 우선권 셋팅 (같은 데미지 고려, 선공 고려)
				if (tpc)
					dropItem->m_preferenceIndex = tpc->m_index;
				else
					dropItem->m_preferenceIndex = -1;

				{
					CNetMsg::SP rmsg(new CNetMsg);
					ItemDropMsg(rmsg, df, dropItem);
					df->m_pArea->SendToCell(rmsg, GET_YLAYER(dropItem), dropItem->m_cellX, dropItem->m_cellZ);
				}

				GAMELOG << init("JEWEL ITEM")
						<< "NPC INDEX" << delim
						<< df->m_proto->m_index << delim
						<< "NPC NAME" << delim
						<< df->m_name << delim
						<< "ITEM" << delim
						<< itemlog(dropItem)
						<< end;
			}
		}
	} // 보석 드롭
	// typedef void (*NPC_DROP_FUNCTION) (CNPC* npc, CPC* pc, CPC* tpc, int level);
	// pc, tpc는 NULL이 될 수 있다
	NPC_DROP_FUNCTION fnNPCDrop[] =
	{
		DropBloodGem,						// 블러드젬 드롭 : 대만 천하대란
		DropLuckySpecialStone,				// 행운의 제련석 드롭 : 대만 천하대란
		DropSpecialRefineStone,				// 고제 드롭
		DropPersonalDungeon2Ticket,			// 퍼스널던전 2 입장권 드롭
		DropBoosterItem,					// 부스터

		DropPersonalDungeon3Ticket,			// 퍼스널던전 3 입장권 드롭
		DropPersonalDungeon4Ticket,			// 퍼스널던전 4 입장권 드롭

		DropPetEgg,							// 애완동물 알 드롭

		DropNewMoonStoneItem,

#ifdef EVENT_VALENTINE
		DropValentineItem,					// 발렌타인
#endif

#ifdef EVENT_WHITEDAY
		DropWhiteDayItem,					// 화이트데이
#endif

#ifdef DROP_MAKE_DOCUMENT
		DropMakeDocument,					// 제작문서 드롭
#endif // DROP_MAKE_DOCUMENT

		DropRecommendItem,					// 추천 서버 전용 인스턴스 포션 아이템

		DropGoldenBallItem,					// 골든볼 이벤트

		RegenBlessWarrior,					// 전사의 축복

		DropHalloween2006Item,				// 2006 할로윈 이벤트

		DropRaidMonsterItem,

		DropMobScrollSpecialStone,

		DropEventGomdori2007,

		DropEventIndependenceDay2007USA,

		DropEventAprilFoolEvent,

#ifdef EVENT_DROPITEM
		DropEventNpcDropItem,
#endif // EVENT_DROPITEM

		DropAPetLifeBook,

		DropPhoenix_MembersTicket,

		DropTriggerItem,

#ifdef LACARETTE_SYSTEM
		DropLacaRette,
#endif
		DropHolyWater,
		DropWorldCupEvent,
		DropHalloween2014Event,
		DropArtifactItem,

#ifdef DEV_EVENT_AUTO
		DropEventItem,
#endif // DEV_EVENT_AUTO
	}; // 드롭 함수 테이블

	// 방어코드 : tpc가 있는데 m_pZone이나 m_pArea가 없으면 NULL로 바꾼다
	if (tpc && (tpc->m_pZone == NULL || tpc->m_pArea == NULL))
		tpc = NULL;

	unsigned int fnDropLoop;
	for (fnDropLoop = 0; fnDropLoop < sizeof(fnNPCDrop) / sizeof(NPC_DROP_FUNCTION); fnDropLoop++)
		(fnNPCDrop[fnDropLoop])(df, opc, tpc, level);

	gserver->doEventDropItem(df, opc, tpc);

	// 돈 떨어뜨릴 확률 : default 80 %
	// BS 수정 : 낮은 레벨 몬스터 잡을때 패널티만 존재
	// 잠수함 : 돈 드롭확률
	int moneyDropProb = MONEY_DROP_PROB * gserver->m_moneyDropProb / 100;
	if (level != -1 && df->m_level - level < 0)
		moneyDropProb += (df->m_level - level) * 500;

	bool hcSepNas = false;
	if (opc && tpc == opc)
	{
		if (opc->m_assist.m_avAddition.hcSepNas)
		{
			opc->m_assist.CureByItemIndex(885);	// 나스
			hcSepNas = true;
			CNetMsg::SP rmsg(new CNetMsg);
			EventErrorMsg(rmsg, MSG_EVENT_ERROR_SEPTEMBER_NAS);
			SEND_Q(rmsg, opc->m_desc);
		}
	}

	// 돈 드롭
	//CItem* money = NULL;
	if (GetRandom(1, 10000) <= moneyDropProb)	// 80%
	{
		// 돈 액수 : +- 50%
		if(!df)
		{
			//잘못된 위치에서 몬스터를 잡았을 경우
			GAMELOG << "NOT FOUND TARGET....."
					<< df->m_idNum
					<< end;
			return ;
		}
		GoldType_t count = df->m_proto->m_price * GetRandom(50, 150) / 100;

#ifdef LC_RUS
		// 러시아는 망각의 신전을 제외한 지역에서 65 레벨 이상의 몬스터가 떨구는 나스는 40% 로 줄인다.
		if (df->m_pZone && df->m_pZone->m_index != ZONE_DUNGEON4 && df->m_level >= 65)
			count = count / 5 * 2;
#endif // LC_RUS

		// 더블이벤트
		if (gserver->m_bDoubleEvent)
		{
#ifdef NEW_DOUBLE_GM_ZONE
			if( gserver->m_bDoubleEventZone == -1 || gserver->m_bDoubleEventZone == df->m_pZone->m_index )
#endif // NEW_DOUBLE_GM_ZONE
				count = count * gserver->m_bDoubleNasPercent / 100 ;
		}

		// 9월 이벤트 나스 10배
		if (hcSepNas)
			count = count * 10;

		// 행운 주문서
		if (tpc && tpc->m_assist.m_avAddition.hcDropPlus_2141)
		{
			if (GetRandom(1, 10000) <= 8000 ) // 80 %
			{
				count *= 2;
			}
		}

//#endif // CAHNCE_EVENT

		if( opc && opc->m_pZone->m_index == ZONE_DRATAN_CASTLE_DUNGEON )
		{
			CDratanCastle * pCastle = CDratanCastle::CreateInstance();
			if( opc->m_guildInfo && opc->m_guildInfo->guild()->index() == pCastle->GetOwnerGuildIndex()  )
			{
				// 세금 없음
			}
			else
			{
				GoldType_t tax=0;
				tax = count * pCastle->m_dvd.GetHuntRate() / 100;
				count = count - tax;
				gserver->AddTaxItemDratan( tax );
			}
		}

		if( tpc == NULL )
		{
			GAMELOG << "NOT FOUND TARGET....." << end;
			return;
		}

		//파티이면서 타입이 균등일때
		if (tpc->IsParty() && (tpc->m_party->GetPartyType(MSG_DIVITYPE_MONEY) == MSG_PARTY_TYPE_RANDOM || tpc->m_party->GetPartyType(MSG_DIVITYPE_MONEY) == MSG_PARTY_TYPE_BATTLE) )
		{
			DivisionPartyMoney(tpc, count);
		}
		//원정대이면서 타입이 균등일때
		else if ( tpc->IsExped() && (tpc->m_Exped->GetExpedType(MSG_DIVITYPE_MONEY) == MSG_EXPED_TYPE_RANDOM || tpc->m_Exped->GetExpedType(MSG_DIVITYPE_MONEY) == MSG_EXPED_TYPE_BATTLE) )
		{
			DivisionExpedMoney(tpc, count);
		}
		//이도 저도 아닐때 (개인 플레이할때)
		else
		{
			int bonus = 0;

			if(tpc->m_avPassiveAddition.money_nas > 0)
			{
				bonus += tpc->m_avPassiveAddition.money_nas;	
			}
			if(tpc->m_avPassiveRate.money_nas > 0)
			{
				bonus = count * (tpc->m_avPassiveRate.money_nas - 100) / SKILL_RATE_UNIT;
			}

			count = count + count * tpc->m_artiGold / 100;
			
			tpc->m_inventory.increaseMoney(count, bonus);
		}

		if (df->m_proto->CheckFlag(NPC_BOSS | NPC_MBOSS))
		{
			GAMELOG << init("MOB DROP MONEY")
					<< "NPC INDEX" << delim
					<< df->m_proto->m_index << delim
					<< "NPC NAME" << delim
					<< df->m_name << delim
					<< "MONEY(NAS)" << delim
					<< count
					<< end;
		}
	}
}
コード例 #4
0
void ProcRVR(CPC* df, CCharacter* of)
{
    CPC* oPC;
    CNPC* oNPC;
    if(IS_PC(of))
    {
        oPC = TO_PC(of);

        if (!df->isSyndicate() && !oPC->isSyndicate())
        {
            return;
        }

        if (df->isSyndicate() && !oPC->isSyndicate())
        {
            LONGLONG point = 1;

            df->m_syndicateManager.decreaseSyndicatePoint(point);
            return;
        }

        if (!df->isSyndicate() && oPC->isSyndicate())
        {
            LONGLONG point = 1;
            oPC->m_syndicateManager.increaseSyndicatePoint(point);
            return;
        }

        if (df->isSyndicate() && oPC->isSyndicate())
        {
            LONGLONG dfPoint = 0;
            LONGLONG attPoint = 0;
            int itemIndex = 0;

            //
            int jewelKailuxPoint		= SyndicateInfoDataManager::instance()->getJewelPoint(SYNDICATE::eSYNDICATE_KAILUX);
            int jewelDealerMoonPoint	= SyndicateInfoDataManager::instance()->getJewelPoint(SYNDICATE::eSYNDICATE_DEALERMOON);

            // 카이룩스의 보석량이 딜라문보다 적다
            if (jewelKailuxPoint < jewelDealerMoonPoint)
            {
                //공격자가 보석량이 작은 결사대 일 경우
                if (oPC->getSyndicateType() == SYNDICATE::eSYNDICATE_KAILUX)
                {
                    // 공격자의 보석량이 적고 공격자의 기여도가 높다
                    if (df->m_syndicateManager.getSyndicatePoint(df->getSyndicateType()) < oPC->m_syndicateManager.getSyndicatePoint(oPC->getSyndicateType()))
                    {
                        attPoint = 2;
                        dfPoint = 5;
                        itemIndex = 10129;
                    }
                    else if(df->m_syndicateManager.getSyndicatePoint(df->getSyndicateType()) == oPC->m_syndicateManager.getSyndicatePoint(oPC->getSyndicateType()))
                    {
                        // 공격자의 보석량이 적고 기여도가 같다
                        attPoint = 3;
                        dfPoint = 3;
                        itemIndex = 10130;
                    }
                    else
                    {
                        // 공격자의 보석량이 적고 기여도가 낮다
                        attPoint = 5;
                        dfPoint = 2;
                        itemIndex = 10130;
                    }
                }
                //공격자가 보석량이 큰 결사대 일 경우
                else if (oPC->getSyndicateType() == SYNDICATE::eSYNDICATE_DEALERMOON)
                {
                    if (df->m_syndicateManager.getSyndicatePoint(df->getSyndicateType()) < oPC->m_syndicateManager.getSyndicatePoint(oPC->getSyndicateType()))
                    {
                        // 공격자의 보석량이 많고 기여도가 높다
                        attPoint = 1;
                        dfPoint = 1;
                        itemIndex = 10129;
                    }
                    else if(df->m_syndicateManager.getSyndicatePoint(df->getSyndicateType()) == oPC->m_syndicateManager.getSyndicatePoint(oPC->getSyndicateType()))
                    {
                        // 공격자의 보석략이 많고 기여도가 같다
                        attPoint = 1;
                        dfPoint = 1;
                        itemIndex = 10130;
                    }
                    else
                    {
                        // 공격자의 보석략이 많고 기여도가 작다
                        attPoint = 2;
                        dfPoint = 1;
                        itemIndex = 10130;
                    }
                }
            }
            else
            {
                if (oPC->getSyndicateType() == SYNDICATE::eSYNDICATE_KAILUX)
                {
                    // 공격자의 보석량이 많고 공격자의 기여도가 높다
                    // 사망자의 보석량이 적고 기여도가 작다
                    if (df->m_syndicateManager.getSyndicatePoint(df->getSyndicateType()) < oPC->m_syndicateManager.getSyndicatePoint(oPC->getSyndicateType()))
                    {
                        attPoint = 1;
                        dfPoint = 1;
                        itemIndex = 10129;
                    }
                    else if(df->m_syndicateManager.getSyndicatePoint(df->getSyndicateType()) == oPC->m_syndicateManager.getSyndicatePoint(oPC->getSyndicateType()))
                    {
                        // 공격자의 보석량이 많고고 기여도가 같다
                        attPoint = 1;
                        dfPoint = 1;
                        itemIndex = 10130;
                    }
                    else
                    {
                        // 공격자의 보석량이 많고 기여도가 낮다
                        attPoint = 2;
                        dfPoint = 1;
                        itemIndex = 10130;
                    }
                }
                else if (oPC->getSyndicateType() == SYNDICATE::eSYNDICATE_DEALERMOON)
                {
                    if (df->m_syndicateManager.getSyndicatePoint(df->getSyndicateType()) < oPC->m_syndicateManager.getSyndicatePoint(oPC->getSyndicateType()))
                    {
                        // 공격자의 보석량이 적고 기여도가 높다
                        attPoint = 2;
                        dfPoint = 5;
                        itemIndex = 10129;
                    }
                    else if(df->m_syndicateManager.getSyndicatePoint(df->getSyndicateType()) == oPC->m_syndicateManager.getSyndicatePoint(oPC->getSyndicateType()))
                    {
                        // 공격자의 보석량이 적고 기여도가 같다
                        attPoint = 3;
                        dfPoint = 3;
                        itemIndex = 10130;
                    }
                    else
                    {
                        // 공격자의 보석량이 적고 기여도가 작다
                        attPoint = 5;
                        dfPoint = 2;
                        itemIndex = 10130;
                    }
                }
            }
            //기여도 수정
            df->m_syndicateManager.decreaseSyndicatePoint(dfPoint);
            oPC->m_syndicateManager.increaseSyndicatePoint(attPoint);

            //창조의 보석 드랍
            if(df->m_syndicateManager.isKing())
            {
                itemIndex = 10131;
            }

            CItem* pItem = gserver->m_itemProtoList.CreateItem(itemIndex, -1, 0, 0, 1);
            pItem = df->m_pArea->DropItem(pItem, (CCharacter*)df);

            if(pItem && pItem->m_pArea)
            {
                pItem->m_preferenceIndex = oPC->m_index;
                CNetMsg::SP rmsg(new CNetMsg);
                ItemDropMsg(rmsg, df, pItem);
                pItem->m_pArea->SendToCell(rmsg, GET_YLAYER(pItem), pItem->m_cellX, pItem->m_cellZ);
                GAMELOG << init("Syndicate Jewel Drop.", df) << "ITEM" << delim << itemlog(pItem) << end;
            }

            switch(itemIndex)
            {
            case 10129:
                df->m_syndicateManager.syndicateDelJewel(1);
                break;
            case 10130:
                df->m_syndicateManager.syndicateDelJewel(5);
                break;
            case 10131:
                df->m_syndicateManager.syndicateDelJewel(30);
                break;
            }
        }

        // 로그 추가
        oPC->m_syndicateManager.historyManager_.battleWinHistory(oPC->getSyndicateType(), df->getSyndicateType(), df->GetName());
        df->m_syndicateManager.historyManager_.battleLoseHistory(df->getSyndicateType(), oPC->getSyndicateType(), oPC->GetName());

        // 히스토리 전달
        oPC->m_syndicateManager.historyManager_.sendHistory(oPC->getSyndicateType());
        df->m_syndicateManager.historyManager_.sendHistory(df->getSyndicateType());
    }
    else if(IS_NPC(of))
    {
        oNPC = TO_NPC(of);

        int jewelKailuxPoint		= SyndicateInfoDataManager::instance()->getJewelPoint(SYNDICATE::eSYNDICATE_KAILUX);
        int jewelDealerMoonPoint	= SyndicateInfoDataManager::instance()->getJewelPoint(SYNDICATE::eSYNDICATE_DEALERMOON);

        if(jewelKailuxPoint > jewelDealerMoonPoint)
        {
            if(df->getSyndicateType() == SYNDICATE::eSYNDICATE_KAILUX)
            {
                df->m_syndicateManager.decreaseSyndicatePoint(2);
            }
            else
            {
                df->m_syndicateManager.decreaseSyndicatePoint(1);
            }
        }
        else
        {
            if(df->getSyndicateType() == SYNDICATE::eSYNDICATE_KAILUX)
            {
                df->m_syndicateManager.decreaseSyndicatePoint(1);
            }
            else
            {
                df->m_syndicateManager.decreaseSyndicatePoint(2);
            }
        }
    }
}
コード例 #5
0
void ProcDead(CPC* df, CCharacter* of)
{
    CDratanCastle * pCastle = CDratanCastle::CreateInstance();
    if (df != NULL)
    {
        pCastle->CheckRespond(df);
    }

    const char* strOFType = "UNKNOWN";
    const char* strOFName = "UNKNOWN";
    int strOFIndex = 0;

    CPC*		opc				= NULL;
    CNPC*		onpc			= NULL;
    CPet*		opet			= NULL;
    CElemental*	oelemental		= NULL;
    CAPet*		oapet			= NULL;

    if( IS_NPC(of) && TO_NPC(of)->Check_MobFlag(STATE_MONSTER_MERCENARY) && TO_NPC(of)->GetOwner() )
    {
        TO_NPC(of)->GetOwner()->SetSummonOwners_target(NULL);
    }

    switch (of->m_type)
    {
    case MSG_CHAR_PC:
        opc = TO_PC(of);
        strOFType = "PC";
        strOFName = opc->GetName();
        strOFIndex = opc->m_index;
        break;

    case MSG_CHAR_NPC:
        onpc = TO_NPC(of);
        strOFType = "NPC";
        strOFName = onpc->m_name;
        strOFIndex = onpc->m_idNum;
        break;

    case MSG_CHAR_PET:
        opet = TO_PET(of);
        opc = opet->GetOwner();
        if (opc == NULL)
            return ;
        strOFType = "PET";
        strOFName = opc->GetName();
        strOFIndex = opc->m_index;
        break;

    case MSG_CHAR_ELEMENTAL:
        oelemental = TO_ELEMENTAL(of);
        opc = oelemental->GetOwner();
        if (opc == NULL)
            return ;
        strOFType = "ELEMENTAL";
        strOFName = opc->GetName();
        strOFIndex = opc->m_index;
        break;
    case MSG_CHAR_APET:
        oapet = TO_APET(of);
        opc = oapet->GetOwner();
        if (opc == NULL)
            return ;
        strOFType = "APET";
        strOFName = opc->GetName();
        strOFIndex = opc->m_index;
        break;

    default:
        return ;
    }

    if( opc )
        opc->SetSummonOwners_target(NULL);

    // NPC에 의한 사망시 사망 패널티는 기본으로 true, PC에게 사망시 사망 패널티는 기본으로 false
    // * bPKPenalty변수는 pk 패널티를 주는것 뿐만 아니라 성향회복에도 관계되므로 성향 회복이나 패널티등 어느것에라도 걸리면 true

    bool bPvP = (opc) ? true : false;
    bool bPKPenalty = (opc) ? IsPK(opc, df) : false;
    bool bDeadPenalty = (bPvP) ? false : true;
    // 아래 boolean변수는 선언과 값대입이 따로 이루어져야 합니다.
    // bool bRestorePKOfDefensePC = true; 이런식으로 선언을 하면 UPDATE1106에서는 사용하지 않는 변수로 warning을 출력합니다.

    //소환NPC에게 죽었을 경우 처리 (EX 트랩) - 트랩의 경우에 타겟을 NPC로 사용하고 있음...ㅡㅡ;;
    if(IS_NPC(of))
    {
        CNPC* npc = TO_NPC(of);
        if(npc->m_owner > 0)
        {
            bPvP = false;
            bPKPenalty = true;
            bDeadPenalty = false;
        }
    }

    bool bRestorePKOfDefensePC;
    bRestorePKOfDefensePC = true;

    // 변신 해제
    if (df->IsSetPlayerState(PLAYER_STATE_CHANGE))
        df->CancelChange();

    if (opc)
    {
#ifdef FREE_PK_SYSTEM
        if( !gserver->m_bFreePk )
        {
#endif // FREE_PK_SYSTEM

#ifdef MAL_DISABLE_PKPENALTY
            if( gserver->m_bDisablePKPaenalty )
                bDeadPenalty = true;
            else if( !gserver->m_bDisablePKPaenalty )
            {
#endif // MAL_DISABLE_PKPENALTY
                // df가 pk모드 이거나 카오면 둘다 트루
                if (df->IsSetPlayerState(PLAYER_STATE_PKMODE) || df->IsChaotic())
                    bDeadPenalty = true;
#ifdef MAL_DISABLE_PKPENALTY
            }
#endif // MAL_DISABLE_PKPENALTY

#ifdef FREE_PK_SYSTEM
        }
#endif // FREE_PK_SYSTEM

        // 길드전
        if (opc->m_guildInfo && (opc->m_guildInfo->guild()->battleState() == GUILD_BATTLE_STATE_ING) &&
                df->m_guildInfo && (df->m_guildInfo->guild()->battleState() == GUILD_BATTLE_STATE_ING))
        {
            if (opc->m_guildInfo->guild()->battleIndex() == df->m_guildInfo->guild()->index() &&
                    df->m_guildInfo->guild()->battleIndex() == opc->m_guildInfo->guild()->index())
            {
                bDeadPenalty = false;

                int killCount = opc->m_guildInfo->guild()->killCount();

                killCount++;

                if (gserver->isRunHelper())
                {
                    CNetMsg::SP rmsg(new CNetMsg);
                    HelperGuildBattleKillReqMsg(rmsg, opc->m_guildInfo->guild()->index(), df->m_guildInfo->guild()->index());
                    SEND_Q(rmsg, gserver->m_helper);
                }
                else
                {
                    GAMELOG << init("GUILD_BATTLE")
                            << "if( gserver->isRunHelper() ) false" << delim
                            << end;
                    CNetMsg::SP rmsg(new CNetMsg);
                    GuildErrorMsg(rmsg, MSG_GUILD_ERROR_GAMESERVER);
                    SEND_Q(rmsg, opc->m_desc);
                }
            }
        }
    } // 공격자가 PC 또는 PC의 소유물일때

    // 공성 포인트 계산
    if (opc)
        CalcWarPoint(opc, df);
    else
        CalcWarPoint(of, df);

    // 공성 도중 사망은 패널티 없음
    CWarCastle* castle = CWarCastle::GetCastleObject(df->m_pZone->m_index);
#ifdef CHECK_CASTLE_AREA
    if (castle && castle->GetState() != WCSF_NORMAL && (df->GetMapAttr() & MATT_WAR || df->m_pZone->IsWarZone((int)df->m_pos.m_x, (int)df->m_pos.m_z)))
#else
    if (castle && castle->GetState() != WCSF_NORMAL && df->GetMapAttr() & MATT_WAR)
#endif // CHECK_CASTLE_AREA
    {
        DropWarCastleTokenDeadPC(df);
        bDeadPenalty = false;
    }

    /////////////////////////////////////////////
    // BANGWALL : 2005-07-18 오전 11:27:24
    // Comment : freepkzone 패널티 없음
    // 공격자와 방어자가 모두 freepkzone에 있으면 pkpenalty 없음
    if( of->GetMapAttr() == df->GetMapAttr() && of->GetMapAttr() & MATT_FREEPKZONE)
        bDeadPenalty = false;

    // PvP에서 PK 적용
    if (opc && bPvP && bPKPenalty)
        CalcPKPoint(opc, df, false);

    bool bDeadExpPenalty = true;

#ifdef FREE_PK_SYSTEM
    if( gserver->m_bFreePk )
    {
        if(!bDeadPenalty)
            bDeadExpPenalty = false;
    }
#endif // FREE_PK_SYSTEM

#if defined(LC_BILA)
    if (bPvP)
#ifdef MAL_DISABLE_PKPENALTY
        if( gserver->m_bDisablePKPaenalty )
        {
            bDeadExpPenalty = false;
        }
#endif // MAL_DISABLE_PKPENALTY
#endif

    // 퍼스널 던전은 무조건 패널티 없음
    if (df->m_pZone->IsPersonalDungeon())
        bDeadPenalty = false;

    // 경험치 하락
    LONGLONG nLoseExp = 0;
    LONGLONG nLoseSP = 0;

    // 하락된 경험치는 최근 것만 기억
    df->m_loseexp = 0;
    df->m_losesp = 0;

    if( df->m_skillPoint < 0 )
        df->m_skillPoint = 0;

    //수비자가 무소속인 경우만 사망 페널티 적용
    if (df->m_pZone->isRVRZone())
    {
        if(df->getSyndicateType() == 0)
            bDeadPenalty = true;
        else
            bDeadPenalty = false;
    }

    if (bDeadPenalty)
    {
        if (bDeadExpPenalty)
        {
            // 사망시 패널티
            if (df->m_level < 11)
            {
                /*				nLoseExp = (LONGLONG)(GetLevelupExp(df->m_level) * DEATH_PENALTY_EXP_1);
                				nLoseSP = (LONGLONG)(df->m_skillPoint * DEATH_PENALTY_SP_1);*/
                nLoseExp = 0;
                nLoseSP = 0;
            }
            else if (df->m_level < 21)
            {
                /* 5% */
                /*				nLoseExp = (LONGLONG)(GetLevelupExp(df->m_level) * DEATH_PENALTY_EXP_2);
                				nLoseSP = (LONGLONG)(df->m_skillPoint * DEATH_PENALTY_SP_2);*/
                nLoseExp = (LONGLONG)((GetLevelupExp(df->m_level) / 100) * 5);
                nLoseSP = (LONGLONG)((df->m_skillPoint / 100) * 5);
            }
            else if (df->m_level < 36)
            {
                /*				nLoseExp = (LONGLONG)(GetLevelupExp(df->m_level) * DEATH_PENALTY_EXP_3);
                				nLoseSP = (LONGLONG)(df->m_skillPoint * DEATH_PENALTY_SP_3);*/
                nLoseExp = (LONGLONG)((GetLevelupExp(df->m_level) / 100) * 3);
                nLoseSP = (LONGLONG)((df->m_skillPoint / 100) * 3);
            }
            else
            {
                /*				nLoseExp = (LONGLONG)(GetLevelupExp(df->m_level) * DEATH_PENALTY_EXP_4);
                				nLoseSP = (LONGLONG)(df->m_skillPoint * DEATH_PENALTY_SP_4);*/
                nLoseExp = (LONGLONG)((GetLevelupExp(df->m_level) / 100) * 2);
                nLoseSP = (LONGLONG)((df->m_skillPoint / 100) * 2);
            }

            // 경험의 결정 시리즈 적용
            switch (df->m_assist.m_avAddition.hcDeathExpPlus)
            {
            case 1:
            {
                nLoseExp -= 50000;
                if(nLoseExp < 0)
                    nLoseExp = 0;
            }
            break;
            case 2:
            {
                nLoseExp -= 600000;
                if(nLoseExp < 0)
                    nLoseExp = 0;
            }
            break;
            case 3:
            {
                nLoseExp /= 2;
            }
            break;
            default:
                break;
            }

            // 노력의 결정 적용
            if (df->m_assist.m_avAddition.hcDeathSPPlus)
                nLoseSP /= 2;
        }

#ifdef FREE_PK_SYSTEM
        if( !gserver->m_bFreePk )
        {
#endif // FREE_PK_SYSTEM

#ifdef MAL_DISABLE_PKPENALTY
            if( !gserver->m_bDisablePKPaenalty )
            {
#endif // MAL_DISABLE_PKPENALTY
                if (df->IsChaotic())
                {
#ifndef REFORM_PK_PENALTY_201108 // PK 패널티 리폼 :: 장비 잠금 상태 기능 삭제
// TODO : DELETE			bSaveLose = false;
                    bool bseal = false;

                    if (df->m_pkPenalty <= -130)
                    {
                        nLoseExp = nLoseExp * 225 / 100;
                        bseal = (GetRandom(1, 100) <= 13) ? true : false;
                    }
                    else if (df->m_pkPenalty <= -100)
                    {
                        nLoseExp = nLoseExp * 200 / 100;
                        bseal = (GetRandom(1, 100) <= 11) ? true : false;
                    }
                    else if (df->m_pkPenalty <=  -70)
                    {
                        nLoseExp = nLoseExp * 175 / 100;
                        bseal = (GetRandom(1, 100) <=  9) ? true : false;
                    }
                    else if (df->m_pkPenalty <=  -40)
                    {
                        nLoseExp = nLoseExp * 150 / 100;
                        bseal = (GetRandom(1, 100) <=  7) ? true : false;
                    }
                    else if (df->m_pkPenalty <=  -10)
                    {
                        nLoseExp = nLoseExp * 125 / 100;
                        bseal = (GetRandom(1, 100) <=  5) ? true : false;
                    }

                    if (bseal)
                    {
                        CItem* table[MAX_WEARING];
                        memset(table, 0, sizeof(CItem*) * MAX_WEARING);
                        int i = 0, j = 0;
                        while (i < MAX_WEARING)
                        {
                            if (df->m_wearInventory.wearItemInfo[i] && !(df->m_wearInventory.wearItemInfo[i]->getFlag() & FLAG_ITEM_SEALED))
                            {
                                // 장비에 따라 봉인 되는지 결정
                                switch (i)
                                {
                                case WEARING_HELMET:
                                case WEARING_ARMOR_UP:
                                case WEARING_WEAPON:
                                case WEARING_ARMOR_DOWN:
                                case WEARING_SHIELD:
                                case WEARING_GLOVE:
                                case WEARING_BOOTS:
                                    if(!(df->m_wearInventory.wearItemInfo[i]->m_itemProto->getItemFlag() & ITEM_FLAG_COSTUME2))
                                        table[j] = df->m_wearInventory.wearItemInfo[i];
                                    j++;
                                    break;

                                default:
                                    break;
                                }
                            }
                            i++;
                        }
                        if (j)
                        {
                            i = GetRandom(0, j - 1);

                            if (table[i])
                            {
                                table[i]->setFlag(table[i]->getFlag() | FLAG_ITEM_SEALED);

                                {
                                    CNetMsg::SP rmsg(new CNetMsg);
                                    UpdateClient::makeUpdateItemFlag(rmsg, table[i]->tab(), table[i]->getInvenIndex(), table[i]->getFlag());
                                    SEND_Q(rmsg, df->m_desc);
                                }

                                {
                                    CNetMsg::SP rmsg(new CNetMsg);
                                    PKItemSealMsg(rmsg, table[i]);
                                    SEND_Q(rmsg, df->m_desc);
                                }

                                GAMELOG << init("ITEM SEAL" , df)
                                        << "ITEM" << delim
                                        << itemlog(table[i])
                                        << end;
                            }
                        }
                    }
#endif // REFORM_PK_PENALTY_201108 // PK 패널티 리폼 :: 장비 잠금 상태 기능 삭제
                    if (nLoseExp < 0)
                        nLoseExp = 0;
                    if (nLoseSP < 0)
                        nLoseSP = 0;

                    // 060318 : bs : 공방 모두 카오PC PvP 시에는 죽은 사람 회복 없음
                    //             : 죽은카오가 선공이면 회복 없음
                    // 성향 회복

#ifndef REFORM_PK_PENALTY_201108 // PK 패널티 리폼 :: 카오 사망시 성향 회복 없음
                    if (bRestorePKOfDefensePC)
                    {
                        if( !gserver->m_bNonPK )
                            df->m_pkPenalty += 5;

                        if (df->m_pkPenalty > 0)
                            df->m_pkPenalty = 0;
                    }

                    {
                        // 페널티 수치 변경 알리기
                        CNetMsg::SP rmsg(new CNetMsg);
                        CharStatusMsg(rmsg, df, 0);
                        df->m_pArea->SendToCell(rmsg, df, false);
                    }

                    df->m_bChangeStatus = true;
                    df->CalcStatus(true);

#endif // REFORM_PK_PENALTY_201108 // PK 패널티 리폼 :: 카오 사망시 성향 회복 없음
                }
                else
                {
                    if (df->m_exp < nLoseExp)
                        nLoseExp = df->m_exp;
                }
#ifdef MAL_DISABLE_PKPENALTY
            }
            else
            {
                if( df->m_exp < nLoseExp )
                    nLoseExp = df->m_exp;
            }
#endif
#ifdef FREE_PK_SYSTEM
        }
        else
        {
            if( df->m_exp < nLoseExp )
                nLoseExp = df->m_exp;
        }
#endif // FREE_PK_SYSTEM


        if (bDeadExpPenalty)
        {
            if (nLoseExp < 0)
                nLoseExp = 0;
            if (nLoseSP < 0)
                nLoseSP = 0;
            if (df->m_skillPoint < nLoseSP)
                nLoseSP = df->m_skillPoint;
// 경험치 - 방지
            if ( df->m_exp < nLoseExp )
                nLoseExp = df->m_exp;

// 수정
            if(df->m_pZone->IsComboZone())
            {
                nLoseExp = nLoseExp / 10;
                nLoseSP = nLoseSP / 10;
            }
            df->m_exp -= nLoseExp;
            if (df->m_exp < 0)
                df->m_exp = 0;

            df->m_skillPoint -= nLoseSP;
            if (df->m_skillPoint < 0)
                df->m_skillPoint = 0;

            df->m_bChangeStatus = true;

// TODO : DELETE			if (bSaveLose)
// TODO : DELETE			{
            df->m_loseexp = nLoseExp;
            df->m_losesp = nLoseSP;
// TODO : DELETE			}
        }

        // Fixed death by npc dropping item
        if(IS_PC(of)) {
            CItem* pItem = gserver->m_itemProtoList.CreateItem(PVP_TOKEN_ID, -1, 0, 0, 1);
            if (pItem) {
                CNetMsg::SP rmsg(new CNetMsg);
                pItem->m_preferenceIndex = of->m_index;
                df->m_pArea->DropItem(pItem, df);
                ItemDropMsg(rmsg, df, pItem);
                pItem->m_pArea->SendToCell(rmsg, df, true);
            }
        }
    } // 사망 패널티 적용

    // Accessory 내구도
    int i;
    for (i = WEARING_ACCESSORY1; i <= WEARING_ACCESSORY3; i++)
    {
        if (!df->m_wearInventory.wearItemInfo[i] || df->m_wearInventory.wearItemInfo[i]->m_itemProto->getItemMaxUse() == -1)
            continue;

        df->m_wearInventory.wearItemInfo[i]->setUsed(df->m_wearInventory.wearItemInfo[i]->getUsed() - ACCESSORY_USED_DEATH);

        // 악세사리 소멸
        if (df->m_wearInventory.wearItemInfo[i]->getUsed() <= 0)
        {
            df->m_wearInventory.wearItemInfo[i]->setUsed(0);
            df->CalcStatus(true);
        }
    }

    // 보조효과 리셋
    df->m_assist.ClearAssist(true, false, true, true, false);

    // 워프중이면 취소
    if (df->IsSetPlayerState(PLAYER_STATE_WARP))
    {
        df->m_reqWarpTime = 0;
        df->m_reqWarpType = -1;
        df->m_reqWarpData = -1;

        df->m_reqWarpTime_skill = -1;
        df->m_reqWarpType_skill = -1;
        df->m_reqWarpData_skill = -1;
    }

    df->ResetPlayerState(PLAYER_STATE_SITDOWN | PLAYER_STATE_MOVING | PLAYER_STATE_WARP | PLAYER_STATE_PKMODE | PLAYER_STATE_DARKNESS);

    CPet* pet = df->GetPet();
    if (pet)
    {
        if (pet->IsMountType())
        {
            if(df->m_pZone != NULL && df->m_pZone->m_bCanMountPet == true)
            {
                // 사망 설정
                pet->SetRemainRebirthTime();
            }
        }

        {
            // 펫 상태 보냄
            CNetMsg::SP rmsg(new CNetMsg);
            ExPetStatusMsg(rmsg, pet);
            SEND_Q(rmsg, df->m_desc);
        }
    }

#ifdef LC_USA
    CAPet* apet = df->GetAPet();
    if(apet)
    {
        {
            // 펫 상태 보냄
            CNetMsg::SP rmsg(new CNetMsg);
            ExAPetStatusMsg(rmsg, apet);
            SEND_Q(rmsg, df->m_desc);
        }
    }
#endif // LC_USA

    // 소환 취소
    while (df->m_elementalList)
        df->UnsummonElemental(df->m_elementalList);
    // 강신 취소
    if (df->m_evocationIndex != EVOCATION_NONE)
        df->Unevocation();
    // 강신 시간 초기화
    df->m_pulseEvocation[0] = 0;
    df->m_pulseEvocation[1] = 0;

#ifdef GER_LOG
    GAMELOGGEM << init( 0, "CHAR_DEATH")
               << LOG_VAL("account-id", df->m_desc->m_idname ) << blank
               << LOG_VAL("character-id", df->m_desc->m_pChar->m_name ) << blank
               << LOG_VAL("zone-id", df->m_desc->m_pChar->m_pZone->m_index ) << blank
               << LOG_VAL("from-id", strOFType ) << blank
               << LOG_VAL("opponent-id", strOFIndex ) << blank
               << LOG_VAL("longitude", GET_X(df) ) << blank
               << LOG_VAL("latitude", GET_Z(df) ) << blank
               << endGer;

    if ( IS_PC(of) )
    {
        CPC *user = TO_PC(of);
        GAMELOGGEM << init( 0, "CHAR_VICTORY")
                   << LOG_VAL("account-id", user->m_desc->m_idname ) << blank
                   << LOG_VAL("character-id", user->m_desc->m_pChar->m_name ) << blank
                   << LOG_VAL("zone-id", user->m_desc->m_pChar->m_pZone->m_index ) << blank
                   /*<< LOG_VAL("from-id", strOFType ) << blank*/
                   << LOG_VAL("opponent-id", df->m_desc->m_idname ) << blank
                   << LOG_VAL("longitude", GET_X(user) ) << blank
                   << LOG_VAL("latitude", GET_Z(user) ) << blank
                   << endGer;
    }
#endif // GER_LOG
    // 로그
    GAMELOG << init("CHAR_DEATH", df)
            << "BY" << delim
            << strOFType << delim
            << strOFName << delim
            << strOFIndex << delim
            << "LOSE EXP" << delim
            << nLoseExp << delim
            << "CUR EXP" << delim
            << df->m_exp << delim
            << "LOSE SP" << delim
            << nLoseSP << delim
            << "CUR SP" << delim
            << df->m_skillPoint
            << "POS_X" << delim
            << GET_X(df) << delim
            << "POS_Z" << delim
            << GET_Z(df) << delim
            << "YLAYER" << delim
            << GET_YLAYER(df) << delim
            << "HEIGHT" << delim
            << GET_H(df)
            << end;

    DelAttackList(df);

    // 정당방위 해제
    DelRaList(df);

    if (pCastle != NULL)
    {
        if (df->GetJoinFlag(ZONE_DRATAN) != WCJF_NONE
                && pCastle->GetState() != WCSF_NORMAL
                && (df->GetMapAttr() & MATT_WAR || df->m_pZone->IsWarZone((int)df->m_pos.m_x, (int)df->m_pos.m_z) ) )
        {
            // 공성중에 공성참가
            int wait_time = -1;
            switch(df->GetJoinFlag(ZONE_DRATAN))
            {
            case WCJF_ATTACK_GUILD:
                // 부활진기가 있으면 부활대기 시간 20초, 없으면 60초
                wait_time = 60;
                if (df->m_guildInfo != NULL
                        && df->m_guildInfo->guild() != NULL)
                {
                    for(int i=0; i<7; i++)
                    {
                        if (df->m_guildInfo->guild()->index() == pCastle->m_nRebrithGuild[i])
                        {
                            wait_time = 20;
                            break;
                        }
                    }
                }
                break;
            case WCJF_OWNER:
            case WCJF_DEFENSE_GUILD:
                //  부활대기 시간 60초 - 워프타워개수*10
                int count = 0;
                for(int i=0; i<5; i++)
                {
                    if(pCastle->m_pWarpNPC[i] != NULL
                            && DEAD(pCastle->m_pWarpNPC[i]) == false)
                    {
                        count++;
                    }
                }

                wait_time = 60 - count*10;
                break;
            }

            if (wait_time > 0)
            {
                CNetMsg::SP rmsg(new CNetMsg);
                WaitTimeMsg(rmsg, wait_time);
                SEND_Q(rmsg, df->m_desc);
            }
        }
    }

#ifdef EXTREME_CUBE
    if(gserver->m_extremeCube.IsGuildCubeTime())
    {
        if(df->m_guildInfo && df->m_guildInfo->guild())
        {
            if(df->m_pZone != NULL && df->m_guildInfo->guild()->m_cubeUniqueIdx >= 0 && df->m_pZone->IsExtremeCube())
            {
                CCubeMemList* memlist = gserver->m_extremeCube.FindMemList(df->m_guildInfo->guild()->m_cubeUniqueIdx);
                if(memlist)
                {
                    memlist->DelPC(df);

                    if(opc && opc->m_guildInfo && opc->m_guildInfo->guild())
                    {
                        CCubeMemList* opcMemList = gserver->m_extremeCube.FindMemList(opc->m_guildInfo->guild());
                        if(opcMemList)
                        {
                            time_t lastCubePoint;
                            int point;
                            time(&lastCubePoint);

                            {
                                CNetMsg::SP rmsg(new CNetMsg);
                                HelperAddCubePointMsg(rmsg, opc->m_guildInfo->guild()->index(), df->m_level * 10, lastCubePoint);
                                SEND_Q(rmsg, gserver->m_helper);
                            }

                            {
                                // 개인 큐브포인트 획득
                                point = opcMemList->GetPersonalCubePoint(opc, df->m_level);
                                CNetMsg::SP rmsg(new CNetMsg);
                                HelperAddCubePointPersonalMsg(rmsg, opc->m_index, point, lastCubePoint);
                                SEND_Q(rmsg, gserver->m_helper);
                            }
                        }
                    }
                }
            }
        }
    }
    else
    {
        if(df->m_party)
        {
            if(df->m_pZone != NULL && df->m_party->m_cubeUniqueIdx >= 0 && df->m_pZone->IsExtremeCube())
            {
                CCubeMemList* memlist = gserver->m_extremeCube.FindMemList(df->m_party->m_cubeUniqueIdx);
                if(memlist)
                {
                    memlist->DelPC(df);
                    // 개인 큐브포인트 획득
                    if(opc && opc->m_party)
                    {
                        CCubeMemList* opcMemList = gserver->m_extremeCube.FindMemList(opc->m_party);
                        if(opcMemList)
                        {
                            int point;
                            time_t lastCubePoint;

                            time(&lastCubePoint);
                            point = opcMemList->GetPersonalCubePoint(opc, df->m_level);
                            CNetMsg::SP rmsg(new CNetMsg);
                            HelperAddCubePointPersonalMsg(rmsg, opc->m_index, point, lastCubePoint);
                            SEND_Q(rmsg, gserver->m_helper);
                        }
                    }
                }
            }
        }
    }
#endif // EXTREME_CUBE

    if(df && df->m_pZone->IsWarGroundZone())
    {
        if(!opc && onpc)
        {
            if(onpc->Check_MobFlag(STATE_MONSTER_TRAP) || onpc->Check_MobFlag(STATE_MONSTER_PARASITE))
            {
                opc = onpc->GetOwner();
            }
        }
        if(opc)
            GAMELOG << init("ROYAL RUMBLE DEAD PC", df) << "ATTACKER" << delim << opc->m_nick << delim << opc->m_index << end;
        CWaitPlayer* p = NULL;
        p = gserver->m_RoyalRumble.m_WaitPlayerList.GetNode(df->m_index);
        if(p)
        {
            int leveltype = p->GetLevelType();
            int leftcount = 0;

            CWaitPlayer* player = NULL;
            CWaitPlayer* playern = NULL;
            playern = gserver->m_RoyalRumble.m_WaitPlayerList.GetHead();
            while((player = playern))
            {
                playern = playern->GetNext();
                if( player->GetLevelType() == leveltype &&
                        player->GetCheckIn() == true )
                    leftcount++;
            }
            leftcount -= 2;

            {
                CNetMsg::SP rmsg(new CNetMsg);
                RoyalRumbleLeftCount(rmsg, leftcount);
                CNetMsg::SP killmsg(new CNetMsg);
                if(opc)
                    RoyalRumbleKillPlayer(killmsg, opc, df);
                switch(leveltype)
                {
                case LEVEL_TYPE_ROOKIE:
                {
                    gserver->m_RoyalRumble.m_pRookieArea->SendToAllClient(rmsg);
                    gserver->m_RoyalRumble.m_pRookieArea->SendToAllClient(killmsg);
                }
                break;
                case LEVEL_TYPE_SENIOR:
                {
                    gserver->m_RoyalRumble.m_pSeniorArea->SendToAllClient(rmsg);
                    gserver->m_RoyalRumble.m_pSeniorArea->SendToAllClient(killmsg);
                }
                break;
                case LEVEL_TYPE_MASTER:
                {
                    gserver->m_RoyalRumble.m_pMasterArea->SendToAllClient(rmsg);
                    gserver->m_RoyalRumble.m_pMasterArea->SendToAllClient(killmsg);
                }
                break;
                default:
                    break;
                }
            }
        }
        gserver->m_RoyalRumble.m_WaitPlayerList.DelNode(df->m_index);
    }
    if(opc && opc->m_pZone->IsWarGroundZone())
    {
        // 전장포인트 1포인트 지급
        opc->AddWarGroundPoint(1);

        // 전장 kill수 1 증가
        opc->AddKillCount(1);
    }

    ProcDeadQuestProc(df, opc);

    // rvr 룰 적용
    if (df->m_pZone->isRVRZone())
    {
        ProcRVR(df, of);
    }

    if( ArtifactManager::instance()->isOwnerPC(df->m_index) == true )
    {
        if(IS_PC(of))
        {
            //pvp를 당했는데 수비자가 유물을 갖고 있는 상태라면 공격자에게 아이템 양도
            ArtifactManager::instance()->hunt(df, TO_PC(of));
        }
        else
        {
            //이외에 죽임을 당했다면 아이템 서버로 반납
            ArtifactManager::instance()->dead(df);
        }
    }

#ifdef HARDCORE_SERVER
    if (gserver->m_hardcore_flag_in_gameserver)
    {
        switch (df->m_pZone->m_index )
        {
        case ZONE_START:
        {
            if (df->GetJoinFlag(df->m_pZone->m_index) == WCJF_NONE)	// 공성중이 아니고
            {
                if ( !(df->GetMapAttr() & MATT_FREEPKZONE) )
                {
                    df->m_desc->Make_1_Level();
                }
            }
        }
        break;

        case ZONE_FREE_PK_DUNGEON:
        case ZONE_PK_TOURNAMENT:
        case ZONE_ROYAL_RUMBLE:
        case ZONE_RVR:
            break;

        default:
        {
            if (df->GetJoinFlag(df->m_pZone->m_index) == WCJF_NONE)	// 공성중이 아니면
            {
                df->m_desc->Make_1_Level();
            }
        }
        break;
        } // end if
    }
#endif
}
コード例 #6
0
bool local_exchangeWeapon(CPC* ch, CItem* item, bool bprolong, RequestClient::doItemUse* packet)
{
	int extra1 = packet->extra_1;
	int extra2 = packet->extra_2;

	CItem* vitem = ch->m_inventory.FindByVirtualIndex(extra1);
	if (!vitem)
		return false;

	if (!vitem->IsWeaponType())
		return false;

	if (vitem->m_itemProto->getItemSubTypeIdx() == extra2)
		return false;

	if (extra2 < 0 || extra2 >= 16)
		return false;

	int itemlevel = vitem->GetItemLevel();

	// 레벨, 한손검, 석궁, 스태프, 대검, 도끼, 숏스테프, 활, 단검, -1, -1, -1, 이도류, 완드, 사이드, 폴암 : 할일 : 소서러
	const static int matchTable[12][16] =
	{
		{1,48,530,600,12,558,356,50,528,-1,-1,-1,459,599,-1,-1},
		{5,53,666,628,51,601,357,56,529,-1,-1,-1,610,619,-1,-1},
		{9,55,637,629,52,602,358,57,532,-1,-1,-1,611,620,-1,-1},
		{13,107,638,630,105,603,359,106,533,-1,-1,-1,612,621,-1,-1},
		{17,180,639,631,306,604,360,185,534,-1,-1,-1,613,622,-1,-1},
		{21,322,640,632,307,605,361,341,535,-1,-1,-1,614,623,-1,-1},
		{25,323,641,633,308,606,362,342,536,-1,-1,-1,615,624,-1,-1},
		{29,324,642,634,309,607,363,343,537,-1,-1,-1,616,625,983,995},
		{33,325,643,635,310,608,364,344,538,-1,-1,-1,617,626,984,-996},
		{37,326,644,636,311,609,365,345,539,-1,-1,-1,618,627,985,997},
		{41,681,721,719,715,645,720,718,722,-1,-1,-1,716,717,986,998},
		{45,800,823,816,793,794,815,808,822,-1,-1,-1,801,809,987,999}
	};

	CItemProto* proto = NULL;
	int i;
	for (i = 0; i < 12; i++)
	{
		if (matchTable[i][0] == itemlevel)
		{
			proto = gserver->m_itemProtoList.FindIndex(matchTable[i][extra2 + 1]);
			break;
		}
	}

	if (proto == NULL)
		return false;

	CItem* newitem = gserver->m_itemProtoList.CreateItem(proto->getItemIndex(), -1, vitem->getPlus(), vitem->getFlag(), 1);
	if (!newitem)
		return false;

	GAMELOG << init("CASHITEM_CHANGE_WEAPON_WITHOUT OPTION", ch)
			<< "OLD" << delim
			<< itemlog(vitem) << delim;

	GAMELOG << "NEW" << delim
			<< itemlog(newitem) << delim;

	ch->m_inventory.decreaseItemCount(vitem, 1);

	if (ch->m_inventory.addItem(newitem) == false)
	{
		ch->m_pArea->DropItem(newitem, ch);
		newitem->m_preferenceIndex = ch->m_index;

		CNetMsg::SP rmsg(new CNetMsg);
		ItemDropMsg(rmsg, ch, newitem);
		ch->m_pArea->SendToCell(rmsg, GET_YLAYER(newitem), newitem->m_cellX, newitem->m_cellZ);
		GAMELOG << "DROP"
				<< end;
	}

	return true;
}
コード例 #7
0
// 펫 사망시 아이템 지급
bool DropPetItem(CPet* pet)
{
	bool bRet = false;

	CPC* owner = pet->GetOwner();

	if (owner)
	{
		const int nHorseDropList = 8;
		const int nDragonDropList = 12;

		int horseDropList[nHorseDropList][2] =
		{
			{886, 70},			// 말굽
			{888, 30},			// 말의갈기
			{889, 70},			// 말총
			{890, 30},			// 말의등뼈
			{891, 70},			// 말의어금니
			{892, 70},			// 말의피
			{893, 30},			// 말가죽
			{894, 100}			// 말의힘줄
		};
		int dragonDropList[nDragonDropList][2] =
		{
			{895, 45},			// 발톱
			{896, 45},			// 날개
			{897, 45},			// 송곳니
			{898, 45},			// 눈알
			{899, 45},			// 뿔
			{900, 45},			// 힘줄
			{901, 45},			// 가죽
			{902, 45},			// 꼬리
			{903, 45},			// 피
			{904, 45},			// 심장
			{905, 45},			// 루비
			{906, 45},			// 등뼈
		};

		// 펫 종류에 따라 드롭 테이블 변경
		bool bNoDrop = true;
		int i;
		int prob = GetRandom(1, 10000);
		int selIndex = 0;	// 아이템 인덱스
		int nStartIndex;
		int j;

		switch (pet->GetPetType())
		{
		case PET_TYPE_HORSE:
		case PET_TYPE_BLUE_HORSE:
		case PET_TYPE_UNKOWN_HORSE:
			nStartIndex = GetRandom(0, nHorseDropList - 1);
			for (i = 0; i < nHorseDropList; i++)
			{
				j = (i + nStartIndex) % nHorseDropList;
				horseDropList[j][1] = horseDropList[j][1] * pet->m_level / 2;
				if (i > 0)
				{
					horseDropList[j][1] += horseDropList[(j + nHorseDropList - 1) % nHorseDropList][1];
				}

				if (prob <= horseDropList[j][1])
				{
					selIndex = horseDropList[j][0];
					bNoDrop = false;
					break;
				}
			}
			break;
		case PET_TYPE_DRAGON:
		case PET_TYPE_PINK_DRAGON:
		case PET_TYPE_UNKOWN_DRAGON:
			nStartIndex = GetRandom(0, nDragonDropList - 1);
			for (i = 0; i < nDragonDropList; i++)
			{
				j = (i + nStartIndex) % nDragonDropList;
				dragonDropList[j][1] = dragonDropList[j][1] * pet->m_level / 2;
				if (i > 0)
					dragonDropList[j][1] += dragonDropList[(j + nDragonDropList - 1) % nDragonDropList][1];

				if (prob <= dragonDropList[j][1])
				{
					selIndex = dragonDropList[j][0];
					bNoDrop = false;
					break;
				}
			}
			break;
		default:
			bNoDrop = true;
		}

		if (!bNoDrop)
		{
			CItem* dropItem = gserver->m_itemProtoList.CreateItem(selIndex, -1, 0, 0, 1);
			if (dropItem)
			{
				// TODO : petlog
				GAMELOG << init("PET ITEM CHANGE")
						<< "PET" << delim
						<< pet->GetPetTypeGrade() << delim
						<< "INDEX" << delim
						<< pet->m_index << delim
						<< "LEVEL" << delim
						<< pet->m_level << delim
						<< "OWNER" << delim
						<< owner->m_index << delim
						<< owner->GetName() << delim
						<< "ITEM" << delim
						<< itemlog(dropItem, true) << delim;

				bool bDrop = false;
				if (owner->m_inventory.addItem(dropItem) == false)
				{
					owner->m_pArea->DropItem(dropItem, owner);
					dropItem->m_preferenceIndex = owner->m_index;
					CNetMsg::SP rmsg(new CNetMsg);
					ItemDropMsg(rmsg, owner, dropItem);
					owner->m_pArea->SendToCell(rmsg, GET_YLAYER(dropItem), dropItem->m_cellX, dropItem->m_cellZ);
					bDrop = true;
				}

				GAMELOG << ((bDrop) ? "DROP" : "GIVE")
						<< end;

				bRet = true;
			}
		}
	}

	return bRet;
}