示例#1
0
void ZSurvival::UpdateNavMeshWeight(float fDelta)
{
	// NavMesh 가중치 업데이트
	if ((ZGetGame()->GetTime() - m_fLastWeightTime) >= 1.0f)
	{
#ifdef _DEBUG
		unsigned long int nLastTime = timeGetTime();
#endif

		RNavigationMesh* pNavMesh = ZGetGame()->GetWorld()->GetBsp()->GetNavigationMesh();		
		if (pNavMesh != NULL)
		{
			pNavMesh->ClearAllNodeWeight();
			ZNPCObjectMap* pNPCObjectMap = ZGetObjectManager()->GetNPCObjectMap();
			for(ZNPCObjectMap::iterator i = pNPCObjectMap->begin();i!=pNPCObjectMap->end();i++)
			{
				ZObject* pNPCObject = i->second;
				RNavigationNode* pNode = pNavMesh->FindClosestNode(pNPCObject->GetPosition());
				if (pNode)
				{
					float fWeight = pNode->GetWeight() + 1.0f;
					pNode->SetWeight(fWeight);
				}
			}
		}
		m_fLastWeightTime = ZGetGame()->GetTime();

	}

}
bool ZModule_PoisonDamage::Update(float fElapsed)
{
	ZObject* pObj = MDynamicCast(ZObject, m_pContainer);
	if (!pObj)
		_ASSERT(0);
	else
	{
		// ������ ���� DAMAGE_DELAY
		if(ZGetGame()->GetTime()>m_fNextDamageTime) {
			m_fNextDamageTime+=DAMAGE_DELAY;

			// ������ �ް� �ִ� ����Ʈ �׾����� ������ ���������� ���� ���¿����� ���δ�..
			if(pObj->IsDie()) {

				if( pObj->m_pVMesh->GetVisibility() < 0.5f ) {//����Ʈ�� Life Ÿ�ӵ� �����ϱ�...
					m_bOnDamage = false;
					return false;
				}

			}
			else //�����������..
			{
				// ������� ������Ʈ�� ���⼭ �����Ϸ��������� ����� ������ �ȵ� �ϴ� �ּ�ó���Ѵ�
				// 5 * (1.f-fPR) �̺κж����� zitem.xml���� damage="1"�κκ��� damage="6"�� �ϴ� ����
				//float fPR = 0;
				//float fDamage = 5 * (1.f-fPR) + (float)m_nDamage;

				pObj->OnDamaged(m_pOwner, pObj->GetPosition(), ZD_LIGHTNING, MWT_NONE, m_fDamage, 1);
				/*ZModule_HPAP *pModule = (ZModule_HPAP*)m_pContainer->GetModule(ZMID_HPAP);
				if(pModule) {
					pModule->OnDamage(m_pOwner,m_fDamage,1);
//					pObj->OnScream();
				}*/
			}
		}

		if(ZGetGame()->GetTime()>m_fNextEffectTime) {

			if(!pObj->IsDie())
			{
				int nEffectLevel = GetEffectLevel()+1;

				m_fNextEffectTime+=EFFECT_DELAY * nEffectLevel;

				ZGetEffectManager()->AddEnchantPoison2( pObj );
			}
		}
	}

	if(m_fNextDamageTime-m_fBeginTime>m_fDuration) {
		m_bOnDamage = false;
		return false;
	}
	return true;
}
示例#3
0
ZObject* ZObjectManager::Pick( rvector& pos, float Radius )
{
	ZObject* pPickObject = NULL;
	ZObject* pObject = NULL;
	float best_dist = Radius;

	for( iterator iter = begin(); iter != end(); ++iter )
	{
		pObject	= iter->second;

		auto vec = pObject->GetPosition() - pos;
		if (Magnitude(vec) < best_dist)
		{
			pPickObject	= pObject;
		}
	}
	return pPickObject;
}
bool ZEffectDash::Draw(unsigned long int nTime)
{
    ZObject *pTarget = ZGetGame()->m_ObjectManager.GetObject(m_uid);

    if(pTarget) {
        ZObserver *pObserver = ZGetGameInterface()->GetCombatInterface()->GetObserver();
        if(pObserver->IsVisible())
        {
            rvector pos,dir;
            pTarget->GetHistory(&pos,&dir,ZGetGame()->GetTime()-pObserver->GetDelay());
            m_Pos = pos;
        } else
            m_Pos = pTarget->GetPosition();
        return ZEffectAniMesh::Draw(nTime);
    }
    /*
    	if(m_pObj) {
    		m_Pos = m_pObj->GetPosition();
    	}

    	return ZEffectSlash::Draw(nTime);
    */
    return false;
}
示例#5
0
void ZBrain::ProcessBuildPath( float fDelta)
{
	// Update timer
	if ( !m_PathFindingTimer.Update( fDelta))
		return;
	
	// Check status
	ZTASK_ID nTaskID = m_pBody->m_TaskManager.GetCurrTaskID();
	if ( (nTaskID == ZTID_ATTACK_MELEE) || (nTaskID == ZTID_ATTACK_RANGE) || (nTaskID == ZTID_ROTATE_TO_DIR) || (nTaskID == ZTID_SKILL))
		return;

	// 맵에 끼었다면 벗어난다
	// 워프해서 끼임을 탈출하는 건 서바이벌일때만으로 제한한다 (워프는 눈에 크게 띄고 조악한 해결법이다. 기존 퀘스트에서 없던 몹워프가 일어나 유저 불만이 있음)
	if (ZGetGameTypeManager()->IsSurvivalOnly( ZGetGame()->GetMatch()->GetMatchType()))
	{
		if (EscapeFromStuckIn(m_WayPointList))
			return;
	}

	// Get target
	ZObject* pTarget = GetTarget();
	if ( !pTarget)
	{
		m_pBody->m_TaskManager.Clear();
		m_pBody->Stop();

		return;
	}


	// 원거리 공격이거나 우호적이면 넘 가까이 다가가지 않고 바라만 본다.
	if ( ( m_Behavior.GetOffenseType() == ZOFFENSETYPE_RANGE) || m_Behavior.IsFriendly())
	{
		// 거리를 구한다.
		float dist = MagnitudeSq( pTarget->GetPosition() - m_pBody->GetPosition());

		bool bStop = false;

		// Friendly type
		if ( m_Behavior.IsFriendly())
		{
			if ( dist < m_fDistForcedIn)
				bStop = true;
		}
		// Else type
		else
		{
			// 직선 거리를 본다.
			if ( ( dist > DIST_FORCEDIN) && (dist < m_fDistIn))
			{
				// 직선 거리는 가까운데 높이가 많이 차이가 나는지 본다.
				dist = pTarget->GetPosition().z - m_pBody->GetPosition().z;

				// 높이가 넘 많이 차이 안나면 정지
				if ( (dist > -DIST_HEIGHT) && (dist < DIST_HEIGHT))
					bStop = true;
			}
		}

		// Stop
		if ( bStop)
		{
			// 볼 수 있는 위치여야지 정지가 가능하다. 만약 안보인다면 뛰어가서 근접공격을 하도록 한다
			if ( m_pBody->CanSee( pTarget) && m_pBody->CanAttackRange( pTarget))
			{
				m_pBody->Stop();
				m_pBody->m_TaskManager.Clear();

				return;
			}
		}
	}


	// Make path
	RNavigationMesh* pNavMesh = ZGetGame()->GetWorld()->GetBsp()->GetNavigationMesh();
	if ( pNavMesh == NULL)
		return;

	// Make navigation path
	rvector tarpos = pTarget->GetPosition();
	if ( !pNavMesh->BuildNavigationPath( m_pBody->GetPosition(), tarpos))
		return;

	m_WayPointList.clear();
	for ( list<rvector>::iterator itor = pNavMesh->GetWaypointList().begin();  itor != pNavMesh->GetWaypointList().end();  ++itor)
		m_WayPointList.push_back( (*itor));


	AdjustWayPointWithBound(m_WayPointList, pNavMesh);

	PushWayPointsToTask();
}
示例#6
0
bool ZBrain::GetUseableSkill( int *pnSkill, MUID *puidTarget, rvector *pTargetPosition)
{
	// Get skill module
	ZModule_Skills *pmod = (ZModule_Skills *)m_pBody->GetModule(ZMID_SKILLS);
	if ( !pmod)
		return false;

	// Set value
	if ( puidTarget)
		(*puidTarget) = MUID(0,0);

	if (pTargetPosition)
		(*pTargetPosition) = rvector(0.0f,0.0f,0.0f);


	// Check skills
	for ( int i = 0;  i < pmod->GetSkillCount();  i++)
	{
		ZSkill *pSkill = pmod->GetSkill( i);

		// Check cool time
		if ( !pSkill->IsReady())
			continue;

		// Get skill description
		ZSkillDesc *pDesc = pmod->GetSkill( i)->GetDesc();


		// 스킬의 적용 대상이 아군인 경우...
		if ( pDesc->IsAlliedTarget())
		{
			// 효과가 있는 대상중 가까이 있는 걸 찾는다.
			float fDist = DIST_OUT;
			ZObject *pAlliedTarget = NULL;


			for ( ZObjectManager::iterator itor = ZGetObjectManager()->begin();  itor != ZGetObjectManager()->end();  ++itor)
			{
				ZObject *pObject = itor->second;

				// 죽은 놈은 넘어간다
				if ( pObject->IsDie())
					continue;

				// 적이면 넘어간다
				if ( ZGetGame()->CanAttack(m_pBody,pObject))
					continue;

				// 자기 자신이면 넘어간다
				if ( pObject == m_pBody)
					continue;


				// Get distance
				float dist = MagnitudeSq( pObject->GetPosition() - m_pBody->GetPosition());
				if ( pSkill->IsUsable( pObject) && ( dist < fDist))
				{
					fDist = dist;
					pAlliedTarget = pObject;
				}
			}	

			// 만약 대상이 없으면 자기 자신한테라도 스킬을 건다.
			if ( ( pAlliedTarget == NULL) && ( pSkill->IsUsable( m_pBody)))
				pAlliedTarget = m_pBody;

			if (pAlliedTarget)
			{
				if ( pnSkill)
					*pnSkill = i;
				
				if ( puidTarget)
					*puidTarget = pAlliedTarget->GetUID();

				if ( pTargetPosition)
					*pTargetPosition = pAlliedTarget->GetCenterPos();

				return true;
			}
		}

		// 스킬의 적용 대상이 적군인 경우...
		else
		{
			ZObject* pTarget = GetTarget();
			if ( pTarget == NULL)
				continue;

			// Check useable
			if ( !pSkill->IsUsable( pTarget))
				continue;

			// Get pick info
			ZPICKINFO pickinfo;
			memset( &pickinfo, 0, sizeof( ZPICKINFO));


			// Check picking
			rvector pos, tarpos, dir;
			// 적과 나의 몸통 실린더에서 가슴 정도의 높이 지점끼리 피킹 쏴본다..
			pos = m_pBody->GetPosition() + rvector( 0, 0, m_pBody->GetCollHeight()*0.5f*0.8f);		// 가슴께로 낮춰주려고 *0.8
			tarpos = pTarget->GetPosition() + rvector( 0, 0, pTarget->GetCollHeight()*0.5f*0.8f);
			dir = tarpos - pos;
			Normalize( dir);

			const DWORD dwPickPassFlag = RM_FLAG_ADDITIVE | RM_FLAG_HIDE | RM_FLAG_PASSROCKET | RM_FLAG_PASSBULLET;
			if ( ZGetGame()->Pick( m_pBody, pos, dir, &pickinfo, dwPickPassFlag))
			{
				if ( pickinfo.pObject)
				{
					if ( pnSkill)
						*pnSkill = i;

					if ( puidTarget)
						*puidTarget = pTarget->GetUID();

					if ( pTargetPosition)
						*pTargetPosition = pTarget->GetCenterPos();

					return true;
				}
			}
		}
	}

	return false;
}