Exemplo n.º 1
0
BOOL CPlayerPet::Init(const DT_PLAYER_PET_DATA& rPetData, CPlayer *pPlayer) {
	if (NULL == pPlayer) {
		return FALSE;
	}

	m_poOwner = pPlayer;
	m_PlayerPetData = rPetData;
	m_PlayerPetData.stPetNeiDan.wPetNum = m_PlayerPetData.stPetDataLst.wPetNum;
	const DT_PET_DATA_LIST& rPetDataLst = rPetData.stPetDataLst;
	for (size_t n = 0; n < rPetDataLst.wPetNum && n < MAX_PET_NUM; ++n) 
	{
		const DT_PET_DATA& rPetData = rPetDataLst.astPetData[n];
		CPet* pPet = CREATE_PET_OBJ(pPlayer->GetPlayerID(), rPetData.wPetId);
		if (NULL == pPet) {
			return FALSE;
		}
		pPet->Init(rPetData, pPlayer, m_PlayerPetData.stPetNeiDan.astNeiDanInfo[n]);
		m_mpPet.insert(make_pair(rPetData.wPetId, pPet));
	}

	m_PlayerPetData.byHaveDataFlag = 1;
	for ( UINT16 wIdx = 0; wIdx < rPetData.stPetCallData.wPetNum; wIdx++)
	{
		m_mapCallInfo[rPetData.stPetCallData.astCallInfo[wIdx].wPetCfgID] =  rPetData.stPetCallData.astCallInfo[wIdx];
	}

    CheckCrossDay();
	return TRUE;
}
Exemplo n.º 2
0
const CPet* CPlayerPet::AddPet(const DT_PET_DATA& rPetData) {
	if (m_mpPet.size() >= MAX_PET_NUM) {
		return NULL;
	}

	UINT16 usPetId = generatePetId();
	CPet* pNewPet = CREATE_PET_OBJ(m_poOwner->GetPlayerID(), usPetId);
	if (NULL == pNewPet) {
		return NULL;
	}

	DT_PET_NEIDAN_DATA_LST stNeiDan = {0};
	pNewPet->Init(rPetData, m_poOwner, stNeiDan);
	pNewPet->SetPetId(usPetId);

	m_mpPet.insert(make_pair(usPetId, pNewPet));
	UpdatePetLstData();
	map<UINT16, DT_PET_CALL_DATA>::iterator itr = m_mapCallInfo.find(rPetData.wPetCfgId);
	if ( itr == m_mapCallInfo.end())
	{
		DT_PET_CALL_DATA stData = {0};
		stData.wPetCfgID = rPetData.wPetCfgId;
		stData.dwPetCallNum = 1;
		m_mapCallInfo[stData.wPetCfgID] = stData;
		SetRuleState(TRUE);
	}
	else
	{
		itr->second.dwPetCallNum++;
	}
	return pNewPet;
}
Exemplo n.º 3
0
bool NormalCloseInAttackAI::StepEndAI()
{
    if(m_pSkill)
    {
        CMoveShape* pMoveshape = dynamic_cast<CMoveShape*>(GetGame()->GetRegion()->FindChildObject(m_pSkill->GetSourType(), m_pSkill->GetSourID()));
        if(pMoveshape)
        {
            AnimInfo::tagActionInfo *pActionInfo = pMoveshape->GetAnimInfo()->GetActionInfo();
            if(pActionInfo && pMoveshape->GetAction() >= CShape::ACT_PERFORM)
            {
                pActionInfo->bCurActionLooped = FALSE;
            }
        }
        if (pMoveshape->GetType() == TYPE_PET)
        {
            CPet *pPet = (CPet*)pMoveshape;
            if (pPet->IsMainPlayerPet())
            {
                tagPetSkillInfo *pPetSkill = pPet->GetPetSkillInfoByID(m_pSkill->GetSkillID());
                if(pPetSkill)
                    pPetSkill->bIsSkillUsingEnd = true;
                //pPet->SkillSuccReceived();
            }
        }
        // 删除特效
        m_pSkill->DelAllEffectListByStep(CSkillXml::STEP_START);
        m_pSkill->DelAllEffectListByStep(CSkillXml::STEP_RUN);
        m_pSkill->DelAllEffectListByStep(CSkillXml::STEP_END);
        m_pSkill->SetIsDeleted(true);
        return true;
    }
    return false;
}
Exemplo n.º 4
0
VOID CSkillMgr::AddBuff(CBattleAttrObj* poSkillOwner, CBattleAttrObj* poTargetObj, UINT16 wSkillID, const SSkillOnceBuffProp& stBuffProp)
{
    //判断添加BUFF概率
    static UINT32 dwSeed = 0;
    dwSeed = (GetCycleCount() + (dwSeed++)) << 7;
    SDSetSeed(dwSeed);
    if(SDRandom(100) > stBuffProp.byBuffRate)
    {
        return;
    }

    CBuff* poBuff = CBuffMgr::Instance()->CreateBuff();
    if(NULL == poBuff)
    {
        return ;
    }
    if(!poBuff->Init(wSkillID, stBuffProp.byBuffKindID, poSkillOwner, poTargetObj, stBuffProp.wBuffParam, stBuffProp.byBuffRound))
    {
        CBuffMgr::Instance()->RemoveBuff(poBuff->GetMemID());
        return ;
    }
    if(!poTargetObj->AddBuff(poBuff))
    {
        CBuffMgr::Instance()->RemoveBuff(poBuff->GetMemID());
        return ;
    }
    CPet* poPet = dynamic_cast<CPet*>(poSkillOwner);
    if ( NULL != poPet)
    {
        poBuff->SetExtValue(poPet->GetLastHurt());
    }
}
Exemplo n.º 5
0
 void PetAI::OnReturnPeace()
 {
     CPet *pet = (CPet*) GetOwner();
     if(!pet->IsDied() && !pet->IsHangUp())
     {
         ChangeStateTo(CShape::STATE_PEACE);
     }
 }
Exemplo n.º 6
0
 bool PetAI::OnMove(float destX, float destY)
 {
     if(!BaseAI::OnMove(destX, destY))
     {
         return false;
     }
     CPet *pet = (CPet*) GetOwner();
     // add ai event to search enemy when moving
     if(pet->GetFightType() == PET_FIGHETYPE_FIGHT && !HasTarget())
     {
         Resume(CONTINUE_TIME);
     }
     return true;
 }
void ProcDead(CElemental* df, CCharacter* of)
{
	CPC*		opc				= NULL;
	CNPC*		onpc			= NULL;
	CPet*		opet			= NULL;
	CAPet*		oapet			= NULL;
	CElemental*	oelemental		= 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);
		break;

	case MSG_CHAR_NPC:
		onpc = TO_NPC(of);
		break;

	case MSG_CHAR_PET:
		opet = TO_PET(of);
		opc = opet->GetOwner();
		break;

	case MSG_CHAR_ELEMENTAL:
		oelemental = TO_ELEMENTAL(of);
		opc = oelemental->GetOwner();
		break;
	case MSG_CHAR_APET:
		oapet = TO_APET(of);
		opc = oapet->GetOwner();
		break;

	default:
		return ;
	}

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

	DelAttackList(df);

	CPC* owner = df->GetOwner();
	if (owner)
		owner->UnsummonElemental(df);
}
Exemplo n.º 8
0
bool CFixSummonAI::StepEndAI()
{
	DelAllEffect();
	m_pSkill->SetIsDeleted(true);
	CMoveShape* pMoveshape = dynamic_cast<CMoveShape*>(GetGame()->GetRegion()->FindChildObject(m_pSkill->GetSourType(), m_pSkill->GetSourID()));
	if(pMoveshape && pMoveshape->GetType() == TYPE_PET)
	{
		CPet *pPet = (CPet*)pMoveshape;
		if (pPet->IsMainPlayerPet())
		{
			tagPetSkillInfo *pPetSkill = pPet->GetPetSkillInfoByID(m_pSkill->GetSkillID());
			if(pPetSkill)
				pPetSkill->bIsSkillUsingEnd = true;
		}
	}
	return true;
}
	bool OnGS2C_LookInfoPet(GS2C_LookInfoPet *value)
	{
		if ( !gMap )
		{
			return false;
		}

		TIME_COST_BEGIN;
		CPet* pPet = CPet::create();
		TIME_COST_LOG_IF("OnGS2C_LookInfoPet CPet::create",3);
		if ( pPet )
		{
			pPet->SetMasterID(value->masterId);		// 设置主人ID
			pPet->SetId(value->id);
			pPet->SetRoleName(value->name);
			pPet->SetDataID(value->dataId);
			pPet->SetMoveSpeed(value->moveSpeed);
			pPet->SetLevel(value->level);

			pPet->SetStateFlag(value->status);

			pPet->SetProperty(RoleProperty_HP,value->hp);
			pPet->SetProperty(RoleProperty_hp_max,value->hpMax);
			pPet->SetProperty(RoleProperty_MP,value->mp);
			pPet->SetProperty(RoleProperty_mp_max,value->mpMax);

			pPet->EnterMap(gMap,value->x,value->y);
			if ( value->posInfos.size() > 0 )
			{
				APath path;
				CHero::PosInfoToPath(value->x,value->y,value->posInfos,path);
				pPet->Move(path,value->movedMs);
			}
		}

		return true;
	}
