1 #include "xr_scene.h"
2 #include "xr_scene_ways.h"
3 #include "xr_reader.h"
4 #include "xr_writer.h"
5 #include "xr_string_utils.h"
6 
7 #include <map>
8 
9 using namespace xray_re;
10 
xr_way_object(xr_scene & scene)11 xr_way_object::xr_way_object(xr_scene& scene):
12 	xr_custom_object(scene, TOOLS_CLASS_WAY),
13 	m_type(WAY_TYPE_PATROL_PATH) {}
14 
~xr_way_object()15 xr_way_object::~xr_way_object() {}
16 
operator ()read_point_le17 struct read_point_le { void operator()(way_point_le& point, xr_reader& r) {
18 	r.r_fvector3(point.position);
19 	point.flags = r.r_u32();
20 	point.id = r.r_u16();
21 	r.r_sz(point.name);
22 }};
23 
load(xr_reader & r)24 void xr_way_object::load(xr_reader& r)
25 {
26 	uint16_t version;
27 	if (!r.r_chunk<uint16_t>(WAYOBJECT_CHUNK_VERSION, version))
28 		xr_not_expected();
29 	xr_assert(version == WAYOBJECT_VERSION);
30 
31 	xr_custom_object::load(r);
32 
33 	if (!r.find_chunk(WAYOBJECT_CHUNK_POINTS))
34 		xr_not_expected();
35 	r.r_seq(r.r_u16(), m_points, read_point_le());
36 	r.debug_find_chunk();
37 
38 	if (!r.find_chunk(WAYOBJECT_CHUNK_LINKS))
39 		xr_not_expected();
40 	r.r_seq(r.r_u16(), m_links, way_link_io());
41 	r.debug_find_chunk();
42 
43 	r.r_chunk<uint32_t>(WAYOBJECT_CHUNK_TYPE, m_type);
44 }
45 
operator ()write_point_le46 struct write_point_le { void operator()(const way_point_le& point, xr_writer& w) const {
47 	w.w_fvector3(point.position);
48 	w.w_u32(point.flags);
49 	w.w_u16(point.id);
50 	w.w_sz(point.name);
51 }};
52 
save(xr_writer & w) const53 void xr_way_object::save(xr_writer& w) const
54 {
55 	xr_custom_object::save(w);
56 	w.w_chunk<uint16_t>(WAYOBJECT_CHUNK_VERSION, WAYOBJECT_VERSION);
57 
58 	w.open_chunk(WAYOBJECT_CHUNK_POINTS);
59 	w.w_size_u16(m_points.size());
60 	w.w_seq(m_points, write_point_le());
61 	w.close_chunk();
62 
63 	w.open_chunk(WAYOBJECT_CHUNK_LINKS);
64 	w.w_size_u16(m_links.size());
65 	w.w_seq(m_links, way_link_io());
66 	w.close_chunk();
67 
68 	w.w_chunk<uint32_t>(WAYOBJECT_CHUNK_TYPE, m_type);
69 }
70 
operator ()write_point_ini71 struct write_point_ini { void operator()(const way_point_le& point, xr_ini_writer* w, uint32_t id) const {
72 	char buffer[128];
73 	char* buf = &buffer[0];
74 	int n = xr_snprintf(buf, sizeof(buffer), "wp_%d_flags", id);
75 	if (n > 0)
76 		w->write(buf, point.flags);
77 
78 	n = xr_snprintf(buf, sizeof(buffer), "wp_%d_name", id);
79 	if (n > 0)
80 		w->write(buf, point.name, false);
81 
82 	n = xr_snprintf(buf, sizeof(buffer), "wp_%d_pos", id);
83 	if (n > 0)
84 		w->write(buf, point.position);
85 
86 	n = xr_snprintf(buf, sizeof(buffer), "wp_%d_selected", id);
87 	if (n > 0)
88 		w->write(buf, "off", false);
89 }};
90 
save_v12(xr_ini_writer * w) const91 void xr_way_object::save_v12(xr_ini_writer* w) const
92 {
93 	xr_custom_object::save_v12(w);
94 
95 	// write links
96 	char buffer[128];
97 	char* buf = &buffer[0];
98 	typedef std::map<uint16_t, uint8_t> dict;
99 	typedef std::pair<uint16_t, uint8_t> dict_pair;
100 	dict indices;
101 	fvector2 link_vector;
102 	link_vector.y = 1.0;
103 
104 	way_link_vec_cit it = m_links.begin(), end = m_links.end();
105 	for (uint8_t id = 0; it != end; ++it) {
106 		way_link* link = (way_link *)&(*it);
107 
108 		dict::iterator pair = indices.find(link->from);
109 		if (pair != indices.end())
110 			id = ++pair->second;
111 		else
112 			indices.insert(dict_pair(link->from, id = 0));
113 
114 		int n = xr_snprintf(buf, sizeof(buffer), "link_wp_%d_%d", link->from, id);
115 		if (n > 0)
116 		{
117 			link_vector.x = link->to;
118 			link_vector.y = link->weight;
119 			w->write(buf, link_vector);
120 		}
121 	}
122 
123 	w->write("type", this->m_type);
124 	w->write("version", WAYOBJECT_VERSION);
125 
126 	// write waypoints
127 
128 	w->w_ini_seq(this->m_points, write_point_ini());
129 	w->write("wp_count", this->m_points.size());
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 
xr_scene_ways(xr_scene & scene)134 xr_scene_ways::xr_scene_ways(xr_scene& scene):
135 	xr_scene_objects(scene, "way.part", SCENE_CHUNK_WAYS) {}
136 
~xr_scene_ways()137 xr_scene_ways::~xr_scene_ways() {}
138 
load(xr_reader & r)139 void xr_scene_ways::load(xr_reader& r)
140 {
141 	uint16_t version = 0;
142 	r.r_chunk<uint16_t>(TOOLS_CHUNK_VERSION, version);
143 	xr_assert(version == 0);
144 	xr_scene_objects::load(r);
145 }
146 
save(xr_writer & w) const147 void xr_scene_ways::save(xr_writer& w) const
148 {
149 	xr_scene_objects::save(w);
150 	w.w_chunk<uint16_t>(TOOLS_CHUNK_VERSION, 0);
151 }
152 
save_v12(xr_ini_writer * w) const153 void xr_scene_ways::save_v12(xr_ini_writer* w) const
154 {
155 	w->open_section("main");
156 	w->write("objects_count", this->objects().size());
157 	w->write("version", 0);
158 	w->close_section();
159 
160 	scene().write_revision(w);
161 
162 	xr_scene_objects::save_v12(w);
163 }
164