Example #1
0
/***********************************************************
constructor from 3 angles
***********************************************************/
LbaQuaternion::LbaQuaternion(float anglex, float angley, float anglez)
{
	LbaQuaternion qx(anglex, LbaVec3(1, 0, 0));
	LbaQuaternion qy(angley, LbaVec3(0, 1, 0));
	LbaQuaternion qz(anglez, LbaVec3(0, 0, 1));
	LbaQuaternion res = (qy * qx * qz);

	X = res.X;
	Y = res.Y;
	Z = res.Z;
	W = res.W;
}
Example #2
0
/***********************************************************
server attach actor
***********************************************************/
void ExternalActor::ServerAttachActor(boost::shared_ptr<DynamicObject> actor, float posX, float posY, float posZ, float rotation)
{
	_externalattachedactor = actor;

	boost::shared_ptr<PhysicalObjectHandlerBase> physo = _character->GetPhysicalObject();
	physo->MoveTo(posX, posY, posZ);
	LbaQuaternion Q(rotation, LbaVec3(0,1,0));
	physo->RotateTo(Q);
}
Example #3
0
/***********************************************************
 update with external info
***********************************************************/
void ExternalPlayer::UpdateMove(double updatetime, const LbaNet::PlayerMoveInfo &info, bool teleport)
{
	// set free move
	_freemove = true;

	if(updatetime > _last_update)
	{
		std::stringstream strs;
		strs<<"Updating external player move with anim"<<info.AnimationIdx;
		LogHandler::getInstance()->LogToFile(strs.str(), _character->GetId());


		// update imediatly modifiable states
		_last_update = updatetime;

		_shouldupdate = true;

		if(!_playingscript)
		{
			boost::shared_ptr<PhysicalObjectHandlerBase> physo = _character->GetPhysicalObject();


			_velocityX = info.CurrentSpeedX;
			_velocityY = info.CurrentSpeedY;
			_velocityZ = info.CurrentSpeedZ;
			_velocityR = info.CurrentSpeedRotation;


			bool finishedmove = false;
			if(teleport || (abs(_velocityX) < 0.000001f && abs(_velocityY) < 0.000001f && abs(_velocityZ) < 0.000001f))
			{
				finishedmove = true;
				physo->SetPosition(info.CurrentPos.X,  info.CurrentPos.Y, info.CurrentPos.Z);
			}

			if(teleport || (abs(_velocityR) < 0.00001f))
			{
				LbaQuaternion Q(info.CurrentPos.Rotation, LbaVec3(0,1,0));
				physo->RotateTo(Q);

				// do not need to update if no rotation and no rotation
				if(finishedmove)
				{
					_shouldupdate = false;
				}
			}
		}

		// update dead reckon for the rest
		_dr.Set(info.CurrentPos.X,  info.CurrentPos.Y, info.CurrentPos.Z, info.CurrentPos.Rotation,
					info.CurrentSpeedX, info.CurrentSpeedY, info.CurrentSpeedZ, info.CurrentSpeedRotation);

		//update animation
		if(info.AnimationIdx != "")
			_character->GetDisplayObject()->Update(new LbaNet::AnimationStringUpdate(info.AnimationIdx), _playingscript);
	}
}
Example #4
0
/***********************************************************
get direction vector
***********************************************************/
LbaVec3 LbaQuaternion::GetDirection(const LbaVec3 &vec)
{
	NxVec3 dir(vec.x, vec.y, vec.z);
	NxQuat current;
	current.setXYZW(X, Y, Z, W);

	current.rotate(dir);

	return LbaVec3(dir.x, dir.y, dir.z);
}
Example #5
0
/***********************************************************
used by lua to get an actor Position
***********************************************************/
LbaVec3 NPCHandler::GetActorPosition(bool fromattackscript)
{
	if(fromattackscript && _freemove)
	{
		if(_character)
		{
			boost::shared_ptr<PhysicalObjectHandlerBase> physO = _character->GetPhysicalObject();
			if(physO)
			{
				float X, Y, Z;
				physO->GetPosition(X, Y, Z);
				return LbaVec3(X, Y, Z);
			}
		}

		return LbaVec3();
	}
	else
		return ActorHandler::GetActorPosition(fromattackscript);
}
Example #6
0
//! update sound with position
void DynamicObject::UpdateSoundPosition()
{
	if(_phH && _soundH)
	{
		float posX, posY, posZ;
		LbaQuaternion Quat;
		_phH->GetPosition(posX, posY, posZ);
		_phH->GetRotation(Quat);

		LbaVec3 ldX(Quat.GetDirection(LbaVec3(0, 0, 1)));
		_soundH->Update(posX, posY, posZ, ldX.x, ldX.y, ldX.z);
	}
}
Example #7
0
/***********************************************************
untarget
***********************************************************/
void ExternalActor::UnTarget()
{
	if(_targetting)
	{
		_currentScripts = _targetsavedScripts;
		if(!_playingscript)
		{
			boost::shared_ptr<PhysicalObjectHandlerBase> physo = _character->GetPhysicalObject();
			LbaQuaternion Q(_targetsavedangle, LbaVec3(0, 1, 0));
			physo->SetRotation(Q);
		}

		_targetsavedScripts = boost::shared_ptr<ScriptPartBase>();
		_targetting = false;
	}
}
Example #8
0
/***********************************************************
when update npc position
***********************************************************/
void ExternalActor::NpcChangedUpdate(double updatetime, 
									float CurrPosX, float CurrPosY, float CurrPosZ,
									float CurrRotation, const std::string &CurrAnimation,
									bool ResetPosition, bool ResetRotation,
									const LbaNet::PlayingSoundSequence	&Sounds,
									LbaNet::NpcUpdateBasePtr Update, 
									ScriptEnvironmentBase* scripthandler)
{
	// reset free move
	_freemove = false;

	// reset projectiles
	if(_character)
		_character->ClearActionsOnAnimation();


	// update only newest info
	if(updatetime < _last_update)
		return;

	_last_update = updatetime;

	if(_playingscript)
		return;


	boost::shared_ptr<PhysicalObjectHandlerBase> physo = _character->GetPhysicalObject();
	float posX, posY, posZ;
	physo->GetPosition(posX, posY, posZ);
	float rotation = physo->GetRotationYAxis();


	// update position and rotation
	float diffpos = (CurrPosX-posX)*(CurrPosX-posX) + 
						(CurrPosY-posY)*(CurrPosY-posY) +
						(CurrPosZ-posZ)*(CurrPosZ-posZ);

	float diffrot = abs(CurrRotation-rotation);


	// reset actor position
	if(ResetPosition || diffpos > 64 || _shouldreset)
	{
		physo->SetPosition(CurrPosX,  CurrPosY, CurrPosZ);
		posX = CurrPosX;
		posY = CurrPosY;
		posZ = CurrPosZ;
	}

	// reset actor rotation
	if(ResetRotation || diffrot > 20 || _shouldreset)
	{
		LbaQuaternion Q(CurrRotation, LbaVec3(0,1,0));
		physo->SetRotation(Q);
		rotation = CurrRotation;
	}

	_differencePosX = CurrPosX-posX;
	_differencePosY = CurrPosY-posY;
	_differencePosZ = CurrPosZ-posZ;
	_differenceRotation = CurrRotation-rotation;

	//update animation
	if(CurrAnimation != "")
		_character->GetDisplayObject()->Update(new LbaNet::AnimationStringUpdate(CurrAnimation), _playingscript);

	_shouldreset = false;


	// update sounds
	boost::shared_ptr<SoundObjectHandlerBase> soundo = _character->GetSoundObject();
	if(soundo)
	{
		soundo->SetSoundVector(Sounds, false);
		_character->UpdateSoundPosition();
	}



	// update the script part
	if(!Update)
	{
		_currentScripts = boost::shared_ptr<ScriptPartBase>();
		return;
	}


	LbaNet::NpcUpdateBase & obj = *Update;
	const std::type_info& info = typeid(obj);

	// StraightWalkToNpcUpd
	if(info == typeid(LbaNet::StraightWalkToNpcUpd))
	{
		LbaNet::StraightWalkToNpcUpd * castedptr = 
			dynamic_cast<LbaNet::StraightWalkToNpcUpd *>(&obj);


		_currentScripts = boost::shared_ptr<ScriptPartBase>(new 
			StraightWalkToScriptPart(0, false, castedptr->PosX, castedptr->PosY, castedptr->PosZ,
										_character));
		return;
	}

	if(info == typeid(LbaNet::WalkToPointNpcUpd))
	{
		LbaNet::WalkToPointNpcUpd * castedptr = 
			dynamic_cast<LbaNet::WalkToPointNpcUpd *>(&obj);


		_currentScripts = boost::shared_ptr<ScriptPartBase>(new 
			WalkToPointScriptPart(0, false, castedptr->PosX, castedptr->PosY, castedptr->PosZ, castedptr->RotationSpeedPerSec, castedptr->moveForward));
		return;
	}

	// GoToNpcUpd
	if(info == typeid(LbaNet::GoToNpcUpd))
	{
		LbaNet::GoToNpcUpd * castedptr = 
			dynamic_cast<LbaNet::GoToNpcUpd *>(&obj);


		_currentScripts = boost::shared_ptr<ScriptPartBase>(new 
			GoToScriptPart(0, false, castedptr->PosX, castedptr->PosY, castedptr->PosZ, castedptr->Speed,
										_character));
		return;
	}

	// RotateNpcUpd
	if(info == typeid(LbaNet::RotateNpcUpd))
	{
		LbaNet::RotateNpcUpd * castedptr = 
			dynamic_cast<LbaNet::RotateNpcUpd *>(&obj);


		_currentScripts = boost::shared_ptr<ScriptPartBase>(new 
			RotateScriptPart(0, false, castedptr->Angle, castedptr->RotationSpeedPerSec, 
								castedptr->ManageAnimation));
		return;
	}

	// AnimateNpcUpd
	if(info == typeid(LbaNet::AnimateNpcUpd))
	{
		LbaNet::AnimateNpcUpd * castedptr = 
			dynamic_cast<LbaNet::AnimateNpcUpd *>(&obj);


		_currentScripts = boost::shared_ptr<ScriptPartBase>(new 
			PlayAnimationScriptPart(0, false, castedptr->AnimationMove, castedptr->NbAnimation));
		return;
	}

	// RotateFromPointNpcUpd
	if(info == typeid(LbaNet::RotateFromPointNpcUpd))
	{
		LbaNet::RotateFromPointNpcUpd * castedptr = 
			dynamic_cast<LbaNet::RotateFromPointNpcUpd *>(&obj);


		_currentScripts = boost::shared_ptr<ScriptPartBase>(new 
			RotateFromPointScriptPart(0, false, castedptr->Angle,
			castedptr->PosX, castedptr->PosY, castedptr->PosZ, castedptr->Speed, _character));
		return;
	}


	// FollowWaypointNpcUpd
	if(info == typeid(LbaNet::FollowWaypointNpcUpd))
	{
		LbaNet::FollowWaypointNpcUpd * castedptr = 
			dynamic_cast<LbaNet::FollowWaypointNpcUpd *>(&obj);


		LbaVec3 Pm1X(castedptr->Pm1X, castedptr->Pm1Y, castedptr->Pm1Z);
		LbaVec3 P0(castedptr->P0X, castedptr->P0Y, castedptr->P0Z);
		LbaVec3 P1(castedptr->P1X, castedptr->P1Y, castedptr->P1Z);
		LbaVec3 P2(castedptr->P2X, castedptr->P2Y, castedptr->P2Z);
		LbaVec3 P3(castedptr->P3X, castedptr->P3Y, castedptr->P3Z);
		LbaVec3 P4(castedptr->P4X, castedptr->P4Y, castedptr->P4Z);


		_currentScripts = boost::shared_ptr<ScriptPartBase>(new 
			FollowWaypointScriptPart(0, false, Pm1X, P0, P1, P2, P3, P4));
		return;
	}

}
Example #9
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))));
			}
		}
	}
}
Example #10
0
/***********************************************************
sphere sphere sweep test
***********************************************************/
bool CollisionTester::SphereSphereSweep(const float ra, //radius of sphere A
											const LbaVec3& A0, //previous position of sphere A
											const LbaVec3& A1, //current position of sphere A
											const float rb, //radius of sphere B
											const LbaVec3& B0, //previous position of sphere B
											const LbaVec3& B1, //current position of sphere B
											float& u0, //normalized time of first collision
											float& u1 //normalized time of second collision
											)
{
    //vector from A0 to A1
    const LbaVec3 va = A1 - A0;

    //vector from B0 to B1
    const LbaVec3 vb = B1 - B0;

    //vector from A0 to B0
    const LbaVec3 AB = B0 - A0;


     //relative velocity (in normalized time)
	const LbaVec3 vab = vb - va;


    const float rab = ra + rb;
	const float ab2 = AB.dot(AB);
	const float rab2 = rab*rab;
	const float fpdot2 = AB.dot(LbaVec3(0,0,0)-vab);


    //check if they're currently overlapping
    if( ab2 <= rab2 )
    {
        u0 = 0;
        u1 = 0;
        return true;
    }


	//TODO - doesnt work...
  //  //u*u coefficient
  //  const float a = vab.dot(vab);

  //  //u coefficient
  //  const float b = 2*fpdot2;//vab.dot(AB);

  //  //constant term 
  //  const float c = ab2 - rab2;


  //  //check if they hit each other
  //  // during the frame
  //  if( QuadraticFormula( a, b, c, u0, u1 ) )
  //  {
  //      if( u0 > u1 )
		//	SWAP( u0, u1 );

		//if(u1 > 1)
		//	return false;

		//if(u0 < 0)
		//	return false;

  //      return true;
  //  }

    return false;
} 
Example #11
0
/***********************************************************
operator -
***********************************************************/
LbaVec3 LbaVec3::operator -(const LbaVec3 & q) const
{
	return LbaVec3(x-q.x, y-q.y, z-q.z);
}
Example #12
0
/***********************************************************
do all check to be done when idle
***********************************************************/
void ExternalPlayer::Process(double tnow, float tdiff, 
								ScriptEnvironmentBase* scripthandler)
{
	if(_playingscript)
	{
		// process script
		if(!ProcessScript(tnow, tdiff, scripthandler))
		{
			// if not moved - move with attached actor
			if(_attachedactor)
			{
				boost::shared_ptr<PhysicalObjectHandlerBase> physo = _character->GetPhysicalObject();
				boost::shared_ptr<PhysicalObjectHandlerBase> attchedphys = _attachedactor->GetPhysicalObject();
				if(physo && attchedphys)
				{
					physo->RotateYAxis(attchedphys->GetLastRotation());

					float addspeedX=0, addspeedY=0, addspeedZ=0;
					attchedphys->GetLastMove(addspeedX, addspeedY, addspeedZ);
					physo->Move(addspeedX, addspeedY, addspeedZ);
				}
			}
		}

		//still update dead recon
		_dr.Update(tnow, tdiff);
		return;
	}


	//update display and animation
	_character->Process(tnow, tdiff);


	if(_shouldupdate)
	{
		boost::shared_ptr<PhysicalObjectHandlerBase> physo = _character->GetPhysicalObject();

		// calculate prediction
		float predicted_posX, predicted_posY, predicted_posZ;
		physo->GetPosition(predicted_posX, predicted_posY, predicted_posZ);
		predicted_posX += (_velocityX*tdiff);
		predicted_posY += (_velocityY*tdiff);
		predicted_posZ += (_velocityZ*tdiff);


		float predicted_rotation = physo->GetRotationYAxis() + (_velocityR*tdiff);

		// calculate dead reckon
		_dr.Update(tnow, tdiff);


		//// do interpolation X
		{
			float diffX = (_dr._predicted_posX - predicted_posX);
			if(fabs(diffX) > 8)
				predicted_posX = _dr._predicted_posX;
			else
				predicted_posX += diffX / 40;
		}


		//// do interpolation Y
		{
			float diffY = (_dr._predicted_posY - predicted_posY);
			if(fabs(diffY) > 8)
				predicted_posY = _dr._predicted_posY;
			else
				predicted_posY += diffY / 40;
		}


		//// do interpolation Z
		{
			float diffZ = (_dr._predicted_posZ - predicted_posZ);
			if(fabs(diffZ) > 8)
				predicted_posZ = _dr._predicted_posZ;
			else
				predicted_posZ += diffZ / 40;
		}


		//// do interpolation rotation
		{
			float diffR = (_dr._predicted_rotation - predicted_rotation);
			if(fabs(diffR) > 20)
				predicted_rotation = _dr._predicted_rotation;
			else
				predicted_rotation += diffR / 5;
		}

		physo->MoveTo(predicted_posX,  predicted_posY, predicted_posZ);
		LbaQuaternion Q(predicted_rotation, LbaVec3(0,1,0));
		physo->RotateTo(Q);
	}


}