uint CGAskDetailXinFaListHandler::Execute( CGAskDetailXinFaList* pPacket, Player* pPlayer ) { __ENTER_FUNCTION GamePlayer* pGamePlayer = (GamePlayer*)pPlayer ; Assert( pGamePlayer ) ; Obj_Human* pHuman = pGamePlayer->GetHuman() ; Assert( pHuman ) ; Scene* pScene = pHuman->getScene() ; if( pScene==NULL ) { Assert(FALSE) ; return PACKET_EXE_ERROR ; } //检查线程执行资源是否正确 Assert( MyGetCurrentThreadID()==pScene->m_ThreadID ) ; ObjID_t ObjID = pHuman->GetID(); if( ObjID == INVALID_ID ) { Assert(FALSE) ; return PACKET_EXE_ERROR ; } Obj_Character *pTarget = (Obj_Character*)(pScene->GetObjManager()->GetObj(pPacket->getTargetID())); if( pTarget==NULL ) { Assert( pTarget ) ; return PACKET_EXE_ERROR ; } // 权限判断 // to be continue... if ( pTarget->GetObjType() != Obj::OBJ_TYPE_HUMAN && pTarget->GetObjType() != Obj::OBJ_TYPE_PET ) { g_pLog->FastSaveLog( LOG_FILE_1, "CGAskDetailXinFaListHandler: faile obj=%d scene=%d", ObjID, pScene->SceneID() ) ; return PACKET_EXE_CONTINUE; } GCDetailXinFaList Msg; Msg.setObjID( pTarget->GetID() ); Msg.setXinFaList(pHuman->Skill_GetXinFaList().m_Count, pHuman->Skill_GetXinFaList().m_aXinFa); pGamePlayer->SendPacket( &Msg ) ; g_pLog->FastSaveLog( LOG_FILE_1, "CGAskDetailXinFaListHandler: ok obj=%d scene=%d", ObjID, pScene->SceneID() ) ; return PACKET_EXE_CONTINUE ; __LEAVE_FUNCTION return PACKET_EXE_ERROR ; }
BOOL RootTrap01_T::EffectOnChar(Obj_Special& rThis, Obj_Character& rTar) const { SpecialObjData_T const* pData = rThis.GetDataRecord(); if(NULL==pData) { AssertEx(FALSE,"[RootTrap01_T::EffectOnChar]: Can't find Data record."); return FALSE; } INT nImpactID = pData->GetDescriptorByIndex(0)->GetValue(); Time_t nContinuance = pData->GetDescriptorByIndex(1)->GetValue(); OWN_IMPACT impact; SOT_Root_T ImpactLogic; ImpactLogic.InitStruct(impact); impact.m_nCasterID = rThis.GetOwnerID(); impact.m_nSkillID = INVALID_ID; impact.m_nImpactID = nImpactID; ImpactLogic.SetContinuance(impact, nContinuance); impact.m_nPRI = rThis.GetXinFaLevelForBuffMutex(); Scene* pScene = rThis.getScene(); if(NULL!=pScene) { pScene->GetEventCore().RegisterBeSkillEvent(rTar.GetID(), rThis.GetOwnerID(), BEHAVIOR_TYPE_HOSTILITY, 500); pScene->GetEventCore().RegisterImpactEvent(rTar.GetID(), rThis.GetOwnerID(), impact, 500); } return FALSE; }
BOOL CharacterManager::DelCharacter( ObjID_t ObjID ) { __ENTER_FUNCTION Obj_Character* pCharacter = (Obj_Character*)(GetScene()->GetObjManager()->GetObj(ObjID)) ; Assert( pCharacter ) ; UINT index = (UINT)(pCharacter->GetCharacterID()) ; Assert( index<m_Count ) ; Assert( m_Count > 0 ) ; Assert( m_pObjIDs[index]==ObjID ) ; m_pObjIDs[index] = m_pObjIDs[m_Count-1] ; pCharacter->SetCharacterID( INVALID_ID ) ; Obj_Character* pNewCharacter = (Obj_Character*)(GetScene()->GetObjManager()->GetObj(m_pObjIDs[index])) ; Assert( pNewCharacter ) ; pNewCharacter->SetCharacterID( index ) ; m_Count -- ; Assert( m_Count>=0 ) ; return TRUE ; __LEAVE_FUNCTION return FALSE ; }
VOID StdImpact072_T::GetRealPos( Obj_Character &rMe, WORLD_POS &sFinalPos, WORLD_POS &sPosTag, WORLD_POS &sDir ) const { __ENTER_FUNCTION FLOAT fLengthOfStep = 0.5f; FLOAT fLengthTmp = 0; WORLD_POS sPosTmp; //按照前进方向以格子边长(0.5)为步长向目标方向查询,遇障碍或到达目标点为止 while( TRUE ) { //比较当前位置和目标点的距离,如果小于步长则直接到达并结束 fLengthTmp = rMe.WordPosLength( sFinalPos.m_fX-sPosTag.m_fX, sFinalPos.m_fZ-sPosTag.m_fZ ); if( fLengthTmp < fLengthOfStep ) { if ( rMe.getScene()->GetMap()->IsCanGo(sFinalPos) ) sPosTag = sFinalPos; break; } //如果大于步长则增加一个步长的距离 sPosTmp.m_fX = sPosTag.m_fX + sDir.m_fX*fLengthOfStep; sPosTmp.m_fZ = sPosTag.m_fZ + sDir.m_fZ*fLengthOfStep; //判断新位置是否可以通过 if ( rMe.getScene()->GetMap()->IsCanGo(sPosTmp) ) sPosTag = sPosTmp; //不可通过则结束 else break; } __LEAVE_FUNCTION }
VOID StdImpact030_T::OnFadeOut(OWN_IMPACT& rImp, Obj_Character& rMe) const { __ENTER_FUNCTION Obj_Character* pTar=NULL; Scene* pScene = rMe.getScene(); if(NULL==pScene) { AssertEx(FALSE, "[StdImpact030_T::OnFadeOut]: Empty scene pointer found!!"); return; } OBJLIST Targets; if(FALSE==ScanUnitForTarget(rImp, rMe, *(rMe.getWorldPos()), (FLOAT)GetScanRadius(rImp), GetEffectedObjCount(rImp), Targets)) { return; } INT nImpact = GetSubImpactIndex(rImp); if(INVALID_ID==nImpact) { return; } // impacts init finished for(INT nIdx=0; Targets.m_Count>nIdx;++nIdx) { pTar = (Obj_Character*)Targets.m_aObj[nIdx]; if(NULL!=pTar) { pScene->GetEventCore().RegisterBeSkillEvent(pTar->GetID(), rMe.GetID(), BEHAVIOR_TYPE_HOSTILITY, 500); g_ImpactCore.SendImpactToUnit(*pTar, nImpact, rMe.GetID(), 500); } } return; __LEAVE_FUNCTION }
BOOL XingXiuSkill008_T::EffectOnUnitEachTick(Obj_Character& rMe, Obj_Character& rTar, BOOL bCriticalFlag) const { __ENTER_FUNCTION SkillInfo_T& rSkillInfo = rMe.GetSkillInfo(); TargetingAndDepletingParams_T& rParams = rMe.GetTargetingAndDepletingParams(); INT nDamage = rSkillInfo.GetDescriptorByIndex(1)->GetValue(); INT nTransferRate = rSkillInfo.GetDescriptorByIndex(2)->GetValue(); INT nAbsorbed = (nDamage*nTransferRate+50)/100; OWN_IMPACT impact1; DI_Damage_T const logic1; logic1.InitStruct(impact1); logic1.SetDamage(impact1, nDamage); OWN_IMPACT impact2; DI_Heal_T const logic2; logic2.InitStruct(impact2); logic2.SetHealedHP(impact2, nAbsorbed); impact2.m_nImpactID = rSkillInfo.GetDescriptorByIndex(0)->GetValue(); //register impact event RegisterImpactEvent(rTar, rMe, impact1, rParams.GetDelayTime(), bCriticalFlag); RegisterImpactEvent(rMe, rMe, impact2, rParams.GetDelayTime(), bCriticalFlag); return TRUE; __LEAVE_FUNCTION return FALSE; }
BOOL GaiBangSkill004_T::EffectOnUnitOnce(Obj_Character& rMe, Obj_Character& rTar, BOOL bCriticalFlag) const { __ENTER_FUNCTION SkillInfo_T& rSkillInfo = rMe.GetSkillInfo(); TargetingAndDepletingParams_T& rParams = rMe.GetTargetingAndDepletingParams(); INT nDepleteStrikePointSegment = rParams.GetDepletedStrikePoints()/STRIKE_POINT_SEGMENT_SIZE; if(1>nDepleteStrikePointSegment) { AssertEx(FALSE,"[GaiBangSkill004_T::TakeEffectNow]: Depleted strike point segment illegal!"); nDepleteStrikePointSegment=1; } else if(MAX_STRIKE_POINT_SEGMENT<nDepleteStrikePointSegment) { AssertEx(FALSE,"[GaiBangSkill004_T::TakeEffectNow]: Depleted strike point segment illegal!"); nDepleteStrikePointSegment=MAX_STRIKE_POINT_SEGMENT; } INT nAdditionalAttackPower = rSkillInfo.GetDescriptorByIndex(nDepleteStrikePointSegment)->GetValue(); // init impact1 OWN_IMPACT impact; CombatCore_T myCombatCore; myCombatCore.Reset(); myCombatCore.SetAdditionalAttackLight(nAdditionalAttackPower); myCombatCore.GetResultImpact(rMe, rTar, impact); // register impact event RegisterImpactEvent(rTar, rMe, impact, rParams.GetDelayTime(), bCriticalFlag); return TRUE; __LEAVE_FUNCTION return FALSE; }
VOID StdImpact059_T::SendLayerChangeMsg( OWN_IMPACT& rImp, Obj_Character& rMe ) const { __ENTER_FUNCTION //通知客户端层数改变 // Info Other Impact //通知其它客户端效果生效 Scene * pScene = rMe.getScene(); if(NULL==pScene||FALSE==rMe.IsActiveObj()) { return; } GCCharBuff Msg2Other; Msg2Other.SetReceiverID(rImp.GetCasterObjID()); Msg2Other.SetSenderID(rImp.GetCasterObjID()); Msg2Other.SetEnable(TRUE); Msg2Other.SetSN(rImp.GetSN()); Msg2Other.SetBuffID(Impact_GetImpactID(rImp)); Msg2Other.SetSenderLogicCount(rImp.GetCasterLogicCount()); Msg2Other.SetSkillID( rImp.GetSkillID() ); Msg2Other.SetLayerCount( rImp.GetLayerCount() ); // 设置技能效果的持续时间 20100531 BLL Msg2Other.SetContinuance( rImp.GetContinuance() ); if(INVALID_ID!=Impact_GetImpactID(rImp)) { pScene->BroadCast(&Msg2Other, &rMe, TRUE); } __LEAVE_FUNCTION }
INT CombatCore_T::MagicalDamage(Obj_Character& rMe, Obj_Character& rTar, INT nAdditionAttack, INT nAdditionDefence) { __ENTER_FUNCTION INT nDamage; INT nAttack = Attr_VerifyGeneralAttack(rMe.GetAttackMagic()+nAdditionAttack); INT nDefence = Attr_VerifyDefence(rTar.GetDefenceMagic()+nAdditionDefence); INT nIgnoreRate = 0; // calculate damage if(Obj::OBJ_TYPE_HUMAN==rTar.GetObjType()) { nIgnoreRate= rTar.ItemValue(IATTRIBUTE_IMMUNITY_P).m_Value; } if(0==nAttack+nDefence) { //never enter here nDamage = 0; } else { nDamage = nAttack*nAttack/(nAttack+nDefence); } 0>nIgnoreRate?nIgnoreRate=0:NULL; 100<nIgnoreRate?nIgnoreRate=100:NULL; nDamage = nDamage - Float2Int((nDamage*nIgnoreRate)/100.0f); 0>nDamage?nDamage=0:NULL; return nDamage; __LEAVE_FUNCTION return 0; }
VOID AI_Monster::AI_Logic_Approach( UINT uTime ) { __ENTER_FUNCTION /** 先进行Approach类型的判断 */ GET_MONSTER_SCENE((VOID)0) Obj* pObj = pScene->GetObjManager()->GetObj(m_CurEnemyID); if (!pObj || !IsCharacterObj(pObj->GetObjType()) || !((Obj_Character*)pObj)->IsAlive() || !((Obj_Character*)pObj)->IsCanViewMe(pMonster) ) {/** 当前敌人无效后转向下一个敌人,直到全部找完为止 */ DelEnemy(m_CurEnemyID); m_CurEnemyID = GetNextEnemy(); if (INVALID_ID == m_CurEnemyID) { ToGoHome(); } return ; } Obj_Character* pCurEnemy = (Obj_Character*)pObj; FLOAT fMTDist,fETDist; if (!pCurEnemy) { Assert(NULL && "AI_Monster::Logic_Approach...pCurEnemy=NULL..."); ToGoHome(); return ; } FLOAT fDist = MySqrt(pMonster->getWorldPos(), pCurEnemy->getWorldPos()); if ( IsToGoHome(fMTDist, fETDist) ) { return ; } if (ZERO_VALUE > fMTDist) {/** 如果到达目的地 */ ToAttack(); } else { if( fETDist > (FLOAT)AIParam(AIPARAM_RESETTARGET_DIST)/1000.0f) {/** 如果目标位置和敌人位置的距离大与一定值则需要重新制定移动目标 */ ToApproachTar( ) ; } else if(!GetCharacter()->IsMoving()) { ToApproachTar( ); } } ExcuteAIScript(SAPPROACH); __LEAVE_FUNCTION }
VOID StdImpact081_T::SendImpactToMe( OWN_IMPACT& rImp, Obj_Character& rMe ) const { //第一个技能是否可以被触发 BOOL bFirstHappend = IsHappend(rMe, rImp, 0); for(INT nID = 0; nID < MAX_IMPACT_NUM_AT_SAME_TIME; nID++) { INT iImpactID = GetImpactID(rImp, nID); if(INVALID_ID == iImpactID) { break; } if(0 == nID) { //如果第一个技能没有概率触发 if(!bFirstHappend) { continue; } } else { if(INVALID_ID == GetEffectRate( rImp , nID)) { //其它的impact的概率值写-1,认为应该取第一项计算出的概率值 if(!bFirstHappend) { continue; } } else { //单独计算其概率值 if(!IsHappend(rMe, rImp, nID)) { continue; } } } Obj_Character* pAttacker = GetBeHitTarget( rMe, rImp ); if(pAttacker) { INT iTargetType = GetTargetType( rImp, nID ); if( iTargetType == TargetTypeMe ) { g_ImpactCore.SendImpactToUnit(rMe, iImpactID, pAttacker->GetID(), 0); } else { g_ImpactCore.SendImpactToUnit(*pAttacker, iImpactID, rMe.GetID(), 0); } } } }
BOOL ImpactCore_T::SendImpactToUnit(Obj_Character& rTar, ID_t nDataIndex, ObjID_t nSender, Time_t nDelayTime, BOOL bCriticalFlag, INT nRefixRate, INT nReserveParam1, INT nReserveParam2) const { __ENTER_FUNCTION OWN_IMPACT impact; if(INVALID_ID == nDataIndex) { return FALSE; } //根据nDataIndex对应的效果逻辑初始化rImp if(TRUE == InitImpactFromData(nDataIndex, impact, rTar, nReserveParam1)) { //获得逻辑对象 ImpactLogic_T const* pLogic = Impact_GetLogic(impact); if(NULL==pLogic) { Assert(NULL=="[ImpactCore_T::SendImpactToUnit]: Can't find sprcific logic for this impact."); return FALSE; } //设置会心标记 if(TRUE == bCriticalFlag) { impact.MarkCriticalFlag(); } if(0!=nRefixRate) { //向效果逻辑设置修正率 pLogic->RefixPowerByRate(impact, nRefixRate); } if(0>nDelayTime) { nDelayTime = 0; } Scene* pScene = rTar.getScene(); Obj_Character* pChar = NULL; if(NULL!=pScene) { Obj* pObj = pScene->GetSpecificObjByID( nSender ); if( IsCharacterObj(pObj->GetObjType()) ) { pChar = static_cast<Obj_Character*>(pObj); SkillInfo_T& rSkillInfo = pChar->GetSkillInfo(); impact.SetSkillID( rSkillInfo.GetSkillID() ); rSkillInfo.SetSendSkillImpactID(impact.GetDataIndex()); } pScene->GetEventCore().RegisterImpactEvent(rTar.GetID(), nSender, impact, nDelayTime); return TRUE; } } // start to fill impact struct return TRUE; __LEAVE_FUNCTION return FALSE; }
INT CombatCore_T::CalculateHitRate(Obj_Character& rAttacker, Obj_Character& rTag) { __ENTER_FUNCTION INT nHit = rAttacker.GetHit(); INT nMiss = rTag.GetMiss(); nHit = Attr_VerifyHitMiss(nHit); nMiss = Attr_VerifyHitMiss(nMiss); //INT iItemPointRefix = 0; //INT iSkillPointRefix = 0; //if( rAttacker.GetObjType() == Obj::OBJ_TYPE_HUMAN ) //{ // //装备对属性的点数影响 // iItemPointRefix = static_cast<Obj_Human&>(rAttacker).GetIattributeHit(); //} //iSkillPointRefix = rAttacker.GetHitRefix(); //INT iItemPointRefixMiss = 0; //INT iSkillPointRefixMiss = 0; //if( rTag.GetObjType() == Obj::OBJ_TYPE_HUMAN ) //{ // //装备对属性的点数影响 // iItemPointRefixMiss = static_cast<Obj_Human&>(rTag).GetIattributeMiss(); //} //iSkillPointRefixMiss = rTag.GetMissRefix(); INT iRateHit = 0; if (Obj::OBJ_TYPE_HUMAN==rAttacker.GetObjType()) { Obj_Human& rHuman = (Obj_Human&)rAttacker; _ITEM_EFFECT* pIE=NULL; pIE = rHuman.ItemEffect(IATTRIBUTE_RATE_HIT); Assert( pIE ); if( pIE->IsActive() ) { iRateHit = pIE->m_Attr.m_Value; } } //总命中率=(75+攻击方总命中-受击方总闪避)/100+攻击方装备对命中率的影响+攻击方技能对命中率的影响-受击方装备对闪避率的影响-受击方技能对闪避率的影响 SkillInfo_T& oSkillInf = rAttacker.GetSkillInfo(); INT iRefix = oSkillInf.GetAccuracy(); if( iRefix < 0 ) { iRefix = 0; } INT iFainlHitRate = ((75 + nHit - nMiss)/100.0 + iRateHit/100.0 + iRefix/100.0) * 100.0; return iFainlHitRate; __LEAVE_FUNCTION return 0; }
BOOL ActionDelegator_T::IsPerformingTheSpecificScript(Obj_Character& rActor, ScriptID_t nScriptID) const { __ENTER_FUNCTION ActionLogic_T const * pActionLogic = rActor.GetActionLogic(); ActionParams_T& rActionParams = rActor.GetActionParams(); if(NULL==pActionLogic) { return FALSE; } return pActionLogic->IsPerformingSpecificScript(rActionParams, nScriptID); __LEAVE_FUNCTION return FALSE; }
uint CGCharAskBaseAttribHandler::Execute( CGCharAskBaseAttrib* pPacket, Player* pPlayer ) { __ENTER_FUNCTION GamePlayer* pGamePlayer = (GamePlayer*)pPlayer ; Assert( pGamePlayer ) ; Obj_Human* pHuman = pGamePlayer->GetHuman() ; Assert( pHuman ) ; Scene* pScene = pHuman->getScene() ; if( pScene==NULL ) { Assert(FALSE) ; return PACKET_EXE_ERROR ; } //检查线程执行资源是否正确 Assert( MyGetCurrentThreadID()==pScene->m_ThreadID ) ; ObjID_t ObjID = pPacket->getTargetID() ; if( ObjID == INVALID_ID ) { return PACKET_EXE_ERROR ; } Obj* pObj = pScene->GetObjManager()->GetObj( ObjID ) ; if( pObj==NULL ) { g_pLog->FastSaveLog( LOG_FILE_1, "CGCharAskBaseAttribHandler: not find obj=%d", ObjID ) ; return PACKET_EXE_CONTINUE ; } if( !IsCharacterObj( pObj->GetObjType() ) ) { g_pLog->FastSaveLog( LOG_FILE_1, "CGCharAskBaseAttribHandler: not character obj=%d", ObjID ) ; return PACKET_EXE_CONTINUE ; } Obj_Character* pCharacter = (Obj_Character*)pObj ; pCharacter->AskMsg_BaseAttrib( pHuman ); //影响效率关掉Log //g_pLog->FastSaveLog( LOG_FILE_1, "CGCharAskBaseAttribHandler: obj=%d", ObjID ) ; return PACKET_EXE_CONTINUE ; __LEAVE_FUNCTION return PACKET_EXE_ERROR ; }
INT CombatCore_T::MagicalFarDamage(Obj_Character& rMe, Obj_Character& rTar, INT nAdditionAttack, INT nAdditionDefence) { __ENTER_FUNCTION INT nDamage; INT nAttack = Attr_VerifyGeneralAttack(rMe.GetAttackMagicFar()+nAdditionAttack); INT nDefence = Attr_VerifyDefence(rTar.GetDefenceMagicFar()+nAdditionDefence); nDamage = NormalDamage(rTar, nAttack, nDefence, IATTRIBUTE_SHIELD_MAGIC_FAR); INT iResist = rTar.GetMagicFarAttReduce(); nDamage = GetFinalDamages(nDamage, iResist); return nDamage; __LEAVE_FUNCTION return 0; }
VOID StdImpact059_T::DoHitTarget( OWN_IMPACT& rImp, Obj_Character& rMe, OBJLIST& rTargets, HitFlagsForOBJLIST_T& HitFlagList, UINT& nCount ) const { __ENTER_FUNCTION WORLD_POS const* pPos = rMe.getWorldPos(); //搜索目标列表 if(NULL!=pPos) { ScanUnitForTarget( rImp, rMe, pPos->m_fX, pPos->m_fZ, rTargets ); } SkillID_t nSkillID = rImp.GetSkillID(); ////根据技能ID从全局技能模板管理器中获得技能模板实例 //const SkillTemplateData_T* pSkillTemplate = g_SkillTemplateDataMgr.GetInstanceByID( iID ); HitFlagList.ClearAllFlags(); INT nIdx = 0; for(nIdx=0; rTargets.m_Count>nIdx; ++nIdx) { Obj* pTarget = rTargets.m_aObj[nIdx]; if(NULL!=pTarget) { Obj_Character* pChar = (Obj_Character*)pTarget; //如果命中,则把命中与否的列表置为命中 if(TRUE==HitThisTarget(rMe, *pChar, nSkillID)) { //判断小球投送对象身上是否已经有同类型的效果存在,如果有 if( !IsCanSendToUnit( rImp, rMe, pChar ) ) { continue; } ////记录小球投送的对象 //(Obj_Character*)(m_aBallUniqueID[nIdx].m_pCharacter) = pChar; ////记录小球的全局ID //(UINT)(m_aBallUniqueID[nIdx].m_uUniqueID) = g_ImpactCore.GetUniqueID(); //pChar->Impact_SetImpactUniqueID( m_aBallUniqueID[nIdx].m_uUniqueID ); INT nDataIndex = GetSubImpactDataIndexByIndex(rImp, 0); if(0<nDataIndex) { g_ImpactCore.SendImpactToUnit( *pChar, nDataIndex, rMe.GetID(), nSkillID ); } //g_ImpactCore.SendBallImpactToUnit( *pChar, STD_IMPACT_058, rMe.GetID() ); //Mark this Target Hitted HitFlagList.MarkFlagByIndex(nIdx); ++nCount; } } } __LEAVE_FUNCTION }
VOID StdImpact072_T::GetFinalPos( OWN_IMPACT& rImp, Obj_Character &rMe, WORLD_POS& sFinalPos, WORLD_POS& sDir, WORLD_POS& sPosTag, WORLD_POS& oTargetPos, FLOAT fDistance ) const { __ENTER_FUNCTION const WORLD_POS* pMyPos = rMe.getWorldPos(); sDir.m_fX = oTargetPos.m_fX - pMyPos->m_fX; sDir.m_fZ = oTargetPos.m_fZ - pMyPos->m_fZ; sPosTag = *pMyPos; //获取方向 rMe.NormalizeWorldPos( sDir ); //最终希望到达的目标点 sFinalPos.m_fX = sPosTag.m_fX + fDistance*sDir.m_fX; sFinalPos.m_fZ = sPosTag.m_fZ + fDistance*sDir.m_fZ; __LEAVE_FUNCTION }
VOID ImpactLogic_T::ContinuanceCalc(OWN_IMPACT& rImp, Obj_Character& rMe, INT nDeltaTime) const { __ENTER_FUNCTION //取得总持续时间 INT const nContinuance = rImp.GetContinuance(); //取得逝去的持续时间 INT nContinuanceElapsed = rImp.GetContinuanceElapsed(); //如果不是消散状态 if(FALSE == rImp.IsFadeOut()) { //如果是持续性效果 if(TRUE == IsOverTimed()) { if(-1==nContinuance) { return; //-1为持续时间无限长 } if(nContinuanceElapsed<=nContinuance) { nContinuanceElapsed += nDeltaTime; } //如果超时,则消散 if(nContinuanceElapsed>nContinuance) { // prepare delete this impact rMe.Impact_OnImpactFadeOut(rImp); } //更新逝去时间 rImp.SetContinuanceElapsed(nContinuanceElapsed); } } __LEAVE_FUNCTION }
INT CombatCore_T::SoilDamage(Obj_Character& rMe,Obj_Character& rTar, INT nAdditionalAttack, INT nAdditionalResist) { INT nDamage; INT nAttack = Attr_VerifyTraitAttack(rMe.GetAttackSoil()+nAdditionalAttack); INT nResist = Attr_VerifyResist(rTar.GetDefenceSoil()+nAdditionalResist); nDamage = AttrDamage(rMe, nResist, nAttack, IATTRIBUTE_SHIELD_SOIL); INT nIgnoreRate = 0; if(Obj::OBJ_TYPE_HUMAN==rTar.GetObjType()) { nIgnoreRate= (INT)(rTar.ItemValue(IATTRIBUTE_RATE_SOIL_ATT_REDUCE).m_Value); } nDamage = nDamage*(100.0-((double)nIgnoreRate))/100.0f; return nDamage; }
VOID StdImpact021_T::OnUseSkillSuccessfully(OWN_IMPACT& rImp, Obj_Character& rMe, SkillInfo_T& rSkill) const { __ENTER_FUNCTION BOOL bFound = FALSE; INT nActiveTimes=GetActivateTimes(rImp); if(0==nActiveTimes) { return; } if(FALSE == Skill_IsSkillInCollection(rSkill, GetTargetCollection(rImp))) { return; } SkillLogic_T const* pSkillLogic = Skill_GetLogic(rSkill); if(NULL==pSkillLogic) { return; } if(0<nActiveTimes) { --nActiveTimes; if(0==nActiveTimes) { rMe.Impact_OnImpactFadeOut(rImp); } SetActivateTimes(rImp, nActiveTimes); return; } __LEAVE_FUNCTION }
BOOL StdImpact059_T::ScanUnitForTarget( OWN_IMPACT& rImp, Obj_Character& rMe, FLOAT fX,FLOAT fZ, OBJLIST& rTargets) const { __ENTER_FUNCTION UINT uCurrentBallCount = rImp.GetLayerCount(); //初始化搜索需要的基础属性 SkillInfo_T rSkillInfo = rMe.GetSkillInfo(); //为了此类buff可以和其它技能并存,所以给ScanOperatorIniter提供造成此类buff的技能SkillInfo_T g_SkillCore.InstanceSkill( rSkillInfo, rMe, rImp.GetSkillID() ); TargetingAndDepletingParams_T& rParams = rMe.GetTargetingAndDepletingParams(); Scene* pScene = rMe.getScene(); SCANOPERATOR_SECTORSKILL_INIT ScanOperatorIniter; ScanOperatorIniter.m_pSkillInfo = &rSkillInfo; ScanOperatorIniter.m_pMe = &rMe; ScanOperatorIniter.m_pScene = rMe.getScene(); ScanOperatorIniter.m_pTargets = &rTargets; ScanOperatorIniter.m_fRadius = rSkillInfo.GetRadius(); ScanOperatorIniter.m_CentrePoint.m_fX = fX; ScanOperatorIniter.m_CentrePoint.m_fZ = fZ; //保护 if( rTargets.MAX_OBJ_LIST_SIZE < uCurrentBallCount ) return FALSE; //搜索人数上限为当前自身实际的小球个数 ScanOperatorIniter.m_nCount = uCurrentBallCount; //初始化搜索对象 ScanOperator_SectorSkill ScanOperator; ScanOperator.Init(&ScanOperatorIniter); //执行搜索 if(NULL!=pScene) { if(FALSE==pScene->Scan(&ScanOperator)) { rParams.SetErrCode(OR_ERROR); return FALSE; } } else { rParams.SetErrCode(OR_ERROR); return FALSE; } return TRUE; __LEAVE_FUNCTION return FALSE; }
VOID DS_EMei014_T::OnFadeOut(OWN_IMPACT& rImp, Obj_Character& rMe) const { __ENTER_FUNCTION Obj_Character* pTar=NULL; OBJLIST Targets; if(FALSE==ScanUnitForTarget(rImp, rMe, *(rMe.getWorldPos()), (FLOAT)GetScanRadius(rImp), GetEffectedObjNumber(rImp), Targets)) { return; } // init impact OWN_IMPACT impact; DI_ModifyRage_T const* pImpactLogic = (DI_ModifyRage_T const*)g_ImpactLogicList.GetLogicById(DI_MODIFY_RAGE); if(NULL==pImpactLogic) { AssertEx(FALSE,"[SOT_EMei014_T::OnFadeOut]:Can't find the logic for DI_MODIFY_RAGE. check now."); return; } pImpactLogic->InitStruct(impact); impact.m_nSkillID = rImp.m_nSkillID; impact.m_nCasterID = rMe.GetID(); impact.m_nImpactID = GetSubImpactID(rImp); INT nRage = GetRageModification(rImp); 0<nRage?nRage=-nRage:NULL; pImpactLogic->SetRageModification(impact, nRage); Scene* pScene = rMe.getScene(); if(NULL==pScene) { AssertEx(FALSE,"[SOT_EMei014_T::OnFadeOut]:Empty Scene pointer. check now."); return; } // impacts init finished for(INT nIdx=0; Targets.m_Count>nIdx;++nIdx) { pTar = (Obj_Character*)Targets.m_aObj[nIdx]; if(NULL==pTar) { continue; } pScene->GetEventCore().RegisterBeSkillEvent(pTar->GetID(), rMe.GetID(), BEHAVIOR_TYPE_HOSTILITY, 500); pScene->GetEventCore().RegisterImpactEvent(pTar->GetID(), rMe.GetID(), impact, 500); } return; __LEAVE_FUNCTION }
BOOL ActionDelegator_T::IsChanneling(Obj_Character& rActor) const { __ENTER_FUNCTION ActionLogic_T const * pActionLogic = rActor.GetActionLogic(); ActionParams_T& rActionParams = rActor.GetActionParams(); if(NULL==pActionLogic) { return FALSE; } if(ACTION_CHANNEL!=pActionLogic->GetLogicID()) { return FALSE; } return TRUE; __LEAVE_FUNCTION return FALSE; }
INT CombatCore_T::PoisonDamage(Obj_Character& rMe,Obj_Character& rTar, INT nAdditionalAttack, INT nAdditionalResist) { INT nDamage; INT nAttack = Attr_VerifyTraitAttack(rMe.GetAttackPoison()+nAdditionalAttack); INT nResist = Attr_VerifyResist(rTar.GetDefencePoison()+nAdditionalResist); if(MAX_EFFECTIVE_RESIST<nResist) { nResist = MAX_EFFECTIVE_RESIST; } if(-MAX_EFFECTIVE_RESIST>nResist) { nResist = -MAX_EFFECTIVE_RESIST; } nDamage = Float2Int(nAttack*(100-nResist)/100); 0>nDamage?nDamage=0:NULL; return nDamage; }
// all interface of actions ORESULT AI_Character::Obj_Move(const WORLD_POS* pTar) { Obj_Character* pCharacter = GetCharacter(); if (!pCharacter) { Assert(NULL && "AI_Character::MoveTo...pCharacter = NULL..."); return OR_ERROR; } if (TRUE == pCharacter->IsLimitMove() ) { return OR_LIMIT_MOVE; } if (pCharacter->IsDie()) { return OR_DIE; } int numNode = 0; const WORLD_POS* pCur = pCharacter->getWorldPos(); WORLD_POS posNode[MAX_CHAR_PATH_NODE_NUMBER]; WORLD_POS posCur = *pCur; pCharacter->getScene()->GetMap()->VerifyPos( const_cast<WORLD_POS*>(pTar) ); pCharacter->getScene()->GetMap()->GetPathFinder()->FindPath(&posCur, const_cast<WORLD_POS*>(pTar), posNode, numNode, pCharacter->GetDriverLevel()); if( numNode == 0 ) return OR_ERROR; return _state->Obj_Move(this, -1, numNode, posNode ); }
BOOL StdImpact059_T::HitThisTarget(Obj_Character& rMe, Obj_Character& rTar, SkillID_t nSkillID) const { __ENTER_FUNCTION //SkillInfo_T& rSkillInfo = rMe.GetSkillInfo(); TargetingAndDepletingParams_T& rParams = rMe.GetTargetingAndDepletingParams(); Scene* pScene = rMe.getScene(); if(TRUE==rMe.IsFriend(&rTar)) { //给友方使用的技能100%命中 return TRUE; } //Hit Or Miss //根据命中率判断是否击中 //注意:此时对技能释放而言,目标已验证为合法,因此只受技能本身的命中率影响 //如果没有命中 if(FALSE == IsHit(rMe, rTar, m_iAccuracy)) { if(NULL!=pScene) { //直接向全局event对象注册没有命中的事件 pScene->GetEventCore().RegisterSkillMissEvent(rTar.GetID(), rMe.GetID(), nSkillID, 0); } return FALSE; } //如果最终命中,向全局event对象注册技能命中目标事件 if(NULL!=pScene) { pScene->GetEventCore().RegisterSkillHitEvent(rTar.GetID(), rMe.GetID(), nSkillID, 0); } return TRUE; __LEAVE_FUNCTION return FALSE; }
FLOAT StdImpact072_T::GetFinalDistance( Obj_Character &rMe, WORLD_POS &oMyPos, WORLD_POS &oTargetPos, FLOAT fMaxDistance ) const { FLOAT fDistance = rMe.WordPosLength( oMyPos.m_fX-oTargetPos.m_fX, oMyPos.m_fZ-oTargetPos.m_fZ ); if( fMaxDistance < fDistance ) { fDistance = fMaxDistance; } return fDistance; }
VOID StdImpact023_T::OnDamageTarget(OWN_IMPACT& rImp, Obj_Character& rMe, Obj_Character& rTar, INT& rDamage, SkillID_t nSkillID) const { __ENTER_FUNCTION INT nMpDamageRate = GetMpDamageRate(rImp); INT nRageDamageRate = GetRageDamageRate(rImp); if(TRUE==rImp.IsFadeOut()) { return; } if(0>=nMpDamageRate && 0>= nRageDamageRate) { return; } Scene* pScene = rMe.getScene(); if(NULL==pScene) { return; } // 生效几率 INT nActivateOdds = GetActivateOdds(rImp); INT nRet = pScene->GetRand100(); if (nRet > nActivateOdds) {// 没有生效则直接返回 return; } // 命中时吸取敌人MP百分率 if(0<nMpDamageRate) { INT nMP = Float2Int((nMpDamageRate*rDamage)/100.0f); rTar.ManaIncrement(-nMP, &rMe); } // 命中时吸取敌人怒气百分率 if(0<nRageDamageRate) { INT nRage = rTar.GetRage(); nRage = Float2Int((nRageDamageRate*nRage)/100.0f); rTar.RageIncrement(-nRage, &rMe); } __LEAVE_FUNCTION }
BOOL ActionDelegator_T::RegisterChargeActionForSkill(Obj_Character& rActor, ActionID_t nAction, Time_t nContinuance) const { __ENTER_FUNCTION ActionParams_T& rActionParams = rActor.GetActionParams(); if(FALSE==CanDoNextAction(rActor)) { return FALSE; } rActionParams.Reset(); rActionParams.SetActor(&rActor); rActionParams.SetContinuance(nContinuance); rActionParams.SetCallBackFunctor(GetGlobalSkillCallBackFunctor()); rActor.SetActionLogic(&(GetGlobalChargeActionLogic())); //info client Charge action start rActor.AddLogicCount(); BroadcastUnitStartChargeAction(rActor,nAction, nContinuance); if(0==rActor.GetActionTime()) { rActor.SetActionTime(MIN_ACTION_TIME); } rActor.OnActionStarted(); return TRUE; __LEAVE_FUNCTION return FALSE; }