1 #include <algorithm>
2 #include "xr_gamemtls_lib.h"
3 #include "xr_file_system.h"
4 #include "xr_utils.h"
5 
6 using namespace xray_re;
7 
~xr_gamemtls_lib()8 xr_gamemtls_lib::~xr_gamemtls_lib()
9 {
10 	delete_elements(m_materials);
11 	delete_elements(m_material_pairs);
12 }
13 
load(xr_reader & r)14 void xr_gamemtl::load(xr_reader& r)
15 {
16 	if (!r.find_chunk(GAMEMTL_CHUNK_MAIN))
17 		xr_not_expected();
18 	id = r.r_u32();
19 	r.r_sz(name);
20 	r.debug_find_chunk();
21 
22 	if (r.find_chunk(GAMEMTL_CHUNK_DESC)) {
23 		r.r_sz(desc);
24 		r.debug_find_chunk();
25 	}
26 
27 	if (!r.find_chunk(GAMEMTL_CHUNK_FLAGS))
28 		xr_not_expected();
29 	flags = r.r_u32();
30 	r.debug_find_chunk();
31 
32 	if (!r.find_chunk(GAMEMTL_CHUNK_PHYSICS))
33 		xr_not_expected();
34 	friction = r.r_float();
35 	damping = r.r_float();
36 	spring = r.r_float();
37 	bouncing_start_velocity = r.r_float();
38 	bounce = r.r_float();
39 	r.debug_find_chunk();
40 
41 	if (!r.find_chunk(GAMEMTL_CHUNK_FACTORS))
42 		xr_not_expected();
43 	shoot_factor = r.r_float();
44 	bounce_damage_factor = r.r_float();
45 	vis_transparency_factor = r.r_float();
46 	snd_occlusion_factor = r.r_float();
47 	r.debug_find_chunk();
48 
49 	//in build 1580 not present
50 	if (!r.r_chunk<float>(GAMEMTL_CHUNK_FLOTATION, flotation_factor))
51 		flotation_factor = 1.0f;
52 
53 	//in build 1865 not present
54 	if (!r.r_chunk<float>(GAMEMTL_CHUNK_INJURY, injurious_speed))
55 		injurious_speed = 0.0f;
56 }
57 
load(xr_reader & r)58 void xr_gamemtlpair::load(xr_reader& r)
59 {
60 	if (!r.find_chunk(GAMEMTLPAIR_CHUNK_PAIR))
61 		xr_not_expected();
62 	mtl0 = r.r_u32();
63 	mtl1 = r.r_u32();
64 	id = r.r_u32();
65 	id_parent = r.r_u32();
66 	own_props = r.r_u32();
67 	r.debug_find_chunk();
68 
69 	if (!r.find_chunk(GAMEMTLPAIR_CHUNK_BREAKING))
70 		xr_not_expected();
71 	r.r_sz(breaking_sounds);
72 	r.debug_find_chunk();
73 
74 	if (!r.find_chunk(GAMEMTLPAIR_CHUNK_STEP))
75 		xr_not_expected();
76 	r.r_sz(step_sounds);
77 	r.debug_find_chunk();
78 
79 	if (!r.find_chunk(GAMEMTLPAIR_CHUNK_COLLIDE))
80 		xr_not_expected();
81 	r.r_sz(collide_sounds);
82 	r.r_sz(collide_particles);
83 	r.r_sz(collide_marks);
84 	r.debug_find_chunk();
85 }
86 
load(xr_reader & r)87 void xr_gamemtls_lib::load(xr_reader& r)
88 {
89 	uint16_t version;
90 	if (!r.r_chunk<uint16_t>(GAMEMTLS_CHUNK_VERSION, version))
91 		xr_not_expected();
92 	xr_assert(version == GAMEMTLS_VERSION);
93 
94 	if (!r.find_chunk(GAMEMTLS_CHUNK_AUTOINC))
95 		xr_not_expected();
96 	m_material_index = r.r_u32();
97 	m_material_pair_index = r.r_u32();
98 	r.debug_find_chunk();
99 
100 	xr_reader* s = r.open_chunk(GAMEMTLS_CHUNK_MATERIALS);
101 	if (s) {
102 		xr_reader* f;
103 		for (uint32_t id = 0; (f = s->open_chunk(id)); ++id) {
104 			xr_gamemtl* material = new xr_gamemtl;
105 			material->load(*f);
106 			m_materials.push_back(material);
107 			s->close_chunk(f);
108 		}
109 		r.close_chunk(s);
110 	}
111 	s = r.open_chunk(GAMEMTLS_CHUNK_MATERIAL_PAIRS);
112 	if (s) {
113 		xr_reader* f;
114 		for (uint32_t id = 0; (f = s->open_chunk(id)); ++id) {
115 			xr_gamemtlpair* gamemtlpair = new xr_gamemtlpair;
116 			gamemtlpair->load(*f);
117 			m_material_pairs.push_back(gamemtlpair);
118 			s->close_chunk(f);
119 		}
120 		r.close_chunk(s);
121 	}
122 }
123 
load(const char * path,const char * name)124 bool xr_gamemtls_lib::load(const char* path, const char* name)
125 {
126 	xr_file_system& fs = xr_file_system::instance();
127 	xr_reader* r = fs.r_open(path, name);
128 	if (r == 0)
129 		return false;
130 	load(*r);
131 	fs.r_close(r);
132 	return true;
133 }
134 
load(const std::string & path)135 bool xr_gamemtls_lib::load(const std::string& path)
136 {
137 	xr_file_system& fs = xr_file_system::instance();
138 	xr_reader* r = fs.r_open(path);
139 	if (r == 0)
140 		return false;
141 	load(*r);
142 	fs.r_close(r);
143 	return true;
144 }
145 
146 struct id_pred {
147 #if 1
operator ()id_pred148 	bool operator()(const xr_gamemtl* l, const xr_gamemtl* r) const { return l->id < r->id; }
149 #else
150 	uint32_t id;
151 	explicit id_pred(uint32_t _id): id(_id) {}
152 	bool operator()(const xr_gamemtl* l) const { return l->id < id; }
153 #endif
154 };
155 
get_material(uint32_t id) const156 const xr_gamemtl* xr_gamemtls_lib::get_material(uint32_t id) const
157 {
158 #if 1
159 	xr_gamemtl pattern;
160 	pattern.id = id;
161 	xr_gamemtl_vec_cit it = std::lower_bound(m_materials.begin(), m_materials.end(), &pattern, id_pred());
162 #else
163 	xr_gamemtl_vec_cit it = lower_bound_if(m_materials.begin(), m_materials.end(), id_pred(id));
164 #endif
165 	return (it == m_materials.end() || (*it)->id != id) ? 0 : *it;
166 }
167 
get_material(const char * name) const168 const xr_gamemtl* xr_gamemtls_lib::get_material(const char* name) const
169 {
170 	for (xr_gamemtl_vec_cit it = m_materials.begin(), end = m_materials.end(); it != end; ++it) {
171 		if ((*it)->name == name)
172 			return *it;
173 	}
174 	return 0;
175 }
176