Exemplo n.º 10
0
// 响应SKILL消息
void OnSkillMessage(CMessage* pMsg)
{
	switch(pMsg->GetType())
	{
	case MSG_S2C_SKILL_LOCK_GOODS:
		{
			long lExtendID = pMsg->GetLong();
			long lPos = pMsg->GetLong();
			CPlayer* pMainPlayer = GetGame()->GetMainPlayer();
			if (pMainPlayer!=NULL)
			{
				CGoods* pGoods = pMainPlayer->GetGoodsByPosition(lExtendID,lPos);
				if (pGoods!=NULL&&!pGoods->IsLocked())
				{
					pGoods->Lock();
					//CItemPageEx* pPage = GetGame()->GetCGuiEx()->GetItemPageEx();
					//if (pPage!=NULL)
					//{
					//	pPage->UpdateGoodsShow(lExtendID,(int)lPos);
					//}
				}
			}
		}
		break;
	case MSG_S2C_SKILL_UNLOCK_GOODS:
		{
			DWORD lExtendID = pMsg->GetDWord();
			DWORD lPos = pMsg->GetDWord();
			CPlayer* pMainPlayer = GetGame()->GetMainPlayer();
			if (pMainPlayer!=NULL)
			{
				CGoods* pGoods = pMainPlayer->GetGoodsByPosition(lExtendID,lPos);
				if (pGoods!=NULL&&pGoods->IsLocked())
				{
					pGoods->UnLock();
					CMainPlayerHand* pHand = 0;//GetGame()->GetCGuiEx()->GetPMainPlayerHand();
					if (pHand!=NULL&&pHand->GetPGoodsOfMainPlayerHand()!=NULL&&
						pHand->GetPGoodsOfMainPlayerHand()->GetExID()==pGoods->GetExID())
					{
						pGoods->SetHaveShadowState(true);
					}
				}
			}
		}
		break;
	case MSG_S2C_SKILL_STATE_CHANGE:
		//##同步状态消息
		{
			LONG lType	= pMsg -> GetLong();
			CGUID ID;
			pMsg->GetGUID(ID);
			DWORD dwHP	= pMsg -> GetDWord();
			WORD wMP	= pMsg -> GetWord();
			WORD eg		= pMsg -> GetWord();
			if(lType==TYPE_PLAYER)
			{
				CPlayer* pMainPlayer = pMsg -> GetPlayer();
				//是自己则改变自己
				if(pMainPlayer->GetExID() == ID)
				{
					pMainPlayer -> SetHp( dwHP );
					pMainPlayer -> SetMp(wMP);
					pMainPlayer -> SetEnergy(eg);
					//pMainPlayer -> SetRP( wRP );
					//pMainPlayer -> SetYP( wYP );
				}
				else
				{
					//看是否是队友
					vector<CPlayer::tagTeammate>& vTeammate = pMainPlayer -> GetTeam();
					for( size_t i = 0; i < vTeammate.size(); i ++ )
					{
						if( vTeammate[i].ID == ID )
						{
							vTeammate[i].wHP = (WORD)dwHP;
							break;
						}
					}
				}
			}
			else
			{
				//改变怪物状态
				CMoveShape* pShape = (CMoveShape*)GetGame()->GetRegion()->FindChildObject(lType, ID);
				if (pShape)
				{
					pShape->SetHp(dwHP);
				}
			}
		}
		break;
	case MSG_S2C_SKILL_USE:
		{
			CHAR cResult = pMsg->GetChar();
			DWORD dwCurTime = GetCurTickCount();
			switch(cResult)
			{
			case SKILL_USE_RESULT_BEGIN:
				{
					CGUID ID;
					pMsg->GetGUID(ID);						

					float fDir = pMsg->GetFloat();			// 释放者朝向

					long lSkillKey = pMsg->GetDWord();		// 从服务器取得技能键值和ID
					long lSkillID = pMsg -> GetLong();
					long lLevel = pMsg->GetByte();			// 技能等级
					long lCurType = pMsg->GetByte();		// 技能的释放状态(吟唱/释放)
					long lTime = pMsg->GetLong();			// 技能的吟唱时间(吟唱阶段有用)
					long lRestoreTime = pMsg->GetLong();	// 技能的冷却时间

					long lDestX = pMsg->GetShort();			// 释放目标的坐标(x,y)
					long lDestY = pMsg->GetShort();	
					long lTypeSize = pMsg->GetByte();		// 释放目标的个数
					vector<long> vecType;					// 目标类型列表
					vector<CGUID> vecID;					// 目标类型的GUID
					CGUID destID;
					for (int i =0; i<lTypeSize; i++)
					{
						vecType.push_back(pMsg->GetLong());
						pMsg->GetGUID(destID);
						vecID.push_back(destID);
					}
					// 确定基本攻击技能
					if(lSkillID == SKILL_BASE_BUFF)
						lSkillID = GetGame()->GetMainPlayer()->GetDefaultAttackSkillID();
					// 技能释放者
					CMoveShape* pMoveShape = (CMoveShape*)pMsg->GetRegion()->FindChildObject(ID);
					if(pMoveShape)
					{
						long lType = pMoveShape->GetType();
						//判断是否是怪物,如果是怪物,播放怪物音效
						if(lType == TYPE_MONSTER)
						{
							GetGame()->GetAudioList()->Play(pMoveShape,TYPE_MONSTER,0xFFF0,Vector3(pMoveShape->GetPosY(),pMoveShape->GetHeight(),pMoveShape->GetPosX()));
						}

						if(lCurType == 1)		// 吟唱阶段
						{
							CPlayer::tagSkill *ptagS = GetGame()->GetMainPlayer()->GetSkill(lSkillID);
							if(ptagS)
							{
                                UpdateHotKeyCoolDownEffect(lSkillID);
							}
							if(pMoveShape->GetType() == TYPE_PET)
							{
								CPet *pPet = (CPet*)pMoveShape;
								//更新当前技能的开始冷却时间
								tagPetSkillInfo *pSkill = pPet->GetPetSkillInfoByID(lSkillID);
								if(pSkill)
									pSkill->lRestorTimeLength = lRestoreTime;

								pPet->SkillSuccReceived();
							}
							/***********************************************************************/
							/* 赵航 fix */
							//CSkillXml *m_pSkill = new CSkillXml();
							/***********************************************************************/
							ConcreteSkillComp* SkillCom = new ConcreteSkillComp();
							//SkillCom的内存交给了CSkillXml的析构来管理
							CSkillXml* pSkill = new ConcreteDecSkillXml(SkillCom); 
							CSkillListXml::tagSkill *pTagSkill = CSkillListXml::GetProperty(lSkillID);
							if (pTagSkill && pTagSkill->dwSkillType == CSkillListXml::SKILLTYPE_PLAY)	// 直接施放
							{
								// 引导类技能添加吟唱条显示时间
								DWORD dwlev = pTagSkill->vectorLevels.size() >= (DWORD)lLevel? (DWORD)lLevel-1:((DWORD)pTagSkill->vectorLevels.size() - 1);
								long lAiID = pTagSkill->vectorLevels[dwlev].dwSkillLevelAI;
								if(pTagSkill->bIsLead)
									pSkill->IntonateTime(lTime);
								// 直接从开始阶段执行
								if(pSkill->StepBegin(lSkillID, lLevel, lType, ID, lDestX, lDestY,fDir,vecType, vecID))
								{
									pSkill->SetSkillKey(lSkillKey);
									pMoveShape->AddCurSkillList(lSkillKey,pSkill);
								}
								else
									SAFE_DELETE(pSkill);
								// 如果开始阶段成功就直接执行施放阶段
								if(pSkill&&pSkill->StepRun(lSkillID, lLevel, lType, ID, lDestX, lDestY, fDir, vecType, vecID) == false)
								{
									//pSkill->SetIsDeleted(true);
									pMoveShape->DeleteCurSkill(lSkillKey);
								}
								if(lType == TYPE_PLAYER )
								{
									if (GetGame()->GetMainPlayer()->GetExID()==ID)
									{
										GetGame()->GetGameControl()->SetControlAble(true);
										GetGame()->GetGameControl()->SetMoveAble(true);
										/***********************************************************************/
										/* zhaohang fix */
										/***********************************************************************/
										// 引导类技能
										if(pTagSkill->bIsLead)
											GetGame()->GetMainPlayer()->SetIntonateSkillKey(lSkillKey);
										else
											GetGame()->GetMainPlayer()->SetIntonateSkillKey(0);
										// 自动攻击累计发送次数清0
										GetGame()->GetGameControl()->SetSendedUseSkillMsgCount(0);
										if(g_bDebug)
										{
											Log4c::Trace(ROOT_MODULE,"直接使用技能,次数清0:%d,key:%d",lSkillID,lSkillKey);
										}
									}else if (lSkillID>=50000&&lSkillID<=50006)
									{
										if (lSkillID>=50000&&lSkillID<=50002)
										{
											((CPlayer*)pMoveShape)->SetToolsID(CDeputyOccuSystemClient::OB_Collection);
										}else if (lSkillID>=50003&&lSkillID<=50005)
										{
											((CPlayer*)pMoveShape)->SetToolsID(CDeputyOccuSystemClient::OB_Facture);
										}else if (lSkillID==50006)
										{
											((CPlayer*)pMoveShape)->SetToolsID(CDeputyOccuSystemClient::OB_TaskCollection,lLevel);
										}
									}
									/////////////////////////////////////////////////////////////////
									//char strInfo[512]="";
									//_snprintf(strInfo,512,"SKILLTYPE_PLAY_Set Intonate Skill Key:%d",0);
									//PutStringToFile("IntonateSkillTest",strInfo);
									/////////////////////////////////////////////////////////////////
								}
								else if (lType == TYPE_PET)
								{
										CPet *pPet = (CPet*)pMoveShape;
										if (pPet->IsMainPlayerPet())
										{
											/***********************************************************************/
											/* zhaohang fix */
											/***********************************************************************/
											if(pTagSkill->bIsLead)
												pPet->SetIntonateSkillKey(lSkillKey);
											else
												pPet->SetIntonateSkillKey(0);
										}
								}
							}
							else if(pTagSkill && pTagSkill->dwSkillType == CSkillListXml::SKILLTYPE_INTONATE) // 吟唱施放
							{
								pSkill->IntonateTime(lTime);
								if(g_bDebug && lType == TYPE_PLAYER)
								{
									dwCurTime = GetCurTickCount();
									Log4c::Trace(ROOT_MODULE,"吟唱技能设置时间:%d,%d,%d",lSkillID,lTime,dwCurTime);
								}
								/***********************************************************************/
								/* zhaohang fix */
								/***********************************************************************/
								bool bIsLead = pTagSkill->bIsLead;
								pTagSkill->bIsLead = false;
								if(pSkill->StepBegin(lSkillID, lLevel, lType, ID, lDestX, lDestY,fDir,vecType, vecID))
								{
									/***********************************************************************/
									/* zhaohang fix */
									/***********************************************************************/
									pTagSkill->bIsLead = bIsLead;
									pSkill->SetSkillKey(lSkillKey);
									pMoveShape->AddCurSkillList(lSkillKey,pSkill);
								}
								else
									SAFE_DELETE(pSkill);
								if( lType == TYPE_PLAYER )
								{
									if (GetGame()->GetMainPlayer()->GetExID()==ID)
									{
										// 吟唱阶段允许玩家移动取消技能
										GetGame()->GetGameControl()->SetControlAble(true);
										GetGame()->GetGameControl()->SetMoveAble(true);
										GetGame()->GetMainPlayer()->SetIntonateSkillKey(lSkillKey);

										// 自动攻击累计发送次数清0
										GetGame()->GetGameControl()->SetSendedUseSkillMsgCount(0);
										/*if(g_bDebug)
										{
											char strInfo[512]="";
											_snprintf(strInfo,512,"技能吟唱中,次数清0:%d,key:%d",lSkillID,lSkillKey);
											PutStringToFile("SkillTimesTest",strInfo);
										}*/
									}else if (lSkillID>=50000&&lSkillID<=50006)
									{
										if (lSkillID>=50000&&lSkillID<=50002)
										{
											((CPlayer*)pMoveShape)->SetToolsID(CDeputyOccuSystemClient::OB_Collection);
										}else if (lSkillID>=50003&&lSkillID<=50005)
										{
											((CPlayer*)pMoveShape)->SetToolsID(CDeputyOccuSystemClient::OB_Facture);
										}else if (lSkillID==50006)
										{
											((CPlayer*)pMoveShape)->SetToolsID(CDeputyOccuSystemClient::OB_TaskCollection,lLevel);
										}
									}

									/////////////////////////////////////////////////////////////////
									//char strInfo[512]="";
									//_snprintf(strInfo,512,"SKILLTYPE_INTONATE_Set Intonate Skill Key:%d",lSkillKey);
									//PutStringToFile("IntonateSkillTest",strInfo);
									/////////////////////////////////////////////////////////////////
								}
							}
							else
							{
								SAFE_DELETE(pSkill);
								return;
							}
							pMoveShape->SetDirEx(fDir);
							// 更新快捷栏的冷却动画
							if(pMoveShape==GetGame()->GetMainPlayer())
							{
								GetGame()->GetMainPlayer()->UpdateSkillCoolDownTime(true);
								//CSkillListXml::tagSkill *pS = CSkillListXml::GetProperty(lSkillID);
								/***********************************************************************/
								/* zhaohang fix */
								/***********************************************************************/
								if(ptagS && pTagSkill && pTagSkill->dwSkillState != 0 && !pTagSkill->bLockSkill)
								{
									ptagS->dwUseingStartTime = timeGetTime();
								}
							}

						}
						else					// 施放阶段
						{
							/***********************************************************************/
							/* 赵航 fix */
							//CSkillXml *m_pSkill = new CSkillXml();
							/***********************************************************************/
							ConcreteSkillComp* SkillCom = new ConcreteSkillComp();
							//SkillCom的内存交给了CSkillXml的析构来管理
							CSkillXml* pSkill = new ConcreteDecSkillXml(SkillCom); 
							pSkill->IntonateTime(lTime);
							if(pSkill&&pSkill->StepRun(lSkillID, lLevel, lType, ID, lDestX, lDestY, fDir, vecType, vecID) )
							{
								pSkill->SetSkillKey(lSkillKey);
								pMoveShape->AddCurSkillList(lSkillKey,pSkill);
								CSkillListXml::tagSkill *pTagSkill = CSkillListXml::GetProperty(lSkillID);
								// 引导类技能
								if(pTagSkill && pTagSkill->bIsLead)
									GetGame()->GetMainPlayer()->SetIntonateSkillKey(lSkillKey);
							}
							else
							{
								SAFE_DELETE(pSkill);
							}

							if(lType == TYPE_PLAYER )
							{
								if (GetGame()->GetMainPlayer()->GetExID()==ID)
								{
									GetGame()->GetGameControl()->SetControlAble(true);

									GetGame()->GetMainPlayer()->SetIntonateSkillKey(0);

									// 自动攻击累计发送次数清0
									GetGame()->GetGameControl()->SetSendedUseSkillMsgCount(0);
									if(g_bDebug)
									{
										Log4c::Trace(ROOT_MODULE,"吟唱技能释放阶段,次数清0,吟唱清空:%d,key:%d",lSkillID,lSkillKey);
									}
								}
								if (lSkillID>=50000&&lSkillID<=50006)
								{
									((CPlayer*)pMoveShape)->SetToolsID(0);
								}
								/////////////////////////////////////////////////////////////////
								//char strInfo[512]="";
								//_snprintf(strInfo,512,"STEP_PLAY Set Intonate Skill Key:%d",0);
								//PutStringToFile("IntonateSkillTest",strInfo);
								/////////////////////////////////////////////////////////////////
							}
						}
					}
					else
					{
						/////////////////////////////////////////////////////////////start
						//test add or delete shape,(author:wangqiao)
						char pszTestInfo[1024]="";
						char pszGUID[64]="";
						ID.tostring(pszGUID);
						//_snprintf(pszTestInfo,1024,"When Use skill,the Firer is not exist.(type:%d,id:%s)",
						//	lType,pszGUID);
						//PutStringToFile("AddDelShapeTest",pszTestInfo);
						////////////////////////////////////////////////////////////end
					}
				}
				break;
			case SKILL_USE_RESULT_END:
				{
					CGUID ID;
					pMsg->GetGUID(ID);
					float fDir = pMsg->GetFloat();
					long lSkillKey = pMsg->GetDWord();				// 从服务器取得技能键值

					long lSkillID = pMsg -> GetLong();
					long lLevel = pMsg->GetByte();

					long lCurType = pMsg->GetByte();
					CMoveShape* pMoveShape = (CMoveShape*)pMsg->GetRegion()->FindChildObject(ID);
					if(pMoveShape)
					{
						long lType = pMoveShape->GetType();
						CSkillXml* pSkill = pMoveShape->GetCurSkill(lSkillKey);
						if(pSkill)
						{
							pSkill->StepEnd(lSkillID, lLevel, lType, ID, fDir);
							pMoveShape->DeleteCurSkill(lSkillKey);
						}

						if(lType == TYPE_PLAYER )
						{
							if (lSkillID>=50000&&lSkillID<=50006)
							{
								((CPlayer*)pMoveShape)->SetToolsID(0);
							}
							if(GetGame()->GetMainPlayer()->GetExID() == ID)
							{
								// 自动攻击累计发送次数清0
								GetGame()->GetGameControl()->SetSendedUseSkillMsgCount(0);
								GetGame()->GetGameControl()->SetControlAble(true);
								// 结束的技能是正在吟唱的技能,取消吟唱
								if(lSkillKey == GetGame()->GetMainPlayer()->GetIntonateKey())
									//|| lSkillID == GetGame()->GetMainPlayer()->GetIntonateState())
								{
									GetGame()->GetMainPlayer()->SetCurIntonateTime(0,0);
									GetGame()->GetMainPlayer()->SetIntonateSkillKey(0);
									if(g_bDebug)
									{
										Log4c::Trace(ROOT_MODULE,"技能结束,吟唱清空,次数清0:%d,key:%d",lSkillID,lSkillKey);
									}
								}
								else
								{
									// 光环类技能重设使用状态
									CPlayer::tagSkill *ptagS = GetGame()->GetMainPlayer()->GetSkill(lSkillID);
									if(ptagS)
										ptagS->dwUseingStartTime = 0;
								}
								// 当使用的是制作的技能时,进行特殊的处理
								if (lSkillID>=50003&&lSkillID<=50005)
								{
									//CFacturePageEx* pFacturePage = GetGame()->GetCGuiEx()->GetFacturePageEx();
									//if (lCurType==2&&pFacturePage!=NULL)
									//{
									//	pFacturePage->UpdateInputNum();
									//	pFacturePage->SetFactureState(false);
									//	if ((CFacturePageEx::eErrorNotice)pFacturePage->IsCanFacture()==CFacturePageEx::eErrorNotice_NoError)
									//	{
									//		pFacturePage->SendFactureOneMes();
									//	}
										//pFacturePage->UpdateFactureLevelExpProcessBar();
									//}		
								}
							}
						}
						if (lType == TYPE_PET)
						{
							CPet *pPet = (CPet*)pMoveShape;
							if (pPet->IsMainPlayerPet())
							{
								if(lSkillKey == pPet->GetIntonateKey()
									&& lSkillID == pPet->GetIntonateState())
								{
									GetGame()->GetMainPlayer()->SetCurIntonateTime(0,0);
									GetGame()->GetMainPlayer()->SetIntonateSkillKey(0);
								}
								tagPetSkillInfo *pPetSkill = pPet->GetPetSkillInfoByID(lSkillID);
								if(pPetSkill)
									pPetSkill->bIsSkillUsingEnd = true;
							}
						}
					}
				}
				break;
			case SKILL_USE_RESULT_FAILED:
				CGUID ID;
				pMsg->GetGUID(ID);

				long lSkillID = pMsg->GetLong();
				long lLevel = pMsg->GetByte();

				long lSkillKey = pMsg->GetLong();
				long lFaildRet = pMsg->GetByte();
				// 将该技能结束
				CMoveShape* pMoveShape = (CMoveShape*)pMsg->GetRegion()->FindChildObject(ID);
				if(pMoveShape)
				{
					long lType = pMoveShape->GetType();
					CSkillXml* pSkill = pMoveShape->GetCurSkill(lSkillKey);
					if(pSkill)
					{
						pSkill->StepEnd(lSkillID, lLevel, lType, ID, pMoveShape->GetDirEx());
						pMoveShape->DeleteCurSkill(lSkillKey);
					}
					if(pMoveShape->GetType() == TYPE_PET)
					{
						CPet *pPet = (CPet*)pMoveShape;
						tagPetSkillInfo *pPetSkill = pPet->GetPetSkillInfoByID(lSkillID);
						if(pPetSkill)
							pPetSkill->bIsSkillUsingEnd = true;
						pPet->SkillFailReceived();
					}
					// 其他对象的技能,不提示
					if( pMoveShape == GetGame()->GetMainPlayer())
					{
						// 自动攻击累计发送次数清0
						GetGame()->GetGameControl()->SetSendedUseSkillMsgCount(0);
						// 如果是本玩家释放的技能,且失败技能为连续技能,停止本玩家自动攻击状态
						CSkillListXml::tagSkill *pS = CSkillListXml::GetProperty(lSkillID);
						if(pS && pS->bLockSkill)
						{
							// 连续攻击技能的mp不足,切换到基本攻击
							if(lFaildRet == SKILL_USE_FAILED_INVALID_MP)
							{
								DWORD dwID = GetGame()->GetMainPlayer()->GetDefaultAttackSkillID();
								GetGame()->GetGameControl()->SetBufferSkillID(dwID);
								CPlayer::tagSkill * pPlayerSkill = GetGame()->GetMainPlayer()->GetSkill(dwID);
								if(pPlayerSkill)
									pPlayerSkill->dwUseingStartTime = timeGetTime();
							}
							if(lFaildRet == SKILL_USE_FAILED_INVALID_HP || lFaildRet == SKILL_USE_FAILED_INVALID_RP)
								GetGame()->GetGameControl()->AutoAttactStop();
						}
						// 光环类技能重设使用状态
						CPlayer::tagSkill *ptagS = GetGame()->GetMainPlayer()->GetSkill(lSkillID);
						if(ptagS && pS && !pS->bLockSkill)
							ptagS->dwUseingStartTime = 0;
						// 结束的技能是正在吟唱的技能,取消吟唱
						if(lSkillKey > 0 && lSkillKey == GetGame()->GetMainPlayer()->GetIntonateKey())
						{
							GetGame()->GetMainPlayer()->SetCurIntonateTime(0,0);
							GetGame()->GetMainPlayer()->SetIntonateSkillKey(0);
							if(g_bDebug)
							{
								Log4c::Trace(ROOT_MODULE,"技能使用失败,次数清0,吟唱清空:%d,类型:%d,key:%d",lSkillID,lFaildRet,lSkillKey);
							}
						}
						if (lSkillID>=50000&&lSkillID<=50006)
						{
							((CPlayer*)pMoveShape)->SetToolsID(0);
						}
						// 如果正处于制作过程中
						//CFacturePageEx* pFacturePage = GetGame()->GetCGuiEx()->GetFacturePageEx();
						/*if (pFacturePage!=NULL && pFacturePage->IsOpen())
						{
							pFacturePage->SetFactureState(false);
							if (pFacturePage->GetCurFactureNum()!=0 || pFacturePage->GetAllFactureState())
							{
								pFacturePage->ClearFactureNum();
							}
						}*/
					}
				}
				GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-48.wav");
				if(pMoveShape && (pMoveShape == GetGame()->GetMainPlayer() ||
					pMoveShape->GetType() == TYPE_PET &&
					((CPet*)pMoveShape)->IsMainPlayerPet() ))
				{
					switch (lFaildRet)
					{
					case SKILL_USE_FAILED_INVALID_STATE:
						{
							// 自动攻击技能
							if(GetGame()->GetGameControl()->GetAutoSkillID() == lSkillID)
								GetGame()->GetGameControl()->SetAutoSkillID(0);
							//GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							//CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_STATE),
							//D3DCOLOR_ARGB(255,255,0,0));
						}
						break;
					case SKILL_USE_FAILED_INVALID_HP:
						//GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
						//	CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_HP),
						//	D3DCOLOR_ARGB(255,255,0,0));
						break;

					case SKILL_USE_FAILED_INVALID_MP:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_MP),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;

					case SKILL_USE_FAILED_INVALID_RP:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_NP),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;

					case SKILL_USE_FAILED_INVALID_YP:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_YVALUE),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;

					case SKILL_USE_FAILED_INVALID_TARGET:
						{
							// 自动攻击技能
							if(GetGame()->GetGameControl()->GetAutoSkillID() == lSkillID)
								GetGame()->GetGameControl()->SetAutoSkillID(0);
							//GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							//	CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_OBJERROR),
							//	D3DCOLOR_ARGB(255,255,0,0));
						}
						break;

					case SKILL_USE_FAILED_INVALID_DISTANT:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
                            CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_OUTAREA),
                            D3DCOLOR_ARGB(255,255,0,0));*/
						break;

					case SKILL_USE_FAILED_INVALID_SKILL:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_NOSKILL),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;

					case SKILL_USE_FAILED_INVALID_TIME:			//##允许再次使用技能的时间未到达
						{
							/*if(GetGame()->GetGameControl()->GetAutoSkillID() != lSkillID)
								GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
								CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_COOLTIME),
								D3DCOLOR_ARGB(255,255,0,0));
							else
								GetGame()->GetGameControl()->SetBufferSkillID(SKILL_BASE_BUFF);*/
							if( GetGame()->GetGameControl()->GetAutoSkillID() == lSkillID)
								GetGame()->GetGameControl()->SetBufferSkillID(SKILL_BASE_BUFF);
						}
						break;

					case SKILL_USE_FAILED_CANNOTCOLLECTION_STATE:	//当前状态(人物的状态)不能采集
						{
							/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
								CStringReading::LoadText(205,18),
								D3DCOLOR_ARGB(255,255,0,0));*/
						}
						break;

					case SKILL_USE_FAILED_CANNOTFACTURE_STATE:		//当前状态(人物的状态)不能制作
						{
							/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
								CStringReading::LoadText(205,19),
								D3DCOLOR_ARGB(255,255,0,0));*/
						}
						break;

					case SKILL_USE_FAILED_INVALID_EQUIP:		//##无效的装备
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_ARM),
							D3DCOLOR_ARGB(255,255,0,0));*/
						// 取消连续攻击技能
						GetGame()->GetGameControl()->SetAutoSkillID(0);
						break;

					case SKILL_USE_FAILED_BLOCKED:				//##被阻挡了
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_BLOCK),
							D3DCOLOR_ARGB(255,255,0,0));*/
						// 取消连续攻击技能
						GetGame()->GetGameControl()->SetAutoSkillID(0);
						break;
					case SKILL_USE_FAILED_BREAK:
						{
							if (lSkillID>=50000&&lSkillID<=50007)
							{
								/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
									CStringReading::LoadText(205,40),
									D3DCOLOR_ARGB(255,255,0,0));*/
							}
							else
							{
								/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
									CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_DELSKILL),
									D3DCOLOR_ARGB(255,255,0,0));*/
							}
							// 取消连续攻击技能
							if(lSkillID != GetGame()->GetGameControl()->GetAutoSkillID())
							{
								GetGame()->GetGameControl()->SetAutoSkillID(0);
								GetGame()->GetMainPlayer()->SetAction(CShape::ACT_STAND);
							}
						}
						break;
					case SKILL_USE_FAILED_NOOBJECT:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_NOOBJ),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;

					case SKILL_USE_FAILED_INVALID_INTONATE:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_INTTIME),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;

					case SKILL_USE_FAILED_INVALID_OCCUPATION:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_OUCC),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_INVALID_FACTURE:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_MADE),
							D3DCOLOR_ARGB(255,255,0,0));
						GetGame()->GetCGuiEx()->GetFacturePageEx()->Close();*/
						break;
					case SKILL_USE_FAILED_INVALID_COLLECT:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_COLLECTION),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_INVALID_ACT:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_ACTING),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_INVALID_MOVING:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_MOVEING),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;

					case SKILL_USE_FAILED_C_NOCOLLECTION:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_NOOBJ),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_C_STATE_ERROR:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_STATE),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_C_UNKNOW_COLLECTION:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_NOINFO),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_C_DOCCU_ERROR:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_OCCUEX),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_C_LEVEL_ERROR:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_LEV),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_C_GOODSCONDITION_ERROR:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_GOODS),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_C_NO_BAGSPACE:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_PACK),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_C_NOT_ROLECOLLECTION:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_NOTQUESTOBJ),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_C_QUESTSTEP_ERROR:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_SPECQUEST),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_C_UNKOWN_COLLECTTYPE:
						/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
							CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_TYPE),
							D3DCOLOR_ARGB(255,255,0,0));*/
						break;
					case SKILL_USE_FAILED_F_NO_FACTURE:
						{
							/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
								CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_NOOBJ),
								D3DCOLOR_ARGB(255,255,0,0));*/
							GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav");
						}
						break;
					case SKILL_USE_FAILED_F_DOCCU_ERROR:
						{
							/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
								CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_OCCUEX),
								D3DCOLOR_ARGB(255,255,0,0));*/
							GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav");
						}
						break;
					case SKILL_USE_FAILED_F_NOTHAS_FACTURE:
						{
							/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
								CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_NOSKILL),
								D3DCOLOR_ARGB(255,255,0,0));*/
							GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav");
						}
						break;
					case SKILL_USE_FAILED_F_GOODSCONDITION_ERROR:
						{
							/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
								CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_TOOL),
								D3DCOLOR_ARGB(255,255,0,0));*/
							GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav");
						}
						break;
					case SKILL_USE_FAILED_F_MATERIALS_ERROR:
						{
							/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
								CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_GOODS),
								D3DCOLOR_ARGB(255,255,0,0));*/
							GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav");
						}
						break;
					case SKILL_USE_FAILED_F_NPC_ERROR:
						{
							/*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
								CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_NPCDEST),
								D3DCOLOR_ARGB(255,255,0,0));*/
							GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav");
						}
						break;
					case SKILL_USE_FAILED_F_NO_BAGSPACE:
						{
// 							GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
// 								CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_PACK),
// 								D3DCOLOR_ARGB(255,255,0,0));
							GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav");
						}
						break;
						// 场景错误
					case SKILL_USE_FAILED_INVALID_REGION:
