Example #1
0
File: Skill.cpp Project: ifzz/loki
/**
 * \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;
    }
  }
}
Example #2
0
File: Skill.cpp Project: ifzz/loki
/**
 * \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;
}