Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | pmbaty | 1 | /* |
2 | * Portions of this file are copyright Rebirth contributors and licensed as |
||
3 | * described in COPYING.txt. |
||
4 | * Portions of this file are copyright Parallax Software and licensed |
||
5 | * according to the Parallax license. |
||
6 | * See COPYING.txt for license details. |
||
7 | */ |
||
8 | |||
9 | #pragma once |
||
10 | |||
11 | #include <type_traits> |
||
12 | #include <physfs.h> |
||
13 | #include "piggy.h" |
||
14 | #include "maths.h" |
||
15 | #include "textures.h" |
||
16 | #include "fwd-object.h" |
||
17 | #include "fwd-segment.h" |
||
18 | #include "cpp-valptridx.h" |
||
19 | |||
20 | namespace dcx { |
||
21 | using actdoornum_t = uint8_t; |
||
22 | constexpr std::integral_constant<std::size_t, 255> MAX_WALLS{}; // Maximum number of walls |
||
23 | constexpr std::integral_constant<std::size_t, 90> MAX_DOORS{}; // Maximum number of open doors |
||
24 | struct active_door; |
||
25 | } |
||
26 | DXX_VALPTRIDX_DECLARE_SUBTYPE(dcx::, active_door, actdoornum_t, MAX_DOORS); |
||
27 | |||
28 | #include "fwd-valptridx.h" |
||
29 | |||
30 | #ifdef dsx |
||
31 | namespace dsx { |
||
32 | #if defined(DXX_BUILD_DESCENT_I) |
||
33 | constexpr std::integral_constant<std::size_t, 30> MAX_WALL_ANIMS{}; // Maximum different types of doors |
||
34 | #elif defined(DXX_BUILD_DESCENT_II) |
||
35 | constexpr std::integral_constant<std::size_t, 60> MAX_WALL_ANIMS{}; // Maximum different types of doors |
||
36 | #endif |
||
37 | |||
38 | enum wall_type_t : uint8_t |
||
39 | { |
||
40 | WALL_NORMAL = 0, // Normal wall |
||
41 | WALL_BLASTABLE = 1, // Removable (by shooting) wall |
||
42 | WALL_DOOR = 2, // Door |
||
43 | WALL_ILLUSION = 3, // Wall that appears to be there, but you can fly thru |
||
44 | WALL_OPEN = 4, // Just an open side. (Trigger) |
||
45 | WALL_CLOSED = 5, // Wall. Used for transparent walls. |
||
46 | #if defined(DXX_BUILD_DESCENT_II) |
||
47 | WALL_OVERLAY = 6, // Goes over an actual solid side. For triggers |
||
48 | WALL_CLOAKED = 7, // Can see it, and see through it |
||
49 | #endif |
||
50 | }; |
||
51 | } |
||
52 | |||
53 | namespace dcx { |
||
54 | typedef unsigned wall_flag_t; |
||
55 | constexpr std::integral_constant<wall_flag_t, 1> WALL_BLASTED{}; // Blasted out wall. |
||
56 | constexpr std::integral_constant<wall_flag_t, 2> WALL_DOOR_OPENED{}; // Open door. |
||
57 | constexpr std::integral_constant<wall_flag_t, 8> WALL_DOOR_LOCKED{}; // Door is locked. |
||
58 | constexpr std::integral_constant<wall_flag_t, 16> WALL_DOOR_AUTO{}; // Door automatically closes after time. |
||
59 | constexpr std::integral_constant<wall_flag_t, 32> WALL_ILLUSION_OFF{}; // Illusionary wall is shut off. |
||
60 | constexpr std::integral_constant<wall_flag_t, 64> WALL_EXPLODING{}; |
||
61 | } |
||
62 | #if defined(DXX_BUILD_DESCENT_II) |
||
63 | namespace dsx { |
||
64 | constexpr std::integral_constant<wall_flag_t, 128> WALL_BUDDY_PROOF{}; // Buddy assumes he cannot get through this wall. |
||
65 | } |
||
66 | #endif |
||
67 | |||
68 | namespace dcx { |
||
69 | typedef unsigned wall_state_t; |
||
70 | constexpr std::integral_constant<wall_state_t, 0> WALL_DOOR_CLOSED{}; // Door is closed |
||
71 | constexpr std::integral_constant<wall_state_t, 1> WALL_DOOR_OPENING{}; // Door is opening. |
||
72 | constexpr std::integral_constant<wall_state_t, 2> WALL_DOOR_WAITING{}; // Waiting to close |
||
73 | constexpr std::integral_constant<wall_state_t, 3> WALL_DOOR_CLOSING{}; // Door is closing |
||
74 | } |
||
75 | #if defined(DXX_BUILD_DESCENT_II) |
||
76 | namespace dsx { |
||
77 | constexpr std::integral_constant<wall_state_t, 4> WALL_DOOR_OPEN{}; // Door is open, and staying open |
||
78 | constexpr std::integral_constant<wall_state_t, 5> WALL_DOOR_CLOAKING{}; // Wall is going from closed -> open |
||
79 | constexpr std::integral_constant<wall_state_t, 6> WALL_DOOR_DECLOAKING{}; // Wall is going from open -> closed |
||
80 | } |
||
81 | #endif |
||
82 | |||
83 | namespace dcx { |
||
84 | enum wall_key_t : uint8_t |
||
85 | { |
||
86 | KEY_NONE = 1, |
||
87 | KEY_BLUE = 2, |
||
88 | KEY_RED = 4, |
||
89 | KEY_GOLD = 8, |
||
90 | }; |
||
91 | |||
92 | constexpr std::integral_constant<fix, 100 * F1_0> WALL_HPS{}; // Normal wall's hp |
||
93 | constexpr std::integral_constant<fix, 5 * F1_0> WALL_DOOR_INTERVAL{}; // How many seconds a door is open |
||
94 | |||
95 | constexpr fix DOOR_OPEN_TIME = i2f(2); // How long takes to open |
||
96 | constexpr fix DOOR_WAIT_TIME = i2f(5); // How long before auto door closes |
||
97 | } |
||
98 | |||
99 | #ifdef dsx |
||
100 | namespace dsx { |
||
101 | #if defined(DXX_BUILD_DESCENT_I) |
||
102 | constexpr std::integral_constant<std::size_t, 20> MAX_CLIP_FRAMES{}; |
||
103 | #elif defined(DXX_BUILD_DESCENT_II) |
||
104 | constexpr std::integral_constant<std::size_t, 50> MAX_CLIP_FRAMES{}; |
||
105 | #endif |
||
106 | } |
||
107 | |||
108 | namespace dcx { |
||
109 | template <unsigned value> |
||
110 | struct WALL_IS_DOORWAY_FLAG |
||
111 | { |
||
112 | constexpr operator unsigned() const { return value; } |
||
113 | template <unsigned F2> |
||
114 | constexpr WALL_IS_DOORWAY_FLAG<value | F2> operator|(WALL_IS_DOORWAY_FLAG<F2>) const |
||
115 | { |
||
116 | return {}; |
||
117 | } |
||
118 | void *operator &() const = delete; |
||
119 | }; |
||
120 | |||
121 | template <unsigned F> |
||
122 | struct WALL_IS_DOORWAY_sresult_t |
||
123 | { |
||
124 | }; |
||
125 | |||
126 | template <unsigned F> |
||
127 | static inline constexpr WALL_IS_DOORWAY_sresult_t<F> WALL_IS_DOORWAY_sresult(WALL_IS_DOORWAY_FLAG<F>) |
||
128 | { |
||
129 | return {}; |
||
130 | } |
||
131 | |||
132 | struct WALL_IS_DOORWAY_result_t; |
||
133 | |||
134 | // WALL_IS_DOORWAY flags. |
||
135 | constexpr WALL_IS_DOORWAY_FLAG<1> WID_FLY_FLAG{}; |
||
136 | constexpr WALL_IS_DOORWAY_FLAG<2> WID_RENDER_FLAG{}; |
||
137 | constexpr WALL_IS_DOORWAY_FLAG<4> WID_RENDPAST_FLAG{}; |
||
138 | constexpr WALL_IS_DOORWAY_FLAG<8> WID_EXTERNAL_FLAG{}; |
||
139 | } |
||
140 | #if defined(DXX_BUILD_DESCENT_II) |
||
141 | namespace dsx { |
||
142 | constexpr WALL_IS_DOORWAY_FLAG<16> WID_CLOAKED_FLAG{}; |
||
143 | } |
||
144 | #endif |
||
145 | |||
146 | namespace dcx { |
||
147 | // WALL_IS_DOORWAY return values F/R/RP |
||
148 | constexpr auto WID_WALL = WALL_IS_DOORWAY_sresult(WID_RENDER_FLAG); // 0/1/0 wall |
||
149 | constexpr auto WID_TRANSPARENT_WALL = WALL_IS_DOORWAY_sresult(WID_RENDER_FLAG | WID_RENDPAST_FLAG); // 0/1/1 transparent wall |
||
150 | constexpr auto WID_ILLUSORY_WALL = WALL_IS_DOORWAY_sresult(WID_FLY_FLAG | WID_RENDER_FLAG); // 1/1/0 illusory wall |
||
151 | constexpr auto WID_TRANSILLUSORY_WALL = WALL_IS_DOORWAY_sresult(WID_FLY_FLAG | WID_RENDER_FLAG | WID_RENDPAST_FLAG); // 1/1/1 transparent illusory wall |
||
152 | constexpr auto WID_NO_WALL = WALL_IS_DOORWAY_sresult(WID_FLY_FLAG | WID_RENDPAST_FLAG); // 1/0/1 no wall, can fly through |
||
153 | constexpr auto WID_EXTERNAL = WALL_IS_DOORWAY_sresult(WID_EXTERNAL_FLAG); // 0/0/0/1 don't see it, dont fly through it |
||
154 | } |
||
155 | #if defined(DXX_BUILD_DESCENT_II) |
||
156 | namespace dsx { |
||
157 | constexpr auto WID_CLOAKED_WALL = WALL_IS_DOORWAY_sresult(WID_RENDER_FLAG | WID_RENDPAST_FLAG | WID_CLOAKED_FLAG); |
||
158 | } |
||
159 | #endif |
||
160 | #endif |
||
161 | |||
162 | namespace dcx { |
||
163 | |||
164 | struct stuckobj; |
||
165 | struct v16_wall; |
||
166 | struct v19_wall; |
||
167 | |||
168 | typedef unsigned wall_clip_flag_t; |
||
169 | constexpr std::integral_constant<wall_clip_flag_t, 1> WCF_EXPLODES{}; //door explodes when opening |
||
170 | constexpr std::integral_constant<wall_clip_flag_t, 2> WCF_BLASTABLE{}; //this is a blastable wall |
||
171 | constexpr std::integral_constant<wall_clip_flag_t, 4> WCF_TMAP1{}; //this uses primary tmap, not tmap2 |
||
172 | constexpr std::integral_constant<wall_clip_flag_t, 8> WCF_HIDDEN{}; //this uses primary tmap, not tmap2 |
||
173 | } |
||
174 | |||
175 | #ifdef dsx |
||
176 | namespace dsx { |
||
177 | struct wall; |
||
178 | struct wclip; |
||
179 | constexpr std::integral_constant<std::size_t, 20> MAX_CLIP_FRAMES_D1{}; |
||
180 | } |
||
181 | |||
182 | #if defined(DXX_BUILD_DESCENT_II) |
||
183 | namespace dsx { |
||
184 | struct cloaking_wall; |
||
185 | constexpr std::integral_constant<std::size_t, 10> MAX_CLOAKING_WALLS{}; |
||
186 | using clwallnum_t = uint8_t; |
||
187 | } |
||
188 | DXX_VALPTRIDX_DECLARE_SUBTYPE(dsx::, cloaking_wall, clwallnum_t, dsx::MAX_CLOAKING_WALLS); |
||
189 | namespace dsx { |
||
190 | DXX_VALPTRIDX_DEFINE_SUBTYPE_TYPEDEFS(cloaking_wall, clwall); |
||
191 | } |
||
192 | #endif |
||
193 | |||
194 | DXX_VALPTRIDX_DECLARE_SUBTYPE(dsx::, wall, wallnum_t, dcx::MAX_WALLS); |
||
195 | namespace dsx { |
||
196 | DXX_VALPTRIDX_DEFINE_SUBTYPE_TYPEDEFS(wall, wall); |
||
197 | using wall_animations_array = std::array<wclip, MAX_WALL_ANIMS>; |
||
198 | constexpr valptridx<wall>::magic_constant<0xffff> wall_none{}; |
||
199 | } |
||
200 | |||
201 | namespace dcx { |
||
202 | DXX_VALPTRIDX_DEFINE_SUBTYPE_TYPEDEFS(active_door, actdoor); |
||
203 | extern unsigned Num_wall_anims; |
||
204 | } |
||
205 | #endif |
||
206 | |||
207 | #if DXX_USE_EDITOR |
||
208 | #ifdef dsx |
||
209 | namespace dsx { |
||
210 | void wall_init(); |
||
211 | } |
||
212 | #endif |
||
213 | #endif |
||
214 | |||
215 | #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) |
||
216 | // Automatically checks if a there is a doorway (i.e. can fly through) |
||
217 | #ifdef dsx |
||
218 | namespace dsx { |
||
219 | WALL_IS_DOORWAY_result_t WALL_IS_DOORWAY(const GameBitmaps_array &GameBitmaps, const Textures_array &Textures, fvcwallptr &vcwallptr, cscusegment seg, const uint_fast32_t side); |
||
220 | |||
221 | // Deteriorate appearance of wall. (Changes bitmap (paste-ons)) |
||
222 | } |
||
223 | #endif |
||
224 | void wall_damage(vmsegptridx_t seg, unsigned side, fix damage); |
||
225 | |||
226 | // Destroys a blastable wall. (So it is an opening afterwards) |
||
227 | void wall_destroy(vmsegptridx_t seg, unsigned side); |
||
228 | |||
229 | #ifdef dsx |
||
230 | namespace dsx { |
||
231 | |||
232 | void wall_illusion_on(fvmwallptr &, vcsegptridx_t seg, unsigned side); |
||
233 | void wall_illusion_off(fvmwallptr &, vcsegptridx_t seg, unsigned side); |
||
234 | |||
235 | // Opens a door |
||
236 | void wall_open_door(vmsegptridx_t seg, unsigned side); |
||
237 | |||
238 | #if defined(DXX_BUILD_DESCENT_I) |
||
239 | #elif defined(DXX_BUILD_DESCENT_II) |
||
240 | // Closes a door |
||
241 | void wall_close_door(wall_array &Walls, vmsegptridx_t seg, unsigned side); |
||
242 | #endif |
||
243 | } |
||
244 | #endif |
||
245 | |||
246 | //return codes for wall_hit_process() |
||
247 | enum class wall_hit_process_t : unsigned |
||
248 | { |
||
249 | WHP_NOT_SPECIAL = 0, //wasn't a quote-wall-unquote |
||
250 | WHP_NO_KEY = 1, //hit door, but didn't have key |
||
251 | WHP_BLASTABLE = 2, //hit blastable wall |
||
252 | WHP_DOOR = 3, //a door (which will now be opening) |
||
253 | }; |
||
254 | |||
255 | // Determines what happens when a wall is shot |
||
256 | //obj is the object that hit...either a weapon or the player himself |
||
257 | #ifdef dsx |
||
258 | class player_flags; |
||
259 | namespace dsx { |
||
260 | wall_hit_process_t wall_hit_process(player_flags, vmsegptridx_t seg, unsigned side, fix damage, unsigned playernum, const object &obj); |
||
261 | |||
262 | // Opens/destroys specified door. |
||
263 | } |
||
264 | #endif |
||
265 | void wall_toggle(fvmwallptr &vmwallptr, vmsegptridx_t segnum, unsigned side); |
||
266 | |||
267 | // Called once per frame.. |
||
268 | #ifdef dsx |
||
269 | namespace dsx { |
||
270 | void wall_frame_process(); |
||
271 | } |
||
272 | #endif |
||
273 | |||
274 | //set the tmap_num or tmap_num2 field for a wall/door |
||
275 | void wall_set_tmap_num(const wclip &, vmsegptridx_t seg, unsigned side, vmsegptridx_t csegp, unsigned cside, unsigned frame_num); |
||
276 | |||
277 | #if defined(DXX_BUILD_DESCENT_II) |
||
278 | //start wall open <-> closed transitions |
||
279 | namespace dsx { |
||
280 | void start_wall_cloak(vmsegptridx_t seg, unsigned side); |
||
281 | void start_wall_decloak(vmsegptridx_t seg, unsigned side); |
||
282 | |||
283 | void cloaking_wall_read(cloaking_wall &cw, PHYSFS_File *fp); |
||
284 | void cloaking_wall_write(const cloaking_wall &cw, PHYSFS_File *fp); |
||
285 | void blast_nearby_glass(const object &objp, fix damage); |
||
286 | } |
||
287 | #endif |
||
288 | #endif |
||
289 | |||
290 | void wclip_read(PHYSFS_File *, wclip &wc); |
||
291 | #if 0 |
||
292 | void wclip_write(PHYSFS_File *, const wclip &); |
||
293 | #endif |
||
294 | |||
295 | void v16_wall_read(PHYSFS_File *fp, v16_wall &w); |
||
296 | void v19_wall_read(PHYSFS_File *fp, v19_wall &w); |
||
297 | void wall_read(PHYSFS_File *fp, wall &w); |
||
298 | |||
299 | void active_door_read(PHYSFS_File *fp, active_door &ad); |
||
300 | void active_door_write(PHYSFS_File *fp, const active_door &ad); |
||
301 | |||
302 | void wall_write(PHYSFS_File *fp, const wall &w, short version); |
||
303 | void wall_close_door_ref(fvmsegptridx &vmsegptridx, wall_array &Walls, const wall_animations_array &WallAnims, active_door &); |
||
304 | #endif |