// 						GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
// 							CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_BYREGION),
// 							D3DCOLOR_ARGB(255,255,0,0));
						break;
					default: break;
					}
				}
				break;
			}
		}
		break;

	case MSG_S2C_SKILL_ADD_EX_STATE:	// 加入一个异常状态
		{
			// 状态承受着的类型和GUID
			long lType = pMsg->GetLong();
			CGUID ID;
			pMsg->GetGUID(ID);
			// 状态ID
			DWORD dwStateID = pMsg->GetDWord();
			DWORD dwLevel = pMsg->GetDWord();			// 状态等级
			DWORD dwRemainedTime = pMsg->GetDWord();
			BYTE bFlag = pMsg->GetByte();

			CMoveShape *pMoveShape = (CMoveShape*)pMsg->GetRegion()->FindChildObject(lType, ID);
			if (pMoveShape)
			{
				pMoveShape->AddStateEx(dwStateID, dwLevel, dwRemainedTime,0,bFlag);
			}
		}
		break;

	case MSG_S2C_SKILL_END_EX_STATE:	// 结束一个异常状态
		{
			long lType = pMsg->GetLong();
			CGUID ID;
			pMsg->GetGUID(ID);
			DWORD dwStateID = pMsg->GetDWord();
			DWORD dwlev = pMsg->GetDWord();
			CMoveShape *pMoveShape = (CMoveShape*)pMsg->GetRegion()->FindChildObject(lType, ID);
			if (pMoveShape)
			{
				pMoveShape->RemoveStateEx(dwStateID,dwlev);
			}
		}
		break;

	case MSG_S2C_SKILL_EX_STATE_ADDITIONAL_DATA:
		{
			long lType = pMsg->GetLong();
			CGUID ID;
			pMsg->GetGUID(ID);
			long lStateID = pMsg->GetLong();
			DWORD dwValue = pMsg->GetDWord();
			if( lStateID == STATE_TEAM )
			{
				CPlayer *pPlayer = dynamic_cast<CPlayer*>(pMsg->GetRegion()->FindChildObject(lType, ID));
				if (pPlayer)
					pPlayer->SetTeammateAmount(dwValue&0xffff);
			}
		}
		break;
		// 打开技能学习页面
	case MSG_S2C_SKILL_STUDY_BEGIN:
		{
			CGUID guid;
			pMsg->GetGUID(guid);
			long num = pMsg->GetLong();
			if(num > 0)
			{
				//GetGame()->GetCGuiEx()->GetLearnSkillPage()->Close();
				for(long i=0; i<num; ++i)
				{
					BYTE bType = pMsg->GetByte();
					DWORD dwSkillID = pMsg->GetDWord();
					//if(dwSkillID > 0)
					//	GetGame()->GetCGuiEx()->GetLearnSkillPage()->PushSkillID(dwSkillID,bType);
				}
				//GetGame()->GetCGuiEx()->GetLearnSkillPage()->Open();
				//GetGame()->GetCGuiEx()->GetLearnSkillPage()->SetNpcGUID(guid);
				//GetGame()->GetCGuiEx()->GetLearnSkillPage()->OpenPage(CLearnSkillPage::TYPE_FIGHTSKILLPAGE);
				GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-20.wav");
			}
			// 职业不符,弹出警告对话框
			else
			{

			}
		}
		break;
		// 打开制作技能学习页面
	case MSG_S2C_OCCUSKILL_STUDY_BEGIN:
		{
			CGUID guid;
			pMsg->GetGUID(guid);
			//GetGame()->GetCGuiEx()->GetLearnSkillPage()->Close();
			long num = pMsg->GetDWord();
			for(WORD i=0; i<num; ++i)
			{
				DWORD dwSkillID = pMsg->GetDWord();
				DWORD dwSkillCost = pMsg->GetDWord();
				//if(dwSkillID > 0)
				//	GetGame()->GetCGuiEx()->GetLearnSkillPage()->AddOccuSkill(dwSkillID,dwSkillCost);
			}
			//GetGame()->GetCGuiEx()->GetLearnSkillPage()->SetNpcGUID(guid);
			//GetGame()->GetCGuiEx()->GetLearnSkillPage()->OpenPage(CLearnSkillPage::TYPE_ASSITSKILLPAGE);
		}
        break;
	case MSG_S2C_OCCUSKILL_STUDY:
		{
			long lBeSucceed = pMsg->GetLong();
			DWORD dwFactureID = pMsg->GetDWord();
			if (lBeSucceed!=0)
			{
				//GetGame()->GetCGuiEx()->GetLearnSkillPage()->ChoseNextSkill(dwFactureID);
			}
			//GetGame()->GetCGuiEx()->GetLearnSkillPage()->StudyOccuSkillResult(lBeSucceed,dwFactureID);
			//long lOccType = GetGame()->GetCGuiEx()->GetMainBarPageEx()->GetOuccType();
			//GetGame()->GetCGuiEx()->GetMainBarPageEx()->SetOccuButtonSpecialState(true,lOccType);
			//GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-27.wav");
		}
        break;
	case MSG_S2C_OCCUSKILL_DELETE:
		{
			GetGame()->GetMainPlayer()->DeleteAllFactureSkill();
			//DWORD dwBeSucceed = pMsg->GetDWord();
			//DWORD dwFactureID = pMsg->GetDWord();
			//GetGame()->GetCGuiEx()->GetLearnSkillPage()->StudyOccuSkillResult(dwBeSucceed,dwFactureID);
		}break;
		// 技能学习失败
	case MSG_S2C_SKILL_STUDY_FAILED:
		{
			long lFaildRet = pMsg->GetLong();
			switch (lFaildRet)
			{
				//职业不符合学习条件
			case SKILL_STUDY_FAILED_OCCUPATION:
// 				GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
// 					CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_OUCC),
// 					D3DCOLOR_ARGB(255,255,0,0));
				break;
				//等级不符合学习条件
			case SKILL_STUDY_FAILED_RANK:
// 				GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
// 					CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_LEV),
// 					D3DCOLOR_ARGB(255,255,0,0));
				break;
				//SP不符合学习条件
			case SKILL_STUDY_FAILED_SP:
// 				GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
// 					CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_SP),
// 					D3DCOLOR_ARGB(255,255,0,0));
				break;
				//前置技能不符合学习条件
			case SKILL_STUDY_FAILED_SKILL:
// 				GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
// 					CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_PRESKILL),
// 					D3DCOLOR_ARGB(255,255,0,0));
				break;
				//前置限制技能不符合条件
			case SKILL_STUDY_FAILED_LIMIT_SKILL:
// 				GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
// 					CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_LIMITSKILL),
// 					D3DCOLOR_ARGB(255,255,0,0));
				break;
				//物品
			case SKILL_STUDY_FAILED_GOOD:
// 				GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
// 					CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_GOODS),
// 					D3DCOLOR_ARGB(255,255,0,0));
				break;
				//金币不足
			case SKILL_STUDY_FAILED_GOLD:
// 				GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
// 					CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_NOGOLDS),
// 					D3DCOLOR_ARGB(255,255,0,0));
				break;
				//银币不足
			case SKILL_STUDY_FAILED_SILVER:
// 				GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
// 					CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_NOSILVER),
// 					D3DCOLOR_ARGB(255,255,0,0));
				//职业等级不符合条件
			case SKILL_STUDY_FAILED_OCCULV:
// 				GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER,
// 					CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_FAILED_OCCULV),
// 					D3DCOLOR_ARGB(255,255,0,0));
				break;
			}
		}
		break;
		// 宠物添加技能
	case MSG_S2C_SKILL_ADD_PET:
		{
			//得到宠物GUID
			CGUID	guid;
			pMsg->GetGUID(guid);

			tagPetSkillInfo skill;
			pMsg->GetEx(&skill, sizeof(tagSkill));
			
			//技能冷却总时间长度
			skill.lRestorTimeLength = pMsg->GetLong();

			//技能当前冷却时间
			skill.lStartCoolTime = 0;

            // 技能范围改为float TODO:修改客户端技能范围相关逻辑
			//最小攻击距离
			skill.lMinAtkDistance = (long)pMsg->GetFloat();
			
			//最大攻击距离
			skill.lMaxAtkDistance = (long)pMsg->GetFloat();
			
			//需要花费MP值
			skill.lCostMp = pMsg->GetLong();
			
			CPet* pPet = dynamic_cast<CPet*>(GetGame()->GetRegion()->FindChildObject(TYPE_PET,guid)) ;
			if (pPet == NULL)
				return;
			if (skill.lPos == 0)
			{
				skill.bAuto = true;	//如果是第一个技能 则打开自动释放
			}
			pPet->AddSkill(skill);

			//CPetPageEx *pPage = GetGame()->GetCGuiEx()->GetPetPageEx();
			
			//if (pPage)
			//	pPage->LearnedNewSkill(pPet,&skill);
		}
		break;
		/***********************************************************************/
		/*  zhaohang 2010-10-18 //技能免疫*/
		/***********************************************************************/
	//case MSG_S2C_SHAPE_ATK_IMMUNITY:
	//	{

	//	}
	//	break;
	}
}
Exemplo n.º 11
0
void cBuffSkillInfo::RemoveBuffStatus( CObject* pTarget ) const
{
	if(0 == pTarget)
	{
		return;
	}

	Status* status = pTarget->GetBuffStatus();

	switch( mInfo.StatusDataType )
	{
	case BUFF_SKILL_INFO::StatusTypePercent:
		{
			status = pTarget->GetRateBuffStatus();
			break;
		}
	}

	if( ! status )
	{
		return;
	}

	SkillScript::Buff buff;
	buff.mKind	= mInfo.Status;
	buff.mValue	= mInfo.StatusData;
	// 081203 LUJ, 속성을 적용한다
	SetStatus(
		*pTarget,
		*status,
		buff,
		SetSkillStatusRemove );

	// 081203 LUJ, 스킬 스크립트를 적용한다
	{
		const SkillScript& script = GAMERESRCMNGR->GetSkillScript( GetIndex() );

		::SetSkillStatus(
			pTarget->GetBuffStatus(),
			pTarget->GetRateBuffStatus(),
			script,
			SetSkillStatusRemove );
		SetBuff(
			*pTarget,
			script,
			SetSkillStatusRemove );
	}

	switch( pTarget->GetObjectKind() )
	{
	case eObjectKind_Player:
		{
			CPlayer* player = ( CPlayer* )pTarget;

			CHARCALCMGR->CalcCharStats( player );
			break;
		}
	case eObjectKind_Pet:
		{
			CPet* pet = ( CPet* )pTarget;

			pet->CalcStats();
			break;
		}
	}
}
Exemplo n.º 12
0
void CPetManager::NetworkMsgParse(BYTE Protocol,void* pMsg)
{
	switch( Protocol )
	{
	case MP_PET_HATCH:
		{
			MSG_PET_INFO* pmsg = ( MSG_PET_INFO* )pMsg;

			PET_OBJECT_INFO* pObjectInfo = new PET_OBJECT_INFO;

			memcpy( pObjectInfo, &( pmsg->PetObjectInfo ), sizeof( PET_OBJECT_INFO ) );

			mPetObjectInfoTable.Add( pObjectInfo, pObjectInfo->ItemDBIdx );

			PET_INFO* pInfo = mPetInfoTable.GetData( pObjectInfo->Kind );
			CItem* pItem = ITEMMGR->GetItem( pObjectInfo->ItemDBIdx );

			if( !pInfo || !pItem )
				return;

			CHATMGR->AddMsg( CTC_SYSMSG, CHATMGR->GetChatMsg(1573), pInfo->Name, pObjectInfo->SkillSlot );

			pItem->ForcedUnseal();
			ITEMMGR->RefreshItem( pItem );
		}
		break;
	case MP_PET_EXP_NOTIFY:
		{
			HEROPET->AddExp();
		}
		break;
	case MP_PET_LEVELUP_NOTIFY:
		{
			MSG_DWORD* pmsg = ( MSG_DWORD* )pMsg;

			CPet* pPet = ( CPet* )OBJECTMGR->GetObject( pmsg->dwData );

			if( !pPet )
				return;

			pPet->LevelUp();

			APPEARANCEMGR->InitAppearance( pPet );

			if( pPet == HEROPET )
			{
				HEROPET->CalcStats();
				// 081112 LYW --- PetManager : 펫이 레벨업 했을경우 잘못 출력되던
				// 메시지 번호를 수정함. 1647 ->1659 (정진문)
				CHATMGR->AddMsg(CTC_SYSMSG, CHATMGR->GetChatMsg(1659));
			}
			TARGETSET set;
			set.pTarget = pPet;
			EFFECTMGR->StartEffectProcess(mLevelUpEffect,pPet,&set,0,pPet->GetID());
		}
		break;
	case MP_PET_LEVEL_NOTIFY:
		{
			MSG_DWORDBYTE* pmsg = ( MSG_DWORDBYTE* )pMsg;

			CPet* pPet = ( CPet* )OBJECTMGR->GetObject( pmsg->dwData );

			if( !pPet )
				return;

			pPet->SetLevel( pmsg->bData );

			APPEARANCEMGR->InitAppearance( pPet );

			if( pPet == HEROPET )
			{
				HEROPET->CalcStats();
				// 081112 LYW --- PetManager ; 펫이 레벨업 했을 경우 잘못 출력되던 메시지 번호를 수정함.
				// 메시지 번호를 수정함. 1647 ->1659 (정진문)
				CHATMGR->AddMsg(CTC_SYSMSG, CHATMGR->GetChatMsg(1659));
			}
		}
		break;
	case MP_PET_GRADEUP_NOTIFY:
		{
			MSG_DWORDBYTE2* pmsg = ( MSG_DWORDBYTE2* )pMsg;

			CPet* pPet = ( CPet* )OBJECTMGR->GetObject( pmsg->dwData );

			if( !pPet )
				return;

			pPet->GradeUp();

			APPEARANCEMGR->InitAppearance( pPet );
			
			if( pPet == HEROPET )
			{
				HEROPET->SetType(
					ePetType(pmsg->bData1));
				HEROPET->SetSkillSlot(
					pmsg->bData2);
				HEROPET->CalcStats();
				CHATMGR->AddMsg(CTC_SYSMSG, CHATMGR->GetChatMsg(1576));
				
				CItem* pItem = ITEMMGR->GetItem( HEROPET->GetItemDBIdx() );

				if( pItem )
				{
					ITEMMGR->RefreshItem( pItem );
				}
			}

			TARGETSET set;
			set.pTarget = pPet;
			EFFECTMGR->StartEffectProcess(mGradeUpEffect,pPet,&set,0,pPet->GetID());
		}
		break;
	case MP_PET_FRIENDLY_SYNC:
		{
			MSG_BYTE* pmsg = ( MSG_BYTE* )pMsg;

			HEROPET->SetFriendly( pmsg->bData );
		}
		break;
	case MP_PET_RESURRECTION_ACK:
		{
			MSG_PET_INFO* pmsg = ( MSG_PET_INFO* )pMsg;

			PET_OBJECT_INFO* oldinfo = mPetObjectInfoTable.GetData( pmsg->PetObjectInfo.ItemDBIdx );
			
			if( oldinfo )
			{
				memcpy( oldinfo, &( pmsg->PetObjectInfo ), sizeof( PET_OBJECT_INFO ) );
			}

			CItem* pItem = ITEMMGR->GetItem( pmsg->PetObjectInfo.ItemDBIdx );

			if( pItem )
			{
				ITEMMGR->RefreshItem( pItem );
			}

			CPetResurrectionDialog* window = GAMEIN->GetPetResurrectionDlg();

			if(	window && window->IsActive() )
			{
				window->SetUsedItem( NULL );
				window->SetActive( FALSE );
			}

			QUICKMGR->RefreshQickItem();
		}
		break;
	case MP_PET_LIFE_NOTIFY:
		{
			MSG_INT* pmsg = ( MSG_INT* )pMsg;

			if( HEROPET )
			HEROPET->SetLife( HEROPET->GetLife() + pmsg->nData );
		}
		break;
	case MP_PET_MAXLIFE_NOTIFY:
		{
			MSG_DWORD* pmsg = ( MSG_DWORD* )pMsg;

			CPet*	pPet	=	(CPet*)OBJECTMGR->GetObject( pmsg->dwObjectID );
			if( pPet )
				pPet->SetMaxLife( pmsg->dwData );
		}
		break;

	case MP_PET_MANA_NOTIFY:			
		{
			MSG_DWORD* pmsg = ( MSG_DWORD* )pMsg;

			if( HEROPET )
			HEROPET->SetMana( pmsg->dwData );
		}
		break;
	case MP_PET_MAXMANA_NOTIFY:
		{
			MSG_DWORD* pmsg = ( MSG_DWORD* )pMsg;

			if( HEROPET )
			HEROPET->SetMaxMana( pmsg->dwData );
		}
		break;
	case MP_PET_OBJECT_INFO:
		{
			MSG_PET_INFO* pmsg = ( MSG_PET_INFO* )pMsg;

			PET_OBJECT_INFO* oldinfo = mPetObjectInfoTable.GetData( pmsg->PetObjectInfo.ItemDBIdx );
			
			if( oldinfo )
			{
				memcpy( oldinfo, &( pmsg->PetObjectInfo ), sizeof( PET_OBJECT_INFO ) );
			}
			else
			{
				PET_OBJECT_INFO* pObjectInfo = new PET_OBJECT_INFO;

				memcpy( pObjectInfo, &( pmsg->PetObjectInfo ), sizeof( PET_OBJECT_INFO ) );

				mPetObjectInfoTable.Add( pObjectInfo, pObjectInfo->ItemDBIdx );
			}

			ITEMMGR->RefreshItemToolTip( pmsg->PetObjectInfo.ItemDBIdx );
			// 퀵슬롯이 세팅된 후에 펫 정보가 전송된다. 따라서 사망 등의 정보가 변경되려면 재호출한다
			QUICKMGR->RefreshQickItem();
		}
		break;

	case MP_PET_DIE_NOTIFY:
		{
			MSG_DWORD* pmsg = ( MSG_DWORD* )pMsg;
			
			PET_OBJECT_INFO* oldinfo = mPetObjectInfoTable.GetData( pmsg->dwData );
			if( oldinfo )
			{
				oldinfo->HP = 0;
				oldinfo->MP = 0;
				oldinfo->Friendly = 0;
				oldinfo->State = ePetState_Die;
			}

			CItem* pItem = ITEMMGR->GetItem( pmsg->dwData );

			if( pItem )
			{
				ITEMMGR->RefreshItem( pItem );
			}

			CHATMGR->AddMsg(CTC_SYSMSG, CHATMGR->GetChatMsg(1578));

			// 081112 LYW --- PetManager : 펫이 사망하였을 경우 펫 ui를 닫도록 수정함.
			cDialog* pDlg = GAMEIN->GetPetUIDlg() ;
			if( pDlg )
			{
				pDlg->SetActive( FALSE ) ;
			}

			// 090212 NYJ - 봉인중 죽어버리면 봉인취소
			CProgressDialog* pProgressDlg = ( CProgressDialog* )WINDOWMGR->GetWindowForID( PROGRESS_DIALOG );
			if(pProgressDlg && pProgressDlg->GetActionType()==CProgressDialog::eActionPetSummon)
			{
				pProgressDlg->Cancel();
			}

			QUICKMGR->RefreshQickItem();
		}
		break;
	case MP_PET_ITEM_INFO:
		{
			MSG_PET_ITEM_INFO* pmsg = ( MSG_PET_ITEM_INFO* )pMsg;

			CPet* pPet = ( CPet* )OBJECTMGR->GetObject( pmsg->ID );

			if( pPet )
			{
				pPet->SetWearedItem( pmsg->Item );
				APPEARANCEMGR->InitAppearance( pPet );
			}
		}
		break;

	case MP_PET_ITEM_DISCARD_ACK:
		{
			MSG_BYTE2* pmsg = ( MSG_BYTE2* )pMsg;

			//시간 소모로 삭제 되었다면 TRUE
			if( pmsg->bData2 )
			{
				CPetWearedDialog* pDlg = GAMEIN->GetPetWearedDlg();

				CItem* pItem = (pDlg) ? (CItem*)pDlg->GetIconForIdx( pmsg->bData1 ) : NULL ;

				if( pItem )
				{
					CHATMGR->AddMsg( CTC_CHEAT_1, CHATMGR->GetChatMsg( 1192 ), CHATMGR->GetChatMsg( 1926 ), pItem->GetItemInfo()->ItemName );
				}
			}

			GAMEIN->GetPetWearedDlg()->DeleteAck( pmsg->bData1 );
		}
		break;
	case MP_PET_ITEM_MOVE_PLAYER_ACK:
		{
			MSG_PET_ITEM_MOVE_SYN* pmsg = ( MSG_PET_ITEM_MOVE_SYN* )pMsg;

			CInventoryExDialog* pPlayerInven = GAMEIN->GetInventoryDialog();
			CStorageDialog* pPlayerStorage = GAMEIN->GetStorageDialog();
			CPetWearedDialog* pPetInven = GAMEIN->GetPetWearedDlg();

			CItem* pPlayerItem = NULL;
			const eITEMTABLE TableIdx = ITEMMGR->GetTableIdxForAbsPos( pmsg->PlayerPos );
			
			if( TableIdx == eItemTable_Storage)
			{
				pPlayerStorage->DeleteItem( pmsg->PlayerPos, &pPlayerItem );
			}
			else if( TableIdx == eItemTable_Inventory )
			{
				pPlayerInven->DeleteItem( pmsg->PlayerPos, &pPlayerItem );
			}
			else
				return;


			cIcon* pIcon = NULL;
			CItem* pPetItem = NULL;
			pPetInven->DeleteItem( pmsg->PetPos, &pIcon );
			pPetItem = ( CItem* )pIcon;

			if( pPlayerItem )
			{
				pPlayerItem->SetPosition( pmsg->PetPos );
				pPetInven->AddItem( pmsg->PetPos, pPlayerItem );
			}

			if( pPetItem )
			{
				pPetItem->SetPosition( pmsg->PlayerPos );

				if( TableIdx == eItemTable_Storage)
				{
					pPlayerStorage->AddItem( pPetItem );
				}
				else if( TableIdx == eItemTable_Inventory )
				{
					pPlayerInven->AddItem( pPetItem );
				}
				else
					return;
			}
		}
		break;
	case MP_PET_ITEM_MOVE_PLAYER_NACK:
		{
			MSG_WORD* msg = (MSG_WORD*)pMsg;

			switch(msg->wData)
			{
			case 1:
				CHATMGR->AddMsg(CTC_SYSMSG, CHATMGR->GetChatMsg(1739));
				break;
			}
		}
		break;
	// 090625 pdy 펫 기간제 아이템 착용처리 추가
	case MP_PET_ITEM_TIMELIMT_ONEMINUTE_FROM_PETINVEN:
		{
			MSG_DWORD2* pmsg = (MSG_DWORD2*)pMsg ;

			ITEM_INFO* pItemInfo = NULL ;
			pItemInfo = ITEMMGR->GetItemInfo( pmsg->dwData1 ) ;
			if( !pItemInfo ) return ;

			POSTYPE pos = (POSTYPE)pmsg->dwData2 ;

			CPetWearedDialog* pDlg = GAMEIN->GetPetWearedDlg();

			CItem* pItem= (pDlg) ? (CItem*)pDlg->GetIconForIdx(pos) : NULL ;

			const ITEMBASE* pItemBase = (pItem) ? &pItem->GetItemBaseInfo() : NULL ;
			
			if( pItemBase )
			{
				CItem* pItem = NULL ;
				pItem = ITEMMGR->GetItem( pItemBase->dwDBIdx ) ;

				if( pItem )
				{
					pItem->SetItemBaseInfo( *pItemBase ) ;
					pItem->SetLastCheckTime(gCurTime) ;
					pItem->SetRemainTime( 50 ) ;
				}
			}

			CHATMGR->AddMsg( CTC_CHEAT_1, CHATMGR->GetChatMsg( 1191 ), CHATMGR->GetChatMsg( 1926 ), pItemInfo->ItemName ) ;
		}
		break;

	case MP_PET_LIFE_BROAD:
		{
			const MSG_INT* const msg	=	(MSG_INT*)pMsg;
			CPet*	pPet	=	(CPet*)OBJECTMGR->GetObject( msg->dwObjectID );
			if( pPet )
			{
				DWORD	dwNewLife	=	pPet->GetLife() + msg->nData;
				pPet->SetLife( dwNewLife );
			}
		}
		break;
	}
}
// pet 색깔 변경하기
bool local_useCashItem_PetColorChange(CPC* ch, CItem* item, bool bprolong, RequestClient::doItemUse* packet)
{
	int extra1 = packet->extra_1;
	CItemProto* itemproto = item->m_itemProto;

	if( ch->m_wearInventory.wearItemInfo[WEARING_PET])
	{
		CPet* pet = ch->GetPet();
		if( !pet )
			return false;
		char PetColorType = 0 ;

		// 말만 가능한 것들
		if( (itemproto->getItemIndex() == PET_BLACK_HEART_COLOR_ITEM) ||
				(itemproto->getItemIndex() == PET_WHITE_HEART_COLOR_ITEM) ||
				(itemproto->getItemIndex() == PET_YELLOW_HEART_COLOR_ITEM) )
		{
			if( (pet->GetPetType() != PET_TYPE_HORSE) &&
					(pet->GetPetType() != PET_TYPE_BLUE_HORSE) &&
					(pet->GetPetType() != PET_TYPE_UNKOWN_HORSE) )
			{
				CNetMsg::SP rmsg(new CNetMsg);
				CashItemMoonstoneStartRepMsg(rmsg, MSG_EX_CASHITEM_MOONSTONE_ERROR_CANTUSE_CASHMOON, -1);
				SEND_Q(rmsg, ch->m_desc);
				return false;
			}
		}

		// 타는말만 가능한 것들 William,Alber,Red eye,Zebra,Harold,Violet
		if( (itemproto->getItemIndex() == HORSE_WILLIAM_COLOR_ITEM)	||
				(itemproto->getItemIndex() == HORSE_ALBER_COLOR_ITEM)	||
				(itemproto->getItemIndex() == HORSE_REDEYE_COLOR_ITEM)	 ||
				(itemproto->getItemIndex() == HORSE_ZEBRA_COLOR_ITEM)	||
				(itemproto->getItemIndex() == HORSE_HAROLD_COLOR_ITEM)	||
				(itemproto->getItemIndex() == HORSE_VIOLET_COLOR_ITEM)	 )
		{
			if( !pet->IsMountType() ||
					(
						(pet->GetPetType() != PET_TYPE_HORSE) &&
						(pet->GetPetType() != PET_TYPE_BLUE_HORSE) &&
						(pet->GetPetType() != PET_TYPE_UNKOWN_HORSE)
					) )
			{
				CNetMsg::SP rmsg(new CNetMsg);
				CashItemMoonstoneStartRepMsg(rmsg, MSG_EX_CASHITEM_MOONSTONE_ERROR_CANTUSE_CASHMOON, -1);
				SEND_Q(rmsg, ch->m_desc);
				return false;
			}
		}

		switch( itemproto->getItemIndex() )
		{
		case PET_RED_COLOR_ITEM:
			PetColorType = (char)RED_COLOR;
			break;
		case PET_SCARLET_COLOR_ITEM:
			PetColorType = (char)SCARLET_COLOR;
			break;
		case PET_YELLOW_COLOR_ITEM:
			PetColorType = (char)YELLOW_COLOR;
			break;
		case PET_GREEN_COLOR_ITEM:
			PetColorType = (char)GREEN_COLOR;
			break;
		case PET_BLUE_COLOR_ITEM:
			PetColorType = (char)BLUE_COLOR;
			break;
		case PET_DEEP_BLUE_COLOR_ITEM:
			PetColorType = (char)DEEP_BLUE_COLOR;
			break;
		case PET_VIOLET_COLOR_ITEM:
			PetColorType = (char)VIOLET_COLOR;
			break;
		case PET_BLACK_COLOR_ITEM:
			PetColorType = (char)BLACK_COLOR;
			break;
		case PET_WHITE_COLOR_ITEM:
			PetColorType = (char)WHITE_COLOR;
			break;
		case PET_NON_COLOR_ITEM:
			PetColorType = (char)NON_COLOR;
			break;
		// 피닉스의 결정
		case 3262:
			PetColorType = (char)PHOENIX_COLOR;
			break;
		case PET_BLACK_HEART_COLOR_ITEM :
			PetColorType = (char) BLACK_HEART_COLOR;
			break;

		case PET_WHITE_HEART_COLOR_ITEM :
			PetColorType = (char) WHITE_HEART_COLOR;
			break;

		case PET_YELLOW_HEART_COLOR_ITEM :
			PetColorType = (char) YELLOW_HEART_COLOR;
			break;
		case HORSE_COLOR_CHANGE_ITEM:
			{
				if(	(pet->GetPetType() != PET_TYPE_HORSE) &&
						(pet->GetPetType() != PET_TYPE_BLUE_HORSE) &&
						(pet->GetPetType() != PET_TYPE_UNKOWN_HORSE))
				{
					CNetMsg::SP rmsg(new CNetMsg);
					CashItemMoonstoneStartRepMsg(rmsg, MSG_EX_CASHITEM_MOONSTONE_ERROR_CANTUSE_CASHMOON, -1);
					SEND_Q(rmsg, ch->m_desc);
					return false;
				}

				if(extra1 < RED_COLOR || extra1 > VIOLET_SKELETON_COLOR )
					return false;

				PetColorType = (char)extra1;
			}
			break;
		case DRAGON_COLOR_CHANGE_ITEM:
			{
				if(	(pet->GetPetType() != PET_TYPE_DRAGON) &&
						(pet->GetPetType() != PET_TYPE_PINK_DRAGON) &&
						(pet->GetPetType() != PET_TYPE_UNKOWN_DRAGON))
				{
					CNetMsg::SP rmsg(new CNetMsg);
					CashItemMoonstoneStartRepMsg(rmsg, MSG_EX_CASHITEM_MOONSTONE_ERROR_CANTUSE_CASHMOON, -1);
					SEND_Q(rmsg, ch->m_desc);
					return false;
				}

				if(extra1 < RED_COLOR || extra1 > VIOLET_SKELETON_COLOR )
					return false;

				if(extra1 >= BLACK_HEART_COLOR && extra1 <= VIOLET_SKELETON_COLOR)
				{
					if( !pet->IsMountType() )
					{
						CNetMsg::SP rmsg(new CNetMsg);
						CashItemMoonstoneStartRepMsg(rmsg, MSG_EX_CASHITEM_MOONSTONE_ERROR_CANTUSE_CASHMOON, -1);
						SEND_Q(rmsg, ch->m_desc);
						return false;
					}
				}

				PetColorType = (char)extra1;
			}
			break;

		case HORSE_WILLIAM_COLOR_ITEM:
			{
				PetColorType = (char) HORSE_WILLIAM_COLOR;
			}
			break;

		case HORSE_ALBER_COLOR_ITEM:
			{
				PetColorType = (char) HORSE_ALBER_COLOR;
			}
			break;

		case HORSE_REDEYE_COLOR_ITEM:
			{
				PetColorType = (char) HORSE_REDEYE_COLOR;
			}
			break;

		case HORSE_ZEBRA_COLOR_ITEM:
			{
				PetColorType = (char) HORSE_ZEBRA_COLOR;
			}
			break;

		case HORSE_HAROLD_COLOR_ITEM:
			{
				PetColorType = (char) HORSE_HAROLD_COLOR;
			}
			break;

		case HORSE_VIOLET_COLOR_ITEM:
			{
				PetColorType = (char) HORSE_VIOLET_COLOR;
			}
			break;
		}

		pet->SetPetColor( PetColorType );

		{
			CNetMsg::SP rmsg(new CNetMsg);
			HelperPetColorChange( rmsg, ch->m_index, pet->m_index, PetColorType );
			SEND_Q( rmsg, gserver->m_helper );
		}

		{
			CNetMsg::SP rmsg(new CNetMsg);
			PetChangeColor( rmsg,  pet->m_index, PetColorType, ch->m_index, pet->GetPetTypeGrade()  );
			ch->m_pArea->SendToCell( rmsg, ch, true );
		}

		return true;
	}
	return false;
}
void ProcDead(CPet* df, CCharacter* of)
{
	CPC*		opc				= NULL;
	CNPC*		onpc			= NULL;
	CPet*		opet			= NULL;
	CAPet*		oapet			= NULL;
	CElemental*	oelemental		= 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);
		break;

	case MSG_CHAR_NPC:
		onpc = TO_NPC(of);
		break;

	case MSG_CHAR_PET:
		opet = TO_PET(of);
		opc = opet->GetOwner();
		break;

	case MSG_CHAR_ELEMENTAL:
		oelemental = TO_ELEMENTAL(of);
		opc = oelemental->GetOwner();
		break;

	case MSG_CHAR_APET:
		oapet = TO_APET(of);
		opc = oapet->GetOwner();
		break;

	default:
		return ;
	}

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

	if (df->GetOwner())
	{
		// NPC 사망시 사망 패널티는 기본으로 true, PC에게 사망시 사망 패널티는 기본으로 false
		// * bPKPenalty변수는 pk 패널티를 주는것 뿐만 아니라 성향회복에도 관계되므로 성향 회복이나 패널티등 어느것에라도 걸리면 true
		bool bPKPenalty = (opc) ? IsPK(opc, df) : false;

		if (bPKPenalty)
			CalcPKPoint(opc, df->GetOwner(), true);
	}

	DelAttackList(df);

	CPC* owner = df->GetOwner();
	const char* ownerName = "NO OWNER";
	const char* ownerNick = "NO OWNER";
	const char* ownerID = "NO OWNER";
	if (owner)
	{
		ownerNick = (owner->IsNick()) ? owner->GetName() : ownerNick;
		ownerName = owner->m_name;
		ownerID = owner->m_desc->m_idname;
	}

	// TODO : petlog
	GAMELOG << init("PET DEAD")
			<< "PET" << delim
			<< df->GetPetTypeGrade() << delim
			<< "INDEX" << delim
			<< df->m_index << delim
			<< "LEVEL" << delim
			<< df->m_level << delim
			<< "OWNER" << delim
			<< ownerName << delim
			<< ownerNick << delim
			<< ownerID << delim
			<< "ATTACKER" << delim
			<< "TYPE" << delim;
	switch (of->m_type)
	{
	case MSG_CHAR_NPC:
		GAMELOG << "NPC" << delim
				<< onpc->m_name
				<< end;
		break;
	case MSG_CHAR_PC:
	case MSG_CHAR_PET:
	case MSG_CHAR_ELEMENTAL:
	default:
		if (opc)
		{
			GAMELOG << "PC" << delim
					<< opc->m_index << delim
					<< opc->GetName()
					<< end;
		}
		else
		{
			GAMELOG << "UNKNOWN" << delim
					<< of->m_index << delim
					<< of->m_name
					<< end;
		}
		break;
	}

	// 060221 : bs : 애완동물 사망시 착용 해제하고 이후 일정 시간동안 착용 불능
	if (owner)
	{
		// 사망 설정
		df->SetRemainRebirthTime();

		{
			// 펫 상태 보냄
			CNetMsg::SP rmsg(new CNetMsg);
			ExPetStatusMsg(rmsg, df);
			SEND_Q(rmsg, owner->m_desc);
		}
	}
}
bool local_useCashItem_PetTurnToNPC(CPC* ch, CItem* item, bool bprolong, RequestClient::doItemUse* packet)
{
	// 사용조건 검사
	// 착용하고 있는 펫에 적용
	// 펫 레벨이 16 이상의 말이고, 탈수 없을때
	CItemProto* itemproto = item->m_itemProto;

	if( ch->m_wearInventory.wearItemInfo[WEARING_PET])
	{
		CPet* pet = ch->GetPet();
		if( !pet )
			return false;

		int toNpc = -1 ;
		int	toNpcSize = 10;

		if( !pet->IsMountType() )
		{
			if( pet->GetPetTurnToNpc() == 0 ) // 변신중이 아니다
			{
				// 아이템이 말타입(1)이고 펫이 말이거나 아이템이 용타입(1)이고 펫이 용이거나 ,아이템 타입이 모두(0)일때
				if( pet->m_level > 15 &&
						( (itemproto->getItemNum4() == 1 && ( pet->GetPetType() & (0x10)) > 0 )
						  || (itemproto->getItemNum4() == 2 && ( pet->GetPetType() & (0x00)) > 0 )
						  || itemproto->getItemNum4() == 0
						)
				  )
				{
					toNpc = itemproto->getItemNum0();	// 변신 NPC 인덱스
					toNpcSize = itemproto->getItemNum1(); // 변신 npc size
				}
			}
			else	// 변신중이면 변신 해제만 가능
			{
				if( itemproto->getItemIndex() == 2605 )	// 변신 해제 아이템
					toNpc = 0;
			}

			if( toNpc > -1 )
			{
				// 이부분은 이벤트 활성화 여부와 상관 없이 막을지 결정해야함.
				if( toNpc > 0 )		// 변신 성공
				{
					//			int	nEventItemIndex = 2360;		// 펫의 명찰
					int nEventItemIndex = 2605;		// 펫 리턴주문서 2009 Xmas 이벤트 변경

					CItem* pEventItem =  gserver->m_itemProtoList.CreateItem( nEventItemIndex, -1, 0, 0, 1 );
					if( !pEventItem )
					{
						CNetMsg::SP rmsg(new CNetMsg);
						SysMsg(rmsg, MSG_SYS_OVER_WEIGHT);
						SEND_Q(rmsg, ch->m_desc);
						return false;
					}

					if (ch->m_inventory.addItem(pEventItem) == false)
					{
						delete pEventItem;

						CNetMsg::SP rmsg(new CNetMsg);
						SysMsg(rmsg, MSG_SYS_OVER_WEIGHT);
						SEND_Q(rmsg, ch->m_desc);
						return false;
					}
				}
				pet->SetPetTurnToNpc( toNpc );
#ifdef PET_TURNTO_NPC_ITEM
				pet->SetPetTurnToNpcSize(toNpcSize);
#endif //PET_TURNTO_NPC_ITEM

				{
					CNetMsg::SP rmsg(new CNetMsg);
					HelperPetTurnToNPCMsg( rmsg, ch->m_index, pet->m_index, toNpc , toNpcSize );
					SEND_Q( rmsg, gserver->m_helper );
				}

				{
					CNetMsg::SP rmsg(new CNetMsg);
					PetTurnToNPCMsg( rmsg,  pet->m_index, toNpc, ch->m_index , toNpcSize );
					//SEND_Q( rmsg, ch->m_desc );
					ch->m_pArea->SendToCell( rmsg, ch, true );
				}
				return true;
			}
		}
		//else
		//{
		// 조건에 맞지 않음
		//}
	}
	return false;
}
Exemplo n.º 16
0
 void PetAI::OnDel()
 {
     CPet *pet = (CPet*) m_Owner;
     pet->DelFromRegion(PET_OT_DISAPPEAR);
 }
