#include "StdAfx.h" #include "PosConstraintEffect.h" #include "Character.h" #include "ClientApp.h" #include "ObjectManager.h" #include "PlayerInputMgr.h" #include "Map/Map.h" PosConstraintEffect::PosConstraintEffect(CCharacter* pkObject) : m_pkObj(pkObject) { m_fSpeed = 0.0f; m_fTotalT = 0.0f; m_uiCharID = 0; setidle = false; pathmove = false; setpos = false; constraintstate = false; m_lockcount = 0; } PosConstraintEffect::~PosConstraintEffect() { //m_pkObj = 0; CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (pkLocal->GetGUID() == m_uiCharID) { m_pkObj = pkLocal; if (constraintstate) { EndUpdate(); } for( int i = 0; i < m_lockcount; ++i ) { if(SYState()->LocalPlayerInput ) { SYState()->LocalPlayerInput->UnlockMove(); SYState()->LocalPlayerInput->UnlockAttack(); } } } } void PosConstraintEffect::SetTarget(ui64 charid) { m_uiCharID = charid; m_pkObj = (CCharacter*)ObjectMgr->GetObject(m_uiCharID); } void PosConstraintEffect::Update(float fTimeLine, float fDeltaTime) { SetCurTime(fTimeLine); if (IsDead()) { unsigned int uiCount = m_kCallbacks.GetSize(); for (unsigned int ui = 0; ui < uiCount; ui++) m_kCallbacks.GetAt(ui)->ActivationChanged(this, false); m_pkObj = (CCharacter*)ObjectMgr->GetObject(m_uiCharID); if (m_pkObj) { EndUpdate(); } Deactivate(); return; } UpdateEffect(fTimeLine, fDeltaTime); } bool PosConstraintEffect::Rush(NiPoint3& src, NiPoint3& dest, float speed) { m_srcPos = src; m_destPos = dest; m_fSpeed = speed; m_pkObj = (CCharacter*)ObjectMgr->GetObject(m_uiCharID); if (!m_pkObj) return false; //只有是本地玩家操作,才回设置锁定状态 CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (pkLocal && m_uiCharID == pkLocal->GetGUID()) { SYState()->LocalPlayerInput->LockMove(); SYState()->LocalPlayerInput->LockAttack(); ++m_lockcount; // m_bLocked = true; } m_iSaveState = m_pkObj->GetMoveState(); NiPoint3 kLength = m_destPos - m_srcPos; if (speed > 0.0f) { m_fTotalT = kLength.Length() / speed; // SetMaxLife(m_fTotalT); } else { return false; } setidle = true; pathmove = true; setpos = true; constraintstate = true; if (constraintstate) { m_pkObj->SetMovementFlag( 1 ); if ( m_pkObj->GetGameObjectType() == GOT_PLAYER ) { CPlayer* pPlayer = (CPlayer*)m_pkObj; pPlayer->EmptyMovement(); } m_pkObj->ForceStateChange(STATE_CONSTRAINT, 0); if (m_pkObj->GetAsPlayer() && m_pkObj->isMount()) { if (m_pkObj->IsMountPlayer()) { m_pkObj->GetMountFoot()->ForceStateChange(STATE_CONSTRAINT, 0); m_pkObj->GetMountFoot()->MoveTo(m_destPos, CMF_None, false); } if (m_pkObj->IsMountCreature()) { m_pkObj->GetMountCreature()->ForceStateChange(STATE_CONSTRAINT, 0); } } } m_pkObj->SetMoveState(CMS_RUSH); if ( m_pkObj->GetGameObjectType() == GOT_PLAYER ) { CPlayer* pPlayer = (CPlayer*)m_pkObj; pPlayer->EmptyMovement(); } m_pkObj->MoveTo(m_destPos, CMF_None, false); m_pkObj->m_rushSpeed = m_fSpeed; return true; } bool PosConstraintEffect::Teleport(float minrange, float maxrange) { if (!m_pkObj) return false; NiPoint3 target; bool done = false; do { float frand1, frand2; frand1 = (float)rand()/RAND_MAX; frand2 = (float)rand()/RAND_MAX; float randangle = frand1*NI_TWO_PI; float dist = minrange + frand2 * (maxrange - minrange); float sn, cs; NiSinCos(randangle, sn, cs); NiPoint3 randvec, tar; randvec = NiPoint3(sn, cs, 0); tar = randvec * dist; NiPoint3 curpos = m_pkObj->GetPosition(); float startz, tarz; NiPoint3 s, e; startz = curpos.z; s = NiPoint3(target.x, tar.y, startz + 10.0f); e = NiPoint3(target.x, tar.y, startz - 10.0f); NiPoint3 extent(0.1f, 0.1f, 0.1f); ResultList ret; bool col = CMap::Get()->MultiCollideBox(s, e, extent, ret); if (col) { tarz = s.z + (e.z-s.z)*ret[0].fTime; if (tarz - startz <= 2.0f) { done = true; target = tar; target.z = tarz; } } } while (done); return true; } void PosConstraintEffect::EndUpdate() { m_pkObj->StopMove(); if (setidle) { //骑宠状态下的动作 if (m_pkObj->IsDead()) { //m_pkObj->ForceStateChange(STATE_DEATH, 0 ); m_pkObj->SetMoveState(CMS_RUN); }else if (m_pkObj->GetAsPlayer() && m_pkObj->GetAsPlayer()->isMount()) { m_pkObj->ForceStateChange(STATE_MOUNT_IDLE, CUR_TIME); if (m_pkObj->IsMountPlayer()) { m_pkObj->GetMountFoot()->ForceStateChange(STATE_MOUNT_IDLE, CUR_TIME); } if (m_pkObj->IsMountCreature()) { m_pkObj->GetMountCreature()->ForceStateChange(STATE_IDLE, CUR_TIME); } m_pkObj->SetMoveState((ECHAR_MOVE_STATE)m_iSaveState); }else { m_pkObj->ForceStateChange(STATE_IDLE, CUR_TIME); m_pkObj->SetMoveState(CMS_RUN); } }else { m_pkObj->SetMoveState(CMS_RUN); } if (setpos) { NiPoint3 cp = m_destPos; NiPoint3 s, e; float tarz; s = NiPoint3(cp.x, cp.y, cp.z + 5.0f); e = NiPoint3(cp.x, cp.y, cp.z - 5.0f); NiPoint3 extent(0.1f, 0.1f, 0.1f); ResultList retList; if (CMap::Get()->MultiCollideBox(s, e, extent, retList)) tarz = s.z + (e.z-s.z)*retList[0].fTime; cp.z = tarz; m_pkObj->SetPosition(cp); } constraintstate = false; CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (pkLocal && m_uiCharID == pkLocal->GetGUID()) { SYState()->LocalPlayerInput->UnlockMove(); SYState()->LocalPlayerInput->UnlockAttack(); --m_lockcount; // m_bLocked = false; } } void PosConstraintEffect::UpdateEffect(float fTimeLine, float fDeltaTime) { NiPoint3 kCurPos; m_pkObj = (CCharacter*)ObjectMgr->GetObject(m_uiCharID); if (!m_pkObj) { //如果对象没有 Deactivate(); return; } if (m_pkObj->IsLocalPlayer()) { //在切换地图的时候,冲撞如果仍旧计算会导致本地玩家的位置错乱 CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (pkLocal->GetIsChangMap()) { pathmove = false ; setpos = false; EndUpdate(); setidle = false ; Deactivate(); return ; } } if (m_pkObj->IsDead()) { // 死亡后. 不设置各种状态的更新 pathmove = false ; setpos = false; setidle = false; EndUpdate(); // 死亡后 位置设置为冲撞目标位置 NiPoint3 cp = m_destPos; NiPoint3 s, e; float tarz; s = NiPoint3(cp.x, cp.y, cp.z + 5.0f); e = NiPoint3(cp.x, cp.y, cp.z - 5.0f); NiPoint3 extent(0.1f, 0.1f, 0.1f); ResultList retList; if (CMap::Get()->MultiCollideBox(s, e, extent, retList)) tarz = s.z + (e.z-s.z)*retList[0].fTime; cp.z = tarz; //m_pkObj->SetPosition(cp); m_pkObj->SetMoveState(CMS_RUN); Deactivate(); return; } if (pathmove) m_pkObj->PathMoveUpdate(fTimeLine); float fAlpha = GetElapsed()/m_fTotalT; if (fAlpha >= 1.0f) { EndUpdate(); Deactivate(); } }