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