Exemplo n.º 17
0
    bool PetAI::SearchEnemy()
    {
        CPet *owner = (CPet*) m_Owner;
        CMoveShape *host = owner->GetHost();
        if(NULL == host)
        {
			LogError(AI_MODULE, "m_Owner->GetHost() error.");
            return false;
        }
        CMoveShape *target = GetTarget();

        // 当前有追踪目标
        if(target != NULL)
        {
            long dis = owner->Distance(target);
            long tracDis = owner->GetTrackRange();
            if(!target->IsDied() &&
                tracDis > dis &&
                !target->IsGod())
            {
                return true;
            }
        }

        // 寻找所在场景
        CServerRegion *region = dynamic_cast<CServerRegion*>(host->GetFather());
        if(NULL == region)
        {
            return false;
        }

        vector<CShape*> vOut;
        region->FindAroundObject(owner, TYPE_PLAYER, vOut);
        region->FindAroundObject(owner, TYPE_MONSTER, vOut);
        region->FindAroundObject(owner, TYPE_PET, vOut);

        bool ret = false;
        map<long, CMoveShape*> AroundObjs;
        long distance = 0;
        for(size_t i=0; i < vOut.size(); ++i)
        {
            target = (CMoveShape*)vOut[i];
            if(target != NULL &&
                target->IsDied() &&
                !target->IsGod() &&
                target->IsAttackAble(owner))
            {
                distance = m_Owner->Distance(target->GetTileX(), target->GetTileY());
                AroundObjs[distance] = target;
                ret = true;
            }
        }

        if(ret)		// 满足条件设置对象
        {
            map<long, CMoveShape*>::iterator itr = AroundObjs.begin();
            target = itr->second;
            SetTarget(target->GetExID(), target->GetType());
            //if(PET_TYPE_TRAP == owner->GetPetType())
            //{
            //    owner->SetActTime(0, 0);		// 避免寻敌后无法攻击
            //    owner->OnTrapSpring();
            //}
        }

        return true;
    }
