#include "StdAfx.h" #include "Animal.h" #include "../LogicServer.h" #include "../skill/SkillSubSystem.h" #include "config/HallowsConfig.h" unsigned int * CAnimal::s_stateForbidMask =NULL; #ifdef _DEBUG extern std::string s_HurtValueMsg; extern char s_HurtValueBuff[100]; #endif bool CAnimal::Init(void * data, size_t size) { m_pAI =NULL; if(Inherited::Init(data,size) ==false) return false; if(m_observerSystem.Create(this,data,size) ==false) { OutputMsg(rmWaning,_T("Init fail for observer system ")); return false; //观察者子系统 } if(m_moveSystem.Create(this,data,size) ==false) { OutputMsg(rmWaning,_T("Init fail for movement system ")); return false; //移动子系统 } if(m_propertySystem.Create(this,data,size) ==false) { OutputMsg(rmWaning,_T("Init fail for property system ")); return false; // 属性子系统的初始化 } if(m_buffSystem.Create(this,data,size) ==false) { OutputMsg(rmWaning,_T("Init fail for buff system ")); return false; // buff子系统的初始化 } if(m_skillSystem.Create(this,data,size) ==false) { OutputMsg(rmWaning,_T("Init fail for skill system ")); return false; // 技能子系统的初始化 } m_effectSystem.Create(this,data,size); return true; } //等级提升 void CAnimal::OnLevelUp(int nUpdateVal) { //需要重新计算属性 CollectOperate(CEntityOPCollector::coRefAbility); // 更新升级后的血、蓝 if(!IsDeath()) CollectOperate(CEntityOPCollector::coResetMaxHPMP); } VOID CAnimal::BeforeLogicRun(TICKCOUNT nCurrentTime) { Inherited::BeforeLogicRun(nCurrentTime); //清空汇总操作标记 } int CAnimal::GetAttackValue(INT_PTR nAttackType) { int nAttackMax,nAttackMin; switch(nAttackType) { case TYPE_PHYSICAL_ATTACK: //物理攻击类型 nAttackMax= GetProperty(PROP_CREATURE_PHYSICAL_ATTACK_MAX); nAttackMin= GetProperty(PROP_CREATURE_PHYSICAL_ATTACK_MIN); break; case TYPE_MAGIC_ATTACK://魔法攻击类型 nAttackMax= GetProperty(PROP_CREATURE_MAGIC_ATTACK_MAX); nAttackMin= GetProperty(PROP_CREATURE_MAGIC_ATTACK_MIN); break; case TYPE_WIZARD_ATTACK://道士攻击类型 nAttackMax= GetProperty(PROP_CREATURE_WIZARD_ATTACK_MAX); nAttackMin= GetProperty(PROP_CREATURE_WIZARD_ATTACK_MIN); break; case TYPE_HOLY_ATTACK: //神圣攻击 if (GetType() == enActor) { switch (((CActorProperty*)((CActor*)this)->GetPropertyPtr())->nVocation) { case enVocWarrior: nAttackMax= GetProperty(PROP_CREATURE_PHYSICAL_ATTACK_MAX); nAttackMin= GetProperty(PROP_CREATURE_PHYSICAL_ATTACK_MIN); break; case enVocMagician: nAttackMax= GetProperty(PROP_CREATURE_MAGIC_ATTACK_MAX); nAttackMin= GetProperty(PROP_CREATURE_MAGIC_ATTACK_MIN); break; case enVocWizard: nAttackMax= GetProperty(PROP_CREATURE_WIZARD_ATTACK_MAX); nAttackMin= GetProperty(PROP_CREATURE_WIZARD_ATTACK_MIN); break; default: return 0; } } else if (GetType() == enMonster) { nAttackMax= GetProperty(PROP_CREATURE_PHYSICAL_ATTACK_MAX); nAttackMin= GetProperty(PROP_CREATURE_PHYSICAL_ATTACK_MIN); } break; default: return 0; } if (nAttackMin == 0) nAttackMin = 1; if (nAttackMax == 0) nAttackMax = 1; if(nAttackMin >= nAttackMax) return nAttackMax; //没什么算的 int nLuck = GetProperty(PROP_CREATURE_LUCK); //幸运 //使用静态遍历,避免每次都去取一下 GLOBALCONFIG& globalConfig = GetLogicServer()->GetDataProvider()->GetGlobalConfig(); int nRandomVal = nAttackMax - nAttackMin + 1; nRandomVal = wrand( nRandomVal ); int nAttackMaxRadom = 0; if (nLuck == 0 ) { return nAttackMin + nRandomVal; } else if (nLuck > 0) { int nRandVal = nLuck * 3; // if (nLuck > 15) // { // nRandVal = 45; // } if (wrand(100) < (unsigned long)nRandVal) { return nAttackMax; } else { return nAttackMin + nRandomVal; } } } void CAnimal::OnEntityDeath() { Inherited::OnEntityDeath(); bool bHasDrop = 0; //声音的id if(enMonster == GetType()) { const PMONSTERCONFIG pMonster= GetLogicServer()->GetDataProvider()->GetMonsterConfig().GetMonsterData(GetProperty(PROP_ENTITY_ID)); if( pMonster !=NULL ) { bHasDrop = ((CMonster*)this)->isHasDrop(); } } char buff[128]; CDataPacket data(buff,sizeof(buff)); data << (BYTE)enDefaultEntitySystemID << (BYTE) sEntityDeath << (Uint64)GetHandle() << (Uint64 )m_killHandler << bHasDrop; m_observerSystem.BroadCast(data.getMemoryPtr(),data.getPosition(),true); m_effectSystem.DelAllEffect(true); //死亡了需要删除所有的特效 m_buffSystem.OnDeadRemoveBuff(); } VOID CAnimal::ChangeHP(int hpDrop, CEntity * pKiller,bool bIgnoreDamageRedure, bool bIgnoreMaxDropHp, bool boSkillResult,int btHitType) { //这里支持哪种每次只掉1滴血的情况 if(hpDrop == 0) { return ; } INT_PTR nKillType =-1; bool hasKiller = false; if(pKiller) { nKillType = pKiller->GetType(); hasKiller =true; m_AttackerHandler = pKiller->GetHandle(); } INT_PTR nSelfType = GetType(); if(nKillType == enActor) { if ( ((CActor*)pKiller)->OnGetIsTestSimulator() || ((CActor*)pKiller)->OnGetIsSimulator()) { hpDrop = 0; } } if(nSelfType == enActor) { if ( ((CActor*)this)->OnGetIsTestSimulator() || ((CActor*)this)->OnGetIsSimulator()) { hpDrop = 0; } } int nHpDrop = 0; int absDrop = 0; //伤害吸收 if(hpDrop < 0) { absDrop = -hpDrop; //掉了多少血 //最原始的掉血,这里要计算目标的最大的掉血 // int originalAbsDrop = absDrop; // int nFinalDamageValue = 0; int S7 = 10000; //[BUFF] 伤害抵消的BUFF状态 ( value:池值, param:吸收万分比 ) CBuffSystem * bufSystem =GetBuffSystem(); CDynamicBuff *pBuff = bufSystem->GetFirstBuff(aDamageAbsorb); if(pBuff && absDrop>0 && !bIgnoreDamageRedure) { INT_PTR nBuffGroup = pBuff->btGroup; //buff if(pBuff->value.nValue > 0) { float fAbsorbRate = ((float)pBuff->pConfig->nParam / (float)10000); S7 -= pBuff->pConfig->nParam; int nBuffAbsorb = fAbsorbRate * absDrop;//吸收的伤害 nBuffAbsorb = __min(nBuffAbsorb, pBuff->value.nValue); // nFinalDamageValue -= nBuffAbsorb; pBuff->value.nValue -= nBuffAbsorb;//池值降低 #ifdef _DEBUG // S8 SNPRINTFA(s_HurtValueBuff,100," //S7::%d",S7); s_HurtValueMsg += s_HurtValueBuff; #endif } if(pBuff->value.nValue <= 0) { bufSystem->Remove(aDamageAbsorb,nBuffGroup); //如果已经吸收完了,就去掉这个buff } } int S8 = 10000; //伤害加成 --mhl if(btHitType != htFire && pKiller && pKiller->isAnimal()) { //伤害加成 S8 += ((CAnimal*)pKiller)->m_nDoubleAtkRate; // int nDouAtkValue = absDrop * (((CAnimal*)pKiller)->m_nDoubleAtkRate / 10000.0); // nFinalDamageValue += nDouAtkValue; #ifdef _DEBUG // S7 SNPRINTFA(s_HurtValueBuff,100," //S8:%d;",S8); s_HurtValueMsg += s_HurtValueBuff; #endif } int S9 = 10000; //[NORMAL] 按比例吸收伤害,降低伤害的数值 if( S9 > 0.0f && !bIgnoreDamageRedure ) { S9 -=(int)(m_fDamgeAbsorbRate*10000); // int nDamgeAbsorb =(int) (absDrop * m_fDamgeAbsorbRate); //这里伤害减免了一定的数值 // nFinalDamageValue -= nDamgeAbsorb; #ifdef _DEBUG // S9伤害减免比例 SNPRINTFA(s_HurtValueBuff,100," //S9::%d",S9); s_HurtValueMsg += s_HurtValueBuff; #endif } //[NORMAL] 伤害转换为mp消耗 int S10 = 10000; int fDamage2MpRate = GetHp2MpRate(); //获取血->蓝的转换比例 if(fDamage2MpRate >0) { S10 -= fDamage2MpRate; int nMp = GetProperty(PROP_CREATURE_MP) ; //获取玩家的蓝 if(nMp >0) { int nDropMp = (int)(((fDamage2MpRate * absDrop)/10000.0)/50); int nAbsorb = __min( nDropMp , nMp); //吸收的点数 if(nAbsorb >0) { // nFinalDamageValue -= nAbsorb; //static float fRate = GetLogicServer()->GetDataProvider()->GetGlobalConfig().fBodyDamageRate; //nAbsorb = (int)(__min(nDropMp * fRate, nMp)); if (nMp - nAbsorb >= 500) { ChangeMP(-1 * nAbsorb); //降低蓝 } } #ifdef _DEBUG // S10 SNPRINTFA(s_HurtValueBuff,100," //S10:%d;",S10); s_HurtValueMsg += s_HurtValueBuff; #endif } } //守护 --mhl bool bGuardEff = false; int S11 = 10000; int nGuardRand =wrand(10000); //取1万之间的随机数 if( m_nGuardRate > 0 && nGuardRand <= m_nGuardRate) { S11 -= m_nGuardValue; // int nAbsorb = absDrop * (10000 - m_nGuardValue)/10000.0; // nFinalDamageValue -= nAbsorb; bGuardEff = true; #ifdef _DEBUG // S10 SNPRINTFA(s_HurtValueBuff,100," //S11:%d;",S11); s_HurtValueMsg += s_HurtValueBuff; #endif } //切割--只对怪物生效 --mhl int S12 = 10000; if(nSelfType == enMonster && (pKiller && pKiller->isAnimal())) { S12 += ((CAnimal*)pKiller)->m_nCuttingRate; // int nCutDmage = absDrop * (((CAnimal*)pKiller)->m_nCuttingRate / 10000.0); // nFinalDamageValue += nCutDmage; #ifdef _DEBUG // S12 SNPRINTFA(s_HurtValueBuff,100," //S12:%d;",S12); s_HurtValueMsg += s_HurtValueBuff; #endif // static int nGuardEffId = GetLogicServer()->GetDataProvider()->GetGlobalConfig().nGuardEffId; // CEntityMsg msg(CEntityMsg::emShowEntityEffect, pKiller->GetHandle()); // msg.nParam1 = nGuardEffId; // this->PostEntityMsg(msg); } //pk伤害减免 int S13 = 10000; if(nSelfType == enActor && nKillType == enActor) { S13 -= m_nPkDamageAbsorbRatio; // int nAbsorb = absDrop * (m_nPkDamageAbsorbRatio / 10000.0); // nFinalDamageValue -= nAbsorb; #ifdef _DEBUG // S12 SNPRINTFA(s_HurtValueBuff,100," //S13:%d;",S13); s_HurtValueMsg += s_HurtValueBuff; #endif } //伤害流程计算 //s6 = s6*s7*s8*s9*s11*s12*s13 absDrop = (int)(absDrop*(S7/10000.0)*(S8/10000.0)*(S9/10000.0)*(S10/10000.0)*(S11/10000.0)*(S12/10000.0)*(S13/10000.0)); // absDrop += nFinalDamageValue; #ifdef _DEBUG // Z1 SNPRINTFA(s_HurtValueBuff,100," //Z1:%d;",absDrop); s_HurtValueMsg += s_HurtValueBuff; #endif if(absDrop <= 0) absDrop = 1; //剧毒绝对(绝对值) if(m_nToxicAttckValue) { #ifdef _DEBUG // J1 SNPRINTFA(s_HurtValueBuff,100," //J1:%d;",m_nToxicAttckValue); s_HurtValueMsg += s_HurtValueBuff; #endif absDrop += m_nToxicAttckValue; static int nTXJDCJ = GetLogicServer()->GetDataProvider()->GetHallowthen().m_HallowsSSCMainInfo.nTXJDCJ; CEntityMsg msg2(CEntityMsg::emShowEntityEffect, GetHandle()); msg2.nParam1 = nTXJDCJ; msg2.nParam3 = (int)m_nToxicAttckValue; this->PostEntityMsg(msg2); m_nToxicAttckValue = 0; } //冰冻伤害(绝对值) if(m_nSZASAttckValue) { #ifdef _DEBUG // J1 SNPRINTFA(s_HurtValueBuff,100," //J2:%d;",m_nSZASAttckValue); s_HurtValueMsg += s_HurtValueBuff; #endif absDrop += m_nSZASAttckValue; static int nTXSZAS = GetLogicServer()->GetDataProvider()->GetHallowthen().m_HallowsSSCMainInfo.nTXSZAS; CEntityMsg msg2(CEntityMsg::emShowEntityEffect, GetHandle()); msg2.nParam1 = nTXSZAS; msg2.nParam3 = (int)m_nSZASAttckValue; this->PostEntityMsg(msg2); m_nSZASAttckValue = 0; } //怪物收到攻击的时候需要计算一下声音 if ((nSelfType == enPet || nSelfType == enActor || nSelfType == enHero) && hasKiller && IsInited() && nKillType == enActor && this != pKiller) { CActor *pAttacked = ((CActor*)this); if (nSelfType == enPet) { pAttacked = ((CPet *)this)->GetMaster(); } else if(nSelfType == enHero) { pAttacked = ((CHero *)this)->GetMaster(); //主人 } if (pAttacked) { CActorPacket pack ; pAttacked->AllocPacket(pack); pack << (BYTE) enSkillSystemID <<(BYTE)sAttackByActor; pack << (Uint64)(pKiller->GetHandle()) ; pack.flush(); //动攻击黄名、白名玩家后,变成褐名 ((CActor*)this)->GetSkillSystem().SetInitiativeAttack(pKiller,pAttacked); if(bGuardEff) { static int nGuardEffId = GetLogicServer()->GetDataProvider()->GetGlobalConfig().nGuardEffId; CEntityMsg msg(CEntityMsg::emShowEntityEffect, pKiller->GetHandle()); msg.nParam1 = nGuardEffId; this->PostEntityMsg(msg); } } } //掉血判断 if(absDrop <=0) { OutputMsg(rmTip, _T("收到攻击,但无伤害!")); return; } nHpDrop = - absDrop; } else { nHpDrop = hpDrop; } if(m_DieRefreshHpPro > 0 || m_MonsterDieHpPro > 0) { if (m_MonsterDieHpPro > 0) { m_DieRefreshHpPro = m_MonsterDieHpPro; } } //兵魂-救主灵刃 if(pKiller)//&& btHitType != htFire) { if(nSelfType == enActor) { int nCurrentHP = GetProperty(PROP_CREATURE_HP); int nMaxHP = GetProperty(PROP_CREATURE_MAXHP); //救主灵刃CD时间为0,不触发 if(m_nSaviorTime && (nCurrentHP - absDrop) < (nMaxHP * (float)GetLogicServer()->GetDataProvider()->GetHallowthen().m_HallowsSSCMainInfo.nSaviorPercen / 10000) && m_nJZLRCDTime < GetGlobalLogicEngine()->getMiniDateTime()) { bool bExitJZLRBuff = true; std::vector::iterator iter = GetLogicServer()->GetDataProvider()->GetHallowthen().m_HallowsSSCMainInfo.vJZLRBuff.begin(); for (; iter != GetLogicServer()->GetDataProvider()->GetHallowthen().m_HallowsSSCMainInfo.vJZLRBuff.end(); ++iter) { CBuffProvider::BUFFCONFIG * pBUFFCONFIG = GetLogicServer()->GetDataProvider()->GetBuffProvider().GetBuff(*iter); if(pBUFFCONFIG) { CDynamicBuff* pDynamicBuff = GetBuffSystem()->GetBuff((GAMEATTRTYPE)pBUFFCONFIG->nType, pBUFFCONFIG->nGroup); if(!pDynamicBuff) { bExitJZLRBuff = false; break; } } } if (bExitJZLRBuff) { //触发效果:抵御本次伤害并回复最大HP的百分比 + 绝对值 nHpDrop = nMaxHP * (m_nSaviorRate / 10000.0) + m_nSaviorValue; //设置救主灵刃CD时间 m_nJZLRCDTime = GetGlobalLogicEngine()->getMiniDateTime() + (m_nSaviorTime / 1000); //设置救主Buff的CD时间 CBuffProvider::BUFFCONFIG * pBUFFCONFIG = GetLogicServer()->GetDataProvider()->GetBuffProvider().GetBuff(nJZBuffId); if(pBUFFCONFIG) { CDynamicBuff* pDynamicBuff = GetBuffSystem()->GetBuff((GAMEATTRTYPE)pBUFFCONFIG->nType, pBUFFCONFIG->nGroup); if( pDynamicBuff ) { pDynamicBuff->m_nBuffCd = (m_nSaviorTime / 1000); GetBuffSystem()->OnBuffChangeCdTime(pDynamicBuff); } } //针对离线CD重置的处理 ((CActor*)this)->SaveJZLRCDTime(szJZLRCDTime, m_nJZLRCDTime); static int nTXJZLR = GetLogicServer()->GetDataProvider()->GetHallowthen().m_HallowsSSCMainInfo.nTXJZLR; CEntityMsg msg(CEntityMsg::emShowEntityEffect, GetHandle()); msg.nParam1 = nTXJZLR; PostEntityMsg(msg); } } } } //OutputMsg(rmTip, _T("真实伤害 玩家name: , 伤害:%d, "), nHpDrop); //Z2 if(hpDrop < 0) { if (!bIgnoreMaxDropHp) //是否忽略每次最大伤害限制 { int nMaxDropHp = GetMaxDropHp(); if(nMaxDropHp > 0) //每次掉血的数量 { if(-nHpDrop > nMaxDropHp ) //如果掉落的血超过了最大,就直接设置为掉落 { nHpDrop = -nMaxDropHp; } } } } if (nSelfType == enMonster) { if(((CMonster*)this)->GetMonsterType() == MONSTERCONFIG::mtKungfu) { if (nKillType == enActor) { char cBuff[30]; SNPRINTFA(cBuff,100,"伤害: %d",-nHpDrop); std::string sFinalHurt; sFinalHurt += cBuff; ((CActor*)pKiller)->SendTipmsg(sFinalHurt.c_str(),tstFigthing); } return; } } Inherited::ChangeHP(nHpDrop,pKiller); //H1 if(hpDrop < 0) { if(btHitType != htFire && pKiller && pKiller->isAnimal()) { if( ((CAnimal*)pKiller)->m_nSuckBloodRatio > 0) { int nDamage = absDrop; if (!bIgnoreMaxDropHp) //是否忽略每次最大伤害限制 { int nMaxDropHp = GetMaxDropHp(); if(nMaxDropHp > 0) //每次掉血的数量 { if(nDamage > nMaxDropHp ) //如果掉落的血超过了最大,就直接设置为掉落 { nDamage = nMaxDropHp; } } } int nSuckBloodRatio = ((CAnimal*)pKiller)->m_nSuckBloodRatio; LONG64 nSuck = (LONG64)(nDamage*( (double)nSuckBloodRatio/10000.0) ); int nSuckBloodRate = GetLogicServer()->GetDataProvider()->GetGlobalConfig().nSuckBloodRate; //吸血属性(怪物) int nSuckBloodRatePlayer = GetLogicServer()->GetDataProvider()->GetGlobalConfig().nSuckBloodRatePlayer ; //吸血属性 (玩家)万分比 if(nSelfType == enActor && nKillType == enActor)//如果是玩家对玩家 { nSuck = (LONG64)nSuck * ((double)nSuckBloodRatePlayer/10000.0); } else { nSuck = (LONG64)nSuck * ((double)nSuckBloodRate/10000.0);//* nSuckBloodRate/10000.0; } //OutputMsg(rmTip, _T("吸血伤害 玩家name: , 原始伤害:%d 吸血:%d 比例:%d "), (int)absDrop, (int)nSuck, ((CAnimal*)pKiller)->m_nSuckBloodRatio); ((CAnimal*)pKiller)->ChangeHP(nSuck); #ifdef _DEBUG // H1 SNPRINTFA(s_HurtValueBuff,100," //H1:%d;",nSuck); s_HurtValueMsg += s_HurtValueBuff; #endif } } } if (nHpDrop < 0)//2017-03-29修改,掉血数据放在changehp后下发,并实时下发当前血量,不用等属性变化再刷新,会有延迟 { int absDrop = -nHpDrop; //掉了多少血 int nHp = GetProperty(PROP_CREATURE_HP); if(hasKiller && nKillType ==enActor && pKiller->IsInited() && this != pKiller) { if(absDrop >0 ) //有掉血的话,就需要给打出伤害这边的发一个消息包 { if(GetType() != enGatherMonster) { int nMusicId=0; if(nSelfType ==enMonster) { const PMONSTERCONFIG pMonster= GetLogicServer()->GetDataProvider()->GetMonsterConfig().GetMonsterData(GetProperty(PROP_ENTITY_ID)); if( pMonster !=NULL ) { int nRate = pMonster->bDamageMusicRate; int nId = pMonster->bDamageMusicId; if(nRate >0 && nId >0) { if(nRate >=100 || nRate >= (int)(wrand(101))) { nMusicId = nId; } } } } //自己对怪物造成的伤害要播放一个声音,宝宝的不要 unsigned int nCritDamage = 0; if (boSkillResult) { nCritDamage = pKiller->GetProperty(PROP_ACTOR_CRIT_DAMAGE); } char buff[1024]; CDataPacket outPack(buff, sizeof(buff)); //下发的数据包 outPack << (BYTE) enSkillSystemID <<(BYTE)sSelfDamageOther; //GetHandle() 用于客户端查找 对应句柄的玩家 outPack <SetProperty(PROP_ACTOR_CRIT_DAMAGE,0); } ((CActor*)pKiller)->SendData(outPack.getMemoryPtr(), outPack.getPosition()); if(nSelfType == enActor) { CActor *pAttacked = ((CActor*)this); if(pAttacked && pAttacked->IsInited()) pAttacked->SendData(outPack.getMemoryPtr(), outPack.getPosition()); } } } } //宠物打出血了,要告诉宠物的主人,通知是自己打出来的 if(hasKiller && (nKillType ==enPet || nKillType == enHero)) { if(absDrop >0 ) //有掉血的话,就需要给打出伤害这边的发一个消息包 { if(GetType() != enGatherMonster) { CActor *pMaster = NULL; if(nKillType == enPet) { pMaster=((CPet*)pKiller)->GetMaster(); //主人 } else if(nKillType == enHero) { pMaster=((CHero*)pKiller)->GetMaster(); //主人 } if(pMaster && pMaster->IsInited()) { CActorPacket pack ; pMaster->AllocPacket(pack); pack << (BYTE) enSkillSystemID <<(BYTE)sSelfDamageOther; pack << GetHandle() << (int)absDrop << (int)0 << (unsigned int)0<m_pSelf->GetSkillSystem(); const CVector & skills= skillSystem.GetSkills(); //这里加这个是为了一个技能 for(INT_PTR i=0; i< skills.count();i++) { if(skills[i].bEvent == mSkilleventAlive) { skillSystem.LaunchSkill(skills[i].nSkillID); } } } void CAnimal::ChangeName(const char* sName) { //OutputMsg(rmNormal, _T("CAnimal::ChangeName(), pShowsNameName=%s"), sName); if(sName ==NULL) return; if( strcmp(GetEntityName(), sName) ==0) return; //如果没有改变就不弄 //SetEntityName(sName); char buff[148]; CDataPacket data(buff,sizeof(buff)); data << (BYTE)enDefaultEntitySystemID <<(BYTE) sChangeShowName ; data << (Uint64) GetHandle(); //实体句柄 data.writeString(GetShowName()); //将这个字符串写入 if(GetType() ==enActor) { m_observerSystem.BroadCast(data.getMemoryPtr(), data.getPosition(),true); } else { m_observerSystem.BroadCast(data.getMemoryPtr(), data.getPosition(),false); } } void CAnimal::ChangeShowName(int nRadius, LPCTSTR sName) { if (sName ==NULL) return; if (strcmp(GetShowName(), sName) ==0) return; //如果没有改变就不弄 CScene * pScene = GetScene(); if (!pScene) return; SetShowName(sName); char sAllName[128]; if (GetType() == enNpc) { sprintf_s(sAllName,sizeof(sAllName),"%s\\%s",sName,GetTitle()); } else { strncpy(sAllName, sName, strlen(sName)); } EntityVector &vecPlys = *(CFuBenManager::m_pVisibleList); vecPlys.clear(); pScene->GetVisibleList(this, vecPlys, -nRadius, nRadius, -nRadius, nRadius); INT_PTR nEntityCount = vecPlys.count(); if (nEntityCount > 0) { Uint64 hEntityHandle = (Uint64)GetHandle(); CEntityManager * pMgr = GetGlobalLogicEngine()->GetEntityMgr(); for (int i = 0; i < nEntityCount; i++) { CEntity * pActor = pMgr->GetEntity(vecPlys[i]); if (pActor && pActor->GetType() == enActor) { CActorPacket ap; CDataPacket & outPack = ((CActor*)pActor)->AllocPacket(ap); outPack << (BYTE)enDefaultEntitySystemID << (BYTE)sChangeShowName; outPack << hEntityHandle; outPack.writeString(sAllName); //名字=名字+'\'+称号,用\隔开 ap.flush(); } } } } void CAnimal::ChangeModel(int nRadius, int nModelId) { CScene * pScene = GetScene(); if (!pScene) return; if (GetProperty(PROP_ENTITY_MODELID) == nModelId) return; SetProperty(PROP_ENTITY_MODELID, nModelId); EntityVector &vecPlys = *(CFuBenManager::m_pVisibleList); vecPlys.clear(); pScene->GetVisibleList(this, vecPlys, -nRadius, nRadius, -nRadius, nRadius); INT_PTR nEntityCount = vecPlys.count(); if (nEntityCount > 0) { Uint64 hEntityHandle = (Uint64)GetHandle(); CEntityManager * pMgr = GetGlobalLogicEngine()->GetEntityMgr(); for (int i = 0; i < nEntityCount; i++) { CEntity * pActor = pMgr->GetEntity(vecPlys[i]); if (pActor && pActor->GetType() == enActor) { CActorPacket ap; CDataPacket & outPack = ((CActor*)pActor)->AllocPacket(ap); outPack << (BYTE)enDefaultEntitySystemID << (BYTE)sEntityPropertyChange; outPack << hEntityHandle << (BYTE)1 << (BYTE)PROP_ENTITY_MODELID << nModelId; ap.flush(); } } } } void CAnimal::SetAttackType(int nType,bool bNeedBroadCast ) { m_nAttackType = nType; if(bNeedBroadCast) { char buff[128]; CDataPacket data(buff,sizeof(buff)); data << (BYTE) enDefaultEntitySystemID << (BYTE) sChangeAttackType << (Uint64)GetHandle() << (BYTE) m_nAttackType; CObserverSystem * pSystem = GetObserverSystem(); if(pSystem) { pSystem->BroadCast(data.getMemoryPtr(),data.getPosition(),false); } } } void CAnimal::SetCamp(int nCampId) { if(GetType() != enActor) { m_nCamp = nCampId; } else { SetProperty(PROP_ACTOR_ZY, nCampId); } } void CAnimal::OnAttacked(CAnimal * pEntity, bool bSetVest) { bool bUpdateAttackStatus = true; INT_PTR nType = GetType(); CAnimalAI* pAI = GetAI(); if (pAI) { pAI->AttackedBy(pEntity); bUpdateAttackStatus = false; } if (pEntity ) { INT_PTR nAttackEntityType = ((CEntity*)pEntity)->GetType(); if ( nAttackEntityType == enActor || nAttackEntityType == enPet || nAttackEntityType == enHero || nAttackEntityType == enMonster ) { if ( (nType == enMonster && GetAttriFlag().attackToScript) || nType != enMonster ) { CFuBen* pFB = GetFuBen(); if (pFB && pFB->IsFb()) { // 副本实体受伤事件 CScriptValueList paramList; paramList << (int)CFubenSystem::enOnAttacked; paramList << (int)pFB->GetConfig()->nFbConfType; paramList << (int)pFB->GetFbId(); paramList << (int)pFB->GetConfig()->nFbEnterType; paramList << pFB; paramList << (int)GetSceneID(); paramList << this; paramList << pEntity; if(!GetGlobalLogicEngine()->GetGlobalNpc()->GetScript().CallModule("FubenDispatcher","OnEvent", paramList, paramList, 1)) { OutputMsg(rmError,"[FubenSystem] OnEvent OnAttacked 错误,副本ID=%d,副本类型=%d !",pFB->GetFbId(),pFB->GetConfig()->nFbConfType); } } if (pFB && !(pFB->IsFb())) { // 触发进入活动区域事件 int nPosX,nPosY; this->GetPosition(nPosX,nPosY); CScene* pScene = this->GetScene(); SCENEAREA* pArea = pScene->GetAreaAttri(nPosX, nPosY); if (pScene && pArea && pScene->HasMapAttribute(nPosX,nPosY,aaActivity,pArea)) { static CNpc* globalNpc = GetGlobalLogicEngine()->GetGlobalNpc(); CScriptValueList paramList; AreaAttri * pAreaAttr = &pArea->attri[aaActivity]; for (size_t i = 0; i < pAreaAttr->nCount; i++) { int nAtvId = pAreaAttr->pValues[i]; // 个人活动 if((this->GetType() == enActor) && ((CActor*)this)->GetActivitySystem().IsActivityRunning(nAtvId)) { if (PersonActivtyData* pActivty = ((CActor*)this)->GetActivitySystem().GetActivity(nAtvId)) { paramList.clear(); paramList << (int)CActivitySystem::enOnAtvAreaAtk; paramList << (int)pActivty->nActivityType; paramList << (int)pActivty->nId; paramList << this; paramList << pEntity; if (!globalNpc->GetScript().CallModule("ActivityDispatcher", "OnEvent", paramList, paramList)) { OutputMsg(rmError,"[Personal Activity] OnEvent错误 enOnEnterArea,活动Type=%d, 活动ID=%d !",pActivty->nActivityType,pActivty->nId); } } } // 全局活动 else if(GetGlobalLogicEngine()->GetActivityMgr().IsRunning(nAtvId)) { if (GlobalActivityData* pActivty = GetGlobalLogicEngine()->GetActivityMgr().GetActivity(nAtvId)) { paramList.clear(); paramList << (int)CActivitySystem::enOnAtvAreaAtk; paramList << (int)pActivty->nActivityType; paramList << (int)pActivty->nId; paramList << this; paramList << pEntity; if (!globalNpc->GetScript().CallModule("ActivityDispatcher", "OnEvent", paramList, paramList)) { OutputMsg(rmError,"[Global Activity] OnEvent错误 enOnEnterArea,活动Type=%d, 活动ID=%d !",pActivty->nActivityType,pActivty->nId); } } } } } } // CActor* pActor = NULL; // if (nAttackEntityType == enPet) // { // pActor = ((CPet*)pEntity)->GetMaster(); // } // else if ( nAttackEntityType == enHero ) // { // pActor = ((CHero*)pEntity)->GetMaster(); // } // else // { // pActor = (CActor*)pEntity; // } // CScriptValueList paramList, retList; // CNpc* pNpc = GetGlobalLogicEngine()->GetGlobalNpc(); // paramList<< (CAnimal*)this << (CActor*)pActor; // if (pNpc != NULL) // { // pNpc->GetScript().Call("OnMonsterAttackBy",paramList,retList ); // } } } } if(! HasState(esStateBattle) ) { if (bUpdateAttackStatus) { AddState(esStateBattle); } } else { // 玩家被非玩家攻击,不推迟离开战斗时间 bool bPostpone = true; if (enActor == GetType() && pEntity->GetType() != enActor) bPostpone = false; if (bPostpone) postponeLeaveCombatTimer(); } } void CAnimal::OnAttackOther(CAnimal * pEntity, bool bChgDura) { if(! HasState(esStateBattle) ) { AddState(esStateBattle ); } else { // 玩家攻击其他非玩家实体,不推迟离开战斗时间 bool bPostpone = true; if (enActor == GetType() && pEntity->GetType() != enActor) bPostpone = false; if (bPostpone) postponeLeaveCombatTimer(); } } void CAnimal::OnEnterBattle() { bool bPostpone = true; if (enActor == GetType()) { EntityHandle eh = GetTarget(); // 虽然enActor也是为0,这里最好别去掉,以防以后修改枚举类型! marked by wp 2011.9.15 if (!eh.IsNull() && eh.GetType() != enActor) bPostpone = false; } if (bPostpone) postponeLeaveCombatTimer(); } void CAnimal::postponeLeaveCombatTimer() { m_battleLeftTime = GetGlobalLogicEngine()->getTickCount() + getLeaveCombatTime(); } bool CAnimal::CheckCommonOpTickBefore(TICKCOUNT nTick) { if ((m_tOpsTimer.GetNextTime() - nTick) > 10000) { m_tOpsTimer.SetNextHitTime(nTick); } } bool CAnimal::CheckCommonOpTick(TICKCOUNT nTick, bool bFailSendmsg, bool bMoveOp) { if (GetType() == enActor && bMoveOp) { return true; } if( m_tOpsTimer.Check(nTick) ) return true; else { if(GetType() == enActor && bFailSendmsg) { /*OutputMsg(rmWaning,_T("Fail 下次的OP=%lld,current=%lld"),m_tOpsTimer.GetNextTime(), nTick );*/ ((CActor*)this)->SendOperateResult(false); } return false; } } void CAnimal::SetCommonOpNextTime(INT_PTR nNextTime,bool bSendResult2Client ,bool bResult, unsigned int nStep, unsigned int nSendPkgTick, bool bUseGateTime,bool bUseCheckCd,bool bNearAttackSuc) { if(GetType() == enActor) { CActor* pActor = (CActor *)this; pActor->SetCommonOpNextTimeImpl(nNextTime, bSendResult2Client, bResult, nStep, nSendPkgTick, bUseGateTime,bUseCheckCd,bNearAttackSuc ); } else { m_tOpsTimer.SetNextHitTimeFromNow(nNextTime); } } VOID CAnimal::ChangeMP(int nValue) { Inherited::ChangeMP(nValue); } VOID CAnimal::LogicRun(TICKCOUNT nCurrentTime) { //DECLARE_FUN_TIME_PROF() if(IsInited() ==false ) return; Inherited::LogicRun(nCurrentTime); //3秒钟回血回蓝 /************************************************************************ * 注意:为了提高程序运行效率。这里定时器不要并排执行,按照精度由高到低进行 层级嵌套。如果因为逻辑功能需要调整定时精度,需谨慎!!!必要时需要 修改层级关系。 /************************************************************************/ //怪物和宠物才执行移动的检测 INT_PTR nType = GetType(); switch(nType) { case enNpc: return; case enMonster: case enPet: case enHero: case enActor: { m_moveSystem.OnTimeCheck(nCurrentTime); break; } } if (m_t500ms.CheckAndSet(nCurrentTime,true)) { if (m_pAI) m_pAI->UpdateAI(nCurrentTime); if(m_nDizzyTime && m_nDizzyTime < nCurrentTime) RemoveDizzyState(); } // 更新观察者、技能子系统、技能AdornFlags if (m_tRefViewTimer.CheckAndSet(nCurrentTime, true)) { m_observerSystem.OnTimeCheck(nCurrentTime); } if(m_t1S.CheckAndSet(nCurrentTime, true)) { m_skillSystem.OnTimeCheck(nCurrentTime); //技能的吟唱 //定时检测buff子系统 m_buffSystem.OnTimeCheck(nCurrentTime); if (HasState(esStateBattle)) { //只有玩家才去掉战斗状态 if (nCurrentTime >= m_battleLeftTime && nType ==enActor) //要脱离战斗了 { RemoveState(esStateBattle); //脱离战斗 /* if (m_pAI) { m_pAI->AttackStop(NULL); } */ } } // 更新效果子系统 m_effectSystem.OnTimeCheck(nCurrentTime); // 生物回血、回蓝处理 if( m_t2s.CheckAndSet(nCurrentTime, true)) { /*if(!IsDeath() && nType == enHero) //英雄回血不需要战斗状态 { if(!GetAttriFlag().DenyAutoAddHp) { static int s_nHpRenewAdd = GetLogicServer()->GetDataProvider()->GetGlobalConfig().nHpRenewAdd; static float s_fHpRenewRate =GetLogicServer()->GetDataProvider()->GetGlobalConfig().fHpRenewRate; int nMaxHp = 0; const CHeroSystem::HERODATA *pHero = ((CHero *)(this))->GetHeroPtr(); nMaxHp = pHero->nBaseMaxHp; int nAddValue = (int) ( ( (int)(nMaxHp * s_fHpRenewRate) + s_nHpRenewAdd )*(1 + (float)GetProperty(PROP_CREATURE_HP_RATE_RENEW)/10000 )); nAddValue = nAddValue + GetProperty( PROP_CREATURE_HP_RENEW ); ChangeHP(nAddValue); } if(!GetAttriFlag().DenyAutoAddMp) { static int s_nMpRenewAdd = GetLogicServer()->GetDataProvider()->GetGlobalConfig().nMpRenewAdd; static float s_nMpRenewRate =GetLogicServer()->GetDataProvider()->GetGlobalConfig().fMpRenewRate; int nMaxMp = 0; const CHeroSystem::HERODATA *pHero = ((CHero *)(this))->GetHeroPtr(); nMaxMp = pHero->nBaseMaxMp; int nAddValue = (int) ( ( (int)(nMaxMp * s_nMpRenewRate) + s_nMpRenewAdd )*(1 + (float)GetProperty(PROP_CREATURE_MP_RATE_RENEW)/10000 )); nAddValue = nAddValue + GetProperty( PROP_CREATURE_MP_RENEW ); ChangeMP(nAddValue); } } else */if(!IsDeath() && !HasState(esStateBattle)) //死了不加血加蓝的 { if (CDynamicBuff * pForbidHpRenewBuff = GetBuffSystem()->GetBuff(aForbidHpRenew, CDynamicBuff::AnyBuffGroup)) { // 施毒术BUFF 禁止回血蓝 } else { if(!GetAttriFlag().DenyAutoAddHp) { int nMaxHp = 0; if (nType == enActor) { nMaxHp = ((CActor *)(this))->m_nBase_MaxHp; } else { nMaxHp = GetProperty< int>( PROP_CREATURE_MAXHP); } if (GetProperty(PROP_CREATURE_HP) < nMaxHp) { int nAddValue = (int) (nMaxHp * ((float)GetProperty(PROP_CREATURE_HP_RATE_RENEW)/10000)); nAddValue = nAddValue + GetProperty( PROP_CREATURE_HP_RENEW ); ChangeHP(nAddValue); } } if(!GetAttriFlag().DenyAutoAddMp) { int nMaxMp = 0; if (nType == enActor) { nMaxMp = ((CActor *)(this))->m_nBase_MaxMp; } else { nMaxMp = GetProperty< int>( PROP_CREATURE_MAXMP); } if (GetProperty(PROP_CREATURE_MP) < nMaxMp) { int nAddValue = (int) (nMaxMp*((float)GetProperty(PROP_CREATURE_MP_RATE_RENEW)/10000)); nAddValue = nAddValue + GetProperty( PROP_CREATURE_MP_RENEW ); ChangeMP(nAddValue); } } } } } if(m_nSaviorTime && m_nJZLRCDTime < GetGlobalLogicEngine()->getMiniDateTime()) { UpdateJZLR(); } } } VOID CAnimal::AfterLogicRun(TICKCOUNT nCurrentTime) { Inherited::AfterLogicRun(nCurrentTime); INT_PTR i; //处理集中的汇总操作 for (i=0; iIsAttackImmune() ) return false; INT_PTR nSrcType = GetType(); INT_PTR nTargetType = pTargetEntity->GetType(); if(this == pTargetEntity) return false; //自己不能攻击自己 if(nTargetType ==enNpc) return false; if (!pTargetEntity->isAnimal()) return false; if(nSrcType ==enPet ) { CPet *pPet = (CPet*)this; if(pPet->GetMaster() == NULL) return false; if (GetAttriFlag().AttackPet) { return true; } return pPet->GetMaster()->CanAttack(pTargetEntity); } else if(nSrcType ==enHero) { CHero *pHero = (CHero*)this; if(pHero->GetMaster() == NULL) return false; return pHero->GetMaster()->CanAttack(pTargetEntity); } if( nTargetType ==enPet) { CPet *pPet = (CPet*)pTargetEntity; if(pPet->GetMaster() == NULL) return false; return CanAttack(pPet->GetMaster(), pPet); //能否攻击他的主人 } else if(nTargetType ==enHero) { CHero *pHero = (CHero*)pTargetEntity; if(pHero->GetMaster() == NULL) return false; return CanAttack(pHero->GetMaster()); } //不能被攻击 if(pTargetEntity->GetAttriFlag().DenyBeAttack) { return false; } //无敌buff不能攻击 if( nSrcType == enActor) { //如果玩家杀对方,对方存在pk保护状态,那么不能杀 if( pTargetEntity->GetBuffSystem()->Exists(aPkProtectState) ) return false; //玩家不能功能本阵营的怪物 if( nTargetType ==enMonster) { if(pTargetEntity->GetCampId() ) { if(pTargetEntity->GetCampId() == GetCampId()) return false; } } if(nTargetType ==enActor) { return ((CActor *)this)->GetPkSystem().CanAttack((CActor*) pTargetEntity, pPet, boAttackNotice); } //怪物拒绝被玩家攻击 if(pTargetEntity->GetAttriFlag().DenyAttackedByActor) { return false; } if (pTargetEntity->IsMonster() ) { CMonster *pMonster = (CMonster *)pTargetEntity; if (pMonster->GetOwner() == GetHandle()) // 不能打归属于自己的怪 return false; //如果配置了行会id if(pTargetEntity->GetNpcGuildId() && GetProperty(PROP_ACTOR_GUILD_ID) == pTargetEntity->GetNpcGuildId()) return false; return true; } } else if(nSrcType == enMonster) { // 怪物不能打NPC和采集怪 if (enGatherMonster == nTargetType) { return false; } // 怪物配置了阵营ID,并且目标怪物或者玩家的阵营相同,不能攻击 else if (enActor == nTargetType) { //如果配置了行会id if(GetNpcGuildId() && pTargetEntity->GetProperty(PROP_ACTOR_GUILD_ID) == GetNpcGuildId()) return false; } // 怪物不打同阵营的玩家 if( GetCampId() && nTargetType ==enActor &&pTargetEntity->GetCampId() == GetCampId()) { return false; } } //拒绝攻击玩家 if(nTargetType == enActor && GetAttriFlag().DenyAttackActor) { return false; } //如果目标是一个怪物,并且没有主人 if(nTargetType == enMonster && /*((CMonster*)pTargetEntity)->GetOwner().IsNull()) && */!GetAttriFlag().CanAttackMonster ) { return false; } if(nSrcType ==enMonster) //如果释放者是一个怪物 { return true; } return false; } bool CAnimal::CanAttack(CAnimal *pTargetEntity, CAnimal *, bool) { // 同阵营判断 if(pTargetEntity->GetCampId()) { if(pTargetEntity->GetCampId() == GetCampId()) return false; } // 怪物的不能被攻击标志判断 if (pTargetEntity->IsMonster()) { if (pTargetEntity->GetAttriFlag().DenyBeAttack) { return false; } return true; } else { // 如果A是宠物,则看主人能否攻击目标 if (GetType() == enPet) { CPet *pSelf = (CPet*)this; if(pSelf->GetMaster() == NULL) return false; return pSelf->GetMaster()->CanAttack(pTargetEntity); } // 如果A是玩家 else if (GetType() == enActor) { CActor *pSelf = ((CActor *)this); // 如果B是宠物 if (pTargetEntity->GetType() == enPet) { CPet *pTarPet = (CPet*)pTargetEntity; if(pTarPet->GetMaster() == NULL) return false; return pSelf->GetPkSystem().CanAttack(pTarPet->GetMaster(), pTarPet) && pSelf->GetPkSystem().IsUnLimited(pTargetEntity); } // 如果B是玩家 else// if (pTargetEntity->GetType() == enActor) { return pSelf->GetPkSystem().CanAttack((CActor*)pTargetEntity) && pSelf->GetPkSystem().IsUnLimited(pTargetEntity); } }else { return true; } } } bool CAnimal::IsFriend(CAnimal *pTargetEntity) { // 同阵营判断 if(pTargetEntity->GetCampId()) { if(pTargetEntity->GetCampId() == GetCampId()) return false; } // 怪物的不能被攻击标志判断 if (pTargetEntity->IsMonster() && pTargetEntity->GetAttriFlag().DenyBeAttack) { return false; } // 如果A是宠物,则看主人能否攻击目标 if (GetType() == enPet) { CPet *pSelf = (CPet*)this; if(pSelf->GetMaster() == NULL) return false; return pSelf->GetMaster()->CanAttack(pTargetEntity); } // 如果A是玩家 else if (GetType() == enActor) { CActor *pSelf = ((CActor *)this); // 如果B是宠物 if (pTargetEntity->GetType() == enPet) { CPet *pTarPet = (CPet*)pTargetEntity; if(pTarPet->GetMaster() == NULL) return false; return pSelf->GetPkSystem().CanAttack(pTarPet->GetMaster()); } // 如果B是玩家 else// if (pTargetEntity->GetType() == enActor) { return pSelf->GetPkSystem().CanAttack((CActor*)pTargetEntity); } } return true; } VOID CAnimal::DoCollectedOperation(CEntityOPCollector::CollecteOPType eOPType) { INT_PTR nEntityType; switch(eOPType) { case CEntityOPCollector::coRefAbility: //TODO:实现刷新人物、被动技能、装备、经脉、BUFF等属性的全部属性刷新功能,并向角色发送属性变更的消息 //#pragma __CPMSG__(TODO:实现刷新人物、被动技能、装备、经脉、BUFF等属性的全部属性刷新功能,并向角色发送属性变更的消息) GetPropertySystem().ResertProperty(); //重置属性 break; case CEntityOPCollector::coRefFeature: nEntityType =GetType(); if(nEntityType == enActor ) { ((CActor*)this)->GetEquipmentSystem().RefreshAppear(); //刷新外形 } break; case CEntityOPCollector::coTransport: //这个玩家是传送过来的,通知其他人,需要播放一个特效 //((CActor*)this)->NotifyNearbyTransport(); this->GetMoveSystem()->SetMoveFlag( CMovementSystem::mfTransport, false); //设置为传送标记 break; case CEntityOPCollector::coResetMaxHPMP: { SetProperty(PROP_CREATURE_HP, GetProperty(PROP_CREATURE_MAXHP)); SetProperty(PROP_CREATURE_MP, GetProperty(PROP_CREATURE_MAXMP)); } break; case CEntityOPCollector::coRefMonsterDynProp: { GetPropertySystem().ResertProperty(); //重置属性 // 将怪物HP设置为满 //if (!HasState(esStateBattle)) //{ //SetProperty(PROP_CREATURE_HP, GetProperty(PROP_CREATURE_MAXHP)); //} break; } default: break; } } void CAnimal::ProcessEntityMsg(const CEntityMsg &msg) { char buff[256]; CEntity * pEntity; int x,y,dis; //如果消息已经被写坏了,则不执行 if(msg.bIsUsed ==false) { OutputMsg(rmError,"name=%s,msgid=%d,ProcessEntityMsg is invalid",GetEntityName(),(int)msg.nMsg); return ; } switch(msg.nMsg) { case CEntityMsg::emRealLaunchSkill: { m_skillSystem.RealLaunchSkill((int)msg.nParam1,(CScene*)msg.pParam2,(int)msg.nParam3, (int)msg.nParam4,(int)msg.nParam5,(CEntity *)msg.pParam6, (int)msg.nParam7,(int)msg.nParam8); } break; case CEntityMsg::emSkillApplyOneRange: { m_skillSystem.SkillApplyOneRange((int)msg.nParam1, (CSkillSubSystem::PSKILLDATA)msg.pParam2,(PSKILLONERANGE)msg.pParam3, (CEntity *)msg.pParam4,(CScene*)msg.pParam5,(int)msg.nParam6,(int)msg.nParam7, (int)msg.nParam8,(int)msg.nParam9,(int)msg.nParam10); } break; case CEntityMsg::emShowSceneEffect: { CDataPacket data(buff,sizeof(buff)); data << (BYTE)enDefaultEntitySystemID <<(BYTE) sAddSceneEffect ; data << (Uint64)msg.nSender; data << (WORD) msg.nParam1; //特效ID data << (WORD) msg.nParam2 << (WORD) msg.nParam3; //x,y m_observerSystem.BroadCast(data.getMemoryPtr(), data.getPosition(),true); } break; case CEntityMsg::emShowEntityEffect: { CDataPacket data(buff,sizeof(buff)); data << (BYTE)enDefaultEntitySystemID <<(BYTE) sAddEffect; data << (Uint64)msg.nSender << (Uint64)GetHandle(); data << (WORD) msg.nParam1; //特效ID data <<(unsigned int)msg.nParam3;// m_observerSystem.BroadCast(data.getMemoryPtr(), data.getPosition(),true); //m_effectSystem.AddEffect( msg.nParam1,msg.nParam2,msg.nParam3); //添加特效 } break; case CEntityMsg::emSkillResult: { CAnimal* pSrc = (CAnimal*)GetEntityFromHandle(msg.nSender); if (!pSrc) return; CSkillResult * result=m_skillSystem.GetSkillResult(); SKILLRESULTPARAM skillParam; //技能的参数 skillParam.pTargetEntity = this; skillParam.pSrcEntity = pSrc; skillParam.nSkillID = msg.nParam1; skillParam.nTargetPosX = (WORD)msg.nParam2; skillParam.nTargetPosY = (WORD)msg.nParam3; skillParam.btIgnoreDefence = (BYTE)msg.nParam4; skillParam.btIgnoreMaxDropHp = (BYTE)msg.nParam5; SKILLRESULT sresult; //技能的结果 sresult.nDelay = 0; sresult.nValue = msg.nParam5; sresult.nId = msg.nParam6; sresult.nResultType = msg.nParam7; skillParam.pSkillResult = &sresult; result->DoResult(&skillParam,true); //无延迟立刻执行 } break; case CEntityMsg::emChangeHp: if (msg.nParam1 > 0 || !IsDeath()) ChangeHP((int)msg.nParam1); break; case CEntityMsg::emReUseMonster: { Reuse(); break; } case CEntityMsg::emEntityTransfer: { int x,y; GetPosition(x,y); CObserverSystem* obs = GetObserverSystem(); TICKCOUNT tc = GetGlobalLogicEngine()->getTickCount(); obs->OnTimeCheck(tc);//先获取所有的可视玩家,因为在之前有可能被清空了 GetMoveSystem()->BroadcastMove(x,y,sActorTransport); break; } case CEntityMsg::emEntityScriptDelay: { OnEntityScriptDelayMsgCallback((unsigned int)(msg.nParam1), (int)msg.nParam2, (int)msg.nParam3, (int)msg.nParam4, (int)msg.nParam5, (int)msg.nParam6); break; } case CEntityMsg::emEntityDead: { if(GetProperty(PROP_CREATURE_HP) == 0) { OnEntityDeath(); } break; } case CEntityMsg::emRealTransfer: { GetGlobalLogicEngine()->GetFuBenMgr()->EnterFuBen(this,(CFuBen *)NULL,msg.nParam1,msg.nParam2,msg.nParam3); break; } default: Inherited::ProcessEntityMsg(msg); break; } } void CAnimal::DestroyAi() { if(m_pAI) { GetGlobalLogicEngine()->GetAiMgr().DestroyAi(m_pAI); //删除ai m_pAI =NULL; } } //初始化状态的禁止表,避免每次循环调用都去搞一下 void CAnimal::InitStateForbidMask() { if(s_stateForbidMask ) return ; //已经初始化好了 s_stateForbidMask = new unsigned int [esMaxStateCount]; //先都清0 memset(s_stateForbidMask,0,esMaxStateCount * sizeof(unsigned int)); //死亡状态 CAnimal::s_stateForbidMask[esStateDeath] = 0xFFFFFFFF; //死亡状态任何都禁止 unsigned int nMask=0; //移动状态禁止摆摊,打坐,和吟唱 CAnimal::SetFlag( nMask,esStateStall,true ); CAnimal::SetFlag( nMask,esStateSing,true ); CAnimal::s_stateForbidMask[esStateMove] = nMask; //禁止移动状态 nMask =0; CAnimal::SetFlag( nMask,esStateMove,true ); CAnimal::s_stateForbidMask[esStateMoveForbid] = nMask; //摆摊状态的一些禁止状态 nMask =0; CAnimal::SetFlag( nMask,esStateMove,true ); CAnimal::SetFlag( nMask,esStateSing,true ); CAnimal::s_stateForbidMask[esStateStall] = nMask; //晕眩状态 nMask =0; CAnimal::SetFlag( nMask,esStateMove,true ); CAnimal::SetFlag( nMask,esStateSing,true ); CAnimal::SetFlag( nMask,esStateStall,true ); CAnimal::s_stateForbidMask[esStateDizzy] = nMask; //吟唱状态 nMask = 0; CAnimal::SetFlag(nMask, esStateBattle, true); CAnimal::SetFlag(nMask, esStateSing, true); CAnimal::s_stateForbidMask[esStateSing] = nMask; } void CAnimal::DestroyStateForbidMask() { //删除这个静态变量 if(s_stateForbidMask != NULL) { delete[] s_stateForbidMask; } }; void CAnimal::Reuse() { //清除所有buff CBuffSystem* pBuff = GetBuffSystem(); if (pBuff) { pBuff->Clear(false); } //删除所有的消息 //ClearDelayDelEntityMsg(); //重置属性 GetPropertySystem().ResertProperty(); ClearDestoryTime(); } void CAnimal::Say(MonsterSayBCType nStyle, const char *pMsg, int tipType, unsigned int nLimitLev) { if (!pMsg || strlen(pMsg) <= 0) return; CVector vecNearEntityList, vecBCEntityList; switch (nStyle) { case mssNear: GetNearActorList(vecBCEntityList); break; case mssScene: GetSceneActorList(GetScene(), vecBCEntityList); break; case mssFuben: GetFubenActorList(vecBCEntityList); break; case mssWorld: GetWorldActorList(vecBCEntityList); break; case mssCamp: GetCampActorList(vecBCEntityList); break; case mssSelf: vecNearEntityList.add(GetHandle()); break; default: break; } INT_PTR nCount = 0; size_t nLen = 1024; // 对于阵营广播,直接广播在中间 CEntityManager* em = GetGlobalLogicEngine()->GetEntityMgr(); if (mssCamp == nStyle) { nCount = vecBCEntityList.count(); for (INT_PTR i = 0; i < nCount; i++) { CEntity *pEntity = em->GetEntity(vecBCEntityList[i]); if (pEntity && pEntity->GetType() == enActor && pEntity->GetProperty(PROP_CREATURE_LEVEL) >= nLimitLev) { ((CActor *)pEntity)->SendTipmsg(pMsg, tipType); } } return; } // 附近频道不在系统频道显示(如果当前是频道类型广播,并且当前不是附近频道) if(GetType() != enActor && (ttChatWindow & tipType) && nStyle != mssNear) { nCount = vecBCEntityList.count(); if (nCount <= 0) return; char buff[1124]={0}; CDataPacket outPack(buff,sizeof(buff)); outPack << (BYTE)enChatSystemID << (BYTE)sSendChat <<(BYTE)ciChannelSystem; outPack.writeString(GetEntityName()); if (strlen(pMsg) < nLen) nLen = strlen(pMsg); outPack.writeString(pMsg, nLen); outPack << (BYTE)0 << (BYTE)0 << (int)0 << (BYTE)0 << (BYTE)0 ; for (INT_PTR i = 0; i < nCount; i++) { CEntity *pEntity = em->GetEntity(vecBCEntityList[i]); if (pEntity && pEntity->GetType() == enActor && pEntity->GetProperty(PROP_CREATURE_LEVEL) >= nLimitLev) { ((CActor *)pEntity)->SendData(outPack.getMemoryPtr(), outPack.getPosition()); } } return; } // 附近头顶泡泡 CVector *pEntityList ; /* if(mssNear == nStyle) { GetNearActorList(vecNearEntityList); pEntityList = &vecNearEntityList; } else { pEntityList = &vecBCEntityList; } */ pEntityList = &vecBCEntityList; nCount = pEntityList->count(); if (nCount > 0) { //如果是玩家的话,比如拾取的时候给玩家的广播 if( GetType() == enActor) { for (INT_PTR i = 0; i < pEntityList->count(); i++) { CEntity *pEntity = em->GetEntity( (*pEntityList)[i]); if (pEntity && pEntity->GetType() == enActor && pEntity->GetProperty(PROP_CREATURE_LEVEL) >= nLimitLev) { ((CActor *)pEntity)->SendTipmsg(pMsg, tipType); } } return; } char buff[1124]={0}; CDataPacket outPack(buff,sizeof(buff)); bool isMonsterNearSay = (mssNear == nStyle); //是怪物在附近广播 if( isMonsterNearSay ) { outPack << (BYTE)enChatSystemID << (BYTE)sNonPlayerChatNear; outPack << (INT64)GetHandle(); if (strlen(pMsg) < nLen) nLen = strlen(pMsg); outPack.writeString(pMsg, nLen); outPack << (BYTE)(tipType == ttChatWindow ? 0 : 1); } for (INT_PTR i = 0; i < pEntityList->count(); i++) { CEntity *pEntity = em->GetEntity( (*pEntityList)[i]); if (pEntity && pEntity->GetType() == enActor &&pEntity->IsInited() && pEntity->GetProperty(PROP_CREATURE_LEVEL) >= nLimitLev) { if (isMonsterNearSay) { ((CActor *)pEntity)->SendData(outPack.getMemoryPtr(), outPack.getPosition()); } else { ((CActor *)pEntity)->SendTipmsg(pMsg, tipType); } } } } } void CAnimal::GetNearActorList(CVector &vecEntityList) { //GetGlobalLogicEngine()->GetFuBenMgr()->GetVisibleList(this,vecEntityList); //CObserverEntityList &otherList = GetObserverSystem()->GetVisibleList(); CObserverEntityList otherList; GetGlobalLogicEngine()->GetFuBenMgr()->GetVisibleList(this, otherList); { CLinkedListIterator iter(otherList); CLinkedNode *pNode = 0; for (pNode = iter.first(); pNode; pNode = iter.next()) { CEntity *pEntity = GetEntityFromHandle(pNode->m_Data.m_handle); if (pEntity && pEntity->GetType() == enActor) { vecEntityList.add(pEntity->GetHandle()); } } } } void CAnimal::GetSceneActorList(CScene *pScene, CVector &vecEntityList) { if (!pScene) return; CEntityManager* pEntityMgr = GetGlobalLogicEngine()->GetEntityMgr(); CEntityList &list = pScene->GetPlayList(); CLinkedListIterator it(list); CLinkedNode *pNode = NULL; for (pNode = it.first(); pNode; pNode = it.next()) { CEntity *pEntity = pEntityMgr->GetEntity(pNode->m_Data); if (pEntity && enActor == pEntity->GetType()) vecEntityList.add(pEntity->GetHandle()); } } void CAnimal::GetFubenActorList(CVector &vecEntityList) { CScene *pScene = GetScene(); if (!pScene) return; CFuBen *pFb = pScene->GetFuBen(); if (!pFb || !pFb->IsFb()) return; CFuBen::SceneList& list = pFb->GetSceneList(); for (INT_PTR i = 0; i < list.count(); i++) { CScene *pScene = list[i]; GetSceneActorList(pScene, vecEntityList); } } void CAnimal::GetWorldActorList(CVector &vecEntityList) { GetGlobalLogicEngine()->GetEntityMgr()->GetOnlineAcotrHandleList(vecEntityList); } void CAnimal::GetCampActorList(CVector &vecEntityList) { int nCampId = GetCampId(); if (nCampId == INVALID_CAMP_ID) return; CVector vecList; CEntityManager *pEntityMgr = GetGlobalLogicEngine()->GetEntityMgr(); pEntityMgr->GetOnlineAcotrHandleList(vecList); for (INT_PTR i = 0; i < vecList.count(); i++) { CActor *pActor = (CActor *)GetEntityFromHandle(vecList[i]); if (pActor && pActor->IsInited() && pActor->GetCampId() == nCampId) vecEntityList.push(vecList[i]); } } //发送复活戒指的CD时间 void CAnimal::SendReliveRingCd() { if(GetType() == enActor ) //玩家 { TICKCOUNT tickNow = GetLogicCurrTickCount(); if( m_nextHpReliveCd >= tickNow ) { CActorPacket pack ; ((CActor*)this)->AllocPacket(pack); pack << (BYTE) enEuipSystemID <<(BYTE)sSendReliveRingCd; pack << (unsigned short)(m_nextHpReliveCd - tickNow ); pack.flush(); } } } //设置麻痹 void CAnimal::SetDizzyTime(int nTime) { TICKCOUNT tickNow = GetLogicCurrTickCount(); m_nDizzyTime = tickNow + nTime; SetDizzyState(); } //更新救主灵刃特效以及当前CD时间 void CAnimal::UpdateJZLR() { std::vector::iterator iter = GetLogicServer()->GetDataProvider()->GetHallowthen().m_HallowsSSCMainInfo.vJZLRBuff.begin(); for (; iter != GetLogicServer()->GetDataProvider()->GetHallowthen().m_HallowsSSCMainInfo.vJZLRBuff.end(); ++iter) { CBuffProvider::BUFFCONFIG * pBUFFCONFIG = GetLogicServer()->GetDataProvider()->GetBuffProvider().GetBuff(*iter); if(pBUFFCONFIG) { CDynamicBuff* pDynamicBuff = GetBuffSystem()->GetBuff((GAMEATTRTYPE)pBUFFCONFIG->nType, pBUFFCONFIG->nGroup); if(!pDynamicBuff) { GetBuffSystem()->Append(*iter); } } } }