-
Notifications
You must be signed in to change notification settings - Fork 5
/
nav_area.cpp
130 lines (95 loc) · 3.71 KB
/
nav_area.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "nav_area.h"
#include <algorithm>
#include <iostream>
namespace nav_mesh {
nav_area::nav_area( nav_buffer& buffer ) {
load( buffer );
}
bool nav_area::is_within( vec3_t position ) {
if ( position.x < m_nw_corner.x )
return false;
if ( position.x > m_se_corner.x )
return false;
if ( position.y < m_nw_corner.y )
return false;
if ( position.y > m_se_corner.y )
return false;
return true;
}
void nav_area::load( nav_buffer& buffer ) {
m_id = buffer.read< std::uint32_t >( );
m_attribute_flags = buffer.read< std::uint32_t >( );
buffer.read( &m_nw_corner, sizeof vec3_t );
buffer.read( &m_se_corner, sizeof vec3_t );
m_center = ( m_nw_corner + m_se_corner ) * .5f;
auto corner_delta = m_se_corner - m_nw_corner;
if ( corner_delta.x > 0.f && corner_delta.y > 0.f ) {
m_inv_dx_corners = 1.f / corner_delta.x;
m_inv_dy_corners = 1.f / corner_delta.y;
} else
m_inv_dx_corners = m_inv_dy_corners = 0.f;
m_ne_z = buffer.read< float >( );
m_sw_z = buffer.read< float >( );
for ( std::uint32_t i = 0; i < 4; i++ ) {
auto connection_count = buffer.read< std::uint32_t >( );
for ( std::uint32_t j = 0; j < connection_count; j++ ) {
auto connect_id = buffer.read< std::uint32_t >( );
if ( connect_id == m_id )
continue;
m_connections.push_back( nav_connect_t( connect_id ) );
}
}
auto hiding_spot_count = buffer.read< std::uint8_t >( );
for ( std::uint32_t i = 0; i < hiding_spot_count; i++ )
m_hiding_spots.push_back( nav_hiding_spot( buffer ) );
auto encounter_path_count = buffer.read< std::uint32_t >( );
for ( std::uint32_t i = 0; i < encounter_path_count; i++ ) {
nav_spot_encounter_t spot_encounter = { };
spot_encounter.from.id = buffer.read< std::uint32_t >( );
spot_encounter.from_direction = buffer.read< std::uint8_t >( );
spot_encounter.to.id = buffer.read< std::uint32_t >( );
spot_encounter.to_direction = buffer.read< std::uint8_t >( );
auto spot_count = buffer.read< std::uint8_t >( );
nav_spot_order_t spot_order = { };
for ( std::uint8_t i = 0; i < spot_count; i++ ) {
spot_order.id = buffer.read< std::uint32_t >( );
spot_order.t = float( buffer.read< std::uint8_t >( ) ) / 255.f;
spot_encounter.spot_order.push_back( spot_order );
}
m_spot_encounters.push_back( spot_encounter );
}
m_place = buffer.read< std::uint16_t >( ) - 1;
for ( std::uint32_t i = 0; i < 2; i++ ) {
auto ladder_count = buffer.read< std::uint32_t >( );
for ( std::uint32_t j = 0; j < ladder_count; j++ ) {
nav_ladder_connect_t ladder_connect( buffer.read< std::uint32_t >( ) );
bool skip = false;
for ( std::uint32_t j = 0; j < m_ladder_connections[ i ].size( ); j++ ) {
if ( m_ladder_connections[ i ][ j ].id == ladder_connect.id ) {
skip = true;
break;
}
}
if ( skip )
continue;
m_ladder_connections[ i ].push_back( ladder_connect );
}
}
for ( std::uint32_t i = 0; i < 2; i++ )
m_earliest_occupy_time[ i ] = buffer.read< float >( );
for ( std::uint32_t i = 0; i < 4; i++ )
m_light_intensity[ i ] = buffer.read< float >( );
auto visible_area_count = buffer.read< std::uint32_t >( );
for ( std::uint32_t i = 0; i < visible_area_count; i++ ) {
nav_area_bind_info_t area_bind_info = { };
area_bind_info.id = buffer.read< std::uint32_t >( );
area_bind_info.attributes = buffer.read< std::uint8_t >( );
m_potentially_visible_areas.push_back( area_bind_info );
}
m_inherit_visibility_from.id = buffer.read< std::uint32_t >( );
//Credits: https://github.com/mrazza/gonav/blob/master/parser.go#L258-L260
auto unknown_count = buffer.read< std::uint8_t >( );
for ( std::uint8_t i = 0; i < unknown_count; i++ )
buffer.skip( 0xE );
}
}