#include "StdAfx.h" #include "Creature.h" #include "SceneManager.h" #include "ItemManager.h" #include "Utils/QuestStarterDB.h" #include "ResourceManager.h" #include "Utils/QuestFinisherDB.h" #include "LocalPlayer.h" #include "ObjectManager.h" #include "Utils/QuestDB.h" #include "Effect/EffectManager.h" #include "Network/PacketBuilder.h" #include "../../../../SDBase/Public/UnitDef.h" #include "../../../../SDBase/Public/SpellDef.h" #include "../../../../SDBase/Public/CreatureDef.h" #include "ui/UIPlayerEquipment.h" #include "Console.h" #include "State/StateAttack.h" #include "State/StateIdle.h" #include "State/StateMove.h" #include "State/StateMoutMove.h" #include "AudioInterface.h" CCreature::CCreature(void) { m_typeid = TYPEID_UNIT; m_valuesCount = UNIT_END; _InitValues(); m_bQuestNpc = false; m_pkMonsterEffect[0] = NULL ; m_pkMonsterEffect[1] = NULL ; m_pkLastCollObject = NULL; m_fLastSafeZ = 0; m_Lastfaceing =0.0f; m_QuestFlag = eNone; m_bPet = false; m_spQuestStart = NULL; m_spQuestStartN = NULL; m_spQuestFinish = NULL; m_spQuestFinishN = NULL; m_Queststate = 0; } #include "UI/UIGamePlay.h" #include "UI/UChat.h" #include "UI/UISystem.h" CCreature::~CCreature(void) { if (m_bPet) { UPetDlg* pPetDlg = INGAMEGETFRAME(UPetDlg, FRAME_IG_PLAYERPETDLG); if (pPetDlg) { pPetDlg->OnPetPlayerDel(GetUInt64Value(UNIT_FIELD_CREATEDBY), GetUInt32Value(UNIT_FIELD_PETNUMBER)); } } if( EffectMgr ) { if (m_pkMonsterEffect[0]) { EffectMgr->ReleaseEffect(m_pkMonsterEffect[0]); m_pkMonsterEffect[0] = NULL ; } if (m_pkMonsterEffect[1]) { EffectMgr->ReleaseEffect(m_pkMonsterEffect[1]); m_pkMonsterEffect[1] = NULL ; } } if(!m_bClientObject) DetachFromScene(true); g_ResMgr->FreeNif(m_spQuestStart); m_spQuestStart = NULL; g_ResMgr->FreeNif(m_spQuestStartN); m_spQuestStartN = NULL; g_ResMgr->FreeNif(m_spQuestFinish); m_spQuestFinish = NULL; g_ResMgr->FreeNif(m_spQuestFinishN); m_spQuestFinishN = NULL; g_ResMgr->FreeNif(m_NPCFlagOBJ); m_NPCFlagOBJ = NULL; } AnimationID CCreature::GetNormalAttackAnimation(UINT uSerial) { if(!m_spActorManager) return INVALID_ANIMID; char szAnimName[128]; //const NiFixedString& RootPath = m_spActorManager->GetKFMTool()->GetModelPath(); //const char* Path = RootPath; //char* p = const_cast(strrchr(Path, '_')); //NIASSERT(p); //p++; //NiStrcpy(szAnimName, 128, "Action_"); //NiStrcpy(szAnimName + 7, 128 - 7, p); //p = strrchr(szAnimName, '.'); //NIASSERT(p); //*p = '\0'; //DWORD Serial = uSerial; //Serial = Serial %100; //if(Serial < 55) // Serial = 0; //else // Serial = 1; ////Classes eJobCls = (Classes)GetByte(UNIT_FIELD_BYTES_0,1); int serial = rand() & 1; NiSprintf(szAnimName, 128, "attack_%02d", serial + 1 ); AnimationID AnimID = GetAnimationIDByName(szAnimName); return AnimID; } void SoundStatusPrint(AudioSource* src, AudioSource::Status eStatus) { } BOOL CCreature::Create(const char* KFMFile, const char* Name) { if(!CreateActor(KFMFile, true)) { return FALSE; } NIASSERT(GetSceneNode()); if( m_uint32Values[UNIT_FIELD_CREATEDBY] == 0 && m_uint32Values[UNIT_FIELD_SUMMONEDBY] == 0) { if (Name) { if( m_uint32Values[UNIT_FIELD_CREATEDBY] == 0 && m_uint32Values[UNIT_FIELD_SUMMONEDBY] == 0) SetName(Name); }else { SetName("Unnamed_Monster"); } } return TRUE; } void CCreature::OnCreate(ByteBuffer* data, ui8 update_flags) { CCharacter::OnCreate(data, update_flags); *data >> m_Queststate; ui32 displayid = GetUInt32Value(UNIT_FIELD_DISPLAYID); std::string strFileName = ""; ItemMgr->GetDisplayInfo(displayid, strFileName, GetRace(), GetGender(), true); if(!strFileName.size()) { char szMsg[128]; NiSprintf(szMsg, 128,"Not found displayid[%u]
", displayid); ChatSystem->AppendChatMsg(CHAT_MSG_SYSTEM,szMsg); } ui32 entryid = GetUInt32Value(OBJECT_FIELD_ENTRY); std::string strCreatureName = ""; if(!ItemMgr->GetCreatureName(entryid, strCreatureName)) { strCreatureName = "name error"; } if(!Create(strFileName.c_str(), strCreatureName.c_str())) { char szMsg[128]; NiSprintf(szMsg, 128,"Not found creature[%s] model file[%s] display[%d]
", strCreatureName.c_str(), strFileName.c_str(), displayid); ChatSystem->AppendChatMsg(CHAT_MSG_SYSTEM,szMsg); } if (GetUInt32Value(UNIT_FIELD_DEATH_STATE)) { OnDeath(false); }else { ResetMovementFlags(); // 重置状态 ResetState(); m_bIsDead = false; } } void CCreature::OnActorLoaded(NiActorManager* pkActorManager) { CCharacter::OnActorLoaded(pkActorManager); NiAVObject* pkBoneNode = 0; pkBoneNode = GetSceneNode()->GetObjectByName("Dummy01"); if (pkBoneNode) RecursiveSetBones((NiNode*)pkBoneNode, 1); pkBoneNode = GetSceneNode()->GetObjectByName("Bip01 Spine1"); if(pkBoneNode) RecursiveSetBones((NiNode*)pkBoneNode, 2); m_kNamePosOffset = 0.0f; NiAVObject* pkNameOffset = GetSceneNode()->GetObjectByName("Dummy02"); float scale = GetFloatValue(OBJECT_FIELD_SCALE_X); if(pkNameOffset) { m_kNamePosOffset = pkNameOffset->GetTranslate().z * scale; } NiPoint3 kPos(0.0, 0.0, m_kNamePosOffset/scale + 1.f); GetNPCFlagOBJ( kPos ); ui32 entryid = GetUInt32Value(OBJECT_FIELD_ENTRY); if(g_pkQuestStarterDB->IsQuestNpc(entryid) || g_pkQuestFinisherDB->GetQuestByNpc(entryid)) { m_bQuestNpc = true; NiAVObjectPtr spAVO = g_ResMgr->LoadNif("Objects\\Effect\\EA0010.nif"); m_spQuestStart = NiDynamicCast(NiNode, spAVO); m_spQuestStart->SetAppCulled(true); m_spQuestStart->SetTranslate(kPos); GetSceneNode()->AttachChild(m_spQuestStart); spAVO = g_ResMgr->LoadNif("Objects\\Effect\\EA0009.nif"); m_spQuestStartN = NiDynamicCast(NiNode, spAVO); m_spQuestStartN->SetAppCulled(true); m_spQuestStartN->SetTranslate(kPos); GetSceneNode()->AttachChild(m_spQuestStartN); spAVO = g_ResMgr->LoadNif("Objects\\Effect\\EA0012.nif"); m_spQuestFinish = NiDynamicCast(NiNode, spAVO); m_spQuestFinish->SetAppCulled(true); m_spQuestFinish->SetTranslate(kPos); GetSceneNode()->AttachChild(m_spQuestFinish); spAVO = g_ResMgr->LoadNif("Objects\\Effect\\EA0011.nif"); m_spQuestFinishN = NiDynamicCast(NiNode, spAVO); m_spQuestFinishN->SetAppCulled(true); m_spQuestFinishN->SetTranslate(kPos); GetSceneNode()->AttachChild(m_spQuestFinishN); PacketBuilder->SendNpcGossipStatus(GetGUID()); } OnQuestStatus( m_Queststate ); GetSceneNode()->UpdateNodeBound(); GetSceneNode()->UpdateProperties(); GetSceneNode()->UpdateEffects(); GetSceneNode()->Update(0.0f); } void CCreature::GetNPCFlagOBJ(NiPoint3 pkPos) { CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (!pkLocal) { return ; } NiAVObjectPtr spAVO = NULL; if (pkLocal->IsHostile(this)) { return ; } ui32 pkCreatureFlag = GetUInt32Value(UNIT_NPC_FLAGS); if (pkCreatureFlag & UNIT_NPC_FLAG_NONE) { return ; }/*else if (pkCreatureFlag & UNIT_NPC_FLAG_TAXIVENDOR) { return ; //飞行管理员 }else if (pkCreatureFlag & UNIT_NPC_FLAG_INNKEEPER) { return ; //旅店老板 }*/else if (pkCreatureFlag & UNIT_NPC_FLAG_BANKER) { spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0007.nif"); //银行 }/*else if (pkCreatureFlag & UNIT_NPC_FLAG_ARENACHARTER) { return ; //竞技场 }else if (pkCreatureFlag & UNIT_NPC_FLAG_BATTLEFIELDPERSON) { return ; //战场 }*/else if (pkCreatureFlag & UNIT_NPC_FLAG_AUCTIONEER) { spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0006.nif"); //拍卖行 }/*else if (pkCreatureFlag & UNIT_NPC_FLAG_GUILD_BANK) { //工会银行 return ; }*/else if (pkCreatureFlag & UNIT_NPC_FLAG_MAIL) { spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0008.nif"); //邮件 }else if (pkCreatureFlag & UNIT_NPC_FLAG_TRANSPORTER) { //传送 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0010.nif"); }else if (pkCreatureFlag & UNIT_NPC_FLAG_GUILD) { //部族管理员 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0015.nif"); }else if (pkCreatureFlag & UNIT_NPC_FLAG_VENDOR_ZAHUO) { //杂货商 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0004.nif"); }else if (pkCreatureFlag & UNIT_NPC_FLAG_VENDOR_YAOSHUI) { //药水 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0005.nif"); }else if (pkCreatureFlag & UNIT_NPC_FLAG_VENDOR_WUQI) { //武器 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0001.nif"); }else if (pkCreatureFlag & UNIT_NPC_FLAG_VENDOR_FANGJU) { //防具 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0002.nif"); }else if (pkCreatureFlag & UNIT_NPC_FLAG_VENDOR_SHOUSHI) { //首饰 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0003.nif"); }else if (pkCreatureFlag & UNIT_NPC_FLAG_VENDOR_ZUOQI) { //坐骑 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0016.nif"); }else if (pkCreatureFlag & UNIT_NPC_FLAG_TRAINER_WUXIU) { //武修 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0011.nif"); }else if (pkCreatureFlag & UNIT_NPC_FLAG_TRAINER_YUJIAN) { //羽箭 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0014.nif"); }else if (pkCreatureFlag & UNIT_NPC_FLAG_TRAINER_XIANDAO) { //仙道 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0012.nif"); }else if (pkCreatureFlag & UNIT_NPC_FLAG_TRAINER_ZHENWU) { //真巫 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0013.nif"); }else if (pkCreatureFlag & UNIT_NPC_FLAG_JIAYUAN) { //家园 spAVO = g_ResMgr->LoadNif("Objects\\Effect\\Effect_mark_0009.nif"); } m_NPCFlagOBJ = NiDynamicCast(NiNode, spAVO); if (m_NPCFlagOBJ) { m_NPCFlagOBJ->SetAppCulled(false); m_NPCFlagOBJ->SetTranslate(pkPos); GetSceneNode()->AttachChild(m_NPCFlagOBJ); } } void CCreature::OnQuestStatus(uint32 uiQuestState) { if(uiQuestState == QMGR_QUEST_FINISHED || uiQuestState == QMGR_QUEST_REPEATABLE_FINISHED) SetQuestFlag(CCreature::eFinish); else if(uiQuestState == QMGR_QUEST_AVAILABLE || uiQuestState == QMGR_QUEST_CHAT || uiQuestState == QMGR_QUEST_REPEATABLE) SetQuestFlag(CCreature::eStart); else if(uiQuestState == QMGR_QUEST_NOT_FINISHED) SetQuestFlag(CCreature::eFinishN); else if(uiQuestState == QMGR_QUEST_AVAILABLELOW_LEVEL) SetQuestFlag(CCreature::eStartN); else SetQuestFlag(CCreature::eNone); } void CCreature::QueryQuestStatus() { PacketBuilder->SendNpcGossipStatus(GetGUID()); } void CCreature::OnValueChanged(class UpdateMask* mask) { CCharacter::OnValueChanged(mask); if( mask->GetBit(UNIT_FIELD_DISPLAYID) ) { ui32 displayid = GetUInt32Value(UNIT_FIELD_DISPLAYID); } if( mask->GetBit(UNIT_FIELD_HEALTH) ) { if( GetUInt32Value( UNIT_FIELD_HEALTH ) == 0 ) { } } if (mask->GetBit(UNIT_FIELD_DEATH_STATE)) { ui32 state = GetUInt32Value(UNIT_FIELD_DEATH_STATE) ; switch(state) { case JUST_DIED: { OnDeath(false); } break; case CORPSE: { OnDeath(true); } break; case DEAD: { } break; case ALIVE: { OnAlive(); } break; } } if(mask->GetBit(UNIT_FIELD_FLAGS)) { if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING)) //恐惧 { } else { } if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED)) //眩晕 { //AddEffect(UNIT_FLAG_STUNNED); } else if(m_UnitFlag & UNIT_FLAG_STUNNED) { //ReleaseEffect(UNIT_FLAG_STUNNED); } } if (mask->GetBit(UNIT_DYNAMIC_FLAGS)) { if(this->HasFlag(UNIT_DYNAMIC_FLAGS, U_DYN_FLAG_LOOTABLE)) { AddEffect(U_DYN_FLAG_LOOTABLE); } else if (m_UnitFlag & U_DYN_FLAG_LOOTABLE) { DelEffect(U_DYN_FLAG_LOOTABLE); } } //for( int i = 0; i < 40; i++ ) //{ // if( mask->GetBit(UNIT_FIELD_AURA+i) ) // { // // 设置或取消对应buf&debuf // if(GetUInt32Value(UNIT_FIELD_AURA+i)) // { // } // } //} UPetDlg* pPetDlg = INGAMEGETFRAME(UPetDlg, FRAME_IG_PLAYERPETDLG); if (pPetDlg) { if (mask->GetBit(UNIT_FIELD_CREATEDBY)) { ui64 playerGuid = GetUInt64Value(UNIT_FIELD_CREATEDBY); if (playerGuid) { pPetDlg->OnPetPlayerGuid(playerGuid, m_titleName); } } if (mask->GetBit(UNIT_FIELD_PETNUMBER)) { ui32 PetNum = GetUInt32Value(UNIT_FIELD_PETNUMBER); //if (PetNum) //{ pPetDlg->OnPetNumberChange(GetGUID(), GetUInt64Value(UNIT_FIELD_CREATEDBY), PetNum); pPetDlg->OnPetExperience(GetUInt32Value(UNIT_FIELD_PETEXPERIENCE), GetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP), PetNum); m_bPet = true; //} } } if( mask->GetBit(UNIT_FIELD_PET_FEED_TIME) ) { ui32 FeedTime = GetUInt32Value(UNIT_FIELD_PET_FEED_TIME); if(FeedTime == 0) { } else { ui32 LeftTime = (uint32)time(NULL) - FeedTime; if(LeftTime > 8*60*60) { // 可以在次喂养 } } } if( mask->GetBit(OBJECT_FIELD_SCALE_X) ) { float scale = GetFloatValue(OBJECT_FIELD_SCALE_X); if(m_spQuestStart && m_spQuestStartN && m_spQuestFinish && m_spQuestFinishN) { float offset = m_kNamePosOffset / scale ; NiPoint3 kPos(0.0, 0.0, offset + 1.0f); m_spQuestStart->SetTranslate(kPos); m_spQuestStartN->SetTranslate(kPos); m_spQuestFinish->SetTranslate(kPos); m_spQuestFinishN->SetTranslate(kPos); } } } void CCreature::AddEffect(UINT flag) { if (flag > 0 && !(m_UnitFlag & flag)) { if (m_pkMonsterEffect[0] == NULL) { m_pkMonsterEffect[0] = (CSceneEffect*)EffectMgr->CreateSceneEffect("Effect_pickup01.nif", true, true); if (m_pkMonsterEffect[0]) { m_pkMonsterEffect[0]->AttachToSceneObject(GetGUID()); m_pkMonsterEffect[0]->SetVisible(false); } } if (m_pkMonsterEffect[1] == NULL) { //由于特效已经放在技能脚本里。 //这里将不再显示. 所以这里暂时没用到..... } DelEffect(m_UnitFlag); switch(flag) { case U_DYN_FLAG_LOOTABLE: if (m_pkMonsterEffect[0]) { m_pkMonsterEffect[0]->SetVisible(true); } break; case UNIT_FLAG_STUNNED: if (m_pkMonsterEffect[1]) { m_pkMonsterEffect[1]->SetVisible(true); } break; } m_UnitFlag |= flag ; } } void CCreature::DelEffect(UINT flag) { if (flag > 0 && (m_UnitFlag & flag)) { m_UnitFlag &= ~flag; switch(flag) { case U_DYN_FLAG_LOOTABLE: if (m_pkMonsterEffect[0]) { m_pkMonsterEffect[0]->SetVisible(false); } break; case UNIT_FLAG_STUNNED: if (m_pkMonsterEffect[1]) { m_pkMonsterEffect[1]->SetVisible(false); } break; } } } void CCreature::SetIdleAnimation() { NiControllerSequence* Seq = SetCurAnimation("Idle"); //NIASSERT(Seq); if(Seq == NULL) return; NiTimeController::CycleType CT = Seq->GetCycleType(); if (CT == NiTimeController::CLAMP) { Seq->SetCycleType(NiTimeController::LOOP); } } void CCreature::SetWalkAnimation() { SetCurAnimation("Walk"); } void CCreature::SetRunAnimation() { if ( m_bPet ) { SetCurAnimation("Walk"); } else SetCurAnimation("Run"); } void CCreature::SetFacingLast() { SetDesiredAngle(m_positionO); } void CCreature::SetRecordLastFacing() { m_Lastfaceing = GetFacing(); } bool CCreature::GetPickBound(NiBound& kBound) { return CAnimObject::GetPickBound(kBound); } bool CCreature::IsPick(NiPick& kPicker,const NiPoint3& kOrig,const NiPoint3& kDir) { if (!GetSceneNode()) return false; return CAnimObject::IsPick(kPicker, kOrig, kDir); } BOOL CCreature::IsLootAble() { return HasFlag(UNIT_DYNAMIC_FLAGS, U_DYN_FLAG_LOOTABLE); } void CCreature::SetDialogAnimation() { NiControllerSequence* Seq = SetCurAnimation("dialog"); //NIASSERT(Seq); if(Seq == NULL) return; //Seq->SetCycleType(NiTimeController::LOOP); } bool CCreature::UpdateMoveTransform(float fTime, float fTimeDelta, float& fT) { bool bRet = false; NiPoint3 kStartPos, kDesiredPos; kStartPos = this->GetPosition(); NiPoint3 vDir = m_kMoveTarget - kStartPos; vDir.z = 0.0f; vDir.Unitize(); // xy plane NiPoint3 kDelta = fTimeDelta * vDir * GetMoveSpeed(); kDesiredPos = kStartPos + kDelta; NiPoint3 vOldVec = vDir; NiPoint3 vNewVec = m_kMoveTarget - kDesiredPos; vOldVec.z = vNewVec.z = 0.0f; vOldVec.Unitize(); vNewVec.Unitize(); CMap* pkMap = CMap::Get(); if(pkMap == NULL) return false; static NiPoint3 kExtent = NiPoint3(0.3f, 0.3f, 0.8f); if (!CanMove() || vOldVec.Dot(vNewVec) <= 0.001f) { kDesiredPos = m_kMoveTarget; bRet = true; if (m_bPet) // 如果是宠物 高度需要重新判断下 { bool Coll = false; NiPoint3 Start, End; Start = m_kMoveTarget + NiPoint3(0,0,2.f); End = m_kMoveTarget - NiPoint3(0,0,2.f); ResultList RList; Coll = pkMap->MultiCollideBox(Start, End , kExtent, RList); if (Coll) { Result result = RList[0]; float collz = Start.z + (End.z - Start.z)* result.fTime; if (result.fTime < 1.0f) { float hz = collz - kExtent.z; if ((hz - m_kMoveTarget.z) > 2.0f && result.pkCollObject != NULL) // exit z { }else { m_kMoveTarget.z = hz ; } } } } if ( !( IsStuned() || IsRoot()) ) { if ( fabs( m_kMoveTarget.z - kStartPos.z) > 5.f || CheckInWater() == WL_UNDER_WATER ) { SetPosition( m_kMoveTarget ); } else { kStartPos.z = m_kMoveTarget.z; if ( (m_kMoveTarget - kStartPos).Length() > 1.f ) { SetPosition( m_kMoveTarget ); } } } // 强制高度啦回来 StopMove(); return true; } float fMapH = pkMap->GetHeight(kDesiredPos.x, kDesiredPos.y); float fZ = kDesiredPos.z; ResultList resultList; float fH = fZ - fMapH ; if (fH < 0.f) { fH = 0.f; } NiPoint3 kStart, kEnd; kStart = kDesiredPos + NiPoint3(0, 0, 1.8f); NiPoint3 sc_kDownRay = NiPoint3(0, 0, 0.f - fH - 1.8f); bool bColl = false; bColl = pkMap->MultiCollideBox(kStart, kStart + sc_kDownRay, kExtent, resultList); if (bColl) { Result result = resultList[0]; NiPoint3 kCollPos = kStart + sc_kDownRay * result.fTime; if (result.fTime < 1.0f) { fZ = kCollPos.z - kExtent.z; if ((fZ - kDesiredPos.z) > 2.0f && result.pkCollObject != NULL) // exit z { fZ = kDesiredPos.z; m_pkLastCollObject = result.pkCollObject; } } } else { fZ = pkMap->GetHeight(kDesiredPos.x, kDesiredPos.y); } kDesiredPos.z = fZ; SetDirectionTo(kDesiredPos); kDesiredPos = CheckMoveable( kStartPos, kDesiredPos, false ); //kStartPos.z = m_kMoveTarget.z; //if ( ( m_kMoveTarget - kStartPos ).Length() > 5.f ) //{ // SetPosition( m_kMoveTarget ); //} //else SetPosition(kDesiredPos); return bRet; } bool CCreature::GetBaseMoveSpeed(float& value) const { uint32 entry = GetUInt32Value(OBJECT_FIELD_ENTRY); float fValue = 0; if( GetMoveState() == CMS_RUN) { return ItemMgr->GetCreatureRunSpeed(entry, value); } else if (GetMoveState() == CMS_WALK) { return ItemMgr->GetCreatureWalkSpeed(entry, value); } else { NIASSERT(0 && "unkown move type!"); return false; } return false; } BOOL CCreature::SetMoveAnimation(UINT Flags, BOOL bForceStart) { ui32 entry = GetUInt32Value(OBJECT_FIELD_ENTRY); float fAnimBaseSpeed = 0.0f; bool ret = GetBaseMoveSpeed(fAnimBaseSpeed); int index = 0; if (Flags == CMS_RUN) { Flags = CAG_RUN; if ( m_bPet ) { Flags = CAG_WALK; } index = 1; } else if (Flags == CMS_WALK) { Flags = CAG_WALK; index = 2; } else if(Flags == CMS_MOUNTRUN) { Flags = CAG_MOUNTRUN; } const char* szIdleAnimName = GetBaseAnimationName((ECHAR_ANIM_GROUP)Flags, index); float fSpeed = GetMoveSpeed(); if (fAnimBaseSpeed > 0.0f) { float fModleScal = GetSceneNode()->GetScale(); if ( fModleScal < 0.0001f) { fModleScal = 1.f; } float fFrequency = 1.f/fModleScal; m_pkMoveSeq = SetCurAnimation(szIdleAnimName, fFrequency, TRUE, TRUE, 1); } else m_pkMoveSeq = SetCurAnimation(szIdleAnimName,1.0, TRUE, TRUE, 1); /*if (m_pkMoveSeq != NULL && fAnimBaseSpeed > 0.0f) { float fSpeed = GetMoveSpeed(); NiBound bound; GetPickBound( bound ); float fModleScal = bound.GetRadius(); if ( fModleScal < 0.00001 ) { fModleScal = 1.f; } float fFrequency = fSpeed / ( fAnimBaseSpeed * fModleScal ); m_pkMoveSeq->SetFrequency(fFrequency); }*/ return m_pkMoveSeq != NULL; } void CCreature::MoveToPosition(const NiPoint3& kLocation, const NiPoint3& kTarget, const uint32& between, ECHAR_MOVE_STATE eMoveState) { StartForward(); m_kMoveTarget = kTarget; NiPoint3 ptCur = GetPosition(); ptCur.z = kLocation.z; if ( ( kLocation - ptCur ).Length() > 3.f ) { SetPosition( kLocation ); } NiPoint3 kDist = kTarget - kLocation; kDist.z = 0; float fNewSpeed = 0.0f; if (between > 0) fNewSpeed = kDist.Length()/((float)between*0.001f); else fNewSpeed = GetMoveSpeed(); if (eMoveState == CMS_RUN) { m_runSpeed = fNewSpeed; } else if (eMoveState == CMS_WALK) { m_walkSpeed = fNewSpeed; } // NIASSERT(m_moveSpeed >= 0.0f); if( GetCurPostureState() != STATE_MOVE ) SetNextState(STATE_MOVE, CUR_TIME); } void CCreature::SetQuestFlag(eQuestFlag eFlag) { if(!m_spQuestStart || !m_spQuestStartN || !m_spQuestFinish || !m_spQuestFinishN ) return; m_QuestFlag = eFlag; m_spQuestStart->SetAppCulled(true); m_spQuestStartN->SetAppCulled(true); m_spQuestFinish->SetAppCulled(true); m_spQuestFinishN->SetAppCulled(true); if (m_NPCFlagOBJ) { m_NPCFlagOBJ->SetAppCulled(true); } switch(eFlag) { case eStart: m_spQuestStart->SetAppCulled(false); break; case eStartN: m_spQuestStartN->SetAppCulled(false); break; case eFinish: m_spQuestFinish->SetAppCulled(false); break; case eFinishN: m_spQuestFinishN->SetAppCulled(false); break; case eNone: if (m_NPCFlagOBJ) { m_NPCFlagOBJ->SetAppCulled(false); } break; } } void CCreature::Update(float dt) { CCharacter::Update(dt); UpdateTransformbyChar( this ); if(IsFleeing() || IsStuned() || IsSleep()) return; //if(( IsRoot() || IsFrozen())) { CCharacter* pChar = GetTargetObject(); if(pChar) { SetDirectionTo(pChar->GetPosition()); } } } IStateProxy* CCreature::GetStateProxy(State StateID) { switch(StateID) { case STATE_IDLE: return StateIdle::Instance(); case STATE_ACTIONIDLE: return StateActionIdle::Instance(); case STATE_MOUNT_IDLE: return StateMoutIdle::Instance(); case STATE_DEATH: return StateDeath::Instance(); case STATE_MOVE: return StateMove::Instance(); case STATE_MOUNT_MOVE: return StateMountMove::Instance(); case STATE_NORMAL_ATTACK: return StateAttack::Instance(); case STATE_SKILL_ATTACK: return StateAttackSkill::Instance(); default: break; } return NULL; } void CCreature::StopMove() { CCharacter::StopMove(); m_kMoveTarget = GetPosition(); }