#include "StdAfx.h" #include "HeroSystem.h" #include "../base/Container.hpp" template<> const CHeroSystem::Inherid::OnHandleSockPacket CHeroSystem::Inherid::Handlers[]= { &CHeroSystem::HandError, //占位 &CHeroSystem::HandGetHeroList, &CHeroSystem::HandHeroStageUp, &CHeroSystem::HandHeroSkillLevelUp, &CHeroSystem::HandChangeHeroName, &CHeroSystem::HandSetHeroState, &CHeroSystem::HandViewHero, &CHeroSystem::HandHeroLevelUp }; CHeroSystem::CHeroSystem() { Destroy(); m_fExpRate =0.0; } CHeroSystem::~CHeroSystem() { Destroy(); } //英雄DB数据 void CHeroSystem::OnDbRetData(INT_PTR nCmd,INT_PTR nErrorCode,CDataPacketReader & reader ) { if(m_pEntity ==NULL) { OutputMsg(rmError,_T("load Hero data error,m_pEntity ==NULL")); return ; } //如果DB的数据已经初始化好了,再收到数据不处理 if(nCmd == jxInterSrvComm::DbServerProto::dcLoadHeroData) //装载玩家的英雄数据 { if(HasDbDataInit() ) { OutputMsg(rmError,_T(" Hero data has loaded")); return ; } if(nErrorCode == jxInterSrvComm::DbServerProto::reSucc) { int nCount=0; reader >> nCount; if(nCount >0) { bool flag =true; HERODATA Hero; Hero.equips.clear(); Hero.skills.clear(); for ( int i=0; i< nCount; i++) { reader >> Hero.data; INT_PTR nPos = GetHeroPos (Hero.data.bID ); if(nPos >=0) { OutputMsg(rmError,_T("add Hero error ,has same Hero id=%d"),(int)Hero.data.bID ); continue; } m_heros.add(Hero); } } } else { OutputMsg(rmError,_T("load[%s]Hero data error,actorid=%u"),((CActor*)m_pEntity)->GetEntityName(),m_pEntity->GetProperty(PROP_ENTITY_ID)); } } else if(nCmd == jxInterSrvComm::DbServerProto::dcLoadHeroSkillData) //装载玩家的英雄技能 { if(HasDbDataInit() ) { OutputMsg(rmError,_T(" Hero data has loaded")); return ; } if(nErrorCode == jxInterSrvComm::DbServerProto::reSucc) { int nCount=0; reader >> nCount; if(nCount >0) { CSkillProvider *pSkillProvider = GetLogicServer()->GetDataProvider()->GetSkillProvider(); //技能数据读取器 CStdItemProvider & itemProvider = GetLogicServer()->GetDataProvider()->GetStdItemProvider(); //物品配置器 HEROSKILLDATA data; for ( int i=0; i< nCount; i++) { memset(&data,0,sizeof(data)); reader >> data; INT_PTR nPos = GetHeroPos (data.nHeroID); if(nPos <0) { OutputMsg(rmError,_T("Hero skill data errr,no Hero=%d"),data.nHeroID); } else { const SKILLONELEVEL * pLevel = pSkillProvider->GetSkillLevelData(data.nSkillID, data.nLevel); const OneSkillData *pConfig = pSkillProvider->GetSkillData(data.nSkillID); if(pLevel ==NULL || pConfig ==NULL) continue; m_heros[nPos].skills.add(data); } } } ((CActor*)m_pEntity)->OnFinishOneInitStep(eMSG_USR_LOGIN_DATA_HERO_SYSTEM); //完成一个步骤 OnDbInitData(); //这个时候才确定db的数据发生了修改 } else { OutputMsg(rmError,_T("load[%s]Hero skill data error,actorid=%d"),((CActor*)m_pEntity)->GetEntityName(),m_pEntity->GetProperty(PROP_ENTITY_ID)); } } } void CHeroSystem::ProcessNetData(INT_PTR nCmd,CDataPacketReader &packet ) { if(m_pEntity ==NULL) return; if(nCmd >=0 && nCmd *Handlers[nCmd] )(packet); } } void CHeroSystem::OnEnterGame() { CallbackBattleHero(false); } void CHeroSystem::OnEnterScene() { } void CHeroSystem::Destroy() { CEntity * pEntity; for(INT_PTR i=0; i< m_heros.count();i++) { m_heros[i].skills.clear(); m_heros[i].equips.clear(); pEntity =GetEntityFromHandle(m_heros[i].handle); if(pEntity) { GetGlobalLogicEngine()->GetEntityMgr()->DestroyEntity(m_heros[i].handle); } } m_heros.clear(); } void CHeroSystem::HandViewHero(CDataPacketReader &packet) { if(m_pEntity ==NULL) return; if (m_pEntity->HasMapAttribute(aaCannotViewOther)) { (m_pEntity)->SendOldTipmsgWithId(tpChatDisableOperator); return; } char msg[54]; packet.readString(msg,sizeof(msg)); msg[sizeof(msg) -1] =0; CActor * pActor = GetGlobalLogicEngine()->GetEntityMgr()->GetActorPtrByName(msg); if(pActor && pActor->IsInited()) { pActor->GetHeroSystem().ViewHeros(m_pEntity); //观察其他玩家的英雄 } else { ((CActor*)m_pEntity)->SendOldTipmsgWithId(tpChatTargetOffLine); } } //查看英雄 void CHeroSystem::ViewHeros(CActor * pActor) { if(m_pEntity ==NULL) return; if(pActor ==NULL || pActor->IsInited() ==false) return; INT_PTR nCount= m_heros.count(); if(nCount <=0 ) { pActor->SendOldTipmsgWithId(tpOtherHasNoHero,ttChatWindow ); return ; } //如果没有出战英雄,默认为第一个英雄 INT_PTR nHeroIndex =0; for(INT_PTR i=0; i< nCount; i++) { HERODATA & HERODATA = m_heros[i]; if( HERODATA.data.bState == psStateNormal) { nHeroIndex = i; break; } } HERODATA &hero = m_heros[nHeroIndex]; HERODBDATA & heroData = m_heros[nHeroIndex].data; CActorPacket actorData; CDataPacket& data = pActor->AllocPacket(actorData); data <<(BYTE)GetSystemID() << (BYTE)sHeroView; data << (BYTE) heroData.bID; //id data << (BYTE) heroData.bState; //状态 data << (BYTE) heroData.bStage; //阶 data << (BYTE) heroData.bLevel; //等级 data << (unsigned int)heroData.nExp; //当前经验 data << (int)heroData.nBodyforce; //当前体力 data << (int)heroData.nBless; //当前祝福 data.writeString(heroData.name); //名字 CVector & skills = m_heros[nHeroIndex].skills; data <<(BYTE) skills.count(); for(INT_PTR j=0;j < skills.count(); j++) { HEROSKILLDATA & skill =hero.skills[j]; data << (WORD) skill.nSkillID; data << (BYTE) skill.nLevel; } actorData.flush(); ((CActor*)m_pEntity)->PlayerViewNotice(pActor); } //计算英雄的属性 void CHeroSystem::CalHeroProp(HERODATA & Hero) { if(m_pEntity ==NULL) return; //英雄未出战,不计算属性 if(Hero.data.bState != psStateNormal) return; Hero.cal.reset(); CAttrCalc calc; PHEROLEVEL levelCfg = GetLogicServer()->GetDataProvider()->GetHeroConfig().GetHeroLevel(Hero.data.bID, Hero.data.bLevel); if(!levelCfg) return; for(int i = 0; i < levelCfg->attri.nCount ; i++) { calc << levelCfg->attri.pAttrs[i]; } for(INT_PTR i=0; i< Hero.skills.count(); i++) { ((CHero*)m_pEntity)->GetSkillSystem().CalcOneSkillAttr(Hero.skills[i].nSkillID,Hero.skills[i].nLevel,calc); } Hero.cal << calc; } //重载这个函数,初始化玩家的一些2级属性 bool CHeroSystem::Initialize(void *data,SIZE_T size) { if(m_pEntity ==NULL ) return false; return true; } void CHeroSystem::Save(PACTORDBDATA pData) { if(m_pEntity ==NULL) return; //保存英雄列表 size_t count; int nRawServerIndex = m_pEntity->GetRawServerIndex(); int nLoginServerIndex = GetLogicServer()->GetServerIndex(); if(m_HeroBasicDataHasModifed) { count = m_heros.count(); CDataPacket& HeroPacket =GetLogicServer()->GetDbClient()->allocProtoPacket(jxInterSrvComm::DbServerProto::dcSaveHeroData); HeroPacket << nRawServerIndex << nLoginServerIndex; HeroPacket <<(unsigned int ) m_pEntity->GetId(); //玩家ID HeroPacket << (int)count; //玩家技能的数量 for (int i=0; i< count; i ++ ) { HERODATA &hero = m_heros[i]; HeroPacket << hero.data; //只保持db需要的那部分 } GetLogicServer()->GetDbClient()->flushProtoPacket(HeroPacket); SetHeroDataModifyFlag(edHeroBasicData,false); } //保存英雄的技能列表 if(m_heroskillHasModified) { count =0; for(INT_PTR i=0; i< m_heros.count(); i++) { count += m_heros[i].skills.count(); } CDataPacket& skillPack =GetLogicServer()->GetDbClient()->allocProtoPacket(jxInterSrvComm::DbServerProto::dcSaveHeroSkillData); skillPack << nRawServerIndex << nLoginServerIndex; skillPack << (unsigned int ) m_pEntity->GetProperty(PROP_ENTITY_ID); //玩家ID skillPack << (int)count; //玩家技能的数量 for (INT_PTR i=0; i< m_heros.count(); i ++ ) { for(INT_PTR j=0;j < m_heros[i].skills.count(); j++) { skillPack << m_heros[i].skills[j]; //只保持db需要的那部分 } } GetLogicServer()->GetDbClient()->flushProtoPacket(skillPack); SetHeroDataModifyFlag(edHeroSkillData,false); } } void CHeroSystem::OnTimeCheck(TICKCOUNT nTickCount) { if(m_pEntity ==NULL) return; INT_PTR nCount =m_heros.count(); if(nCount <=0) return; for(INT_PTR i= nCount-1; i>-1; i--) { INT_PTR nState = m_heros[i].data.bState; if(nState ==psStateNormal) { CEntity *pHero = GetEntityFromHandle(m_heros[i].handle); if(pHero ) { bool hasHpMpChange =false; //HP,MP是否发生了改变 unsigned int nHp = pHero->GetProperty(PROP_CREATURE_HP); unsigned int nMp = pHero->GetProperty(PROP_CREATURE_MP); if(nHp >0) { if(m_heros[i].data.nHp != nHp) { m_heros[i].data.nHp = nHp; hasHpMpChange = true; } } if(m_heros[i].data.nMp != nMp) { m_heros[i].data.nMp = nMp; hasHpMpChange =true; } //数据发生了改变 if(hasHpMpChange) { SetHeroDataModifyFlag(edHeroBasicData,true); } } } } } //英雄属性附加到人物 CAttrCalc & CHeroSystem::CalcAttributes(CAttrCalc &cal) { for(INT_PTR i=0; i< m_heros.count(); i++) { if ( m_heros[i].data.bState == psStateMerge) //附体属性 { cal << m_heros[i].mergeCal; //附体 } } return cal; } //是否能增加英雄 bool CHeroSystem::CanAddHero(bool bWithTipmsg) { if(m_pEntity ==NULL) return false; int nMaxCount = GetLogicServer()->GetDataProvider()->GetHeroConfig().GetHeroMaxCount(); bool flag= m_heros.count() < nMaxCount; if(!flag && bWithTipmsg) { m_pEntity->SendOldTipmsgWithId(tpHeroCanNotGetMore,ttChatWindow); } return flag; } //添加英雄 int CHeroSystem::AddHero(int nHeroId, int nStage, int nLevel) { if(m_pEntity ==NULL) return -1; if(!CanAddHero() || GetHeroPos(nHeroId) >= 0) return -1; PHEROCONFIG HeroCfg = GetLogicServer()->GetDataProvider()->GetHeroConfig().GetHeroData(nHeroId); PHEROSTAGE StageCfg = GetLogicServer()->GetDataProvider()->GetHeroConfig().GetHeroStage(nHeroId, nStage); if(!HeroCfg || !StageCfg) return - 1; HERODATA hero; HERODBDATA &heroData =hero.data; int nOldCount = (int)m_heros.count(); heroData.bStage = (BYTE)__max(nStage,1); heroData.bLevel = (BYTE)__max(nLevel,1); heroData.bID = nHeroId; heroData.bVocation = enVocWarrior; //默认为战士 heroData.nModel = StageCfg->nModel; heroData.nWeaponAppear = StageCfg->nWeapon; heroData.nBodyforce = StageCfg->nGiveForce; //创建时系统给于的体力值 strncpy(heroData.name, HeroCfg->name,sizeof(heroData.name)); m_heros.add(hero); SendHeroData(hero); SetHeroDataModifyFlag(edHeroBasicData,true); LogHero(GameLog::clHeroAdd, (int)heroData.bID, (int)nOldCount, m_heros.count()); ResetAllHeroProperty(); return heroData.bID; } //下发英雄数据 void CHeroSystem::HandGetHeroList(CDataPacketReader &packet) { if(m_pEntity ==NULL) return; CActorPacket pack; CDataPacket & data = ((CActor*)m_pEntity)->AllocPacket(pack); data << (BYTE)GetSystemID() << (BYTE)sHeroList; INT_PTR nCount= m_heros.count(); data << (BYTE)nCount; for(INT_PTR i=0; i< nCount; i++) { HERODBDATA & heroData = m_heros[i].data; HERODATA &hero = m_heros[i]; data << (BYTE) heroData.bID; //id data << (BYTE) heroData.bState; //状态 data << (BYTE) heroData.bStage; //阶 data << (BYTE) heroData.bLevel; //等级 data << (unsigned int)heroData.nExp; //经验 data << (int)heroData.nBodyforce; //体力 data << (int)heroData.nBless; //祝福 data.writeString(heroData.name); //名字 } pack.flush(); SendAllSkills(); } //下发英雄的技能 void CHeroSystem::SendAllSkills() { if(m_pEntity ==NULL) return; INT_PTR nCount=0; for(INT_PTR i=0;i < m_heros.count(); i++) { nCount += m_heros[i].skills.count(); } CActorPacket pack; CDataPacket & data = ((CActor*)m_pEntity)->AllocPacket(pack); data << (BYTE)GetSystemID() << (BYTE)sHeroSkillList; data << (BYTE)nCount; for(INT_PTR i=0;i < m_heros.count(); i++) { for(INT_PTR j=0;j < m_heros[i].skills.count(); j++) { HEROSKILLDATA & skill = m_heros[i].skills[j]; pack << (BYTE) skill.nHeroID; pack << (WORD) skill.nSkillID; pack << (BYTE) skill.nLevel; } } pack.flush(); } //获取战斗中的英雄 CHero * CHeroSystem::GetBattleHeroPtr() { for(INT_PTR i=0 ;i < m_heros.count(); i++) { if(m_heros[i].data.bState ==psStateNormal) { return (CHero*) GetEntityFromHandle(m_heros[i].handle); } } return NULL; } //获取战斗中的英雄ID int CHeroSystem::GetBattleHeroId() { for(INT_PTR i=0;i > bHeroID ; INT_PTR nPos = GetHeroPos(bHeroID) ; if(nPos <0) return ; char name[32]; packet.readString(name,sizeof(name)); if( GetGlobalLogicEngine()->GetChatMgr().Filter(name) >0) { m_pEntity->SendOldTipmsgWithId(tpInputIsForbid,ttFlyTip); return; } ChangeHeroName(nPos,name); } void CHeroSystem::ChangeHeroName(INT_PTR nPos,char * name) { if(m_pEntity ==NULL) return; HERODATA &Hero = m_heros[nPos]; HERODBDATA &data = Hero.data; if(strcmp(name,data.name) ==0 ) return ; if(strlen(name) == 0) { m_pEntity->SendOldTipmsgWithId(tpHeroNameIsEmpty,ttFlyTip); return; } for (int i=0; i < strlen(name); i++) { if (name[i] == '"' || name[i] == '\\' || name[i] == '\''|| name[i] == '\''|| name[i] == '\''|| name[i] == '\'') { m_pEntity->SendOldTipmsgWithId(tpInputIsForbid,ttFlyTip); return; } } strncpy(data.name,name,sizeof(data.name)); SendHeroData(Hero); //如果英雄已出战 if(data.bState ==psStateNormal) { CHero *pHero =(CHero*) GetEntityFromHandle(m_heros[nPos].handle); if(pHero ) { char sName[50]; sprintf_s(sName,sizeof(sName),"%s\\%s",name, m_pEntity->GetEntityName()); pHero->SetEntityName(data.name); pHero->SetShowName(sName); pHero->ChangeName(sName); } } LogHero(GameLog::clHeroChangeName, data.bID, 0, 0); SetHeroDataModifyFlag(edHeroBasicData,true); m_pEntity->SendOldTipmsgWithId(tpHeroChangeNameSuccess,ttFlyTip); } //英雄事件 void CHeroSystem::TriggerEvent(INT_PTR nSubEvent,INT_PTR nParam1,INT_PTR nParam2,INT_PTR nParam3,INT_PTR nParam4) { if(m_pEntity ==NULL) return; CScriptValueList paramList; //((CActor*)m_pEntity)->InitEventScriptVaueList(paramList,aeHero); paramList << (int)nSubEvent; if(nParam1 >=0) { paramList << (int)nParam1; if(nParam2 >=0) { paramList << (int)nParam2; if(nParam3 >=0) { paramList << (int)nParam3; if(nParam4 >=0) { paramList << (int)nParam4; } } } } ((CActor*)m_pEntity)->OnEvent(aeHero,paramList,paramList); } //英雄学习技能 bool CHeroSystem::LearnSkill(int nHeroID, int nSkillID) { if(m_pEntity ==NULL) return false; INT_PTR nPos = GetHeroPos(nHeroID) ; if(nPos <0) return false ; HERODATA &Hero = m_heros[nPos]; if(GetSkillLevel(nHeroID,nSkillID) > 0 ) { return false; } HEROSKILLDATA data; data.nHeroID = nHeroID; data.nSkillID = nSkillID; data.nLevel =1; CSkillProvider *pSkillProvider = GetLogicServer()->GetDataProvider()->GetSkillProvider(); const SKILLONELEVEL * pLevel = pSkillProvider->GetSkillLevelData(data.nSkillID, data.nLevel); const OneSkillData *pConfig = pSkillProvider->GetSkillData(data.nSkillID); if(pLevel ==NULL || pConfig ==NULL) return false; Hero.skills.add(data); CActorPacket pack; CDataPacket & dataPack = ((CActor*)m_pEntity)->AllocPacket(pack); dataPack << (BYTE)GetSystemID() << (BYTE)sHeroSkillUpdate; dataPack << (BYTE)nHeroID; //英雄的ID dataPack << (WORD)nSkillID; //技能的ID dataPack << (BYTE)data.nLevel; //技能的等级 pack.flush(); //如果处于战斗状态的话,英雄立即学习技能 if(Hero.data.bState == psStateNormal) { CHero *pHero = (CHero*)GetEntityFromHandle(Hero.handle); if(pHero) { //if(!pConfig->bIsDelete) //{ pHero->GetSkillSystem().LearnSkill(nSkillID,1,false,true,true); pHero->GetAI()->RefreshSkillDis(); //} TriggerEvent(OpHeroBattle,nHeroID,nSkillID, 1); //script run ResetProperty(nPos); } } //记录日志 LogHero(GameLog::clHeroLearnSkill, nHeroID,nSkillID,1); SetHeroDataModifyFlag(edHeroSkillData,true); return true; } //英雄技能升级 void CHeroSystem::HandHeroSkillLevelUp(CDataPacketReader &packet) { if(m_pEntity ==NULL) return; BYTE bHeroID=0; WORD wSkillId =0; packet >> bHeroID >> wSkillId ; INT_PTR nPos = GetHeroPos(bHeroID) ; if(nPos <0) return ; int nLevel = GetSkillLevel(bHeroID,wSkillId); if(nLevel <=0 ) { m_pEntity->SendOldTipmsgFormatWithId(tpHeroSkillNotActivate, ttFlyTip); return; } CSkillProvider *pSkillProvider = GetLogicServer()->GetDataProvider()->GetSkillProvider(); const SKILLONELEVEL * pLevel = pSkillProvider->GetSkillLevelData(wSkillId, nLevel+1); if(pLevel == NULL ) { m_pEntity->SendOldTipmsgFormatWithId(tpHeroSkillLevelFull, ttFlyTip); return; } TriggerEvent(OpHeroUpSkill,bHeroID,wSkillId,nLevel); //script run } bool CHeroSystem::SkillLevelUp(int nHeroId,int nSkillId) { if(m_pEntity ==NULL) return false; INT_PTR nPos = GetHeroPos(nHeroId) ; if(nPos <0) return false ; int nSkillLevel = GetSkillLevel(nHeroId,nSkillId); if(nSkillLevel <= 0) return false; nSkillLevel = nSkillLevel + 1; //已达到最高技能等级 CSkillProvider *pSkillProvider = GetLogicServer()->GetDataProvider()->GetSkillProvider(); const OneSkillData *pConfig = pSkillProvider->GetSkillData(nSkillId); const SKILLONELEVEL * pLevel = pSkillProvider->GetSkillLevelData(nSkillId, nSkillLevel); if(pConfig ==NULL || pLevel ==NULL ) return false; HERODATA &Hero = m_heros[nPos]; CVector &skills = Hero.skills; for(INT_PTR i=0;i < skills.count(); i++) { if(skills[i].nSkillID == nSkillId) { skills[i].nLevel += 1; //记录日志 LogHero(GameLog::clHeroSkillLevelUp, nHeroId, nSkillId, skills[i].nLevel); break; } } CActorPacket pack; CDataPacket & dataPack = ((CActor*)m_pEntity)->AllocPacket(pack); dataPack << (BYTE)GetSystemID() << (BYTE)sHeroSkillUpdate ; dataPack << (BYTE)nHeroId; dataPack << (WORD)nSkillId; dataPack << (BYTE)nSkillLevel; pack.flush(); //如果处于战斗状态的话,英雄立即学习技能 if(Hero.data.bState == psStateNormal) { CHero *pHero = (CHero*)GetEntityFromHandle(Hero.handle); if(pHero) { //if(!pConfig->bIsDelete) //{ pHero->GetSkillSystem().LearnSkill(nSkillId,nSkillLevel,false,true,true); pHero->GetAI()->RefreshSkillDis(); //} TriggerEvent(OpHeroBattle,nHeroId,nSkillId, nSkillLevel); //script run ResetProperty(nPos); //重置属性 } } SetHeroDataModifyFlag(edHeroSkillData,true); m_pEntity->SendOldTipmsgFormatWithId(tpHeroSkillLevelUp,ttTipmsgWindow,Hero.data.name, GetLogicServer()->GetDataProvider()->GetSkillProvider()->GetSkillNameById(nSkillId), nSkillLevel); return true; } //获取英雄等级 int CHeroSystem::GetSkillLevel(int nHeroId, int nSkillId) { INT_PTR nPos = GetHeroPos(nHeroId) ; if(nPos <0) return -1 ; HERODATA &Hero = m_heros[nPos]; CVector &skills = Hero.skills; for(INT_PTR i=0;i < skills.count(); i++) { if(skills[i].nSkillID == nSkillId) { return skills[i].nLevel; } } return -1 ; } //英雄升级 void CHeroSystem::HandHeroLevelUp(CDataPacketReader &packet) { TriggerEvent(OpHeroLevelUp); } //英雄升阶 void CHeroSystem::HandHeroStageUp(CDataPacketReader &packet) { BYTE bHeroID=0; BYTE bCount =0; packet >> bHeroID >> bCount; INT_PTR nPos = GetHeroPos(bHeroID) ; if(nPos <0) return ; HERODATA &Hero = m_heros[nPos]; TriggerEvent(OpHeroUpStage,bHeroID,Hero.data.bStage,Hero.data.nBless,bCount); //script run } bool CHeroSystem::StageUp(int nHeroId, int nStage, int nBless) { if(m_pEntity ==NULL) return false; INT_PTR nPos = GetHeroPos(nHeroId) ; if(nPos <0) return false; HERODATA &Hero = m_heros[nPos]; int nOldStage = Hero.data.bStage; CHeroProvider &provider = GetLogicServer()->GetDataProvider()->GetHeroConfig(); PHEROCONFIG heroCfg = provider.GetHeroData(nHeroId); PHEROSTAGE stageCfg = provider.GetHeroStage(nHeroId,nStage); if(!heroCfg || !stageCfg) return false; Hero.data.bStage = nStage; if(nBless > stageCfg->nMaxBless) { Hero.data.nBless = stageCfg->nMaxBless; }else { Hero.data.nBless = nBless; } Hero.data.nModel = stageCfg->nModel; //升阶改变英雄模型 Hero.data.nWeaponAppear = stageCfg->nWeapon; SendHeroData(Hero); ResetProperty(nPos,false,true); SetHeroDataModifyFlag(edHeroBasicData,true); LogHero(GameLog::clHeroStageUp, (int)Hero.data.bID, nOldStage, nStage); ResetAllHeroProperty(); return true; } //下发英雄数据(创建&&更新) void CHeroSystem::SendHeroData(HERODATA &Hero) { if(m_pEntity ==NULL) return; CActorPacket pack; CDataPacket & data = ((CActor*)m_pEntity)->AllocPacket(pack); data << (BYTE)GetSystemID() << (BYTE)sHeroUpdate; data << (BYTE) Hero.data.bID; //id data << (BYTE) Hero.data.bState; //状态 data << (BYTE) Hero.data.bStage; //阶 data << (BYTE) Hero.data.bLevel; //等级 data << (unsigned int)Hero.data.nExp; //当前经验 data << (int)Hero.data.nBodyforce; //当前体力 data << (int)Hero.data.nBless; //当前祝福 data.writeString(Hero.data.name); //名字 pack.flush(); } //收回英雄 bool CHeroSystem::SetHeroSleep(INT_PTR nHeroId,bool bClient) { if(m_pEntity ==NULL) return false; INT_PTR nPos = GetHeroPos(nHeroId); if(nPos <0) return false; HERODATA & Hero = m_heros[nPos]; INT_PTR nCurrentState = Hero.data.bState; if( nCurrentState== psStateNormal) //战斗状态 { GetGlobalLogicEngine()->GetEntityMgr()->DestroyEntity(Hero.handle); Hero.handle =0; m_pEntity->CollectOperate(CEntityOPCollector::coRefAbility); //重新刷能力,玩家的属性发生了改变 } else if(nCurrentState == psStateMerge) //如果当前是合体状态的话 { m_pEntity->CollectOperate(CEntityOPCollector::coRefAbility); //重新刷能力,玩家的属性发生了改变 m_pEntity->RemoveState(esStateHeroMerge); //去除附体状态 } Hero.data.bState = psStateSleep; if(bClient) { SendHeroStateChange(nPos); } SetHeroDataModifyFlag(edHeroBasicData,true); return true; } //玩家Death时英雄的处理 void CHeroSystem::OnDeath() { for(INT_PTR i=0;i < m_heros.count();i ++) { if(m_heros[i].data.bState == psStateNormal) { SetHeroSleep(m_heros[i].data.bID,true); } } } //下发英雄经验 void CHeroSystem::SetClientHeroExp(HERODATA &Hero) { if(m_pEntity ==NULL) return; CActorPacket pack; CDataPacket & dataPack = ((CActor*)m_pEntity)->AllocPacket(pack); dataPack << (BYTE)GetSystemID() << (BYTE)sHeroExpChange ; dataPack << (BYTE)Hero.data.bID << (unsigned int) Hero.data.nExp; pack.flush(); } //下发英雄状态 void CHeroSystem::SendHeroStateChange(INT_PTR nPos) { if(m_pEntity ==NULL) return; if(nPos <0 || nPos >= m_heros.count()) return; HERODBDATA &data = m_heros[nPos].data; CActorPacket pack; CDataPacket & dataPack = ((CActor*)m_pEntity)->AllocPacket(pack); dataPack << (BYTE)GetSystemID() << (BYTE)sHeroStateChange ; dataPack << (BYTE)data.bID << (BYTE) data.bState; pack.flush(); SetHeroDataModifyFlag(edHeroBasicData,true); } //英雄被攻击 void CHeroSystem::OnAttacked(CAnimal *pEntity) { CHero * pHero; for(INT_PTR i=0; i< m_heros.count(); i++) { if(m_heros[i].data.bState ==psStateNormal) { pHero= (CHero*)GetEntityFromHandle(m_heros[i].handle); if(pHero &&pHero->GetAI()) { pHero->GetAI()->AttackedBy(pEntity); } } } } //英雄攻击 void CHeroSystem::OnAttackOther(CAnimal * pEntity) { CHero * pHero; for(INT_PTR i=0; i< m_heros.count(); i++) { if(m_heros[i].data.bState ==psStateNormal) { pHero= (CHero*)GetEntityFromHandle(m_heros[i].handle); if(pHero &&pHero->GetAI()) { pHero->GetAI()->AttackedBy(pEntity); } } } } //英雄跟随 void CHeroSystem::FollowEntity(CAnimal *pActor) { CHero * pHero; for(INT_PTR i=0; i< m_heros.count(); i++) { if(m_heros[i].data.bState ==psStateNormal) { pHero= (CHero*)GetEntityFromHandle(m_heros[i].handle); if(pHero &&pHero->GetAI()) { if (pHero->GetMoveSystem()->GetMotionType() == CMovementSystem::mtMotionTypeChase) { pHero->GetMoveSystem()->PopCurrentMotionState(); } pHero->GetAI()->EnterEvadeMode();//退出战斗 pHero->GetMoveSystem()->MoveFollow(pActor); } } } } //英雄获得打怪经验 void CHeroSystem::OnAddExp(unsigned int nExp,bool boRate, int nHeroId) { for(INT_PTR i=0;i = m_heros.count()) return false; HERODATA &Hero= m_heros[nPos]; HERODBDATA &data = Hero.data; int nHeroId = data.bID; int nStage = data.bStage; int nLevel = data.bLevel; CHeroProvider &provider = GetLogicServer()->GetDataProvider()->GetHeroConfig(); PHEROSTAGE stageCfg = provider.GetHeroStage(nHeroId,nStage); PHEROLEVEL levelCfg = provider.GetHeroLevel(nHeroId, nLevel); BOOL boLevelUp = false; unsigned int nRealAddExp = 0; if(nAddExp > 0 && stageCfg && levelCfg) { bool boLoop = true; while (boLoop) { levelCfg = provider.GetHeroLevel(nHeroId, data.bLevel); if(!levelCfg) { boLoop = false; break; } //已达本阶最高级 if(data.bLevel >= stageCfg->nMaxLevel) { boLoop = false; if( (data.nExp + nAddExp) > levelCfg->nLevelUpExp) { nRealAddExp += levelCfg->nLevelUpExp - (unsigned int)data.nExp; data.nExp = levelCfg->nLevelUpExp; }else { nRealAddExp += nAddExp; data.nExp += nAddExp; } break; }else { //可以升级了 if((data.nExp + nAddExp) >= (unsigned int)levelCfg->nLevelUpExp) { BYTE nNewLevel = data.bLevel + 1; PHEROLEVEL nextLevelCfg = provider.GetHeroLevel(nHeroId, nNewLevel); if(nextLevelCfg) { boLevelUp = true; data.bLevel = nNewLevel; int nDecExp = (unsigned int)levelCfg->nLevelUpExp - (unsigned int)data.nExp; data.nExp = 0; //升级后经验需要归0 nRealAddExp += nDecExp; nAddExp -= nDecExp; }else { boLoop = false; } }else { data.nExp += nAddExp; nRealAddExp += nAddExp; boLoop = false; } } } if(nRealAddExp > 0) { if(m_fExpRate > 0.0) { int nRateValue = (int)( (nRealAddExp / (1 + m_fExpRate)) * m_fExpRate ); m_pEntity->SendOldTipmsgFormatWithId(tpHeroGetExpRate, ttTipmsgWindow,nRealAddExp,nRateValue); }else { m_pEntity->SendOldTipmsgFormatWithId(tpHeroGetExp, ttTipmsgWindow,nRealAddExp); } } if(boLevelUp) { CHero *pHero = (CHero*)GetEntityFromHandle(Hero.handle); if (pHero) { pHero->SetLevel(data.bLevel); } ResetProperty(nPos); SendHeroData(Hero); LogHero(GameLog::clHeroUpgrade, data.bID, nLevel, data.bLevel); } SetHeroDataModifyFlag(edHeroBasicData,true); SetClientHeroExp(Hero); return true; } return false; } //重置所有英雄属性 void CHeroSystem::ResetAllHeroProperty(bool bNewHero,bool bRefeshAppear) { for(INT_PTR i=0; i < m_heros.count();i ++) { ResetProperty(i, bNewHero, bRefeshAppear); } } //重置英雄属性 void CHeroSystem::ResetProperty(INT_PTR nHeroPos,bool boNewHero ,bool boRefAppear) { if (nHeroPos < 0 || nHeroPos >= m_heros.count()) return; HERODATA &Hero = m_heros[nHeroPos]; CalHeroProp(Hero); if(Hero.data.bState == psStateNormal) //如果处于出战状态,需要刷新属性 { CHero * pHero = (CHero*)(GetEntityFromHandle(Hero.handle)); if(pHero) { //最大hp, mp unsigned int nMaxHp = (unsigned int)Hero.cal.m_AttrValues[aMaxHpAdd].nValue; //最大hp unsigned int nMaxMp = (unsigned int)Hero.cal.m_AttrValues[aMaxMpAdd].nValue; //最大mp pHero->SetProperty(PROP_CREATURE_MAXHP, nMaxHp); pHero->SetProperty(PROP_CREATURE_MAXMP, nMaxMp); pHero->CollectOperate(CEntityOPCollector::coRefAbility); pHero->SetLevel(Hero.data.bLevel); pHero->GetAI()->RefreshSkillDis(); if(boRefAppear) { pHero->SetProperty(PROP_ENTITY_MODELID,Hero.data.nModel); pHero->SetProperty(PROP_ACTOR_WEAPONAPPEARANCE,Hero.data.nWeaponAppear); } } } } //英雄出战 bool CHeroSystem::SetHeroBattle(INT_PTR nHeroId,bool boClient) { if(m_pEntity ==NULL) return false; INT_PTR nPos = GetHeroPos(nHeroId); if(nPos <0) return false; HERODATA & Hero = m_heros[nPos]; PHEROCONFIG HeroCfg = GetLogicServer()->GetDataProvider()->GetHeroConfig().GetHeroData((int)nHeroId); PHEROLEVEL LevelCfg = GetLogicServer()->GetDataProvider()->GetHeroConfig().GetHeroLevel(Hero.data.bID, Hero.data.bLevel); if(!HeroCfg && !LevelCfg) return false; //已出战的其他英雄收回 CallbackBattleHero(boClient); HERODBDATA & data= Hero.data; CScene *pScene = m_pEntity->GetScene(); if(pScene ==NULL) return false; int nPosX,nPosY; m_pEntity->GetPosition(nPosX,nPosY); //已经放出了一个英雄 CEntity* pEntity =GetEntityFromHandle(Hero.handle); if(pEntity != NULL) { return false; } //创建一个英雄 int nNewPosX = 0, nNewPosY = 0; pScene->GetEntityAppearPos(nPosX, nPosY, 4,nNewPosX, nNewPosY); if(nNewPosX > 0 && nNewPosY > 0) { pEntity = pScene->CreateEntityAndEnterScene(nHeroId,enHero,nNewPosX,nNewPosY,data.bLevel,m_pEntity); }else { pEntity = pScene->CreateEntityAndEnterScene(nHeroId,enHero,nPosX,nPosY,data.bLevel,m_pEntity); } if(pEntity ==NULL) return false; CHero *pHero = (CHero*) pEntity; Hero.data.bState = psStateNormal; Hero.handle = pEntity->GetHandle(); //计算英雄属性 CalHeroProp(Hero); char sAllName[512]; sprintf_s(sAllName,sizeof(sAllName),"%s\\%s",data.name, m_pEntity->GetEntityName()); pHero->SetEntityName(data.name); pHero->SetShowName(sAllName); //设置模型,hp,mp(用属性值的填充) pEntity->SetProperty(PROP_ENTITY_MODELID,data.nModel); pEntity->SetProperty(PROP_ACTOR_WEAPONAPPEARANCE,data.nWeaponAppear); CAttrCalc &cal = Hero.cal; unsigned int nMaxHp = (unsigned int)cal.m_AttrValues[aMaxHpAdd].nValue; //最大hp unsigned int nMaxMp = (unsigned int)cal.m_AttrValues[aMaxMpAdd].nValue; //最大mp pEntity->SetProperty(PROP_CREATURE_MAXHP, nMaxHp); pEntity->SetProperty(PROP_CREATURE_HP, nMaxHp); pEntity->SetProperty(PROP_CREATURE_MP,nMaxMp); pEntity->SetProperty(PROP_CREATURE_MAXMP,nMaxMp); Hero.nBaseMaxHp = nMaxHp; Hero.nBaseMaxMp = nMaxMp; Hero.fExpRate = HeroCfg->fExpRate; pHero->InitAi(); if( pHero->GetAI() ==NULL) { OutputMsg(rmError,"hero InitAi fail, hero id = %d",data.bID); return false; } int nAttackSpd = pHero->GetProperty(PROP_CREATURE_ATTACK_SPEED); if(nAttackSpd > 0) { pHero->SetAttackInterval(nAttackSpd); } pEntity->SetInitFlag(true); //立即学习技能 for(INT_PTR i=0;i < Hero.skills.count(); i++) { int nSkillId = Hero.skills[i].nSkillID; int nSkillLevel = Hero.skills[i].nLevel; CSkillProvider *pSkillProvider = GetLogicServer()->GetDataProvider()->GetSkillProvider(); const OneSkillData *pConfig = pSkillProvider->GetSkillData(nSkillId); //if(!pConfig->bIsDelete) //{ pHero->GetSkillSystem().LearnSkill(nSkillId,nSkillLevel,false,true,true); //} TriggerEvent(OpHeroBattle,nHeroId,nSkillId, nSkillLevel); //script run } pHero->GetAI()->RefreshSkillDis(); //重新刷新技能 pHero->GetAttriFlag().DenyAutoAddHp = false; //允许回血 pHero->GetAttriFlag().DenyAutoAddMp = false; //允许回蓝 pHero->GetAttriFlag().DenyUseNearAttack =false; //支持肉搏 if(boClient) { SendHeroStateChange(nPos); } return true; } void CHeroSystem::HandSetHeroState(CDataPacketReader &packet) { if(m_pEntity ==NULL) return; BYTE bHeroId=0,bState =0; packet >> bHeroId >> bState ; INT_PTR nPos = GetHeroPos(bHeroId) ; if(nPos <0) return ; HERODATA &Hero = m_heros[nPos]; HERODBDATA &data = Hero.data; if(data.bState == bState)return; if(bState == psStateNormal) { CScene *pScene = m_pEntity->GetScene(); int x, y; m_pEntity->GetPosition(x,y); if (pScene && pScene->HasMapAttribute(x, y, aaNotCallHero)) { m_pEntity->SendOldTipmsgFormatWithId(tpCannotCallHeroInTheArea, ttFlyTip); return; } CHeroProvider &provider = GetLogicServer()->GetDataProvider()->GetHeroConfig(); PHEROCONFIG HeroCfg = provider.GetHeroData(bHeroId); if(HeroCfg) { if(data.nBodyforce < HeroCfg->nBattleForce) { m_pEntity->SendOldTipmsgFormatWithId(tpHeroBattleForceLacking, ttFlyTip); return; } data.nBodyforce = data.nBodyforce - HeroCfg->nBattleForce; SetHeroDataModifyFlag(edHeroBasicData,true); SendHeroData(Hero); SetHeroBattle(bHeroId); } } else if(bState == psStateSleep) { SetHeroSleep(bHeroId); } ResetAllHeroProperty(); } //收回所有出战英雄 void CHeroSystem::CallbackBattleHero(bool boClient) { for(int i = 0; i < m_heros.count(); i++) { if(m_heros[i].data.bState ==psStateNormal) { SetHeroSleep(m_heros[i].data.bID,boClient); } } } //跨天清除祝福值 void CHeroSystem::EveryDayClearBless() { for(int i= 0; i < m_heros.count(); i++) { HERODATA &Hero = m_heros[i]; CHeroProvider &provider = GetLogicServer()->GetDataProvider()->GetHeroConfig(); PHEROSTAGE stage = provider.GetHeroStage(Hero.data.bID, Hero.data.bStage); if(stage && stage->boEveryDayClearBless) { Hero.data.nBless = 0; SetHeroDataModifyFlag(edHeroBasicData,true); SendHeroData(Hero); } } } //英雄 合体 bool CHeroSystem::SetHeroMerge(INT_PTR nHeroId,bool bClient) { return true; }