Skip to content

Commit 41a8b18

Browse files
authored
Qtfred visibility layers (scp-fs2open#7314)
* add visibility layers * save/load object layers using the mission file * use fill * fix rebase error
1 parent f991bf1 commit 41a8b18

15 files changed

Lines changed: 613 additions & 2 deletions

code/mission/missionparse.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,12 @@ path_restriction_t Path_restrictions[MAX_PATH_RESTRICTIONS];
184184

185185
extern int debrief_find_persona_index();
186186

187+
static bool mission_has_layer_name(const mission* pm, const SCP_string& layerName) {
188+
return std::any_of(pm->fred_layers.begin(), pm->fred_layers.end(), [&layerName](const SCP_string& existingLayer) {
189+
return stricmp(existingLayer.c_str(), layerName.c_str()) == 0;
190+
});
191+
}
192+
187193
//XSTR:OFF
188194

189195
const char *Nebula_filenames[NUM_NEBULAS] = {
@@ -2252,6 +2258,7 @@ int parse_create_object_sub(p_object *p_objp, bool standalone_ship)
22522258
}
22532259

22542260
shipp->group = p_objp->group;
2261+
shipp->fred_layer = p_objp->fred_layer;
22552262
shipp->escort_priority = p_objp->escort_priority;
22562263
shipp->ship_guardian_threshold = p_objp->ship_guardian_threshold;
22572264
shipp->use_special_explosion = p_objp->use_special_explosion;
@@ -3782,6 +3789,17 @@ int parse_object(mission *pm, int /*flag*/, p_object *p_objp)
37823789
if (optional_string("+Group:"))
37833790
stuff_int(&p_objp->group);
37843791

3792+
if (optional_string("+Layer:")) {
3793+
stuff_string(p_objp->fred_layer, F_NAME);
3794+
if (!mission_has_layer_name(&The_mission, p_objp->fred_layer)) {
3795+
if (p_objp->fred_layer.empty()) {
3796+
p_objp->fred_layer = "Default";
3797+
} else {
3798+
The_mission.fred_layers.push_back(p_objp->fred_layer);
3799+
}
3800+
}
3801+
}
3802+
37853803
bool table_score = false;
37863804
if (optional_string("+Use Table Score:")) {
37873805
table_score = true;
@@ -5190,6 +5208,17 @@ void parse_prop(mission* /*pm*/)
51905208
}
51915209
}
51925210

5211+
if (optional_string("+Layer:")) {
5212+
stuff_string(p.fred_layer, F_NAME);
5213+
if (!mission_has_layer_name(&The_mission, p.fred_layer)) {
5214+
if (p.fred_layer.empty()) {
5215+
p.fred_layer = "Default";
5216+
} else {
5217+
The_mission.fred_layers.push_back(p.fred_layer);
5218+
}
5219+
}
5220+
}
5221+
51935222
// if idx is still -1 then we have an empty props.tbl so we parse
51945223
// everything here and just discard it. A warning has already been generated above.
51955224
if (idx < 0) {
@@ -5371,6 +5400,11 @@ void post_process_mission_props()
53715400
if (propp.flags[Mission::Parse_Object_Flags::OF_No_collide]) {
53725401
obj.flags.remove(Object::Object_Flags::Collides);
53735402
}
5403+
5404+
auto createdProp = prop_id_lookup(obj.instance);
5405+
if (createdProp != nullptr) {
5406+
createdProp->fred_layer = propp.fred_layer;
5407+
}
53745408
}
53755409
}
53765410
}
@@ -7130,6 +7164,8 @@ void mission::Reset()
71307164

71317165
custom_data.clear();
71327166
custom_strings.clear();
7167+
fred_layers.clear();
7168+
fred_layers.emplace_back("Default");
71337169
}
71347170

71357171
void support_ship_info::reset()

