/** * \brief 向客户端发送自己的血和经验 * */ void ScenePet::sendHpExp() { SceneEntryPk * master = getMaster(); if (!master) return; if (zSceneEntry::SceneEntry_Player==master->getType()) { Cmd::stHpExpPetCmd ref; ref.type = type; ref.id = tempid; if( npc->kind == NPC_TYPE_GHOST ) //sky 元神特殊处理下 { if(hp>petData.maxhp) hp = petData.maxhp; } else { if (hp>getMaxHP()) hp = getMaxHP(); } ref.hp = petData.hp = hp; ref.exp = petData.exp; ((SceneUser *)master)->sendCmdToMe(&ref,sizeof(ref)); } }
/** * \brief 检查是否在PK区域 * \param other PK相关人 * \return 是否在PK区域 */ bool ScenePet::isPkZone(SceneEntryPk *other) { SceneEntryPk * master = getMaster(); if (!master) return false; return master->isPkZone(other); }
/** * \brief 在主人周围2格内随机移动 * 离主人只有1格时随便走,超过1格就要检测下一步是否在活动范围内 * * \return 是否移动成功 */ bool ScenePet::randomMove() { if(type == Cmd::PET_TYPE_TURRET) return false; //sky 炮台也是不移动的 if (type == Cmd::PET_TYPE_SEMI) return SceneNpc::randomMove(); if (!canMove()) return false; SceneEntryPk * master = getMaster(); if (!master) return false; if (checkMoveTime(SceneTimeTick::currentTime) && canMove()) if (selectByPercent(2) || ((getPetType()==Cmd::PET_TYPE_CARTOON || getPetType()==Cmd::PET_TYPE_RIDE) && scene->checkBlock(getPos()) && scene->zPosShortRange(getPos(),master->getPos(),1))) { int dir = randBetween(0,7); zPos newPos; scene->getNextPos(pos,dir,newPos); zPosI newPosI = 0; scene->zPos2zPosI(newPos,newPosI); if (getPosI()==newPosI//不切屏 && scene->zPosShortRange(master->getPos(),newPos,SceneNpc::npc_pet_chase_region))//主人2格内 return shiftMove(dir);//随机移动 } return false; }
/** * \brief 获取主人的法力值 * \return 主人法力值 */ DWORD ScenePet::getMasterMana() { DWORD mana = 0; SceneEntryPk * master = getMaster(); if (master) mana= master->getMP(); return mana; }
/** * \brief 得到最上层主人的指针 * 没有主人返回自己 * \return 主人的指针 * */ SceneEntryPk * ScenePet::getTopMaster() { if (type==Cmd::PET_TYPE_SEMI) return this; SceneEntryPk * m = this; while ((m->getType()!=zSceneEntry::SceneEntry_Player) && (m->getMaster())) m = m->getMaster(); if (!m) return this; return m; }
/** * \brief 返回是否红名 * * \return 是否红名 */ bool ScenePet::isRedNamed(bool allRedMode) { if (type==Cmd::PET_TYPE_SEMI) return false; SceneEntryPk * master = getMaster(); if (master) return master->isRedNamed(allRedMode); //Zebra::logger->error("ScenePet::isRedNamed(): %s 没有主人",name); return false; }
/** * \brief 回到活动范围 * */ void ScenePet::returnToRegion() { if (type==Cmd::PET_TYPE_SEMI) return; SceneEntryPk * master = getMaster(); if (master) { if (!scene->zPosShortRange(master->getPos(),getPos(),SceneNpc::npc_pet_warp_region)) { warp(master->getPos()); return; } setSpeedRate(getSpeedRate()*2.0); return; } }
//向9屏发送宠物数据 void ScenePet::sendPetDataToNine() { Cmd::stAddMapPetMapScreenUserCmd ret; full_t_MapPetData(ret.pet); if (npc->kind == NPC_TYPE_TRAP) { SceneEntryPk * pMaster = getMaster(); if (pMaster && pMaster->getType()==zSceneEntry::SceneEntry_Player) { ((SceneUser *)pMaster)->sendCmdToMe(&ret,sizeof(ret)); } } else { scene->sendCmdToNine(getPosI(),&ret,sizeof(ret),this->dupIndex); } }
/** * \brief 查找主人的敌人 * * * \param ret 找到的目标 * \return 是否找到 */ bool ScenePet::checkMasterTarget(SceneEntryPk *&ret) { if ((Cmd::PET_TYPE_RIDE==getPetType()) || (Cmd::PET_TYPE_GUARDNPC==getPetType()) || (Cmd::PET_TYPE_SEMI==getPetType())) { ret = 0; return false; } SceneEntryPk * master = getMaster(); if (master) { int r = npc_search_region; if (aif&AIF_DOUBLE_REGION) r *= 2; SceneEntryPk * tmp = 0; if (petData.ai&Cmd::PETAI_ATK_ACTIVE)//主人攻击的对象 tmp = master->getCurTarget(); else if (petData.ai&Cmd::PETAI_ATK_PASSIVE)//攻击主人的对象 tmp = master->getDefTarget(); if ((tmp)&&(tmp!=this)) if (tmp->getState() == zSceneEntry::SceneEntry_Normal && isEnemy(tmp) && canReach(tmp) && canFight()) { ret = tmp; return true; } return false; } //Zebra::logger->error("ScenePet::checkMasterTarget(): %s 没有主人",name); ret = 0; return false; }
/** * \brief 处理宠物死亡 * */ void ScenePet::petDeath() { SceneEntryPk * master = getMaster(); if (master) { /* //马不会死了 if (Cmd::PET_TYPE_RIDE==type&&zSceneEntry::SceneEntry_Player==master->getType()) { SceneUser * m = (SceneUser *)master; Cmd::stDelPetPetCmd del; del.id= tempid; del.type = Cmd::PET_TYPE_RIDE; m->sendCmdToMe(&del,sizeof(del)); m->horse.horse(0); Zebra::logger->info("%s 的 %s 死亡",m->name,name); } */ petData.state = Cmd::PET_STATE_DEAD; master->killOnePet(this); } setMoveTime(SceneTimeTick::currentTime,define->interval*1000); }
/** * \brief 选择敌人 * * \return 敌人的指针 */ SceneEntryPk * ScenePet::chooseEnemy(SceneEntryPk_vec &enemies) { if (type==Cmd::PET_TYPE_SEMI || type==Cmd::PET_TYPE_TURRET) return SceneNpc::chooseEnemy(enemies); //非战斗npc if (!canFight()) return false; SceneEntryPk * ret = 0; SceneEntryPk * ct = 0; checkChaseAttackTarget(ct); if (ct && lockTarget) { return ct; } checkMasterTarget(ret); if (ret) { chaseSceneEntry(ret->getType(),ret->tempid); return ret; } else return SceneNpc::chooseEnemy(enemies); }
/** * \brief 向客户端发送自己的数据 * */ void ScenePet::sendData() { SceneEntryPk * master = getMaster(); if (!master) return; if (Cmd::PET_TYPE_RIDE==type) { ((SceneUser *)master)->horse.sendData(); } else { if (zSceneEntry::SceneEntry_Player==master->getType()) { Cmd::stRefreshDataPetCmd ref; ref.type = type; ref.id = tempid; full_PetDataStruct(ref.data); #ifdef _DEBUG Zebra::logger->debug("发送宠物信息 name=%s ai=%x hp=%u maxhp=%u",name,petData.ai,petData.hp,petData.maxhp); #endif ((SceneUser *)master)->sendCmdToMe(&ref,sizeof(ref)); } } }
//sky 特殊处理一个用户的死亡事件 bool GangScene::UserDeathRun(DWORD DeathID, DWORD MurderID) { SceneUser * Duser = SceneUserManager::getMe().getUserByTempID(DeathID); if(!Duser) return true; SceneEntryPk * Muser; Muser = (SceneEntryPk *)SceneUserManager::getMe().getUserByTempID(MurderID); if(!Muser) Muser = (SceneEntryPk *)SceneNpcManager::getMe().getNpcByTempID(MurderID); //sky 先复活死亡的玩家(战场的死亡状态是以灵魂形式存在的) Duser->relive(Cmd::ReliveBattle,0,0); //sky 给予用户灵魂状态 Cmd::stAttackMagicUserCmd cmd; zSkill * s = zSkill::create(Duser,88,1); cmd.byAttackType = Cmd::ATTACKTYPE_U2U; cmd.dwDefenceTempID = Duser->tempid; cmd.dwUserTempID = Duser->tempid; cmd.wdMagicType = 88; cmd.byAction = Cmd::Ani_Die; cmd.xDes = Duser->getPos().x; cmd.yDes = Duser->getPos().y; cmd.byDirect = Duser->getDir(); if (s) { zSkill * useSkill = NULL; useSkill = zSkill::createTempSkill(Duser,s->data.skillid,1); if(useSkill) { useSkill->action(&cmd,sizeof(cmd)); SAFE_DELETE(useSkill); } } //sky 当复活类型是强制复活 设置30秒复活时间 if(reliveType != Compulsory_Resurrection) { std::map<DWORD ,BCampData*>::iterator iter = camp.find(Duser->BattCampID); if(iter != camp.end()) { std::vector<stCampMember>::iterator it; for(it=iter->second->CampMembe.begin(); it!=iter->second->CampMembe.end(); it++) { if(it->userid == DeathID) it->DeathTime = 30; } //sky 阵营灵魂人数自加 iter->second->SoulUserNum++; } } if(Muser) { //sky 把阵营的杀人数字增加 std::map<DWORD ,BCampData*>::iterator iter = camp.find(Muser->BattCampID); if(iter != camp.end()) { iter->second->KillUserNum++; } //sky 先检测下关于成员死亡的胜利条件是否满足 switch(VictoryType) { case BATTLEFIELF_WINNT_KILLUSERNUM: { WinnerCamp = IfKillUserNum(Muser->BattCampID); if(WinnerCamp != 0) return true; } break; case BATTLEFIELF_WINNT_KILLALLUSER: { WinnerCamp = IfKillAllUser(); if(WinnerCamp != 0) return true; } break; default: break; } //sky 以上胜利条件都不成立的时候 //sky 增加杀死对方阵营的玩家的战场点 if(Muser->getType()==zSceneEntry::SceneEntry_Player) AddUserCamePoint(MurderID, killPoint); //sky 减少被杀玩家的战场点 DesUserCampPoint(DeathID, killPoint); } return false; }
/** * \brief 敌我判断 * \param entry 判断的对象 * \param notify 判断失败时是否提示(不能攻击10级以下的玩家) * \return 0:友方 1:敌人 -1:中立 */ int ScenePet::isEnemy(SceneEntryPk * entry,bool notify,bool good) { int ret=0; bool isPlayer = false; if (entry) { if (type==Cmd::PET_TYPE_SEMI) { ret = SceneNpc::isEnemy(entry,notify,good); } else { SceneEntryPk * master = getMaster(); if (master) { if (master->scene==scene) { if (scene->zPosShortRange(getPos(),master->getPos(),SCREEN_WIDTH*2,SCREEN_HEIGHT*2)) { if (this!=entry) { if (!((entry->frenzy)||(frenzy))) { if (master->getType()==zSceneEntry::SceneEntry_Player) { isPlayer = true; //Zebra::logger->debug("isPetEnemy 119 %s->%s",master->name,entry->name); ret = isUserMasterEnemy(entry); } else { //Zebra::logger->debug("isPetEnemy 124 %s->%s",master->name,entry->name); ret = master->isEnemy(entry,notify); } } else ret = 1; } else ret = 0; } else ret = -1; } else ret = -1; } else ret = -1; } } else ret = -1; if (isPlayer) { if (ret==1) return 1; else return 0; } else { return ret; } }
/* * \brief 宠物升级 * * */ void ScenePet::levelUp() { if( type == Cmd::PET_TYPE_TURRET ) return; //sky 朋友,炮台是不会获取经验升级滴 SceneEntryPk * master = getMaster(); if (!master) return; if (master->getType()!=zSceneEntry::SceneEntry_Player) return; DWORD maxlv = 1; switch (getPetType()) { case Cmd::PET_TYPE_PET: { maxlv = ((SceneUser *)master)->charbase.level+5; while ((petData.exp>=petData.maxexp)&&(petData.lv<maxlv)) { petData.exp -= petData.maxexp; petData.lv++; getAbilityByLevel(petData.lv); hp = getMaxHP(); } if (petData.exp>petData.maxexp) petData.exp = petData.maxexp; } break; case Cmd::PET_TYPE_SUMMON: { while ((petData.exp>=petData.maxexp)&&(petData.lv<maxlevel)) { zNpcB *base = npcbm.get(id+1); if (!base) break; petData.exp -= petData.maxexp; petData.maxexp = base->exp; petData.lv++; npc = base; id++; petData.id++; hp = npc->hp; } if (petData.exp>petData.maxexp) petData.exp = petData.maxexp; } break; case Cmd::PET_TYPE_CARTOON: { maxlv = ((SceneUser *)master)->charbase.level; while ((petData.exp>=petData.maxexp)&&(petData.lv<maxlv)) { petData.exp -= petData.maxexp; petData.lv++; /* petData.maxexp = base->exp; npc = base; id++; petData.id++; hp = npc->hp; */ } if (petData.exp>petData.maxexp) petData.exp = petData.maxexp; } break; case Cmd::PET_TYPE_GUARDNPC: case Cmd::PET_TYPE_RIDE: default: return; } sendMeToNine(); }
/** * \brief 向主人移动 * * \return 是否移动成功 */ bool ScenePet::moveToMaster() { #ifdef _DEBUG //Channel::sendNine(this,"ScenePet::moveToMaster()"); #endif if (type==Cmd::PET_TYPE_SEMI || type==Cmd::PET_TYPE_TURRET ) return false; //sky 炮台也是不移动的 SceneEntryPk * master = getMaster(); if (!master) return false; if ( petData.ai&Cmd::PETAI_MOVE_FOLLOW ) { AIC->setActRegion(master->getPos(),2,2); if (!canMove()) { check(); if (getMaster()) return false; else return true; } //check(); if (checkMoveTime(SceneTimeTick::currentTime)) { if (master->scene == scene) { check(); if (0==masterID) return true;//运镖成功删除了主人 //超出瞬移范围 if (!(scene->zPosShortRange(getPos(),master->getPos(),npc_pet_warp_region))) return warp(master->getPos()); //离开较远距离 int region = isFighting()?npc_pet_run_region+4:npc_pet_run_region; if (!(scene->zPosShortRange(getPos(),master->getPos(),region))) { if (!speedUpOffMaster) { setSpeedRate(getSpeedRate()*2.0); speedUpOffMaster = true; } } else { //在主人身边 region = isFighting()?npc_pet_chase_region+5:npc_pet_chase_region; if ((scene->zPosShortRange(getPos(),master->getPos(),region))) { if (speedUpOffMaster) { resetSpeedRate(); speedUpOffMaster = false; } //check(); return false; } } unChaseUser(); if (aif&AIF_WARP_MOVE) return warp(master->getPos()); else { if (!gotoFindPath(getPos(),master->getPos())) return goTo(master->getPos()); } } else { if (master->scene) { if (changeMap(master->scene,master->getPos())) { check(); return true; } else return false; } } } } return false; }
/** * \brief 当主人是玩家时,以主人的身份进行敌我判断 * \param entry 判断的对象 * \return 0:友方 1:敌人 -1:中立 */ int ScenePet::isUserMasterEnemy(SceneEntryPk * entry) { SceneEntryPk * temp = getTopMaster(); SceneUser * tm = 0;//top master if (temp && temp->getType()==zSceneEntry::SceneEntry_Player) tm = (SceneUser*)temp; else return -1; // TODO 判断传入角色与主人是否为朋友关系 if (tm==entry) return 0; SceneEntryPk * entryMaster = entry->getTopMaster(); using namespace Cmd; //if (PKMODE_ENTIRE==pkMode) return 1; switch (entryMaster->getType()) { case zSceneEntry::SceneEntry_Player: { SceneUser *pUser = (SceneUser *)entryMaster; if (pUser == tm) return 0; bool def_gem = false; bool my_gem = false; if (tm->issetUState(Cmd::USTATE_TOGETHER_WITH_TIGER) || tm->issetUState(Cmd::USTATE_TOGETHER_WITH_DRAGON)) { my_gem = true; } if (pUser->issetUState(Cmd::USTATE_TOGETHER_WITH_TIGER) || pUser->issetUState(Cmd::USTATE_TOGETHER_WITH_DRAGON)) { def_gem = true; } if ((pUser->charbase.level<20) && (!pUser->isWarRecord(Cmd::COUNTRY_FORMAL_DARE,tm->charbase.country)) && (!def_gem)) return 0; if ((tm->charbase.level<20) && (!tm->isWarRecord(Cmd::COUNTRY_FORMAL_DARE,pUser->charbase.country)) && (!my_gem)) return 0; if (tm->scene == pUser->scene && !(my_gem || def_gem)) { //if (tm->charbase.country == pUser->charbase.country) //{ if (tm->charbase.level <= tm->scene->getPkLevel() && pUser->charbase.level >tm->scene->getPkLevel() && (!tm->isWarRecord(Cmd::SEPT_NPC_DARE,pUser->charbase.septid))) { return 0; } if (tm->charbase.level > tm->scene->getPkLevel() && pUser->charbase.level <= tm->scene->getPkLevel() && (!tm->isWarRecord(Cmd::SEPT_NPC_DARE,pUser->charbase.septid))) { return 0; } //} //else //{ // if (tm->charbase.level <= tm->scene->getPkLevel()-10 && pUser->charbase.level >tm->scene->getPkLevel()-10 // && (!tm->isWarRecord(Cmd::SEPT_NPC_DARE,pUser->charbase.septid))) // { // return 0; // } // if (tm->charbase.level > tm->scene->getPkLevel()-10 && pUser->charbase.level <= tm->scene->getPkLevel()-10 // && (!tm->isWarRecord(Cmd::SEPT_NPC_DARE,pUser->charbase.septid))) // { // return 0; // } //} } if (tm->isDiplomatState() ==0 || pUser->isDiplomatState() == 0) { return 0; } switch (tm->pkMode) { case PKMODE_NORMAL: { return 0; } break; case PKMODE_TEAM: { //是同一组队或者是增益类魔法 if ((tm->TeamThisID != 0) && (pUser->TeamThisID == tm->TeamThisID)) return 0; else return 1; } break; case PKMODE_TONG: { if (tm->charbase.unionid != 0 && tm->charbase.unionid == pUser->charbase.unionid) return 0; else return 1; } break; case PKMODE_SEPT: { if (tm->charbase.septid != 0 && tm->charbase.septid == pUser->charbase.septid) return 0; else return 1; } break; case PKMODE_COUNTRY: { if (tm->charbase.country != 0 && ((tm->charbase.country == pUser->charbase.country) || (CountryAllyM::getMe().getFriendLevel(tm->charbase.country, pUser->charbase.country)>0 && (pUser->isSpecWar(Cmd::COUNTRY_FORMAL_DARE) || tm->isSpecWar(Cmd::COUNTRY_FORMAL_DARE))))) return 0; else return 1; } break; case PKMODE_GOODNESS: { if (pUser->isRedNamed(false)||pUser->charbase.country!=tm->charbase.country) return 1; else return 0; } break; case PKMODE_ALLY: { if ((CountryAllyM::getMe().getFriendLevel(pUser->charbase.country,tm->charbase.country)>0)|| (pUser->charbase.country==tm->charbase.country)) return 0; else return 1; } break; case PKMODE_ENTIRE: { if (pUser->isPkZone(tm)&&tm->isPkZone(pUser)) return 1; else return 0; } default: break; } return 0; } break; case zSceneEntry::SceneEntry_NPC: { SceneNpc * n = (SceneNpc *)entry; if (n->id==COUNTRY_MAIN_FLAG //这几个不在这里判断 || n->id==COUNTRY_SEC_FLAG || n->isMainGeneral() || n->id==COUNTRY_KING_MAIN_FLAG || n->id==COUNTRY_KING_SEC_FLAG || n->id==COUNTRY_SEC_GEN || n->id==COUNTRY_EMPEROR_MAIN_GEN || n->id==COUNTRY_EMPEROR_SEC_GEN) return 1; //国外npc if (!n->isBugbear()) { if (n->npc->flags==1 && tm->charbase.country!=n->scene->getCountryID()) return 1; else return -1; } SceneEntryPk * m = n->getMaster(); if (m) { //Zebra::logger->debug("isPetEnemy 183 %s->%s",tm->name,n->getMaster()->name); if (!scene->zPosShortRange(n->getPos(),m->getPos(),20) && n->getPetType()==Cmd::PET_TYPE_GUARDNPC) return 1; else return tm->isEnemy(m); } if ((n->aif&AIF_ATK_REDNAME)||(n->npc->kind==NPC_TYPE_GUARD)) { if (tm->isRedNamed()) return 1; if (tm->charbase.country!=tm->scene->getCountryID()) return 1; if (tm->charbase.goodness&Cmd::GOODNESS_ATT) return 1; } switch (n->npc->kind) { case NPC_TYPE_HUMAN: ///人型 case NPC_TYPE_NORMAL: /// 普通类型 case NPC_TYPE_BBOSS: /// 大Boss类型 case NPC_TYPE_LBOSS: /// 小Boss类型 case NPC_TYPE_PBOSS: /// 紫Boss类型 case NPC_TYPE_BACKBONE: /// 精英类型 case NPC_TYPE_GOLD: /// 黄金类型 case NPC_TYPE_SUMMONS: /// 召唤类型 case NPC_TYPE_AGGRANDIZEMENT: /// 强化类型 case NPC_TYPE_ABERRANCE: /// 变异类型 case NPC_TYPE_BACKBONEBUG: /// 精怪类型 case NPC_TYPE_PET: /// 宠物类型 case NPC_TYPE_TOTEM: /// 图腾类型 case NPC_TYPE_GHOST: ///元神类 case NPC_TYPE_TURRET: /// 炮塔 case NPC_TYPE_BARRACKS: case NPC_TYPE_CAMP: case NPC_TYPE_ANIMON: /// 动物类 //case NPC_TYPE_DUCKHIT: /// 花草 return 1; case NPC_TYPE_GUARD: /// 士兵类型 case NPC_TYPE_SOLDIER: /// 士兵类型 { if (tm->charbase.country!=scene->getCountryID()) return 1; if (tm->pkMode==PKMODE_ENTIRE) return 1; return 0; } case NPC_TYPE_UNIONGUARD: if (tm->isAtt(Cmd::UNION_CITY_DARE)) return 1; else if (tm->scene->getUnionDare() && !tm->isSpecWar(Cmd::UNION_CITY_DARE) && !n->isMainGeneral())//大将军第三方不能打 return 1;//中立方 else return 0;//城战期间打城战而且不是攻方,就是守方 break; case NPC_TYPE_UNIONATTACKER: if (tm->isAtt(Cmd::UNION_CITY_DARE)) return 0; else if (tm->scene->getUnionDare() && !tm->isSpecWar(Cmd::UNION_CITY_DARE)) return 1;//中立方 else return 1;//城战期间打城战而且不是攻方,就是守方 break; default: return -1; } return -1; } break; default: return -1; break; } }