bool local_useCashItem_1519(CPC* ch, CItem* item, bool bprolong, RequestClient::doItemUse* packet)
{
	// 1. nPetIndex 아이템 찾고
	// 2. 펫 착용 해제 상태인지 보고
	// 3. 해당 아이템의 펫을 찾고
	// 4. 펫의 타입과 스킬 검사하고
	// 5. 펫 마운트 취소후
	// 6. 펫 상태 알리고
	// 7. 결과 알림
	int extra1 = packet->extra_1;
	bool bFail = false;

	// 1. extra1으로 아이템 찾고
	CItem* pItemPet = ch->m_inventory.FindByVirtualIndex(extra1);
	if (!pItemPet)
		bFail = true;

	// 2. 펫 착용 해제 상태인지 보고
	else if (pItemPet->getWearPos() != WEARING_NONE)
		bFail = true;
	else
	{
		// 3. 해당 아이템의 펫을 찾고
		CPet* pPet = ch->GetPet(pItemPet->getPlus());
		if (!pPet)
			bFail = true;

		// 4. 펫의 타입과 스킬 검사하고
		else if (!pPet->IsMountType() || pPet->GetSkillList()->count() > 1)
			bFail = true;

		else
		{
			// TODO : petlog
			GAMELOG << init("PET RESET MOUNT", ch)
					<< "PET ITEM" << delim
					<< itemlog(pItemPet) << delim
					<< "PET" << delim
					<< pPet->GetPetTypeGrade() << delim
					<< "INDEX" << delim
					<< pPet->m_index << delim
					<< "LEVEL" << delim
					<< pPet->m_level
					<< end;

			pPet->SetPetColor( (char)NON_COLOR );

			{
				CNetMsg::SP rmsg(new CNetMsg);
				HelperPetColorChange( rmsg, ch->m_index, pPet->m_index, (char)NON_COLOR );
				SEND_Q( rmsg, gserver->m_helper );
			}

			// 5. 펫 마운트 취소후
			pPet->ResetMountType();

			{
				// 6. 펫 상태 알리고
				CNetMsg::SP rmsg(new CNetMsg);
				ExPetStatusMsg(rmsg, pPet);
				SEND_Q(rmsg, ch->m_desc);
			}
		}
	}

	// 7. 결과 알림
	if (bFail)
	{
		CNetMsg::SP rmsg(new CNetMsg);
		SysMsg(rmsg, MSG_SYS_CANNOT_RESET_MOUNT);
		SEND_Q(rmsg, ch->m_desc);
		return false;
	}
	else
	{
		CNetMsg::SP rmsg(new CNetMsg);
		SysMsg(rmsg, MSG_SYS_RESET_MOUNT);
		SEND_Q(rmsg, ch->m_desc);
		return true;
	}
}
Exemplo n.º 19
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
}
Exemplo n.º 20
0
SKILL_RESULT cSkillManager::OnPetSkillStartSyn(MSG_SKILL_START_SYN* pmsg, ITEMBASE* pItemBase)
{
	/// 시전자 정보가 없다면 실패
	// 080602 LUJ, 스킬 발동은 플레이어만 할 수 있으므로 캐스팅한다
	CPet* pOperator = ( CPet* )g_pUserTable->FindUser( pmsg->Operator );

	// 080602 LUJ, 검사 구문 추가
	if( !	pOperator											||
			pOperator->GetObjectKind()	!= eObjectKind_Pet	||
			pOperator->CurCastingSkillID )
	{
		return SKILL_OPERATOR_INVALUED;
	}

	// 080410 KTH -- 일반 스킬일 경우 스킬 트리에 포함 되어있는 스킬인지 확인한다.
	if( pItemBase )
	{
		ITEM_INFO* pItemInfo = ITEMMGR->GetItemInfo( pItemBase->wIconIdx );
		const cSkillInfo* pSkillInfo = SKILLMGR->GetSkillInfo( pmsg->SkillIdx );

		if( pSkillInfo == NULL || pItemInfo == NULL )
			return SKILL_INFO_INVALUED;

		if( pmsg->SkillIdx / 100 != pItemInfo->SupplyValue / 100 )
			return SKILL_INFO_INVALUED;
	}
	// 090226 LUJ, 스킬 검사
	else
	{
		const SkillScript&	skillScript	= GAMERESRCMNGR->GetSkillScript( pmsg->SkillIdx );
		const BOOL			checkFailed	= ( skillScript.mIsNeedCheck && ! pOperator->IsHaveSkill( pmsg->SkillIdx ) );

		if( checkFailed )
		{
			LogScriptHack(
				*pOperator,
				"SkillList.bin",
				"*pet has no skill" );
			return SKILL_OPERATOR_INVALUED;
		}
	}

	const cSkillInfo* ptemp = GetSkillInfo( pmsg->SkillIdx );

	if( ptemp == NULL )
	{
		return SKILL_INFO_INVALUED;
	}

	cActiveSkillInfo* pSkillInfo = ( cActiveSkillInfo* )ptemp;

	if( pOperator->GetAbnormalStatus()->IsSilence )
	{
		// 080616 LUJ, 침묵 중에는 물리 공격만 가능하다
		if( pSkillInfo->GetKind() != SKILLKIND_PHYSIC )
		{
			return SKILL_STATE_INVALUED;
		}
	}
	if( pOperator->GetAbnormalStatus()->IsBlockAttack )
	{
		if( pSkillInfo->GetInfo().Unit == UNITKIND_PHYSIC_ATTCK )
			return SKILL_STATE_INVALUED;
	}

	/// 최초 접속시 무적 상태 해제
	if( pOperator->GetState() == eObjectState_Immortal )
		OBJECTSTATEMGR_OBJ->EndObjectState( pOperator, eObjectState_Immortal, 0 );

	/// 길드 토너먼트나 공성전에서 관람자는 스킬을 사용할 수 없다
	{
		CObject* const ownerObject = g_pUserTable->FindUser(
			pOperator->GetOwnerIndex());

		if(0 == ownerObject)
		{
			return SKILL_STATE_INVALUED;
		}
		else if(2 == ownerObject->GetBattleTeam())
		{
			return SKILL_STATE_INVALUED;
		}
	}

	if(FALSE == pSkillInfo->IsExcutableSkillState(*pOperator, pmsg->mConsumeItem))
	{
		return SKILL_STATE_INVALUED;
	}

	VECTOR3 TargetPos;
	CObject * pTargetObject = NULL;
	float TargetRadius;

	/// 타겟 설정 확인
	if(GetMainTargetPos(&pmsg->MainTarget,&TargetPos, &pTargetObject) == FALSE)
	{
		/// 타겟이 없다
		return SKILL_TARGET_INVALUED;
	}

	switch( pSkillInfo->GetInfo().Target )
	{
	case eSkillTargetKind_None:
		{
			return SKILL_TARGET_INVALUED;
		}
		break;
	case eSkillTargetKind_OnlyOthers:
		{
			if( pTargetObject == pOperator )
			{
				return SKILL_TARGET_INVALUED;
			}
		}
		break;
	case eSkillTargetKind_Ground:
		{
		}
		break;
	case eSkillTargetKind_OnlySelf:
		{
			if( pTargetObject != pOperator )
			{
				return SKILL_TARGET_INVALUED;
			}
		}
		break;
	case eSkillTargetKind_AllObject:
		{
		}
		break;
	}

	/// 타겟 오브젝트의 크기를 구한다
	if(pmsg->MainTarget.MainTargetKind == MAINTARGET::MAINTARGETKIND_POS)
		TargetRadius = 0;
	else
	{
		pTargetObject = g_pUserTable->FindUser( pmsg->MainTarget.dwMainTargetID );
		TargetRadius = pTargetObject->GetRadius();
	}	

	if( pSkillInfo->IsInRange(*pOperator, TargetPos, TargetRadius) == FALSE)
	{
		if(pTargetObject)
		{
			RESULTINFO DamageInfo = {0};
			DamageInfo.mSkillIndex = pSkillInfo->GetIndex();

			pTargetObject->Damage(pOperator, &DamageInfo);
		}
		return SKILL_RANGE_NOTENOUGH;
	}
	
	if( pSkillInfo->GetKind() == SKILLKIND_ONOFF )
	{
		BOOL destroy = FALSE;

		for( WORD i = 0; i < MAX_BUFF_COUNT; i++ )
		{
			const DWORD idx = pSkillInfo->GetInfo().Buff[ i ];
			
			if( cSkillObject* pSkill = pTargetObject->GetBuffList().GetData( idx / 100 ) )
			{
				if( pSkill->GetSkillIdx() <= pSkillInfo->GetInfo().Buff[ i ] )
				{
					pSkill->SetEndState();
					pSkill->EndState();
					destroy = TRUE;
				}
			}
		}
		
		if( destroy )
		{
			return SKILL_DESTROY;
		}
	}

	// 080602 LUJ, 전역 스킬은 DB에서 직접 처리한 후 전송된다. 취소 등을 위해 오브젝트 ID를 직접 받아온다
	const DWORD skillObjectIndex = GetNewSkillObjectID();

	sSKILL_CREATE_INFO info;
	info.level = pSkillInfo->GetInfo().Level;
	info.operatorId = pOperator->GetID();
	info.mainTarget = pmsg->MainTarget;
	info.skillDir = pmsg->SkillDir;	

	/// 스킬 오브젝트 생성
	cSkillObject* pSObj = pSkillInfo->GetSkillObject();

	/// 스킬 객체 ID
	// 080602 LUJ, DB 업데이트 실패 시 스킬 오브젝트를 취소할 수 있도록 위에서 인덱스를 미리 받아놓도록 했다
	info.skillObjectId = skillObjectIndex;
	
	if( pSkillInfo->GetInfo().Target )
	{
		info.pos.x = TargetPos.x;
		info.pos.z = TargetPos.z;
	}
	else
	{
		info.pos = *CCharMove::GetPosition(pOperator);
	}

	// 090123 LUJ, 객체를 초기화한 후 타겟 검사를 수행해야한다.
	pSObj->Init( &info );
	pSObj->SetMultiTarget( &( pmsg->TargetList ) );
	pSObj->SetBattle( pOperator->GetBattleID(), pOperator->GetBattleTeam() );
	pSObj->SetGridID( pOperator->GetGridID() );

	/// 테이블에 등록
	m_SkillObjectTable.Add( pSObj, pSObj->GetID() );
	mProcessList.push_back(pSObj->GetID());
	g_pServerSystem->AddSkillObject( pSObj, &info.pos );

	/// 스킬 생성 성공
	return SKILL_SUCCESS;
}
// 믈리 어택
void do_pd_Attack(CPC* pc, CNetMsg::SP& msg)
{
	CDratanCastle * pCastle = CDratanCastle::CreateInstance();
	pCastle->CheckRespond(pc);

	RequestClient::doPDAttack* packet = reinterpret_cast<RequestClient::doPDAttack*>(msg->m_buf);

	if (packet->multicount > 20)
	{
		LOG_ERROR("HACKING : invalid multi count[%d]. charIndex[%d]", packet->multicount, pc->m_index);
		pc->m_desc->Close("invalid multi count");
		return;
	}

	// multi target의 중복 검사
	if (packet->multicount > 1)
	{
		std::set<int> tset;
		for (int i = 0; i < packet->multicount; ++i)
		{
			if (tset.insert(packet->list[i].index).second == false)
			{
				LOG_ERROR("HACKING : duplicate multi target[%d]. charIndex[%d]", packet->list[i].index, pc->m_index);
				pc->m_desc->Close("duplicate multi target");
				return;
			}
		}
	}

	// 대상 검색 : 인접 셀에서만
	CArea* area = pc->m_pArea;
	if (area == NULL)
	{
		LOG_ERROR("HACKING : not found area. charIndex[%d]", pc->m_index);
		pc->m_desc->Close("not found area");
		return;
	}

	CCharacter* tch = area->FindCharInCell(pc, packet->tIndex, (MSG_CHAR_TYPE)packet->tCharType);
	if (tch == NULL)
		return;

	int preIndex = -1;
	for (int i = 0; i < packet->multicount; ++i)
	{
		if(preIndex == packet->list[i].index)
		{
			// 가까운 마을로
			int nearZone;
			int nearZonePos;
			CZone* pZone = gserver->FindNearestZone(pc->m_pZone->m_index, GET_X(pc), GET_Z(pc), &nearZone, &nearZonePos);
			if (pZone == NULL)
				return;

			GoZone(pc, nearZone,
				   pZone->m_zonePos[nearZonePos][0],															// ylayer
				   GetRandom(pZone->m_zonePos[nearZonePos][1], pZone->m_zonePos[nearZonePos][3]) / 2.0f,		// x
				   GetRandom(pZone->m_zonePos[nearZonePos][2], pZone->m_zonePos[nearZonePos][4]) / 2.0f);		// z

			return;
		}

		preIndex = packet->list[i].index;

		CCharacter* ch = area->FindCharInCell(pc, packet->list[i].index, (MSG_CHAR_TYPE) MSG_CHAR_NPC);

		if(!ch) continue;

		if( !IS_NPC(ch) )
		{
			CPC* bugPC = NULL;
			if( IS_ELEMENTAL(ch) )
			{
				CElemental *ele = TO_ELEMENTAL(ch);
				bugPC = ele->GetOwner();
			}
			if( IS_PET(ch) )
			{
				CPet* pet = TO_PET(ch);
				bugPC = pet->GetOwner();
			}

			if( IS_PC(ch) )
			{
				bugPC = TO_PC(ch);
			}

			if( !bugPC )
				return;

			// 가까운 마을로
			int nearZone;
			int nearZonePos;
			CZone* pZone = gserver->FindNearestZone(bugPC->m_pZone->m_index, GET_X(bugPC), GET_Z(bugPC), &nearZone, &nearZonePos);
			if (pZone == NULL)
				return;

			GoZone(bugPC, nearZone,
				   pZone->m_zonePos[nearZonePos][0],															// ylayer
				   GetRandom(pZone->m_zonePos[nearZonePos][1], pZone->m_zonePos[nearZonePos][3]) / 2.0f,		// x
				   GetRandom(pZone->m_zonePos[nearZonePos][2], pZone->m_zonePos[nearZonePos][4]) / 2.0f);		// z

			GAMELOG << init("PD_BUG", bugPC)
					<< end;
			return;
		}

		int ret = ProcAttack(ch, tch, ch->GetAttackType(NULL), NULL, 0);
		if (ret == -1)
			return ;
	}
}
void ProcDead(CNPC* df, CCharacter* of)
{
	CPC*		opc				= NULL;
	CNPC*		onpc			= NULL;
	CPet*		opet			= NULL;
	CElemental*	oelemental		= NULL;
	CAPet*		oapet			= NULL;

	bool bNPCKilledNPC = false; // npc가 npc를 죽인 경우 꼭 이것을 true로 해줘야한다.

	switch (of->m_type)
	{
	case MSG_CHAR_PC:
		opc = TO_PC(of);
		if (opc == NULL)
			goto END_PROC;
		break;

	case MSG_CHAR_NPC:
		onpc = TO_NPC(of);
		break;

	case MSG_CHAR_PET:
		opet = TO_PET(of);
		opc = opet->GetOwner();
		if (opc == NULL)
			goto END_PROC;
		break;

	case MSG_CHAR_ELEMENTAL:
		oelemental = TO_ELEMENTAL(of);
		opc = oelemental->GetOwner();
		if (opc == NULL)
			goto END_PROC;
		break;
	case MSG_CHAR_APET:
		oapet	= TO_APET(of);
		opc		= oapet->GetOwner();
		if( opc == NULL )
			goto END_PROC;
		break;

	default:
		goto END_PROC;
	}
#ifdef SYSTEM_TREASURE_MAP
//	if( df->m_idNum == TREASURE_BOX_NPC_INDEX)	 // 보물상자 npc를 잡았다. 정보를 없애주자.
//		df->m_pZone->RemoveTreasureBoxNpc(df );
#endif

	// 공주구출 퀘스트 (퍼스널 던전 2) 실패
	ProcDead_PD2(df);

	// 죽은 것이 테이밍 몬스터일 경우
	if (df->Check_MobFlag( STATE_MONSTER_TAMING ) )
	{
		CPC* owner = NULL;			// 몬스터를 테이밍한 캐릭터
		owner = df->GetOwner();		// 몬스터가 테이밍 되었는지 확인

		// 주인이 공격하고 있는 타겟을 지워준다. 주인이 테이밍 중이 아닌걸로 바꿔준다.
		if ( owner )
		{
			owner->DeleteSlave( df );
		}
		goto SKIP_DROP;
	}

	// 죽인 것이 테이밍 몬스터일 경우
	if (onpc && onpc->Check_MobFlag( STATE_MONSTER_TAMING ) )
	{
		CPC* owner = NULL;				// 몬스터를 테이밍한 캐릭터
		owner = onpc->GetOwner();		// 몬스터가 테이밍 되었는지 확인

		// 주인이 공격하고 있는 타겟을 지워준다.
		if ( owner )
		{
			owner->SetOwners_target(NULL);
			// opc에 주인을 넣어준다.
			opc = owner;
			bNPCKilledNPC = true;
		}
		else
			goto SKIP_DROP;
	}
	else if( onpc && onpc->GetOwner() ) // 공격한 NPC가 오너가 있다면
	{
		CNPC* sumNpc = onpc->GetOwner()->GetSummonNpc(onpc);
		if( sumNpc )
		{
			if( sumNpc->Check_MobFlag((STATE_MONSTER_MERCENARY)) )
			{
				sumNpc->GetOwner()->SetSummonOwners_target(NULL);
			}

			opc = onpc->GetOwner();
			bNPCKilledNPC = true;
		}
		else
			goto SKIP_DROP;
	}

	if( df && df->GetOwner() ) // 죽은 넘이 owner 있다면
	{
		if( df->Check_MobFlag(STATE_MONSTER_PARASITE) ) // 패러사이트에 걸려있다면.
		{
			int parasiteCnt = GetRandom(0,3);
			parasiteCnt -= df->GetOwner()->GetBombSummonCont();
			if( parasiteCnt > 0 )
			{
				int parasiteIdx = df->m_assist.GetSummonNpcIndex();
				if( parasiteIdx > 0 )
				{
					int i;
					for(i=0; i<parasiteCnt; i++)
					{
						CNPC* pParasiteNPC;
						pParasiteNPC = gserver->m_npcProtoList.Create(parasiteIdx, NULL );
						if( pParasiteNPC == NULL )
							continue;

						GET_X(pParasiteNPC) = GET_X(df);
						GET_Z(pParasiteNPC) = GET_Z(df);
						GET_R(pParasiteNPC) = GET_R(df);
						GET_YLAYER(pParasiteNPC) = GET_YLAYER(df);

						float fRand = GetRandom(0,1) ? 1.0f : -1.0f ;
						float x  = 2.0f + ( fRand * (float)(GetRandom( 0 , 200 ) / 100.0f) );
						fRand = GetRandom(0,1) ? 1 : -1 ;
						float z  = 2.0f + ( fRand * (float)(GetRandom( 0 , 200 ) / 100.0f) );

						pParasiteNPC->m_regenX = GET_X(pParasiteNPC) += x;
						pParasiteNPC->m_regenZ = GET_Z(pParasiteNPC) += z;
						pParasiteNPC->m_regenY = GET_YLAYER(pParasiteNPC);

						pParasiteNPC->CalcStatus(false);

						CSkill * pSkill = gserver->m_skillProtoList.Create( 1133 ); // 자살 공격
						if( pSkill == NULL )
						{
							delete pParasiteNPC ;
							pParasiteNPC = NULL;
							continue;
						}

						pParasiteNPC->SetOwner(df->GetOwner());

						bool bApply;
						if( 0 != ApplySkill((CCharacter*)df->GetOwner(), (CCharacter*)pParasiteNPC, pSkill, -1, bApply) )
						{
							delete pSkill;
							pSkill = NULL;

							delete pParasiteNPC;

							continue;
						}
						delete pSkill;
						pSkill = NULL;

						if( bApply == false )
						{
							delete pParasiteNPC ;
							pParasiteNPC = NULL;
							continue;
						}
						df->GetOwner()->SetBombSummonNPC(pParasiteNPC);

						int cx, cz;
						df->m_pArea->AddNPC(pParasiteNPC);
						df->m_pArea->PointToCellNum(GET_X(pParasiteNPC), GET_Z(pParasiteNPC), &cx, &cz);
						df->m_pArea->CharToCell(pParasiteNPC, GET_YLAYER(pParasiteNPC), cx, cz);

						{
							CNetMsg::SP rmsg(new CNetMsg);
							AppearMsg(rmsg, pParasiteNPC, true);
							df->m_pArea->SendToCell(rmsg, GET_YLAYER(pParasiteNPC), cx, cz);
						}
					}
				}
			}
		}

		CNPC* sumNpc = df->GetOwner()->GetSummonNpc(df);
		if( sumNpc )
		{
#ifdef BUGFIX_MERCNERAY_DELETE
			sumNpc->GetOwner()->SummonNpcRemove(df, false);
#else
			sumNpc->GetOwner()->SummonNpcRemove(df);
#endif
			goto SKIP_DROP;
		}
	}
	/*

	*/

	// 이곳으로 넘어오면 테이밍이 아니므로, 모든 몬스터는 몬스터에게 죽으면 패스
	else if (onpc && !bNPCKilledNPC)
	{
		goto SKIP_DROP;
	}

	// pc가 npc를 죽이면 테이밍 몬스터의 타겟을 지워준다.
	if (opc)
	{
		opc->SetOwners_target(NULL);
		opc->SetSummonOwners_target(NULL);
	}

	// 리더 사망시 처리
	if (!df->m_proto->CheckFlag(NPC_RAID))
		ProcFollowNPC(df);

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

	// 죽은 NPC가 공성탑이나 수호병이 아닐 경우 처리
	if (!df->m_proto->CheckFlag(NPC_CASTLE_TOWER | NPC_CASTLE_GUARD))
	{
		int level = -1;
		LONGLONG nTotalDamage = 0;
		// 우선권 PC, 평균 레벨 구하기
		CPC* tpc = FindPreferencePC(df, &level, &nTotalDamage);
#ifdef GER_LOG
		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("victim-id", df->m_index ) << blank
					   /*<< LOG_VAL("opponent-id", kill) << blank*/
					   << LOG_VAL("longitude", GET_X(user) ) << blank
					   << LOG_VAL("latitude", GET_Z(user) ) << blank
					   << endGer;
		}
#endif
		// 보스몹
		if (df->m_proto->CheckFlag(NPC_BOSS | NPC_MBOSS | NPC_RAID))
		{
			GAMELOG << init("MOB DEAD")
					<< "INDEX" << delim
					<< df->m_proto->m_index << delim
					<< "NAME" << delim
					<< df->m_name << delim
					<< "ZONE" << delim
					<< df->m_pZone->m_index << delim
					<< "POSITION" << delim
					<< GET_X(df) << delim
					<< GET_Z(df) << delim
					<< GET_YLAYER(df) << delim
					<< "KILL BY" << delim;
			if (opc)
			{
				GAMELOG << opc->m_index << delim
						<< opc->m_name << delim
						<< opc->m_nick << delim
						<< opc->m_job << delim
						<< opc->m_job2 << delim
						<< opc->m_level;
			}
			else
			{
				GAMELOG << of->m_type << delim
						<< of->m_index << delim
						<< of->m_name << delim
						<< of->m_level;
			}
			GAMELOG << end;

			if (df->m_proto->CheckFlag(NPC_BOSS | NPC_MBOSS))
			{
				// 카오 성향 회복 : 보스몹을 잡으면 회복 보너스
				if (opc && opc->IsChaotic() && tpc == opc)
				{
					if( !gserver->m_bNonPK )
						opc->m_pkPenalty += df->m_level / 10;

					if (opc->m_pkPenalty > 0)
						opc->m_pkPenalty = 0;

					{
						CNetMsg::SP rmsg(new CNetMsg);
						CharStatusMsg(rmsg, opc, 0);
						opc->m_pArea->SendToCell(rmsg, opc, false);
					}

					opc->m_bChangeStatus = true;
				}
			}
		} // 보스몹

		if(opc && opc->m_pArea && df->m_proto->m_index == 1002 && df->m_pZone && df->m_pZone->m_index == ZONE_ALTER_OF_DARK)
		{
			// 네임드 몬스터 죽은 것으로 체크
			opc->m_pArea->m_CTriggerList.Set_TriggerFlag(TRIGGER_FLAG_NAMEDNPC_DEATH1);
			opc->m_pArea->m_CTriggerList.Set_TriggerFlag(TRIGGER_FLAG_NAMEDNPC_DEATH1002_BEFORE);
			opc->m_pArea->m_CTriggerList.SaveTriggerInfo(TRIGGER_SAVE_ALTER_OF_DARK_1002, opc->m_nJoinInzone_RoomNo);	//트리거 정보 저장
			opc->m_pArea->Change_NpcRegenRaid(TRIGGER_SAVE_ALTER_OF_DARK_1002, 1002);
		}
		else if(opc && opc->m_pArea && df->m_proto->m_index == 1003 && df->m_pZone && df->m_pZone->m_index == ZONE_ALTER_OF_DARK)
		{
			// 네임드 몬스터 죽은 것으로 체크
			opc->m_pArea->m_CTriggerList.Set_TriggerFlag(TRIGGER_FLAG_NAMEDNPC_DEATH2);
			opc->m_pArea->m_CTriggerList.Set_TriggerFlag(TRIGGER_FLAG_NAMEDNPC_DEATH1003_BEFORE);
			opc->m_pArea->m_CTriggerList.SaveTriggerInfo(TRIGGER_SAVE_ALTER_OF_DARK_1003, opc->m_nJoinInzone_RoomNo);	//트리거 정보 저장
			opc->m_pArea->Change_NpcRegenRaid(TRIGGER_SAVE_ALTER_OF_DARK_1003, 1003);
		}
		else if(opc && opc->m_pArea && df->m_proto->m_index == 1018 && df->m_pZone && df->m_pZone->m_index == ZONE_ALTER_OF_DARK)
		{
			// 네임드 몬스터 죽은 것으로 체크
			opc->m_pArea->m_CTriggerList.Set_TriggerFlag(TRIGGER_FLAG_NAMEDNPC_DEATH1018_BEFORE);
			opc->m_pArea->m_CTriggerList.SaveTriggerInfo(TRIGGER_SAVE_ALTER_OF_DARK_1018, opc->m_nJoinInzone_RoomNo);	//트리거 정보 저장
			opc->m_pArea->Change_NpcRegenRaid(TRIGGER_SAVE_ALTER_OF_DARK_1018, 1018);
		}
		else if (opc && opc->m_pArea && df->m_proto->m_index == 963 && df->m_pZone && df->m_pZone->m_index == ZONE_CAPPELLA_1)
		{
			// 트리거를 사용하기 위한 npc963 죽은 count 세기
			opc->m_pArea->m_CTriggerList.m_nNPC963_KilledCount += 1;
		}

		int nObjectData;
		int nAkanNpcIdx = df->m_proto->m_index;

		switch(nAkanNpcIdx)
		{
		case 1115:				// 파독스의 인형(Hard)
		case 1170:				// 파독스의 인형(Normal)
			{
				nObjectData = 10;
				if(opc && opc->m_pArea && df->m_pZone && df->m_pZone->m_index == ZONE_AKAN_TEMPLE)
				{
					CNetMsg::SP rmsg(new CNetMsg);
					RaidSceneMsg(rmsg, OBJECT_TYPE_TODO, KILL_NPC, nAkanNpcIdx, nObjectData);
					do_ExRaidScene(opc, rmsg);
				}
			}
			break;
		case 1112:				// 툴만
		case 1116:				// 파독스
		case 1120:				// 쿤타
		case 1124:				// 유작
		case 1126:				// 고위 연금술사 제롬
		case 1127:				// 고위 마법술사 미엘
		case 1128:				// 제사장 미쿠
		case 1167:				// 툴만
		case 1171:				// 파독스
		case 1175:				// 쿤타
		case 1179:				// 유작
		case 1180:				// 고위 연금술사 제롬
		case 1181:				// 고위 마법술사 미엘
		case 1182:				// 제사장 미쿠
			{
				nObjectData = 1;
				if(opc && opc->m_pArea && df->m_pZone && df->m_pZone->m_index == ZONE_AKAN_TEMPLE)
				{
					{
						CNetMsg::SP rmsg(new CNetMsg);
						RaidSceneMsg(rmsg, OBJECT_TYPE_TODO, KILL_NPC, nAkanNpcIdx, nObjectData);
						do_ExRaidScene(opc, rmsg);
					}
				}
			}
			break;
		case 1259:	//망각의 신전
			{
				nObjectData = 1;
				if(opc && opc->m_pArea && df->m_pZone && df->m_pZone->m_index == ZONE_DUNGEON4)
				{
					CNetMsg::SP rmsg(new CNetMsg);
					RaidSceneMsg(rmsg, OBJECT_TYPE_TODO, KILL_NPC, nAkanNpcIdx, nObjectData);
					do_ExRaidScene(opc, rmsg);
				}
			}
			break;
		case 1364:
			{
				if(opc && opc->m_pArea && df->m_pZone && df->m_pZone->m_index == ZONE_TARIAN_DUNGEON)
				{
					CNetMsg::SP rmsg(new CNetMsg);
					RaidSceneMsg(rmsg, OBJECT_TYPE_TODO, KILL_NPC, nAkanNpcIdx, 1);
					do_ExRaidScene(opc, rmsg);
				}
			}
			break;
		default:
			break;
		}

#ifdef REFORM_PK_PENALTY_201108 // PK 패널티 리폼 :: npc를 잡으면 무조건 헌터 쪽으로 향상 시켜준다.
		if( !gserver->m_bNonPK )
		{
			if(df && opc)
			{
				int nlevel = df->m_level - opc->m_level;
				int pkPenalty = 0;
				if( nlevel > 4 )
					pkPenalty += 15;
				else if( nlevel > -5 )
					pkPenalty += 10;
				else if( nlevel <= -5 && nlevel >= -10)
					pkPenalty += 5;

				// 성향 수치 상승 증폭제를 사용 중이라면
				if( opc->m_assist.m_avRate.pkDispositionPointValue > 0 )
				{
					pkPenalty = pkPenalty * opc->m_assist.m_avRate.pkDispositionPointValue;
					opc->m_assist.CureByItemIndex(7474);	// 성향 수치 상승 증폭제
					opc->m_assist.CureByItemIndex(7475);	// 성향 수치 상승 증폭제
					opc->m_assist.CureByItemIndex(7476);	// 성향 수치 상승 증폭제
				}
				opc->AddPkPenalty( pkPenalty );

				{
					CNetMsg::SP rmsg(new CNetMsg);
					CharStatusMsg(rmsg, opc, 0);
					opc->m_pArea->SendToCell(rmsg, opc, false);
				}

				opc->m_bChangeStatus = true;
			}
		}
#else // REFORM_PK_PENALTY_201108 // PK 패널티 리폼
		if (opc && opc->IsChaotic() && df->m_level >= opc->m_level - 5)
		{
			opc->m_pkRecoverNPCCount++;
			if (opc->m_pkRecoverNPCCount >= 25)
			{
				opc->m_pkRecoverNPCCount = 0;

				if( !gserver->m_bNonPK )
					opc->m_pkPenalty++;

				{
					CNetMsg::SP rmsg(new CNetMsg);
					CharStatusMsg(rmsg, opc, 0);
					opc->m_pArea->SendToCell(rmsg, opc, false);
				}

				opc->m_bChangeStatus = true;
			}
		} // 카오 성향 회복
#endif // REFORM_PK_PENALTY_201108 // PK 패널티 리폼
		// Exp, SP 분배
		// 이루틴중 레벨업을 하여 존이동을 하였을 경우 나머지 실행하지 않는다.
		if( DivisionExpSP(df, tpc, nTotalDamage) )
			goto END_PROC;

		// 아이템 드롭
		ProcDropItemAfterBattle(df, opc, tpc, level);

		// 진행중인 Quest 중 죽은 npc로 진행중이면 UpdateData
		if (opc && opc == tpc)
		{
			if( opc->m_pZone->IsPersonalDungeon() )
			{
				opc->m_pArea->m_nMakeNPC++;

#if defined ( LC_GAMIGO ) || defined ( LC_KOR ) || defined ( LC_USA )
				if( df->m_proto->m_index == 5 )
				{
					if(opc->m_pArea->m_nMakeNPC < 103)
						goto SKIP_DROP;
					else
					{
						GAMELOG << init("QUEST COMPLETE PD1", opc)
								<< opc->m_pArea->m_nMakeNPC
								<< end;
					}
				}
				else if(df->m_proto->m_index == 201 && opc->m_pArea->m_nMakeNPC < 50)
				{
					goto SKIP_DROP;
				}
#else
				if( (df->m_proto->m_index == 5 || df->m_proto->m_index == 201 ) && opc->m_pArea->m_nMakeNPC < 50 )
				{
					goto SKIP_DROP;
				}
#endif // LC_GAMIGO || LC_KOR || LC_USA
			}

#ifdef PARTY_QUEST_ITEM_BUG_
			ProcDeadQuestProc(opc, df, QTYPE_SCALE_PERSONAL); // 내가 어그로도 먹고 몬스터도 막타 쳤단다.
#else
			CQuest* pQuest = NULL;
			CQuest* pQuestNext = opc->m_questList.GetNextQuest(NULL, QUEST_STATE_RUN);
			while ((pQuest = pQuestNext))
			{
				pQuestNext = opc->m_questList.GetNextQuest(pQuestNext, QUEST_STATE_RUN);
				// 퀘스트 있고 수행중이고 반복, 수집, 격파, 구출 퀘스트이면
				switch (pQuest->GetQuestType0())
				{
				case QTYPE_KIND_REPEAT:
				case QTYPE_KIND_COLLECTION:
				case QTYPE_KIND_DEFEAT:
				case QTYPE_KIND_SAVE:
					pQuest->QuestUpdateDataForParty(opc, df);
					break;

				default:
					break;
				}
			}
			if( pQuest == NULL && opc->IsParty() && opc->m_party )
			{
				int i;
				const CPartyMember* pPartyMember;
				CPC*	pPartyPC;

				for(i=0; i<MAX_PARTY_MEMBER; ++i)
				{
					pPartyMember = opc->m_party->GetMemberByListIndex(i);
					if(pPartyMember && pPartyMember->GetMemberPCPtr())
					{
						pPartyPC = pPartyMember->GetMemberPCPtr();

						if(opc->m_pArea->FindCharInCell(opc, pPartyPC->m_index, MSG_CHAR_PC))
						{
							pQuest = pPartyPC->m_questList.FindQuestByMob( df->m_idNum);

							if( pQuest == NULL)
								continue;

							if( pQuest->GetPartyScale() != QTYPE_SCALE_PARTY)
								break;

							switch (pQuest->GetQuestType0())
							{
							case QTYPE_KIND_REPEAT:
							case QTYPE_KIND_COLLECTION:
							case QTYPE_KIND_DEFEAT:
							case QTYPE_KIND_SAVE:
								pQuest->QuestUpdateData(pPartyPC, df);
								break;

							default:
								break;
							}
						}
					}
				}
			}
#endif // PARTY_QUEST_ITEM_BUG_
		}
#ifdef PARTY_QUEST_ITEM_BUG_
		else if(opc) // [2010/12/28 derek] opc == NULL 인데도 들어가져서 퀘스트 찾다가 서버 다운되어 추가함.
		{
#ifdef _BATTLEGROUP_QUEST_BUG_PIX
			if( opc->IsExped() ) // 어글은 않먹었지만 막타로 잡았으면
				ProcDeadQuestProc(opc, df, QTYPE_SCALE_BATTLEGROUP);
			else
#endif
				ProcDeadQuestProc(opc, df, QTYPE_SCALE_PARTY);
		}

#endif //PARTY_QUEST_ITEM_BUG_
	} // 죽은 NPC가 공성탑이나 수호병이 아닐 경우 처리
	else
	{
		int level = -1;
		LONGLONG nTotalDamage = 0;
		// 우선권 PC, 평균 레벨 구하기
		CPC* tpc = FindPreferencePC(df, &level, &nTotalDamage);
		DropWarCastleToken(df, opc, tpc, level);
	}