code/mission/missionparse.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ typedef struct mission {
235235
SCP_map<SCP_string, SCP_string> custom_data;
236236

237237
SCP_vector<custom_string> custom_strings;
238+
SCP_vector<SCP_string> fred_layers;
238239

239240
void Reset( );
240241

@@ -475,6 +476,7 @@ class p_object
475476
object *created_object = nullptr; // Goober5000
476477
int collision_group_id = 0; // Goober5000
477478
int group = -1; // group object is within or -1 if none.
479+
SCP_string fred_layer = "Default";
478480
int persona_index = -1;
479481
int kamikaze_damage = 0; // base damage for a kamikaze attack
480482

code/missioneditor/missionsave.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4097,6 +4097,17 @@ int Fred_mission_save::save_objects()
40974097
fout(" %d", shipp->group);
40984098
}
40994099

4100+
if (save_config.save_format != MissionFormat::RETAIL &&
4101+
!shipp->fred_layer.empty() &&
4102+
stricmp(shipp->fred_layer.c_str(), "Default") != 0) {
4103+
if (optional_string_fred("+Layer:", "$Name:"))
4104+
parse_comments();
4105+
else
4106+
fout("\n+Layer:");
4107+
4108+
fout(" %s", shipp->fred_layer.c_str());
4109+
}
4110+
41004111
// always write out the score to ensure backwards compatibility. If the score is the same as the value
41014112
// in the table write out a flag to tell the game to simply use whatever is in the table instead
41024113
if (Ship_info[shipp->ship_info_index].score == shipp->score) {
@@ -5220,6 +5231,17 @@ int Fred_mission_save::save_props()
52205231
fout(" \"no_collide\"");
52215232
fout(" )");
52225233

5234+
if (save_config.save_format != MissionFormat::RETAIL &&
5235+
!p->fred_layer.empty() &&
5236+
stricmp(p->fred_layer.c_str(), "Default") != 0) {
5237+
if (optional_string_fred("+Layer:", "$Name:"))
5238+
parse_comments();
5239+
else
5240+
fout("\n+Layer:");
5241+
5242+
fout(" %s", p->fred_layer.c_str());
5243+
}
5244+
52235245
fso_comment_pop();
52245246
}
52255247
}

code/prop/prop.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ typedef struct prop {
3333
uint create_time; // time prop was created, set by gettime()
3434
fix time_created;
3535
float alpha_mult;
36+
SCP_string fred_layer = "Default";
3637
// glow points
3738
SCP_deque<bool> glow_point_bank_active;
3839
flagset<Prop::Prop_Flags> flags;
@@ -49,6 +50,7 @@ typedef struct parsed_prop {
4950
matrix orientation;
5051
vec3d position;
5152
flagset<Mission::Parse_Object_Flags> flags;
53+
SCP_string fred_layer = "Default";
5254
} parsed_prop;
5355

5456
extern bool Props_inited;

code/ship/ship.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7273,6 +7273,7 @@ void ship::clear()
72737273
swarm_missile_bank = -1;
72747274

72757275
group = -1;
7276+
fred_layer = "Default";
72767277
death_roll_snd = sound_handle::invalid();
72777278
ship_list_index = -1;
72787279

code/ship/ship.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@ class ship
696696
int swarm_missile_bank; // The missilebank the swarm was originally launched from
697697

698698
int group; // group ship is in, or -1 if none. Fred thing
699+
SCP_string fred_layer = "Default"; // FRED view layer assignment
699700
sound_handle death_roll_snd; // id of death roll sound, may need to be stopped early
700701
int ship_list_index; // index of ship in Ship_objs[] array
701702

qtfred/source_groups.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ add_file_folder("Source/UI/Dialogs"
164164
src/ui/dialogs/GlobalShipFlagsDialog.h
165165
src/ui/dialogs/JumpNodeEditorDialog.cpp
166166
src/ui/dialogs/JumpNodeEditorDialog.h
167+
src/ui/dialogs/LayerManagerDialog.cpp
168+
src/ui/dialogs/LayerManagerDialog.h
167169
src/ui/dialogs/MissionCutscenesDialog.cpp
168170
src/ui/dialogs/MissionCutscenesDialog.h
169171
src/ui/dialogs/MissionEventsDialog.cpp

0 commit comments

Comments
 (0)