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; }
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; }
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; }
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()); } }
void PetAI::OnReturnPeace() { CPet *pet = (CPet*) GetOwner(); if(!pet->IsDied() && !pet->IsHangUp()) { ChangeStateTo(CShape::STATE_PEACE); } }
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); }
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; }
// 响应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; } }
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; } } }
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; }
void PetAI::OnDel() { CPet *pet = (CPet*) m_Owner; pet->DelFromRegion(PET_OT_DISAPPEAR); }
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; } }
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 }
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); } }