66#include " model/model.h"
77#include " model/modelreplace.h"
88#include " parse/parselo.h"
9+ #include " prop/prop_flags.h"
910#include " render/3d.h"
1011#include " ship/shipfx.h"
1112#include " object/objcollide.h"
@@ -24,6 +25,15 @@ SCP_vector<prop_category> Prop_categories;
2425
2526static SCP_vector<SCP_string> Removed_props;
2627
28+ flag_def_list_new<Prop::Info_Flags> Prop_flags[] = {
29+ { " no_collide" , Prop::Info_Flags::No_collide, true , false },
30+ { " no_fred" , Prop::Info_Flags::No_fred, true , false },
31+ { " no lighting" , Prop::Info_Flags::No_lighting, true , false }
32+ // { "no impact debris", Prop::Info_Flags::No_impact_debris, true, false },
33+ };
34+
35+ const size_t Num_prop_flags = sizeof (Prop_flags) / sizeof (flag_def_list_new<Prop::Info_Flags>);
36+
2737/* *
2838 * Return the index of Prop_info[].name that is *token.
2939 */
@@ -193,7 +203,7 @@ void parse_prop_table(const char* filename)
193203 pip->name = fname;
194204 }
195205
196- if (optional_string (" + POF file:" )) {
206+ if (optional_string (" $ POF file:" )) {
197207 char temp[32 ];
198208 stuff_string (temp, F_NAME, MAX_FILENAME_LEN);
199209
@@ -257,6 +267,44 @@ void parse_prop_table(const char* filename)
257267 stuff_string (pip->category , F_NAME);
258268 }
259269
270+ if (optional_string (" $Flags:" )) {
271+ SCP_vector<SCP_string> prop_strings;
272+ stuff_string_list (prop_strings);
273+
274+ for (const auto & flag : prop_strings) {
275+ // get ship type from ship flags
276+ const char * cur_flag = flag.c_str ();
277+ bool flag_found = false ;
278+
279+ // check various ship flags
280+ for (size_t idx = 0 ; idx < Num_prop_flags; idx++) {
281+ if (!stricmp (Prop_flags[idx].name , cur_flag)) {
282+ flag_found = true ;
283+
284+ if (!Prop_flags[idx].in_use )
285+ Warning (LOCATION,
286+ " Use of '%s' flag for Prop Class '%s' - this flag is no longer needed." ,
287+ Prop_flags[idx].name ,
288+ pip->name .c_str ());
289+ else
290+ pip->flags .set (Prop_flags[idx].def );
291+
292+ break ;
293+ }
294+ }
295+
296+ // catch typos or deprecations
297+ if (!stricmp (cur_flag, " no-collide" ) || !stricmp (cur_flag, " no_collide" )) {
298+ flag_found = true ;
299+ pip->flags .set (Prop::Info_Flags::No_collide);
300+ }
301+
302+ if (!flag_found) {
303+ Warning (LOCATION, " Bogus string in ship flags: %s\n " , cur_flag);
304+ }
305+ }
306+ }
307+
260308 if (optional_string (" $Custom data:" )) {
261309 parse_string_map (pip->custom_data , " $end_custom_data" , " +Val:" );
262310 }
@@ -723,6 +771,40 @@ void prop_render(object* obj, model_draw_list* scene)
723771 model_render_queue (&render_info, scene, pip->model_num , &obj->orient , &obj->pos );
724772}
725773
774+ // Draft. Props vector uses std::optional to allow for empty slots for deleted props so the indices of the remaining
775+ // props do not change. In long FRED sessions without saving and loading, this can lead to a lot of empty slots. However,
776+ // saving and loading the level will naturally compact the props vector by way of clearing and re-adding props.
777+ void compact_props_vector ()
778+ {
779+ SCP_vector<std::optional<prop>> new_props;
780+ SCP_unordered_map<int , int > index_remap;
781+
782+ for (size_t i = 0 ; i < Props.size (); ++i) {
783+ if (Props[i].has_value ()) {
784+ index_remap[static_cast <int >(i)] = static_cast <int >(new_props.size ());
785+ new_props.push_back (std::move (Props[i]));
786+ }
787+ }
788+
789+ Props = std::move (new_props);
790+
791+ // Remap object instances
792+ for (object* obj = GET_FIRST (&obj_used_list); obj != END_OF_LIST (&obj_used_list); obj = GET_NEXT (obj)) {
793+ if (obj->type == OBJ_PROP && obj->instance >= 0 ) {
794+ auto it = index_remap.find (obj->instance );
795+ Assertion (it != index_remap.end (), " Object is pointing to invalid prop index %d! Get a coder!" , obj->instance );
796+
797+ if (it != index_remap.end ()) {
798+ obj->instance = it->second ;
799+ }
800+ }
801+ }
802+ }
803+
804+ void props_level_init () {
805+ Props.clear ();
806+ }
807+
726808void props_level_close ()
727809{
728810 for (auto & opt_prop : Props) {
@@ -735,7 +817,6 @@ void props_level_close()
735817 Props.clear ();
736818}
737819
738-
739820// handles prop-ship/debris/asteroid/weapon collisions
740821int prop_check_collision (object* prop_obj, object* other_obj, vec3d* hitpos, collision_info_struct* prop_hit_info)
741822{
0 commit comments