Example #1
0
void cMonster::SetPitchAndYawFromDestination()
{
	Vector3d FinalDestination = m_FinalDestination;
	if (m_Target != NULL)
	{
		if (m_Target->IsPlayer())
		{
			FinalDestination.y = ((cPlayer *)m_Target)->GetStance();
		}
		else
		{
			FinalDestination.y = GetHeight();
		}
	}

	Vector3d Distance = FinalDestination - GetPosition();
	if (Distance.SqrLength() > 0.1f)
	{
		{
			double Rotation, Pitch;
			Distance.Normalize();
			VectorToEuler(Distance.x, Distance.y, Distance.z, Rotation, Pitch);
			SetHeadYaw(Rotation);
			SetPitch(-Pitch);
		}

		{
			Vector3d BodyDistance = m_Destination - GetPosition();
			double Rotation, Pitch;
			Distance.Normalize();
			VectorToEuler(BodyDistance.x, BodyDistance.y, BodyDistance.z, Rotation, Pitch);
			SetYaw(Rotation);
		}
	}
}
Example #2
0
void cMonster::SetPitchAndYawFromDestination(bool a_IsFollowingPath)
{
	Vector3d BodyDistance;
	if (!a_IsFollowingPath && (GetTarget() != nullptr))
	{
		BodyDistance = GetTarget()->GetPosition() - GetPosition();
	}
	else
	{
		BodyDistance = m_NextWayPointPosition - GetPosition();
	}
	double BodyRotation, BodyPitch;
	BodyDistance.Normalize();
	VectorToEuler(BodyDistance.x, BodyDistance.y, BodyDistance.z, BodyRotation, BodyPitch);
	SetYaw(BodyRotation);

	Vector3d HeadDistance;
	if (GetTarget() != nullptr)
	{
		if (GetTarget()->IsPlayer())  // Look at a player
		{
			HeadDistance = GetTarget()->GetPosition() - GetPosition();
		}
		else  // Look at some other entity
		{
			HeadDistance = GetTarget()->GetPosition() - GetPosition();
			// HeadDistance.y = GetTarget()->GetPosY() + GetHeight();
		}
	}
	else  // Look straight
	{
		HeadDistance = BodyDistance;
		HeadDistance.y = 0;
	}

	double HeadRotation, HeadPitch;
	HeadDistance.Normalize();
	VectorToEuler(HeadDistance.x, HeadDistance.y, HeadDistance.z, HeadRotation, HeadPitch);
	if ((std::abs(BodyRotation - HeadRotation) < 70) && (std::abs(HeadPitch) < 60))
	{
		SetHeadYaw(HeadRotation);
		SetPitch(-HeadPitch);
	}
	else
	{
		SetHeadYaw(BodyRotation);
		SetPitch(0);
	}
}
Example #3
0
void Entity::BillboardXZ(Entity *Target)
{
	Vector3d Projection;		// Vector dirección proyectado en el plano XZ.
	Vector3d AxisX(1,0,0);		// Eje de las X. Nos interesa averiguar el ángulo que forma Projection con este eje.
	Vector3d Normal;			// Indica si el ángulo es negativo o positivo.
	float AngleCosine;			// Coseno del ángulo.

	// Obtenemos el vector dirección, lo proyectamos sobre XZ y lo normalizamos.
	Target->Position.Subtract(Position, Projection);
	Projection.y = 0;
	Projection.Normalize();

	// Calculamos el angulo que forman el vector direccion y el eje de las X.
	AngleCosine = AxisX.DotProduct(Projection);

	// Evitamos posibles problemas de precisión
	if (AngleCosine > 1)
		AngleCosine = 1;
	else if (AngleCosine < -1)
		AngleCosine = -1;
 
	// Determinamos si el angulo es positivo o negativo.
	Normal = AxisX.CrossProduct(Projection);
	if( Normal.x==0 && Normal.y==0 && Normal.z==0 )
		Normal.y=1;
	
	// Realizamos el giro de las coordenadas cilíndricas
	if( Normal.y>0 )
		SetRotationY(acos(AngleCosine) * 180.0f/3.14f);
	else
		SetRotationY(-acos(AngleCosine) * 180.0f/3.14f);
}
Example #4
0
colorf DefaultShader::Run(const ShaderArgs &args)
{
//  std::cout << "DefaultShader Run" << std::endl;

    colorf color = args.scene->GetAmbientLight();
    std::vector<SimpleLight *> lightList = args.scene->GetLightList();

    for (std::vector<SimpleLight *>::const_iterator i = lightList.begin(); i != lightList.end(); i++) {
        const SimpleLight *l = *i;

        // cast a ray at each light, see if we're in a shadow
        Ray ray;
        ray.origin = args.pos + args.normal * 0.001f;
        ray.dir = l->GetPos() - ray.origin;
        ray.dir.Normalize();
        ray.light = true;

//      std::cout << "casting ray back to light" << std::endl;
        if (!args.scene->DoesIntersect(ray, (ray.origin - l->GetPos()).Length())) {
            Vector3d suntosurface = l->GetPos() - args.pos;
            suntosurface.Normalize();

//          std::cout << "does not intersect" << std::endl;

            float light = Dot(suntosurface, args.normal);

            // calculate falloff

            color += (l->GetColor() * light) * m_DiffuseColor;
        }
    }

//  std::cout << "color " << color << std::endl;
    // see how much of it is a pure reflection
    if (m_Shinyness > 0.0f) {
        Ray ray;
        ray.origin = args.pos;

        // calculate the reflection ray
        float d = Dot(args.ray->dir, args.normal);

        Vector3d reflect(
            args.ray->dir.getx() - 2.0 * d * args.normal.getx(),
            args.ray->dir.gety() - 2.0 * d * args.normal.gety(),
            args.ray->dir.getz() - 2.0 * d * args.normal.getz());

        ray.dir = reflect;

        color *= (1.0f - m_Shinyness);

        // recursively trace to see
        colorf reflectcolor;
        if (args.tracer->Cast(reflectcolor, ray)) {
            color += reflectcolor * m_Shinyness;
        }
    }

//  std::cout << "default shader color " << color << std::endl;
    return color;
}
Example #5
0
void cMonster::SetPitchAndYawFromDestination()
{
	Vector3d FinalDestination = m_FinalDestination;
	if (m_Target != nullptr)
	{
		if (m_Target->IsPlayer())
		{
			FinalDestination.y = static_cast<cPlayer *>(m_Target)->GetStance() - 1;
		}
		else
		{
			FinalDestination.y = m_Target->GetPosY() + GetHeight();
		}
	}


	Vector3d BodyDistance;
	if (!m_IsFollowingPath && (m_Target != nullptr))
	{
		BodyDistance = m_Target->GetPosition() - GetPosition();
	}
	else
	{
		BodyDistance = m_NextWayPointPosition - GetPosition();
	}
	double BodyRotation, BodyPitch;
	BodyDistance.Normalize();
	VectorToEuler(BodyDistance.x, BodyDistance.y, BodyDistance.z, BodyRotation, BodyPitch);
	SetYaw(BodyRotation);

	Vector3d Distance = FinalDestination - GetPosition();
	{
		double HeadRotation, HeadPitch;
		Distance.Normalize();
		VectorToEuler(Distance.x, Distance.y, Distance.z, HeadRotation, HeadPitch);
		if (std::abs(BodyRotation - HeadRotation) < 90)
		{
			SetHeadYaw(HeadRotation);
			SetPitch(-HeadPitch);
		}
		else  // We're not an owl. If it's more than 120, don't look behind and instead look at where you're walking.
		{
			SetHeadYaw(BodyRotation);
			SetPitch(-BodyPitch);
		}
	}
}
Example #6
0
void cMonster::MoveToWayPoint(cChunk & a_Chunk)
{
	if ((m_NextWayPointPosition - GetPosition()).SqrLength() < WAYPOINT_RADIUS * WAYPOINT_RADIUS)
	{
		return;
	}


	if (m_JumpCoolDown == 0)
	{
		if (DoesPosYRequireJump(FloorC(m_NextWayPointPosition.y)))
		{
			if (((IsOnGround()) && (GetSpeed().SqrLength() == 0.0f)) ||
			(IsSwimming()))
			{
				m_bOnGround = false;
				m_JumpCoolDown = 20;
				// TODO: Change to AddSpeedY once collision detection is fixed - currently, mobs will go into blocks attempting to jump without a teleport
				AddPosY(1.6);  // Jump!!
				SetSpeedX(3.2 * (m_NextWayPointPosition.x - GetPosition().x));  // Move forward in a preset speed.
				SetSpeedZ(3.2 * (m_NextWayPointPosition.z - GetPosition().z));  // The numbers were picked based on trial and error and 1.6 and 3.2 are perfect.
			}
		}
	}
	else
	{
		--m_JumpCoolDown;
	}

	Vector3d Distance = m_NextWayPointPosition - GetPosition();
	if ((Distance.x != 0.0f) || (Distance.z != 0.0f))
	{
		Distance.y = 0;
		Distance.Normalize();

		if (m_bOnGround)
		{
			Distance *= 2.5f;
		}
		else if (IsSwimming())
		{
			Distance *= 1.3f;
		}
		else
		{
			// Don't let the mob move too much if he's falling.
			Distance *= 0.25f;
		}
		// Apply walk speed:
		Distance *= m_RelativeWalkSpeed;
		/* Reduced default speed.
		Close to Vanilla, easier for mobs to follow m_NextWayPointPositions, hence
		better pathfinding. */
		Distance *= 0.5;
		AddSpeedX(Distance.x);
		AddSpeedZ(Distance.z);
	}
}
Example #7
0
Vector3d cPlayer::GetThrowSpeed(double a_SpeedCoeff) const
{
	Vector3d res = GetLookVector();
	res.Normalize();
	
	// TODO: Add a slight random change (+-0.0075 in each direction)
	
	return res * a_SpeedCoeff;
}	
Example #8
0
void Rotation::setValue(const Vector3d & axis, const double fAngle)
{
    // Taken from <http://de.wikipedia.org/wiki/Quaternionen>
    //
    this->quat[3] = (double)cos(fAngle/2.0);
    Vector3d norm = axis;
    norm.Normalize();
    double scale = (double)sin(fAngle/2.0);
    this->quat[0] = norm.x * scale;
    this->quat[1] = norm.y * scale;
    this->quat[2] = norm.z * scale;
}
Example #9
0
// Retun the normal for an arbitary polygon
Vector3d PolygonNormal(Vector3d polyData[]) {
	// Construct a normal for this polygon
	Vector3d v1 = polyData[0] - polyData[1];
	Vector3d v2 = polyData[1] - polyData[2];

	Vector3d normal;
	normal = Vector3d::CrossProduct(v1, v2);

	// Make sure this normal is a unit vector
	normal.Normalize();

	return normal;
}
void PolygonGraphRenderer::PreparePolygons()
{
   m_displayListPolygons.Init();

   m_displayListPolygons.Open();

   for (PolygonGraph::CenterPtr p : m_graph.m_centers)
   {
      std::vector<PolygonGraph::CornerPtr> vecCorners = p->corners;

      // order them clockwise
      std::sort(vecCorners.begin(), vecCorners.end(),
         PolygonGraph::CornerSorter(p->point));

      // draw triangle fan
      glBegin(GL_TRIANGLE_FAN);

      Color c = PolygonGraph::ColorByBiomeType(p->enBiomeType);
      //Color c = PolygonGraph::ColorByTerrainType(p->enTerrainType);
      //Color c = PolygonGraph::ColorByElevation(p->elevation);
      //Color c = PolygonGraph::ColorByMoisture(p->moisture);


      glColor3ubv(c.m_color);

      // normal
      ATLASSERT(vecCorners.size() >= 2);
      Vector3d center(p->point.X(), p->elevation * c_dElevationScaleFactor, p->point.Y());
      Vector3d p1(vecCorners[0]->point.X(), vecCorners[0]->elevation * c_dElevationScaleFactor, vecCorners[0]->point.Y());
      Vector3d p2(vecCorners[1]->point.X(), vecCorners[1]->elevation * c_dElevationScaleFactor, vecCorners[1]->point.Y());
      Vector3d normal;
      normal.Cross(center-p1, center-p2);
      normal.Normalize();

      glNormal3dv(normal.Data());

      // center
      glVertex3d(p->point.X(), p->elevation * c_dElevationScaleFactor, p->point.Y());

      for (PolygonGraph::CornerPtr q : vecCorners)
         glVertex3d(q->point.X(), q->elevation * c_dElevationScaleFactor, q->point.Y());

      glVertex3d(vecCorners[0]->point.X(), vecCorners[0]->elevation * c_dElevationScaleFactor,
         vecCorners[0]->point.Y());

      glEnd();
   }

   m_displayListPolygons.Close();
}
Example #11
0
void CSimObjMoveable::Calc(float total, float dt)
{
	Vector3d v = (m_dir-m_pos);
	v.Normalize();
	m_pos.x += v.x * m_speed * dt;
	m_pos.y += v.y * m_speed * dt;
	m_pos.z += v.z * m_speed * dt;

	if (Reached(m_dir, m_pos))
	{
		m_pos = m_dir;
		if (m_path.Count() > 1)
		{ 
			m_next_node = (m_next_node + 1) % m_path.Count();
			m_dir = m_path.GetNode(m_next_node);
		}
	}
	//m_pos += v * m_speed * dt;
}
void ModelDisplayState::RenderModelNormals(const Group& group) const
{
   AnimatedModel3d& model = *m_spModel->GetAnimated();
   const Data& data = model.GetData();

   OpenGL::PushedAttributes attrib(GL_LINE_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT);

   glDisable(GL_LIGHTING);
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_TEXTURE_2D);

   glLineWidth(2.0f);

   glBegin(GL_LINES);

   for (size_t uiTriangleIndex : group.m_vecTriangleIndices)
   {
      ATLASSERT(uiTriangleIndex < data.m_vecTriangles.size());

      const Triangle& t = data.m_vecTriangles[uiTriangleIndex];
      for (unsigned int v=0; v<3; v++)
      {
         size_t vertexIndex = t.auiVertexIndices[v];
         const Vertex& vert = data.m_vecVertices[vertexIndex];

         Vector3d vVertex = vert.m_vPos;
         model.TransformVertex(vert, m_vecJointRenderData, vVertex);

         Vector3d vNormal = t.aNormals[v];
         model.TransformNormal(vert, m_vecJointRenderData, vNormal);

         vNormal.Normalize();
         vNormal *= 0.1;
         vNormal += vVertex;

         glVertex3dv(vVertex.Data());
         glVertex3dv(vNormal.Data());
      }
   }

   glEnd();
}
bool Matrix4D::toAxisAngle (Vector3d& rclBase, Vector3d& rclDir, double& rfAngle, double& fTranslation) const
{
  // First check if the 3x3 submatrix is orthogonal
  for ( int i=0; i<3; i++ ) {
    // length must be one
    if ( fabs(dMtrx4D[0][i]*dMtrx4D[0][i]+dMtrx4D[1][i]*dMtrx4D[1][i]+dMtrx4D[2][i]*dMtrx4D[2][i]-1.0) > 0.01 )
      return false;
    // scalar product with other rows must be zero
    if ( fabs(dMtrx4D[0][i]*dMtrx4D[0][(i+1)%3]+dMtrx4D[1][i]*dMtrx4D[1][(i+1)%3]+dMtrx4D[2][i]*dMtrx4D[2][(i+1)%3]) > 0.01 )
      return false;
  }

  // Okay, the 3x3 matrix is orthogonal.
  // Note: The section to get the rotation axis and angle was taken from WildMagic Library.
  //
  // Let (x,y,z) be the unit-length axis and let A be an angle of rotation.
  // The rotation matrix is R = I + sin(A)*P + (1-cos(A))*P^2 where
  // I is the identity and
  //
  //       +-        -+
  //   P = |  0 -z +y |
  //       | +z  0 -x |
  //       | -y +x  0 |
  //       +-        -+
  //
  // If A > 0, R represents a counterclockwise rotation about the axis in
  // the sense of looking from the tip of the axis vector towards the
  // origin.  Some algebra will show that
  //
  //   cos(A) = (trace(R)-1)/2  and  R - R^t = 2*sin(A)*P
  //
  // In the event that A = pi, R-R^t = 0 which prevents us from extracting
  // the axis through P.  Instead note that R = I+2*P^2 when A = pi, so
  // P^2 = (R-I)/2.  The diagonal entries of P^2 are x^2-1, y^2-1, and
  // z^2-1.  We can solve these for axis (x,y,z).  Because the angle is pi,
  // it does not matter which sign you choose on the square roots.
  //
  // For more details see also http://www.math.niu.edu/~rusin/known-math/97/rotations

  double fTrace = dMtrx4D[0][0] + dMtrx4D[1][1] + dMtrx4D[2][2];
  double fCos = 0.5*(fTrace-1.0);
  rfAngle = acos(fCos);  // in [0,PI]

  if ( rfAngle > 0.0f )
  {
    if ( rfAngle < F_PI )
    {
      rclDir.x = (dMtrx4D[2][1]-dMtrx4D[1][2]);
      rclDir.y = (dMtrx4D[0][2]-dMtrx4D[2][0]);
      rclDir.z = (dMtrx4D[1][0]-dMtrx4D[0][1]);
      rclDir.Normalize();
    }
    else
    {
      // angle is PI
      double fHalfInverse;
      if ( dMtrx4D[0][0] >= dMtrx4D[1][1] )
      {
        // r00 >= r11
        if ( dMtrx4D[0][0] >= dMtrx4D[2][2] )
        {
          // r00 is maximum diagonal term
          rclDir.x = (0.5*sqrt(dMtrx4D[0][0] - dMtrx4D[1][1] - dMtrx4D[2][2] + 1.0));
          fHalfInverse = 0.5/rclDir.x;
          rclDir.y = (fHalfInverse*dMtrx4D[0][1]);
          rclDir.z = (fHalfInverse*dMtrx4D[0][2]);
        }
        else
        {
          // r22 is maximum diagonal term
          rclDir.z = (0.5*sqrt(dMtrx4D[2][2] - dMtrx4D[0][0] - dMtrx4D[1][1] + 1.0));
          fHalfInverse = 0.5/rclDir.z;
          rclDir.x = (fHalfInverse*dMtrx4D[0][2]);
          rclDir.y = (fHalfInverse*dMtrx4D[1][2]);
        }
      }
      else
      {
        // r11 > r00
        if ( dMtrx4D[1][1] >= dMtrx4D[2][2] )
        {
          // r11 is maximum diagonal term
          rclDir.y = (0.5*sqrt(dMtrx4D[1][1] - dMtrx4D[0][0] - dMtrx4D[2][2] + 1.0));
          fHalfInverse  = 0.5/rclDir.y;
          rclDir.x = (fHalfInverse*dMtrx4D[0][1]);
          rclDir.z = (fHalfInverse*dMtrx4D[1][2]);
        }
        else
        {
          // r22 is maximum diagonal term
          rclDir.z = (0.5*sqrt(dMtrx4D[2][2] - dMtrx4D[0][0] - dMtrx4D[1][1] + 1.0));
          fHalfInverse = 0.5/rclDir.z;
          rclDir.x = (fHalfInverse*dMtrx4D[0][2]);
          rclDir.y = (fHalfInverse*dMtrx4D[1][2]);
        }
      }
    }
  }
  else
  {
    // The angle is 0 and the matrix is the identity.  Any axis will
    // work, so just use the x-axis.
    rclDir.x = 1.0;
    rclDir.y = 0.0;
    rclDir.z = 0.0;
    rclBase.x = 0.0;
    rclBase.y = 0.0;
    rclBase.z = 0.0;
  }

  // This is the translation part in axis direction
  fTranslation = (dMtrx4D[0][3]*rclDir.x+dMtrx4D[1][3]*rclDir.y+dMtrx4D[2][3]*rclDir.z);
  Vector3d cPnt(dMtrx4D[0][3],dMtrx4D[1][3],dMtrx4D[2][3]);
  cPnt = cPnt - fTranslation * rclDir;

  // This is the base point of the rotation axis
  if ( rfAngle > 0.0f )
  {
    double factor = 0.5*(1.0+fTrace)/sin(rfAngle);
    rclBase.x = (0.5*(cPnt.x+factor*(rclDir.y*cPnt.z-rclDir.z*cPnt.y)));
    rclBase.y = (0.5*(cPnt.y+factor*(rclDir.z*cPnt.x-rclDir.x*cPnt.z)));
    rclBase.z = (0.5*(cPnt.z+factor*(rclDir.x*cPnt.y-rclDir.y*cPnt.x)));
  }

  return true;
}
Example #14
0
void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);

	if (m_Health <= 0)
	{
		// The mob is dead, but we're still animating the "puff" they leave when they die
		m_DestroyTimer += a_Dt / 1000;
		if (m_DestroyTimer > 1)
		{
			Destroy(true);
		}
		return;
	}

	// Burning in daylight
	HandleDaylightBurning(a_Chunk);
	
	HandlePhysics(a_Dt,a_Chunk);
	BroadcastMovementUpdate();

	a_Dt /= 1000;

	if (m_bMovingToDestination)
	{
		Vector3f Pos( GetPosition() );
		Vector3f Distance = m_Destination - Pos;
		if( !ReachedDestination() )
		{
			Distance.y = 0;
			Distance.Normalize();
			Distance *= 3;
			SetSpeedX( Distance.x );
			SetSpeedZ( Distance.z );

			if (m_EMState == ESCAPING)
			{	//Runs Faster when escaping :D otherwise they just walk away
				SetSpeedX (GetSpeedX() * 2.f);
				SetSpeedZ (GetSpeedZ() * 2.f);
			}
		}
		else
		{
			m_bMovingToDestination = false;
		}

		if( GetSpeed().SqrLength() > 0.f )
		{
			if( m_bOnGround )
			{
				Vector3f NormSpeed = Vector3f(GetSpeed()).NormalizeCopy();
				Vector3f NextBlock = Vector3f( GetPosition() ) + NormSpeed;
				int NextHeight;
				if (!m_World->TryGetHeight((int)NextBlock.x, (int)NextBlock.z, NextHeight))
				{
					// The chunk at NextBlock is not loaded
					return;
				}
				if( NextHeight > (GetPosY() - 1.0) && (NextHeight - GetPosY()) < 2.5 )
				{
					m_bOnGround = false;
					SetSpeedY(5.f); // Jump!!
				}
			}
		}
	}

	Vector3d Distance = m_Destination - GetPosition();
	if (Distance.SqrLength() > 0.1f)
	{
		double Rotation, Pitch;
		Distance.Normalize();
		VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch );
		SetHeadYaw (Rotation);
		SetRotation( Rotation );
		SetPitch( -Pitch );
	}

	switch (m_EMState)
	{
		case IDLE:
		{
			// If enemy passive we ignore checks for player visibility
			InStateIdle(a_Dt);
			break;
		}
	
		case CHASING:
		{
			// If we do not see a player anymore skip chasing action
			InStateChasing(a_Dt);
			break;
		}
	
		case ESCAPING:
		{
			InStateEscaping(a_Dt);
			break;
		}
	}  // switch (m_EMState)
}
Example #15
0
void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);

	if (m_Health <= 0)
	{
		// The mob is dead, but we're still animating the "puff" they leave when they die
		m_DestroyTimer += a_Dt / 1000;
		if (m_DestroyTimer > 1)
		{
			Destroy(true);
		}
		return;
	}

	if ((m_Target != NULL) && m_Target->IsDestroyed())
		m_Target = NULL;

	// Burning in daylight
	HandleDaylightBurning(a_Chunk);

	a_Dt /= 1000;

	if (m_bMovingToDestination)
	{
		if (m_bOnGround)
		{
			if (DoesPosYRequireJump((int)floor(m_Destination.y)))
			{
				m_bOnGround = false;

				// TODO: Change to AddSpeedY once collision detection is fixed - currently, mobs will go into blocks attempting to jump without a teleport
				AddPosY(1.2);  // Jump!!
			}
		}

		Vector3d Distance = m_Destination - GetPosition();
		if (!ReachedDestination() && !ReachedFinalDestination())  // If we haven't reached any sort of destination, move
		{
			Distance.y = 0;
			Distance.Normalize();

			if (m_bOnGround)
			{
				Distance *= 2.5f;
			}
			else if (IsSwimming())
			{
				Distance *= 1.3f;
			}
			else
			{
				// Don't let the mob move too much if he's falling.
				Distance *= 0.25f;
			}

			// Apply walk speed:
			Distance *= m_RelativeWalkSpeed;

			AddSpeedX(Distance.x);
			AddSpeedZ(Distance.z);

			// It's too buggy!
			/*
			if (m_EMState == ESCAPING)
			{
				// Runs Faster when escaping :D otherwise they just walk away
				SetSpeedX (GetSpeedX() * 2.f);
				SetSpeedZ (GetSpeedZ() * 2.f);
			}
			*/
		}
		else
		{
			if (ReachedFinalDestination())  // If we have reached the ultimate, final destination, stop pathfinding and attack if appropriate
			{
				FinishPathFinding();
			}
			else
			{
				TickPathFinding();  // We have reached the next point in our path, calculate another point
			}
		}
	}

	SetPitchAndYawFromDestination();
	HandleFalling();

	switch (m_EMState)
	{
		case IDLE:
		{
			// If enemy passive we ignore checks for player visibility
			InStateIdle(a_Dt);
			break;
		}
		case CHASING:
		{
			// If we do not see a player anymore skip chasing action
			InStateChasing(a_Dt);
			break;
		}
		case ESCAPING:
		{
			InStateEscaping(a_Dt);
			break;
		}
			
		case ATTACKING: break;
	}  // switch (m_EMState)

	BroadcastMovementUpdate();
}