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); } }
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); } } }
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); } } }
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) }