Exemplo n.º 1
0
/* virtual */ void COrder_Still::OnAnimationAttack(CUnit &unit)
{
	CUnit *goal = this->GetGoal();
	if (goal == NULL) {
		return;
	}
	if (IsTargetInRange(unit)(goal) == false) {
		this->ClearGoal();
		return;
	}

	FireMissile(unit, goal, goal->tilePos);
	UnHideUnit(unit);
}
Exemplo n.º 2
0
/* virtual */ void COrder_Still::OnAnimationAttack(CUnit &unit)
{
	if (unit.CanAttack(false) == false) {
		return;
	}
	
	CUnit *goal = this->GetGoal();
	if (goal == nullptr) {
		return;
	}
	if (IsTargetInRange(unit)(goal) == false) {
		this->ClearGoal();
		return;
	}

	FireMissile(unit, goal, goal->tilePos, goal->MapLayer->ID);
	UnHideUnit(unit);
	unit.StepCount = 0;
}
Exemplo n.º 3
0
/***********************************************************
process child
***********************************************************/
void NPCHandler::ProcessChild(double tnow, float tdiff)
{
	bool animfinished = false;

	// process attack script
	if(_fightscriptrunning)
	{
		//process NPC animation
		int pout = _character->Process(tnow, tdiff);
		animfinished = (pout == 1);


		if(_weaponanimating)
		{
			// wait until prepare weapon anim finished before processing with attack script
			if(animfinished)
				_weaponanimating = false;
		}
		else
		{
			if(!_fightscriptpartrunning && m_scripthandler && m_attackfunctionname != "")
				m_scripthandler->RunAttackScript(GetId(), m_attackfunctionname);
		}
	}
	else
	{
		//process char in case we are not scripted
		if(m_paused || m_launchedscript < 0)
		{
			int pout = _character->Process(tnow, tdiff);
			animfinished = (pout == 1);
		}
	}

	//target players that are too close
	if(_aggresive && _targetedattackplayer < 0)
	{
		//todo - target player that are too close
	}

	//flag saying if we should move according to animations
	bool movewithanimation = false;

	//in case of hurt
	if(_agentstatenum == 2)
	{
		if(animfinished)
		{
			#ifdef _DEBUG_NPC_
			filecheck<<SynchronizedTimeHandler::GetTimeString()<<" "<<"hurt finished"<<std::endl;
			#endif

			// revert back to previous state
			if(ChangeState(_savedstate))
				UpdateActorAnimation(_savedanim, false, false);		
		}
		else
			movewithanimation = true;
	}

	// in case of use weapon
	if(_agentstatenum == 6)
	{
		if(animfinished)
		{
			#ifdef _DEBUG_NPC_
			filecheck<<SynchronizedTimeHandler::GetTimeString()<<" "<<"use weapon finished"<<std::endl;
			#endif

			//stop hurt player
			m_currenthitpower = -1;
			_immuneplayers.clear();

			// inform script
			YieldRunningScript();	
		}
		else
			movewithanimation = true;
	}

	// in case we rotate to target
	if(_agentstatenum == 7)
	{
		float rotdiff = GetTargetRotationDiff();
		if(fabs(rotdiff) <= m_rotationtargettolerance)
		{
			#ifdef _DEBUG_NPC_
			filecheck<<SynchronizedTimeHandler::GetTimeString()<<" "<<"rotate finished"<<std::endl;
			#endif

			// inform script
			YieldRunningScript();
		}
		else
		{
			//rotate to direction
			boost::shared_ptr<PhysicalObjectHandlerBase> physo = _character->GetPhysicalObject();
			if(physo)
			{
				if((rotdiff > 0 && rotdiff < 180) || (rotdiff < -180))
					physo->RotateYAxis(std::min((m_rotationtargetspeed*tdiff), (float)(fabs(rotdiff))));	
				else
					physo->RotateYAxis(std::max((-m_rotationtargetspeed*tdiff), (float)(-fabs(rotdiff))));
			}
		}
	}




	// move agent depending of animation
	if(movewithanimation)
	{
		boost::shared_ptr<PhysicalObjectHandlerBase> physo = _character->GetPhysicalObject();
		boost::shared_ptr<DisplayObjectHandlerBase> disso = _character->GetDisplayObject();

		// get animation speed
		float speedX = disso->GetCurrentAssociatedSpeedX();
		float speedY = disso->GetCurrentAssociatedSpeedY();
		float speedZ = disso->GetCurrentAssociatedSpeedZ();

		LbaQuaternion Q;
		physo->GetRotation(Q);
		LbaVec3 current_directionX(Q.GetDirection(LbaVec3(0, 0, 1)));
		LbaVec3 current_directionZ(Q.GetDirection(LbaVec3(1, 0, 0)));
		float ajustedspeedx = speedX*current_directionX.x + speedZ*current_directionZ.x;
		float ajustedspeedZ = speedX*current_directionX.z + speedZ*current_directionZ.z;

		if(speedX != 0 || speedY != 0 || speedZ != 0)
			physo->Move(ajustedspeedx*tdiff, speedY*tdiff, ajustedspeedZ*tdiff, false);
	}


	//if dead - respawn
	if(_agentState->IsDead() && _respwantime >= 0)
	{
		if((tnow - _dietime) > (_respwantime*1000))
		{
			Respawn();
		}
	}

	//if chasing
	if(_agentstatenum == 4)
	{
		// check if we arrive at destination
		if(IsTargetInRange(m_minimalchasingdistance))
		{
			// inform script
			YieldRunningScript();	
		}
		else
		{
			//check if did not get stuck
			if((tnow-_lastchasingchecktime) > 500)
			{
				boost::shared_ptr<PhysicalObjectHandlerBase> physo = _character->GetPhysicalObject();
				if(physo)
				{
					float checkX, checkY, checkZ;
					physo->GetPosition(checkX, checkY, checkZ);

					float diff =	fabs(checkX-_lastchasingcheckposX) +
									fabs(checkY-_lastchasingcheckposY) +
									fabs(checkZ-_lastchasingcheckposZ);

					if(diff < 0.3f)
					{
						//reset target
						if(_targetedattackplayer > 0 && m_NavMAgent && m_scripthandler)
						{
							LbaVec3 pos = m_scripthandler->GetPlayerPositionVec((long)_targetedattackplayer);
							m_NavMAgent->SetTargetPosition(false, pos.x, pos.y, pos.z);
						}
					}

					_lastchasingcheckposX = checkX;
					_lastchasingcheckposY = checkY;
					_lastchasingcheckposZ = checkZ;
				}

				_lastchasingchecktime = tnow;
			}
		}
	}

	//if coming back
	if(_agentstatenum == 5)
	{
		//check if we arrived
		boost::shared_ptr<PhysicalObjectHandlerBase> physo = _character->GetPhysicalObject();
		if(physo)
		{
			float curX, curY, curZ;
			physo->GetPosition(curX, curY, curZ);
			float diff = fabs(m_saved_X-curX) + fabs(m_saved_Y-curY) + fabs(m_saved_Z-curZ);
			if(diff <= 0.6f)
			{
				//rotate back to starting point
				ChangeState(8);
			}
			else if((tnow-_lastchasingchecktime) > 500)//check if did not get stuck
			{
				float difftt =	fabs(curX-_lastchasingcheckposX) +
								fabs(curY-_lastchasingcheckposY) +
								fabs(curZ-_lastchasingcheckposZ);

				//reset target
				if(difftt < 0.3f && m_NavMAgent)
				{
					++_counterresetchasing;
					if(_counterresetchasing >= 8)
					{
						//stop chasing if we get stuck too long
						ChangeState(8);
					}
					else
						m_NavMAgent->SetTargetPosition(false, m_saved_X, m_saved_Y, m_saved_Z);
				}

				_lastchasingcheckposX = curX;
				_lastchasingcheckposY = curY;
				_lastchasingcheckposZ = curZ;


				_lastchasingchecktime = tnow;
			}
		}
	}

	//if rotating back
	if(_agentstatenum == 8)
	{
		//check if we arrived
		boost::shared_ptr<PhysicalObjectHandlerBase> physo = _character->GetPhysicalObject();
		if(physo)
		{
			float currrot = physo->GetRotationYAxis();

			float rdiff = fmod((m_saved_rot - currrot), 360);
			if(rdiff > 180)
				rdiff = rdiff - 360;
			if(rdiff < -180)
				rdiff = rdiff + 360;

			if(fabs(rdiff) <= 4)
			{
				EndChasing();
			}
			else
			{
				//rotate to direction
				if((rdiff > 0 && rdiff < 180) || (rdiff < -180))
					physo->RotateYAxis(std::min((0.1f*tdiff), (float)(fabs(rdiff))));	
				else
					physo->RotateYAxis(std::max((-0.1f*tdiff), (float)(-fabs(rdiff))));
			}
		}
	}
}