Advertisement
BratokHR

NPC LOGIC

Apr 10th, 2018
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.26 KB | None | 0 0
  1. /*
  2. ================
  3. find_position
  4.  
  5. ================
  6. */
  7. bool find_position( float *start, float *end )
  8. {
  9.     size_t n, i, j;
  10.     node_t tmp_node;
  11.     float tmp_pos[ 3 ], end_pos[ 3 ];
  12.     bool tmp_found;
  13.     int id;
  14.  
  15.     bool found = false;
  16.  
  17.     int pw[ 4 ] = { -1, 1, 0, 0 };
  18.     int ph[ 4 ] = { 0, 0, -1, 1 };
  19.  
  20.     // удаляем старые узлы
  21.     if ( !nodes.empty() )
  22.         reset_nodes();
  23.  
  24.     // добавляем первый узел
  25.     VectorCopy( start, tmp_pos );
  26.     tmp_pos[ 2 ] -= MAX_DIST_ROUTE;
  27.     GetPositionBulletTrace( tmp_node.origin, start, tmp_pos );
  28.     tmp_node.parent = -1;
  29.     tmp_node.origin[ 2 ] += 20; // увеличиваем высоту узла, для предотвращения застреваний в текстуре
  30.     nodes.push_back( tmp_node );
  31.  
  32.     // добавляем последний узел
  33.     VectorCopy( end, end_pos );
  34.     end_pos[ 2 ] -= MAX_DIST_ROUTE;
  35.     GetPositionBulletTrace( end_pos, end, end_pos );
  36.     end_pos[ 2 ] += 20;
  37.  
  38.     // сканируем местность вокруг первого узла
  39.     for ( n = 0; ; n++ )
  40.     {
  41.         // для компилятора nodes.size() автоматически равен 1, исправлем это
  42.         if ( n >= nodes.size() )
  43.             break;
  44.  
  45.         if ( nodes.size() > MAX_NODES )
  46.             break;
  47.  
  48.         // если уже нашли точку
  49.         if ( found )
  50.             break;
  51.  
  52.         // расширяем площадь узлов по всем 4 сторонам, учитывая подъемы/лестницы
  53.         // [ С, Ю, З, В ]
  54.         for ( i = 0; i < 4; i++ )
  55.         {
  56.             tmp_pos[ 0 ] = nodes[ n ].origin[ 0 ] + MIN_RANGE * pw[ i ];
  57.             tmp_pos[ 1 ] = nodes[ n ].origin[ 1 ] + MIN_RANGE * ph[ i ];
  58.             tmp_pos[ 2 ] = nodes[ n ].origin[ 2 ] + 40;
  59.  
  60.             if ( IsVisible( nodes[ n ].origin, tmp_pos ) )
  61.             {
  62.                 VectorCopy( tmp_pos, tmp_node.origin );
  63.                 tmp_pos[ 2 ] -= MAX_DIST_ROUTE;
  64.  
  65.                 GetPositionBulletTrace( tmp_pos, tmp_node.origin, tmp_pos );
  66.                 tmp_pos[ 2 ] += 10;
  67.  
  68.                 if ( IsVisible( nodes[ n ].origin, tmp_pos ) )
  69.                 {
  70.                     if ( tmp_pos[ 2 ] - nodes[ n ].origin[ 2 ] > 30 )
  71.                         continue;
  72.  
  73.                     tmp_found = false;
  74.  
  75.                     // несколько узлов могут находится на одних и тех же координатах
  76.                     // исключаем эту возможность
  77.                     for ( j = 0; j < nodes.size(); j++ )
  78.                     {
  79.                         if ( GetDistance( nodes[ j ].origin, tmp_pos ) < 5 )
  80.                         {
  81.                             tmp_found = true;
  82.                             break;
  83.                         }
  84.                     }
  85.  
  86.                     // если место свободное, то добавляем сюда узел
  87.                     if ( !tmp_found )
  88.                     {
  89.                         VectorCopy( tmp_pos, tmp_node.origin );
  90.                         tmp_node.parent = n; // записываем узел из которого стреляли лучи
  91.  
  92.                         nodes.push_back( tmp_node );
  93.  
  94.                         if ( IsVisible( tmp_pos, end_pos ) )
  95.                         {
  96.                             // мы нашли нужную координату, добавим ее и закончим искать
  97.                             VectorCopy( tmp_pos, tmp_node.origin );
  98.                             tmp_node.parent = nodes.size() - 1;
  99.                             nodes.push_back( tmp_node );
  100.                             found = true;
  101.                         }
  102.                     }
  103.                 }
  104.             }
  105.         }
  106.     }
  107.  
  108.     if ( !found )
  109.         return false;
  110.  
  111.     if ( !route.empty() )
  112.     {
  113.         for ( i = 0; i < route.size(); i++ )
  114.         {
  115.             route[ i ].arcs.clear();
  116.             route[ i ].dists.clear();
  117.         }
  118.  
  119.         route.clear();
  120.     }
  121.  
  122.     // последний узел у нас является конечным
  123.     // строим маршрут
  124.     id = nodes.size() - 1;
  125.  
  126.     while ( nodes[ id ].parent != -1 )
  127.     {
  128.         route.push_back( nodes[ id ] );
  129.         id = nodes[ id ].parent;
  130.     }
  131.  
  132.     // удаляем другие точки, нет смысла их хранить
  133.     reset_nodes();
  134.  
  135.     // разворачиваем маршрут в обратную сторону
  136.     std::reverse( route.begin(), route.end() );
  137.  
  138.     if ( route.size() < 4 )
  139.         return true;
  140.  
  141.     // фильтруем узлы, убираяя средние и оставляя крайние
  142.     for ( i = 1; i < route.size() - 2; i++ ) // -2 чтобы не зайти за границы и не удалить последний узел
  143.     {
  144.         if ( IsVisible( route[ i - 1 ].origin, route[ i + 1 ].origin ) &&
  145.             IsVisible( route[ i - 1 ].origin, route[ i ].origin ) &&
  146.             IsVisible( route[ i ].origin, route[ i + 1 ].origin ) )
  147.         {
  148.             route.erase( route.begin() + i );
  149.             i--;
  150.         }
  151.     }
  152.  
  153.     return true;
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement