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 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; }
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 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 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 ; }