Skip to content

Commit f22e58a

Browse files
committed
parse prop flags and further ensure props are inited and closed correctly
1 parent 7cceae0 commit f22e58a

File tree

9 files changed

+99
-3
lines changed

9 files changed

+99
-3
lines changed

code/lab/manager/lab_manager.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "ship/ship.h"
1111
#include "ship/shipfx.h"
1212
#include "particle/particle.h"
13+
#include "prop/prop.h"
1314
#include "weapon/muzzleflash.h"
1415
#include "weapon/beam.h"
1516
#include "ai/aigoals.h"
@@ -45,6 +46,7 @@ LabManager::LabManager() {
4546
debris_init();
4647
extern void debris_page_in();
4748
debris_page_in();
49+
props_level_init();
4850
asteroid_level_init();
4951
shockwave_level_init();
5052
ship_level_init();

code/lab/manager/lab_manager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ class LabManager {
5858
// Unload any asteroids that were loaded
5959
asteroid_level_close();
6060

61+
// Unload any props that were loaded
62+
props_level_close();
63+
6164
// Lab can only be entered from the Mainhall so this should be safe
6265
model_free_all();
6366

code/object/object.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,10 @@ void obj_delete_all()
672672
obj_delete(i);
673673
}
674674

675+
// If we've removed all objects then we can safely
676+
// clear the Props vector TODO maybe remove this?
677+
Props.clear();
678+
675679
mprintf(("Cleanup: Deleted %i objects\n", counter));
676680
}
677681

code/prop/prop.cpp

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
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

2526
static 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+
726808
void 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
740821
int prop_check_collision(object* prop_obj, object* other_obj, vec3d* hitpos, collision_info_struct* prop_hit_info)
741822
{

code/prop/prop.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ int prop_create(matrix* orient, vec3d* pos, int prop_type, const char* name = nu
7878
void prop_delete(object* obj);
7979
void prop_render(object* obj, model_draw_list* scene);
8080

81+
void props_level_init();
8182
void props_level_close();
8283

8384
int prop_info_lookup(const char* token);

code/prop/prop_flags.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ FLAG_LIST(Prop_Flags){
2424
FLAG_LIST(Info_Flags){
2525
No_collide = 0, // No collisions
2626
No_fred, // not available in fred
27-
//No_impact_debris,
2827
No_lighting,
28+
//No_impact_debris,
2929

3030
NUM_VALUES};
3131

fred2/management.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,7 @@ void clear_mission(bool fast_reload)
877877
model_free_all(); // Free all existing models
878878

879879
ai_init();
880+
props_level_init();
880881
asteroid_level_init();
881882
ship_level_init();
882883
nebula_init(Nebula_index, Nebula_pitch, Nebula_bank, Nebula_heading);

freespace2/freespace.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,7 @@ void game_level_close()
935935
shockwave_level_close();
936936
fireball_close();
937937
shield_hit_close();
938+
props_level_close();
938939
asteroid_level_close();
939940
jumpnode_level_close();
940941
waypoint_level_close();
@@ -1064,6 +1065,7 @@ void game_level_init()
10641065
NavSystem_Init(); // zero out the nav system
10651066

10661067
ai_level_init(); // Call this before ship_init() because it reads ai.tbl.
1068+
props_level_init();
10671069
multi_init_oo_and_ship_tracker(); // Inits/resets multiplayer ship tracking system. Has to be done before creating any ships.
10681070
ship_level_init();
10691071
player_level_init();

qtfred/src/mission/Editor.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <mission/missiongoals.h>
1414
#include <asteroid/asteroid.h>
1515
#include <jumpnode/jumpnode.h>
16+
#include <prop/prop.h>
1617
#include <util.h>
1718
#include <mission/missionmessage.h>
1819
#include <gamesnd/eventmusic.h>
@@ -484,6 +485,7 @@ void Editor::clearMission(bool fast_reload) {
484485
model_free_all(); // Free all existing models
485486

486487
ai_init();
488+
props_level_init();
487489
asteroid_level_init();
488490
ship_level_init();
489491
nebula_init(Nebula_index, Nebula_pitch, Nebula_bank, Nebula_heading);

0 commit comments

Comments
 (0)