SKIP_DROP:

	// 수호탑은 DelNPC() 안하고 UpdateGateState() 후에 메시지로 알린다.
	if (df->m_proto->CheckFlag(NPC_CASTLE_TOWER) != 0)
	{
		int gstate_old = 0, gstate_new = 0;

		CWarCastle * castle = CWarCastle::GetCastleObject(ZONE_MERAC);
		CDratanCastle * pCastle = CDratanCastle::CreateInstance();

		if (of->m_pZone->m_index == ZONE_MERAC)
		{
			if (castle != NULL)
			{
				gstate_old = castle->GetGateState();
				gstate_old |= pCastle->GetGateState();
				castle->UpdateGateState(df);
				gstate_new = castle->GetGateState();
				gstate_new |= pCastle->GetGateState();
			}
		}
		else if (of->m_pZone->m_index == ZONE_DRATAN)
		{
			gstate_old = pCastle->GetGateState();

			if (castle != NULL)
			{
				gstate_old |= castle->GetGateState();
			}

			pCastle->UpdateGateState(df);
			gstate_new = pCastle->GetGateState();

			if (castle != NULL)
			{
				gstate_new |= castle->GetGateState();
			}

			if (df->m_proto->CheckFlag(NPC_WARCASTLE) != 0)
			{
				// NPC_CASTLE_TOWER 에 NPC_WARCASTLE 면
				// 마스터 타워와 부활진지
				int qindex = df->m_proto->m_index;
				if (qindex >= 390 && qindex <= 396)
				{
					// 부활진지 파괴 알림
					CNetMsg::SP rmsg(new CNetMsg);
					CastleTowerQuartersCrushMsg(rmsg, qindex);
					of->m_pArea->SendToAllClient(rmsg);

					// 부활진지 파괴 처리
					/*pCastle->m_nRebrithGuild[df->m_proto->m_index - 390] =  -1;
					memset((void *)pCastle->m_strRebrithGuild[df->m_proto->m_index - 390], 0, 51);*/
				}
			}
		}

		if (gstate_old != gstate_new)
		{
			CNetMsg::SP rmsg(new CNetMsg);
			GuildWarGateStateMsg(rmsg, gstate_old, gstate_new);
			of->m_pArea->SendToAllClient(rmsg);
		}

		DelAttackList(df);

		if (of->m_pZone->m_index == ZONE_DRATAN)
		{
			if( df->m_proto->m_index == 351)
			{
				// 마스터 타워
				// 모든 타워 기능 정지
				pCastle->StopCastleTower();
			}
			else if (df->m_proto->CheckFlag(NPC_CASTLE_TOWER) != 0)
			{
				// 공격 수호상 (결계의 눈 등..) 로그
				GAMELOG << init("DRATAN CASTLE NPC DEAD : ") << df->m_proto->m_name
						<< " BROKEN BY : " << of->m_name << end;
				// 마스터 타워가 아닌 모든 타워
				int  i;
				// 부활 진지 삭제
//				for (i=0; i<7; i++)
//				{
//					if (pCastle->m_pRebrithNPC[i] == df)
//					{
//						pCastle->m_pRebrithNPC[i] = NULL;
//						pCastle->m_nRebrithGuild[i] = -1;
//						memset((void *)pCastle->m_strRebrithGuild[i], 0, 51);
//#ifdef BUGFIX_WARCASTLE_REGEN
//						pCastle->m_nRegenTimeRebirthNPC[i] = gserver->getNowSecond() + pCastle->GetRegenNPCRebirthTime();
//#else
//						pCastle->m_nRegenTimeRebirthNPC[i] = gserver->m_pulse + pCastle->GetRegenNPCRebirthTime();
//#endif // BUGFIX_WARCASTLE_REGEN
//					}
//				}

				// 워프 타워 삭제
				for (i=0; i<5; i++)
				{
					if (pCastle->m_pWarpNPC[i] == df)
					{
						pCastle->m_pWarpNPC[i] = NULL;
					}
				}

				// 결계의 눈 삭제
				for (i=0; i<5; i++)
				{
					if (pCastle->m_gateNPC[i] == df)
					{
						pCastle->m_gateNPC[i] = NULL;
					}
				}

				// 알림
				of->m_pArea->CharFromCell(df, true);
				of->m_pArea->DelNPC(df);
			}
		}
		return ;
	} // 수호탑은 DelNPC() 안하고 UpdateGateState() 후에 메시지로 알린다.
