diff --git a/source/renderer/WaterManager.cpp b/source/renderer/WaterManager.cpp index 779c3021c5..1b16318aad 100644 --- a/source/renderer/WaterManager.cpp +++ b/source/renderer/WaterManager.cpp @@ -52,7 +52,7 @@ WaterManager::WaterManager() m_RefractionTexture = 0; m_WaterTexTimer = 0.0; m_Shininess = 150.0f; - m_SpecularStrength = 0.45f; + m_SpecularStrength = 0.4f; m_Waviness = 8.0f; m_ReflectionTint = CColor(1.0f, 1.0f, 1.0f, 1.0f); m_ReflectionTintStrength = 0.0f; diff --git a/source/simulation/EntityStateProcessing.cpp b/source/simulation/EntityStateProcessing.cpp index d918979cbf..0f8a216600 100644 --- a/source/simulation/EntityStateProcessing.cpp +++ b/source/simulation/EntityStateProcessing.cpp @@ -475,10 +475,26 @@ bool CEntity::processContactActionNoPathing( CEntityOrder* current, size_t times float adjMinRange = action->m_MinRange + m_bounds->m_radius + target->m_bounds->m_radius; if( delta.within( adjMinRange ) ) { - // Too close... do nothing. - entf_clear(ENTF_IS_RUNNING); - entf_clear(ENTF_SHOULD_RUN); - return( false ); + // Too close... avoid it if allowed by the current stance. + if( current->m_source == CEntityOrder::SOURCE_UNIT_AI && !m_stance->allowsMovement() ) + { + popOrder(); + m_actor->SetRandomAnimation( "idle" ); + return false; // We're not allowed to move at all by the current stance + } + + entf_set(ENTF_SHOULD_RUN); + chooseMovementSpeed( action->m_MinRange ); + + // The pathfinder will push its result in front of the current order + if( !g_Pathfinder.requestAvoidPath( me, current, action->m_MinRange + 2.0f ) ) + { + popOrder(); // Nothing we can do.. maybe we'll find a better target + m_actor->SetRandomAnimation( "idle" ); + return false; + } + + return true; } } diff --git a/source/simulation/PathfindEngine.cpp b/source/simulation/PathfindEngine.cpp index b2385b2da9..cdc5fd592b 100644 --- a/source/simulation/PathfindEngine.cpp +++ b/source/simulation/PathfindEngine.cpp @@ -6,6 +6,8 @@ #include "Entity.h" #include "EntityTemplate.h" #include "PathfindEngine.h" +#include "graphics/Terrain.h" +#include "ps/World.h" CPathfindEngine::CPathfindEngine() @@ -94,8 +96,9 @@ void CPathfindEngine::requestContactPath( HEntity entity, CEntityOrder* current, CEntityOrder waypoint; waypoint.m_type = CEntityOrder::ORDER_GOTO_WAYPOINT_CONTACT; waypoint.m_source = current->m_source; - waypoint.m_data[0].location = current->m_data[0].entity->m_position; - *((float*)&waypoint.m_data[0].data) = std::max( current->m_data[0].entity->m_bounds->m_radius, range ); + HEntity target = current->m_data[0].entity; + waypoint.m_data[0].location = target->m_position; + *((float*)&waypoint.m_data[0].data) = std::max( target->m_bounds->m_radius, range ); entity->m_orderQueue.push_front( waypoint ); //pathSparse( entity, current->m_data[0].entity->m_position ); @@ -112,3 +115,34 @@ void CPathfindEngine::requestContactPath( HEntity entity, CEntityOrder* current, // } //} } + +bool CPathfindEngine::requestAvoidPath( HEntity entity, CEntityOrder* current, float avoidRange ) +{ + /* TODO: Same as non-contact: need high-level planner */ + + // TODO: Replace this with a new type of goal which is to avoid some point or line segment + // (requires changes to pathfinder to support this type of goal) + + CEntityOrder waypoint; + waypoint.m_type = CEntityOrder::ORDER_GOTO_WAYPOINT_CONTACT; + waypoint.m_source = current->m_source; + + // Figure out a direction to move + HEntity target = current->m_data[0].entity; + CVector3D dir = entity->m_position - target->m_position; + if(dir.LengthSquared() == 0) // shouldn't happen, but just in case + dir = CVector3D(1, 0, 0); + float dist = dir.GetLength(); + dir.Normalize(); + + waypoint.m_data[0].location = entity->m_position + dir * (avoidRange - dist); + + if( !g_Game->GetWorld()->GetTerrain()->isOnMap( waypoint.m_data[0].location ) ) + { + return false; + } + + *((float*)&waypoint.m_data[0].data) = 0.0f; + entity->m_orderQueue.push_front( waypoint ); + return true; +} diff --git a/source/simulation/PathfindEngine.h b/source/simulation/PathfindEngine.h index 94276035ac..36af3bbd84 100644 --- a/source/simulation/PathfindEngine.h +++ b/source/simulation/PathfindEngine.h @@ -39,6 +39,7 @@ public: float radius, CEntityOrder::EOrderSource orderSource ); void requestContactPath( HEntity entity, CEntityOrder* current, float range ); + bool requestAvoidPath( HEntity entity, CEntityOrder* current, float avoidRange ); private: CAStarEngineLowLevel mLowPathfinder; };