/** * \brief 执行一个技能操作(一个操作包含若干个技能状态,操作有不同的目标对象和范围等)[sky]技能操作 */ void zSkill::doOperation(const SkillStatus *pSkillStatus) { _entry->carrier.status = pSkillStatus; // 一个技能操作 //_entry->carrier.skilltype = base->usetype; // 技能使用类型 //_entry->carrier.skillID = id; // 技能ID _entry->carrier.skillbase = actionbase; // 技能字典 _entry->carrier.revCmd = *curRevCmd; // 保存本次收到的攻击消息 _entry->carrier.attacker = _entry; // 攻击者的指针 WORD wdTarget = pSkillStatus->target; if (wdTarget& TARGET_SELF) { if (_entry->skillStatusM.putOperationToMe(_entry->carrier,true)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); } wdTarget&=(0xff & (~(1))); // 清除表示自己的位,如果只对自己施法那么wdTarget将为0 } _entry->pkValue.damagebonus = actionbase->damnum; Scene *pScene = NULL; pScene = _entry->scene; if (wdTarget) { if (1 == pSkillStatus->range) // 1据说表示单格,所以做为单攻的判断标志 { switch(curRevCmd->byAttackType) { case Cmd::ATTACKTYPE_N2U: /// Npc攻击用户 { //if (!_entry->isPkZone()) return; /*if (_entry->tempid == curRevCmd->dwDefenceTempID) { ScenePk::attackUserCmdToNine(curRevCmd,_entry); return; }*/ SceneUser *pDef = pScene->getUserByTempID(curRevCmd->dwDefenceTempID); if (pDef) { if (wdTarget&TARGET_FRIEND) { if (!_entry->isEnemy(pDef,false,true)&&_entry->checkMagicFlyRoute(pDef,pSkillStatus->mode)) { if (pDef->skillStatusM.putOperationToMe(_entry->carrier,true)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); } return; } } if (wdTarget&TARGET_ENEMY) { if (pDef->getTopMaster()&&pDef->getTopMaster()->getType() == zSceneEntry::SceneEntry_Player) { if (!(pDef->isPkZone(_entry) && _entry->isPkZone(pDef))) // 新加&&this->isPkZone(pDef) { ScenePk::attackFailToMe(curRevCmd,_entry); return; } } if (_entry->isEnemy(pDef,_entry->getType() == zSceneEntry::SceneEntry_Player)&& // 判断敌人友和检查PK模式是一个方法,所以只要判断一次就OK了 _entry->checkMagicFlyRoute(pDef,pSkillStatus->mode)) { if (pDef->skillStatusM.putOperationToMe(_entry->carrier)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); } return; } } } } break; case Cmd::ATTACKTYPE_U2U: /// 用户攻击用户 { //if (!_entry->isPkZone()) return; /*if (_entry->tempid == curRevCmd->dwDefenceTempID) { ScenePk::attackUserCmdToNine(curRevCmd,_entry); return; }*/ SceneUser *pDef = pScene->getUserByTempID(curRevCmd->dwDefenceTempID); if (pDef) { if (wdTarget&TARGET_FRIEND) { if (!_entry->isEnemy(pDef,false,true)&&_entry->checkMagicFlyRoute(pDef,pSkillStatus->mode)) { if (pDef->skillStatusM.putOperationToMe(_entry->carrier,true)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); } return; } } if (wdTarget&TARGET_ENEMY) { if (_entry->isEnemy(pDef,_entry->getType() == zSceneEntry::SceneEntry_Player)&& // 判断敌人友和检查PK模式是一个方法,所以只要判断一次就OK了 pDef->isPkZone(_entry)&&_entry->isPkZone(pDef)&&//新加 _entry->isPkZone(pDef) _entry->checkMagicFlyRoute(pDef,pSkillStatus->mode)) { if (pDef->skillStatusM.putOperationToMe(_entry->carrier)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); } return; } else { ScenePk::attackFailToMe(curRevCmd,_entry); } } } } break; case Cmd::ATTACKTYPE_U2N: /// 用户攻击Npc { SceneNpc *pNpc = SceneNpcManager::getMe().getNpcByTempID(curRevCmd->dwDefenceTempID); if (pNpc) { if (wdTarget&TARGET_PET) { if (!_entry->isEnemy(pNpc,false,true)&&_entry->checkMagicFlyRoute(pNpc,pSkillStatus->mode)&&pNpc->getPetType()==Cmd::PET_TYPE_PET) { if (pNpc->skillStatusM.putOperationToMe(_entry->carrier,true)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); } return; } } else if (wdTarget&TARGET_SUMMON) { if (!_entry->isEnemy(pNpc,false,true)&&_entry->checkMagicFlyRoute(pNpc,pSkillStatus->mode)&&pNpc->getPetType()==Cmd::PET_TYPE_SUMMON) { if (pNpc->skillStatusM.putOperationToMe(_entry->carrier,true)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); } return; } } else if (wdTarget&TARGET_NPC) { if (pNpc->getTopMaster()&&pNpc->getTopMaster()->getType() == zSceneEntry::SceneEntry_Player) { if (!(pNpc->isPkZone(_entry) && _entry->isPkZone(pNpc))) // 新加&&this->isPkZone(pDef) { ScenePk::attackFailToMe(curRevCmd,_entry); return; } } if (_entry->isEnemy(pNpc)&& // 判断敌人友和检查PK模式是一个方法,所以只要判断一次就OK了 _entry->checkMagicFlyRoute(pNpc,pSkillStatus->mode)) { if (pNpc->skillStatusM.putOperationToMe(_entry->carrier)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); } return; } else { ScenePk::attackFailToMe(curRevCmd,_entry); } } } } break; case Cmd::ATTACKTYPE_N2N: /// Npc攻击Npc { SceneNpc *pNpc = SceneNpcManager::getMe().getNpcByTempID(curRevCmd->dwDefenceTempID); if (pNpc) { if (wdTarget&TARGET_PET) { if (!_entry->isEnemy(pNpc,false,true)&&_entry->checkMagicFlyRoute(pNpc,pSkillStatus->mode)&&pNpc->getPetType()==Cmd::PET_TYPE_PET) { if (pNpc->skillStatusM.putOperationToMe(_entry->carrier,true)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); } return; } } else if (wdTarget&TARGET_SUMMON) { if (!_entry->isEnemy(pNpc,false,true)&&_entry->checkMagicFlyRoute(pNpc,pSkillStatus->mode)&&pNpc->getPetType()==Cmd::PET_TYPE_SUMMON) { if (pNpc->skillStatusM.putOperationToMe(_entry->carrier,true)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); return; } else { return; } } } else if (wdTarget&TARGET_NPC) { if (_entry->getTopMaster() && _entry->getTopMaster()->getType() == zSceneEntry::SceneEntry_Player && pNpc->getTopMaster() && pNpc->getTopMaster()->getType() == zSceneEntry::SceneEntry_Player) { if (!(pNpc->isPkZone(_entry) && _entry->isPkZone(pNpc))) // 新加&&this->isPkZone(pDef) { ScenePk::attackFailToMe(curRevCmd,_entry); return; } } if (_entry->isEnemy(pNpc)&& // 判断敌人友和检查PK模式是一个方法,所以只要判断一次就OK了 _entry->checkMagicFlyRoute(pNpc,pSkillStatus->mode)) { if (pNpc->skillStatusM.putOperationToMe(_entry->carrier)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); } return; } } } } break; case Cmd::ATTACKTYPE_U2P: /// 用户攻击点 { zPos pd; DWORD num =0; pd.x = (DWORD)curRevCmd->xDes; pd.y = (DWORD)curRevCmd->yDes; if (findAttackTarget(pSkillStatus,pd,num)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); } return; } break; case Cmd::ATTACKTYPE_U2B: /// 用户攻击建筑 default: { //if (!ScenePk::attackUserCmdToNine(curRevCmd,_entry)) //{ // return; //} return; } break; } // ScenePk::attackFailToMe(curRevCmd,_entry); } else { zPos center,pd; BYTE byDir=0; if (curRevCmd->dwDefenceTempID!=0) { switch(curRevCmd->byAttackType) { case Cmd::ATTACKTYPE_N2U: /// Npc攻击用户 case Cmd::ATTACKTYPE_U2U: /// Npc攻击用户 { SceneUser *pDef = pScene->getUserByTempID(curRevCmd->dwDefenceTempID); if (pDef) { center = pDef->getPos(); } else { center.x = (DWORD)curRevCmd->xDes; center.y = (DWORD)curRevCmd->yDes; } } break; case Cmd::ATTACKTYPE_N2N: /// Npc攻击用户 case Cmd::ATTACKTYPE_U2N: /// Npc攻击用户 { SceneNpc *pNpc = SceneNpcManager::getMe().getNpcByTempID(curRevCmd->dwDefenceTempID); if (pNpc) { center = pNpc->getPos(); } else { center.x = (DWORD)curRevCmd->xDes; center.y = (DWORD)curRevCmd->yDes; } } break; default: { center.x = (DWORD)curRevCmd->xDes; center.y = (DWORD)curRevCmd->yDes; } break; } } else { center.x = (DWORD)curRevCmd->xDes; center.y = (DWORD)curRevCmd->yDes; } switch(pSkillStatus->center) { case SKILL_CENTER_TYPE_MOUSE: { // center.x = (DWORD)curRevCmd->xDes; // center.y = (DWORD)curRevCmd->yDes; byDir = curRevCmd->byDirect; _entry->setDir(byDir); #ifdef _DEBUG Channel::sendSys(_entry->tempid,Cmd::INFO_TYPE_GAME,"中心点类型:鼠标(%u,%u) 方向:%u",center.x,center.y,byDir); #endif // debug提示 } break; case SKILL_CENTER_TYPE_SELF: { center.x = _entry->getPos().x; center.y = _entry->getPos().y; byDir = curRevCmd->byDirect;//_entry->getDir(); _entry->setDir(byDir); #ifdef _DEBUG Channel::sendSys(_entry->tempid,Cmd::INFO_TYPE_GAME,"中心点类型:自身(%u,%u) 方向:%u",center.x,center.y,byDir); #endif } break; default: #ifdef _DEBUG Channel::sendSys(_entry->tempid,Cmd::INFO_TYPE_GAME,"中心点类型:填写错误请查证"); #endif break; } switch(pSkillStatus->range) { case 20: { DWORD tempLen = sizeof(struct Cmd::stAttackMagicUserCmd); DWORD itemNum = 0; #ifdef _DEBUG Zebra::logger->error("!!!---客户端发过来的攻击指令原始长度[%u] 当前长度[%u]",tempLen,curRevCmdLen); #endif if (curRevCmdLen>tempLen) { itemNum = (curRevCmdLen-tempLen)/sizeof(DWORD); #ifdef _DEBUG Zebra::logger->error("!!!---客户端发过来的攻击列表数目[%u]",itemNum); #endif if (itemNum >5) itemNum=5; for (DWORD i=0; i<itemNum; i++) { SceneNpc *pNpc=NULL; SceneUser *pUser=NULL; #ifdef _DEBUG Zebra::logger->error("!!!---客户端发过来的被攻击临时坐标[%u]",curRevCmd->dwTempIDList[i]); #endif if ((pNpc=_entry->scene->getNpcByTempID(curRevCmd->dwTempIDList[i]))!=NULL) { pd = pNpc->getPos(); } else if ((pUser=_entry->scene->getUserByTempID(curRevCmd->dwTempIDList[i]))!=NULL) { pd = pUser->getPos(); } else continue; /* pd.x= (curRevCmd->dwTempIDList[i]>>16) &0xffff; pd.y= (curRevCmd->dwTempIDList[i]&0xff); */ #ifdef _DEBUG Zebra::logger->error("!!!---客户端发过来的攻击坐标[%u][x=%u,y=%u]",curRevCmd->dwTempIDList[i],pd.x,pd.y); #endif //-技能范围测试 #ifdef _DEBUG zObjectB *base = objectbm.get(501); if (base) { zObject *o=zObject::create(base,1); _entry->scene->addObject(o,pd); } #endif DWORD num=0; if (!findAttackTarget(pSkillStatus,pd,num)) break; } } } break; case 21: { zPosVector range; pScene->findEntryPosInNine(_entry->getPos(),_entry->getPosI(),range); for(zPosVector::iterator iter = range.begin(); iter != range.end() ; iter ++) { pd = *iter; //-技能范围测试 #ifdef _DEBUG zObjectB *base = objectbm.get(585); if (base) { zObject *o=zObject::create(base,randBetween(1,10)); _entry->scene->addObject(o,pd); } #endif DWORD num=0; if (!findAttackTarget(pSkillStatus,pd,num)) break; } } break; case 22: { if (_entry->getType() == zSceneEntry::SceneEntry_Player) { SceneUser *pUser = (SceneUser *)_entry; TeamManager * team = SceneManager::getInstance().GetMapTeam(pUser->TeamThisID); if (team) { SendStatusToTeamExec exec(pUser,pSkillStatus); team->execEveryOne(exec); } } } break; case 50: { zPosVector range; int count=0; pScene->findEntryPosInOne(_entry->getPos(),_entry->getPosI(),range); for(zPosVector::iterator iter = range.begin(); iter != range.end() ; iter ++) { count++; if (count>20) break; pd = *iter; //-技能范围测试 #ifdef _DEBUG zObjectB *base = objectbm.get(585); if (base) { zObject *o=zObject::create(base,randBetween(1,10)); _entry->scene->addObject(o,pd); } #endif DWORD num=0; if (!findAttackTarget(pSkillStatus,pd,num)) break; } } break; default: { SMagicRange range; DWORD maxCount =0; DWORD count=0; MagicRangeInit::getInstance().get(pSkillStatus->range,byDir % 2,range); maxCount = range.num; if (0==maxCount) maxCount = 65535; for(std::vector<RelativePos>::iterator iter = range.lib.begin(); iter != range.lib.end() ; iter ++) { SWORD rangDamageBonus=0; pd = iter->getAbsolutePos(center,byDir); rangDamageBonus = (*iter).w; //-技能范围测试 #ifdef _DEBUG zObjectB *base = objectbm.get(585); if (base) { zObject *o=zObject::create(base,randBetween(1,10)); _entry->scene->addObject(o,pd); } #endif DWORD num=0; if (!findAttackTarget(pSkillStatus,pd,num,rangDamageBonus)) break; if (num>0) { count++; if (count>= maxCount) break; } } } } return; } } }
/** * \brief 投送操作到目标对象身上 * \param pSkillStatus 操作 * \param pd 坐标点 * \return 如果是返回true表示可以继续处理攻击攻击过程否则false表示返回 */ bool zSkill::findAttackTarget(const SkillStatus *pSkillStatus,zPos &pd,DWORD &count,SWORD rangDamageBonus) { WORD wdTarget = pSkillStatus->target; Scene *pScene = _entry->scene; //检查范围有效 if (!pScene->zPosValidate(pd)) { return true; } SceneUser *pFindUser = NULL; SceneNpc *pFindNpc = NULL; if (wdTarget&TARGET_FRIEND) { pFindUser = pScene->getSceneUserByPos(pd); if (pFindUser/* && pFindUser!=_entry*/) { if (!_entry->isEnemy(pFindUser,false,true)&&_entry->checkMagicFlyRoute(pFindUser,pSkillStatus->mode)) { count=1; if (pFindUser->skillStatusM.putOperationToMe(_entry->carrier,true,rangDamageBonus)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); return true; } else { return false; } } } } if (wdTarget&TARGET_ENEMY) { if (!pFindUser) pFindUser = pScene->getSceneUserByPos(pd); if (pFindUser && pFindUser!=_entry) { if (_entry->getTopMaster()&&_entry->getTopMaster()->getType() == zSceneEntry::SceneEntry_Player) { if (!(pFindUser->isPkZone(_entry) && _entry->isPkZone(pFindUser))) // 新加&&this->isPkZone(pDef) { return true; } } if (_entry->isEnemy(pFindUser)&& _entry->checkMagicFlyRoute(pFindUser,pSkillStatus->mode)) { count=1; if (pFindUser->skillStatusM.putOperationToMe(_entry->carrier,false,rangDamageBonus)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); return true; } else { return false; } } } } if (!pFindUser) { if (wdTarget&TARGET_PET) { pFindNpc = pScene->getSceneNpcByPos(pd); if (pFindNpc/* && pFindNpc!=_entry*/) { if (!_entry->isEnemy(pFindNpc,false,true)&&_entry->checkMagicFlyRoute(pFindNpc,pSkillStatus->mode)&&pFindNpc->getPetType()==Cmd::PET_TYPE_PET) { count=1; if (pFindNpc->skillStatusM.putOperationToMe(_entry->carrier,true,rangDamageBonus)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); return true; } else { return false; } } } } if (wdTarget&TARGET_SUMMON) { pFindNpc = pScene->getSceneNpcByPos(pd); if (pFindNpc/* && pFindNpc!=_entry*/) { if (!_entry->isEnemy(pFindNpc,false,true)&&_entry->checkMagicFlyRoute(pFindNpc,pSkillStatus->mode)&&pFindNpc->getPetType()==Cmd::PET_TYPE_SUMMON) { count=1; if (pFindNpc->skillStatusM.putOperationToMe(_entry->carrier,true,rangDamageBonus)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); return true; } else { return false; } } } } if (wdTarget&TARGET_NPC) { if (!pFindNpc) pFindNpc = pScene->getSceneNpcByPos(pd); if (pFindNpc && pFindNpc!=_entry) { if (_entry->getTopMaster() && _entry->getTopMaster()->getType() == zSceneEntry::SceneEntry_Player && pFindNpc->getTopMaster() && pFindNpc->getTopMaster()->getType() == zSceneEntry::SceneEntry_Player) { if (!(pFindNpc->isPkZone(_entry) && _entry->isPkZone(pFindNpc))) // 新加&&this->isPkZone(pDef) { return true; } } if (_entry->isEnemy(pFindNpc)&& _entry->checkMagicFlyRoute(pFindNpc,pSkillStatus->mode)) { count=1; if (pFindNpc->skillStatusM.putOperationToMe(_entry->carrier,false,rangDamageBonus)) { //ScenePk::attackUserCmdToNine(curRevCmd,_entry); return true; } else { return false; } } } } } return true; }