//#endif

#ifdef EXTREME_CUBE
	if(df->m_bCubeRegen)
	{
		CCubeSpace* cube = gserver->m_extremeCube.GetExtremeCube(df->m_pArea->m_index);
		if(cube)
		{
			cube->DelMob(df);

			if(gserver->m_extremeCube.IsGuildCubeTime() && opc && opc->m_guildInfo && opc->m_guildInfo->guild())
			{
				CCubeMemList* CubeMemList;
				CubeMemList = gserver->m_extremeCube.FindMemList(opc->m_guildInfo->guild());
				if(CubeMemList)
				{
					time_t lastCubePoint;

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

	if(df->m_pZone != NULL && df->m_proto->m_index == 529 && df->m_pZone->IsExtremeCube())
	{
		CCubeSpace* cube = gserver->m_extremeCube.GetExtremeCube(df->m_pArea->m_index);

		if(cube && (cube->m_crystal == df) )
		{
			// cube->m_crystal = NULL;

			cube->DelCrystal(false);
			cube->m_waitTime = gserver->m_pulse + PULSE_REAL_SEC * 10;
			return ;
		}
	}
	else if(df->m_pZone != NULL && df->m_proto->m_index == 527 && df->m_pZone->IsExtremeCube())
	{
		CCubeSpace* cube = gserver->m_extremeCube.GetExtremeCube(df->m_pArea->m_index);

		if(cube && (cube->m_crystal == df) )
		{
			// cube->m_crystal = NULL;

			cube->DelCrystal(false);
			cube->m_waitTime = gserver->m_pulse + PULSE_REAL_SEC * 10;
			return ;
		}
	}
#endif // EXTREME_CUBE

	if(df && opc)
	{
		vec_affinityList_t::iterator it = df->m_proto->m_affinityList.begin();
		vec_affinityList_t::iterator endit = df->m_proto->m_affinityList.end();
		
		int point = 0;

		for(; it != endit; ++it)
		{
			CAffinityProto* proto = *(it);

			CAffinity* affinity = opc->m_affinityList.FindAffinity(proto->m_index);
			if(affinity)
			{
				point = proto->GetAffinityPointOfNPC(df->m_idNum);
				int bonus = 0;
				if(opc->m_avPassiveAddition.affinity_monster > 0)
				{
					bonus += opc->m_avPassiveAddition.affinity_monster;
				}
				if(opc->m_avPassiveRate.affinity_monster > 0)
				{
					bonus = point * (opc->m_avPassiveRate.affinity_monster - 100) / SKILL_RATE_UNIT;
				}

				affinity->AddPoint( point, opc, bonus);
			}
		}
	}

	if(df->m_ctCount > 0)
	{
		gserver->m_npc_ctTime.erase(df->m_index);
	}

END_PROC:

	//rvr 존에서 공격시에 동작해야 되는 함수 (NPC 가 죽었을 경우)
	if(opc != NULL && of->m_pZone->isRVRZone() && df->m_pZone->isRVRZone())
	{
		ProcDead_RVR(opc, df);
	}

	// 모든 몬스터는 몬스터에게 죽으면 패스
	if ( onpc || bNPCKilledNPC )
	{
		// 해당 에어리어에 죽은 수를 표시한다.  여기서는 바로 안지우고 따로 처리..
		// MobActivity.cpp::MobActivity() 타고 들어오면 꼭 여길 거쳐야한다.
		onpc->m_pArea->m_nNPC_Killed_NPC++;
	}
	else
	{
		DelAttackList(df);
		of->m_pArea->CharFromCell(df, true);
		of->m_pArea->DelNPC(df);
	}
}