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; }
BOOL CommonSkill001_T::OnCancel(Obj_Character& rMe) const { __ENTER_FUNCTION SkillInfo_T& rSkillInfo = rMe.GetSkillInfo(); TargetingAndDepletingParams_T& rParams = rMe.GetTargetingAndDepletingParams(); Obj_Character* pTar = (Obj_Character*)(GetTargetObj(rMe)); if(NULL==pTar) { rParams.SetErrCode(OR_INVALID_TARGET); return FALSE; } if(NULL==pTar || FALSE==pTar->IsAlive() || FALSE == pTar->IsActiveObj() || Obj::OBJ_TYPE_PET != pTar->GetObjType()) { rParams.SetErrCode(OR_INVALID_TARGET); return FALSE; } GCManipulatePetRet msg; msg.SetGUID(((Obj_Human*)&rMe)->GetGUIDOfCallUpPet()); msg.SetFightingFlag(FALSE); msg.SetManipulateRet(GCManipulatePetRet::MANIPULATEPET_RET_CALLUPFALID); ((Obj_Human*)&rMe)->GetPlayer()->SendPacket(&msg); // 减少该宠物身上的捕获玩家数 ((Obj_Horse*)pTar)->DelCapturer(rMe.GetID()); return TRUE; __LEAVE_FUNCTION return FALSE; }
BOOL CommonSkill001_T::EffectOnUnitOnce(Obj_Character& rMe, Obj_Character& rTar, BOOL bCriticalFlag) const { __ENTER_FUNCTION SkillInfo_T& rSkillInfo = rMe.GetSkillInfo(); TargetingAndDepletingParams_T& rParams = rMe.GetTargetingAndDepletingParams(); if(FALSE==rTar.IsAlive() || FALSE == rTar.IsActiveObj() || Obj::OBJ_TYPE_HORSE != rTar.GetObjType()) { rParams.SetErrCode(OR_INVALID_TARGET); return FALSE; } if(Obj::OBJ_TYPE_HUMAN != rMe.GetObjType()) { rParams.SetErrCode(OR_U_CANNT_DO_THIS_RIGHT_NOW); return FALSE; } {// Test code INT nDataIndex = Skill_GetSkillInfoDescriptorValueByIndex(rSkillInfo, 0); g_ImpactCore.SendImpactToUnit(rTar, nDataIndex, rMe.GetID(), 500); } PET_LOG_PARAM PetLogParam; BOOL bRet = ((Obj_Human*)&rMe)->CaptureHorse(&PetLogParam,rTar.GetID()); GCManipulatePetRet msg; if(bRet) { msg.SetManipulateRet(GCManipulatePetRet::MANIPULATEPET_RET_CAPTURESUCC); ((Obj_Human*)&rMe)->GetPlayer()->SendPacket(&msg); // 向正在捕获的其它玩家发送失败消息 ((Obj_Horse&)rTar).SendCaptureFailedToOthers(rMe.GetID()); // 清空宠物身上所有的玩家数 ((Obj_Horse&)rTar).DelCapturer(rMe.GetID()); HorseManager* pHorseMgr = rMe.getScene()->GetHorseManager(); if (pHorseMgr) { pHorseMgr->RemoveHorse(rTar.GetID()); } PetLogParam.OPType = PET_OP_CATCH; SavePetLog(&PetLogParam); } else { // 减少该宠物身上的捕获玩家数 ((Obj_Horse&)rTar).DelCapturer(rMe.GetID()); msg.SetManipulateRet(GCManipulatePetRet::MANIPULATEPET_RET_CAPTUREFALID); ((Obj_Human*)&rMe)->GetPlayer()->SendPacket(&msg); } return TRUE; __LEAVE_FUNCTION return FALSE; }
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 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 StdImpact059_T::BroadcastTargetListMessage( OWN_IMPACT& rImp, Obj_Character& rMe, OBJLIST& rTargets, HitFlagsForOBJLIST_T& rHitFlagsForObjList ) const { __ENTER_FUNCTION SkillInfo_T& rSkillInfo = rMe.GetSkillInfo(); TargetingAndDepletingParams_T& rParams = rMe.GetTargetingAndDepletingParams(); GCTargetListAndHitFlags msg; GCTargetListAndHitFlags::HitFlagList_T& rHitFlags = msg.GetHitFlagList(); msg.SetDataType(msg.BUFF_ACTIVETE); msg.SetObjID(rMe.GetID()); msg.SetUserPos(*(rMe.getWorldPos())); msg.SetLogicCount(rMe.GetLogicCount()); msg.SetSkillOrSpecialObjDataID(rImp.GetSkillID()); msg.SetTargetID(rParams.GetTargetObj()); msg.SetTargetPos(rParams.GetTargetPosition()); msg.SetDir(rParams.GetTargetDirection()); BYTE nNum = rTargets.m_Count; if(msg.MAX_TARGET_LIST_SIZE<nNum) { nNum = msg.MAX_TARGET_LIST_SIZE; } msg.SetTargetNum(nNum); int iTemp = nNum; INT nIdx=0; for(nIdx=0; nNum>nIdx; ++nIdx) { Obj* pTarget = rTargets.m_aObj[nIdx]; if(NULL!=pTarget) { msg.SetTargetObjIDByIndex(nIdx, pTarget->GetID()); if(TRUE == rHitFlagsForObjList.GetFlagByIndex(nIdx)) { rHitFlags.MarkFlagByIndex(nIdx); //msg.SetBallIDByIndex( nIdx, m_aBallUniqueID[nIdx].m_uUniqueID ); } } } Scene* pScene = rMe.getScene(); if(NULL!=pScene) { pScene->BroadCast(&msg, &rMe, TRUE); } __LEAVE_FUNCTION }
BOOL CombatCore_T::IsCriticalHit(Obj_Character& rAttacker, INT nCriticalRate, INT nRand, INT iToughness) { __ENTER_FUNCTION INT iSkillPointRefix = 0; SkillInfo_T& rSkillInf = rAttacker.GetSkillInfo(); iSkillPointRefix = rSkillInf.GetCriticalRate(); if( 0 > iSkillPointRefix ) { iSkillPointRefix = 0; } INT iRateCrit = 0; if (Obj::OBJ_TYPE_HUMAN==rAttacker.GetObjType()) { Obj_Human& rHuman = (Obj_Human&)rAttacker; _ITEM_EFFECT* pIE=NULL; pIE = rHuman.ItemEffect(IATTRIBUTE_RATE_CRIT); Assert( pIE ); if( pIE->IsActive() ) { iRateCrit = pIE->m_Attr.m_Value; } } //暴击率=(5+攻击方总暴击-受击方总韧性)/100+攻击方装备对暴击率的影响+攻击方技能对暴击率的影响 INT iFanlCriticalRate = Float2Int((( 5 + nCriticalRate - iToughness )/100.0 + iRateCrit/100.0 +iSkillPointRefix/100.f) * 100.0); iFanlCriticalRate = Attr_VerifyCritical(iFanlCriticalRate); if( nRand < iFanlCriticalRate ) return TRUE;//会心一击 return FALSE;//普通一击 __LEAVE_FUNCTION return FALSE; }
BOOL ScriptLogic_T::StartChanneling(Obj_Character& rMe) const { __ENTER_FUNCTION SkillInfo_T& rSkillInfo = rMe.GetSkillInfo(); TargetingAndDepletingParams_T& rParams = rMe.GetTargetingAndDepletingParams(); Time_t nChannelTime = rSkillInfo.GetChannelTime(); Time_t nCooldown = rSkillInfo.GetCooldownTime(); if(0<nChannelTime) { if(FALSE==rParams.GetIgnoreConditionCheckFlag()) { if(FALSE==Script_OnConditionCheck(rMe)) { return FALSE; } if(FALSE==Script_OnDeplete(rMe)) { return FALSE; } } SetCooldown(rMe,(CooldownID_t)rSkillInfo.GetCooldownID(),nCooldown); if(TRUE==GetGlobalActionDelegator().RegisterChannelActionForScript(rMe, rParams.GetActivatedSkill(), nChannelTime, rSkillInfo.GetChargesOrInterval())) { rParams.SetErrCode(OR_OK); Script_OnActivateOnce(rMe); return TRUE; } } else { return StartLaunching(rMe); } return FALSE; __LEAVE_FUNCTION return FALSE; }
BOOL StdImpact072_T::GetTargetPos( OWN_IMPACT& rImp, Obj_Character &rMe, WORLD_POS& oTargetPos, FLOAT& fDistance ) const { __ENTER_FUNCTION TargetingAndDepletingParams_T& rParams = rMe.GetTargetingAndDepletingParams(); //计算方向 FLOAT fMaxDistance = (FLOAT)GetDistance( rImp ); ID_t nTargetMode = rMe.GetSkillInfo().GetTargetingLogic(); if( INVALID_ID == nTargetMode ) { //g_pLog->FastSaveLog( LOG_FILE_1, "瞬移技能 error, INVALID_ID == nTargetMode" ); return FALSE; } WORLD_POS oMyPos = *(rMe.getWorldPos()); if( TARGET_POS == nTargetMode ) { oTargetPos = rParams.GetTargetPosition(); fDistance = GetFinalDistance(rMe, oMyPos, oTargetPos, fMaxDistance); } else if( TARGET_SPECIFIC_UNIT == nTargetMode ) { ObjID_t iID = rParams.GetTargetObj(); Obj_Character* pTag = (Obj_Character*)rMe.getScene()->GetObjManager()->GetObj( iID ); if( NULL == pTag ) { //g_pLog->FastSaveLog( LOG_FILE_1, "瞬移技能 error, NULL == pTag" ); return FALSE; } oTargetPos = *(pTag->getWorldPos()); fDistance = GetFinalDistance(rMe, oMyPos, oTargetPos, fMaxDistance); fDistance -= 0.5f; } else if( TARGET_SELF == nTargetMode ) { fDistance = fMaxDistance; oTargetPos = *(rMe.getWorldPos()); FLOAT fDir = rParams.GetTargetDirection(); oTargetPos.m_fX += sinf( fDir ) * fDistance; oTargetPos.m_fZ += cosf( fDir ) * fDistance; } else { //g_pLog->FastSaveLog( LOG_FILE_1, "瞬移技能 error, TargetMode invalid" ); return FALSE; } if( fDistance < 0.005f ) { rMe.DirectTo( &oMyPos, FALSE ); //g_pLog->FastSaveLog( LOG_FILE_1, "瞬移技能 OK, but too near to target" ); return FALSE; } return TRUE; __LEAVE_FUNCTION return FALSE; }
BOOL SkillCore_T::ActiveSkillNow(Obj_Character& rMe) const { __ENTER_FUNCTION SkillInfo_T& rSkillInfo = rMe.GetSkillInfo(); TargetingAndDepletingParams_T& rParams = rMe.GetTargetingAndDepletingParams(); if(FALSE==rMe.IsAlive()||FALSE==rMe.IsActiveObj()) { rParams.SetErrCode(OR_DIE); return FALSE; } rSkillInfo.Init(); if(FALSE==InstanceSkill(rSkillInfo, rMe, rParams.GetActivatedSkill(), rParams.GetSkillLevel())) { rParams.SetErrCode(OR_INVALID_SKILL); rParams.SetErrParam(rParams.GetActivatedSkill()); return FALSE; } //refix skill instance rMe.RefixSkill(rSkillInfo); //perform checking INT nLogicID = rSkillInfo.GetLogicID(); SkillLogic_T const* pLogic = g_SkillLogicList.GetLogicById(nLogicID); if(NULL==pLogic) { rParams.SetErrCode(OR_INVALID_SKILL); rParams.SetErrParam(rParams.GetActivatedSkill()); return FALSE; } if(TRUE == pLogic->IsPassive()) { AssertEx(FALSE,"[SkillCore_T::HeartBeat]: Found passive Skill!!!Data error!!"); rParams.SetErrCode(OR_ERROR); return FALSE; } if(TRUE == pLogic->CancelSkillEffect(rMe)) { rParams.SetErrCode(OR_OK); return TRUE; } //Prefix end if(FALSE==rMe.Skill_IsSkillCooldowned(rParams.GetActivatedSkill())&& FALSE==rParams.GetIgnoreConditionCheckFlag()) { rParams.SetErrCode(OR_COOL_DOWNING); return FALSE; } if(TRUE == rSkillInfo.GetMustUseWeaponFlag()) { if(Obj::OBJ_TYPE_HUMAN==rMe.GetObjType()) { Obj_Human* pHuman = (Obj_Human*)&rMe; Item* pItem=HumanItemLogic::GetEquip(pHuman, HEQUIP_WEAPON); if(NULL==pItem) { rParams.SetErrCode(OR_NEED_A_WEAPON); return FALSE; } else if(TRUE==pItem->IsEmpty()) { rParams.SetErrCode(OR_NEED_A_WEAPON); return FALSE; } } } if(FALSE==rParams.GetIgnoreConditionCheckFlag()) { if(FALSE == pLogic->IsConditionSatisfied(rMe)) { return FALSE; } if(FALSE==pLogic->SpecificOperationOnSkillStart(rMe)) { return FALSE; } } switch (rSkillInfo.GetSkillType()) { case SKILL_INSTANT_LAUNCHING: pLogic->StartLaunching(rMe); break; case SKILL_NEED_CHARGING: pLogic->StartCharging(rMe); break; case SKILL_NEED_CHANNELING: pLogic->StartChanneling(rMe); break; default: AssertEx(FALSE,"[SkillCore_T::ActiveSkillNow]: Try to active a un-active skill!"); break; } return TRUE; __LEAVE_FUNCTION return FALSE ; }