Skip to content

Commit 18fd870

Browse files
authored
Allow rendering tech models with destroyed subsystems (#7218)
* allow rendering tech models with destroyed subsystems * fix copy/paste error
1 parent 219f692 commit 18fd870

3 files changed

Lines changed: 69 additions & 9 deletions

File tree

code/model/modelrender.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3113,7 +3113,7 @@ void modelinstance_replace_active_texture(polymodel_instance* pmi, const char* o
31133113

31143114
// renders a model as if in the tech room or briefing UI
31153115
// model_type 1 for ship class, 2 for weapon class, 3 for pof
3116-
bool render_tech_model(tech_render_type model_type, int x1, int y1, int x2, int y2, float zoom, bool lighting, int class_idx, const matrix* orient, const SCP_string &pof_filename, float close_zoom, const vec3d *close_pos, const SCP_string& tcolor)
3116+
bool render_tech_model(tech_render_type model_type, int x1, int y1, int x2, int y2, float zoom, bool lighting, int class_idx, const matrix* orient, const SCP_string &pof_filename, float close_zoom, const vec3d *close_pos, const SCP_string& tcolor, const SCP_vector<SCP_string>& destroyed_subsystems)
31173117
{
31183118

31193119
lighting_profiles::set_non_mission_profile non_mission_lighting_profile;
@@ -3229,8 +3229,33 @@ bool render_tech_model(tech_render_type model_type, int x1, int y1, int x2, int
32293229

32303230
// Create an instance for ships that can be used to clear out destroyed subobjects from rendering
32313231
if (model_type == TECH_SHIP) {
3232+
auto sip = &Ship_info[class_idx];
3233+
auto pm = model_get(model_num);
32323234
model_instance = model_create_instance(model_objnum_special::OBJNUM_NONE, model_num);
3233-
model_set_up_techroom_instance(&Ship_info[class_idx], model_instance);
3235+
model_set_up_techroom_instance(sip, model_instance);
3236+
3237+
if (!destroyed_subsystems.empty()) {
3238+
auto pmi = model_get_instance(model_instance);
3239+
flagset<Ship::Subsystem_Flags> empty;
3240+
3241+
for (int idx = 0; idx < sip->n_subsystems; ++idx) {
3242+
auto& subsystem = sip->subsystems[idx];
3243+
3244+
if (subsystem.subobj_num < 0 || subsystem.subobj_num >= pm->n_models ||
3245+
subsystem.model_num != model_num) {
3246+
continue;
3247+
}
3248+
3249+
for (auto& destroyed_name : destroyed_subsystems) {
3250+
if (!stricmp(subsystem.subobj_name, destroyed_name.c_str()) ||
3251+
!stricmp(subsystem.name, destroyed_name.c_str())) {
3252+
pmi->submodel[subsystem.subobj_num].blown_off = true;
3253+
model_replicate_submodel_instance(pm, pmi, subsystem.subobj_num, empty);
3254+
break;
3255+
}
3256+
}
3257+
}
3258+
}
32343259
}
32353260

32363261
render_info.set_detail_level_lock(0);

code/model/modelrender.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ bool model_render_check_detail_box(const vec3d* view_pos, const polymodel* pm, i
317317
void model_render_arc(const vec3d* v1, const vec3d* v2, const SCP_vector<vec3d> *persistent_arc_points, const color* primary, const color* secondary, float arc_width, ubyte depth_limit);
318318
void model_render_insignias(const insignia_draw_data* insignia);
319319
void model_render_set_wireframe_color(const color* clr);
320-
bool render_tech_model(tech_render_type model_type, int x1, int y1, int x2, int y2, float zoom, bool lighting, int class_idx, const matrix* orient, const SCP_string& pof_filename = "", float closeup_zoom = 0, const vec3d* closeup_pos = &vmd_zero_vector, const SCP_string& tcolor = "");
320+
bool render_tech_model(tech_render_type model_type, int x1, int y1, int x2, int y2, float zoom, bool lighting, int class_idx, const matrix* orient, const SCP_string& pof_filename = "", float closeup_zoom = 0, const vec3d* closeup_pos = &vmd_zero_vector, const SCP_string& tcolor = "", const SCP_vector<SCP_string>& destroyed_subsystems = SCP_vector<SCP_string>());
321321

322322
float convert_distance_and_diameter_to_pixel_size(float distance, float diameter, float field_of_view, int screen_width);
323323

code/scripting/api/objs/shipclass.cpp

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "graphics/matrix.h"
1919
#include "missionui/missionscreencommon.h"
2020
#include "scripting/api/objs/weaponclass.h"
21+
#include "scripting/lua/LuaTable.h"
2122
#include "model/modelrender.h"
2223
#include "utils/string_utils.h"
2324

@@ -1146,7 +1147,7 @@ ADE_FUNC(isInTechroom, l_Shipclass, NULL, "Gets whether or not the ship class is
11461147
ADE_FUNC(renderTechModel,
11471148
l_Shipclass,
11481149
"number X1, number Y1, number X2, number Y2, [number RotationPercent =0, number PitchPercent =0, number "
1149-
"BankPercent=40, number Zoom=1.3, boolean Lighting=true, teamcolor TeamColor=nil]",
1150+
"BankPercent=40, number Zoom=1.3, boolean Lighting=true, teamcolor TeamColor=nil, string[] DestroyedSubsystems=nil]",
11501151
"Draws ship model as if in techroom. True for regular lighting, false for flat lighting.",
11511152
"boolean",
11521153
"Whether ship was rendered")
@@ -1157,7 +1158,8 @@ ADE_FUNC(renderTechModel,
11571158
float zoom = 1.3f;
11581159
bool lighting = true;
11591160
int tc_idx = -1;
1160-
if(!ade_get_args(L, "oiiii|ffffbo", l_Shipclass.Get(&idx), &x1, &y1, &x2, &y2, &rot_angles.h, &rot_angles.p, &rot_angles.b, &zoom, &lighting, l_TeamColor.Get(&tc_idx)))
1161+
auto destroyed_subsystems_table = luacpp::LuaTable::create(L);
1162+
if(!ade_get_args(L, "oiiii|ffffbot", l_Shipclass.Get(&idx), &x1, &y1, &x2, &y2, &rot_angles.h, &rot_angles.p, &rot_angles.b, &zoom, &lighting, l_TeamColor.Get(&tc_idx), &destroyed_subsystems_table))
11611163
return ade_set_error(L, "b", false);
11621164

11631165
if(idx < 0 || idx >= ship_info_size())
@@ -1190,18 +1192,35 @@ ADE_FUNC(renderTechModel,
11901192
}
11911193
}
11921194

1193-
return ade_set_args(L, "b", render_tech_model(TECH_SHIP, x1, y1, x2, y2, zoom, lighting, idx, &orient, "" , 0.0f, &vmd_zero_vector, tcolor));
1195+
SCP_vector<SCP_string> destroyed_subsystems;
1196+
if (destroyed_subsystems_table.isValid()) {
1197+
for (const auto& item : destroyed_subsystems_table) {
1198+
if (!item.second.is(luacpp::ValueType::STRING)) {
1199+
LuaError(L, "DestroyedSubsystems must be a table of strings.");
1200+
return ade_set_args(L, "b", false);
1201+
}
1202+
1203+
try {
1204+
destroyed_subsystems.emplace_back(item.second.getValue<SCP_string>());
1205+
} catch (const luacpp::LuaException& /*e*/) {
1206+
return ade_set_args(L, "b", false);
1207+
}
1208+
}
1209+
}
1210+
1211+
return ade_set_args(L, "b", render_tech_model(TECH_SHIP, x1, y1, x2, y2, zoom, lighting, idx, &orient, "", 0.0f, &vmd_zero_vector, tcolor, destroyed_subsystems));
11941212
}
11951213

11961214
// Nuke's alternate tech model rendering function
1197-
ADE_FUNC(renderTechModel2, l_Shipclass, "number X1, number Y1, number X2, number Y2, [orientation Orientation=nil, number Zoom=1.3, teamcolor TeamColor=nil]", "Draws ship model as if in techroom", "boolean", "Whether ship was rendered")
1215+
ADE_FUNC(renderTechModel2, l_Shipclass, "number X1, number Y1, number X2, number Y2, [orientation Orientation=nil, number Zoom=1.3, teamcolor TeamColor=nil, string[] DestroyedSubsystems=nil]", "Draws ship model as if in techroom", "boolean", "Whether ship was rendered")
11981216
{
11991217
int x1,y1,x2,y2;
12001218
int idx;
12011219
float zoom = 1.3f;
12021220
matrix_h *mh = nullptr;
12031221
int tc_idx = -1;
1204-
if(!ade_get_args(L, "oiiiio|fo", l_Shipclass.Get(&idx), &x1, &y1, &x2, &y2, l_Matrix.GetPtr(&mh), &zoom, l_TeamColor.Get(&tc_idx)))
1222+
auto destroyed_subsystems_table = luacpp::LuaTable::create(L);
1223+
if(!ade_get_args(L, "oiiiio|fot", l_Shipclass.Get(&idx), &x1, &y1, &x2, &y2, l_Matrix.GetPtr(&mh), &zoom, l_TeamColor.Get(&tc_idx), &destroyed_subsystems_table))
12051224
return ade_set_error(L, "b", false);
12061225

12071226
if(idx < 0 || idx >= ship_info_size())
@@ -1223,7 +1242,23 @@ ADE_FUNC(renderTechModel2, l_Shipclass, "number X1, number Y1, number X2, number
12231242
}
12241243
}
12251244

1226-
return ade_set_args(L, "b", render_tech_model(TECH_SHIP, x1, y1, x2, y2, zoom, true, idx, orient, "" , 0.0f, &vmd_zero_vector, tcolor));
1245+
SCP_vector<SCP_string> destroyed_subsystems;
1246+
if (destroyed_subsystems_table.isValid()) {
1247+
for (const auto& item : destroyed_subsystems_table) {
1248+
if (!item.second.is(luacpp::ValueType::STRING)) {
1249+
LuaError(L, "DestroyedSubsystems must be a table of strings.");
1250+
return ade_set_args(L, "b", false);
1251+
}
1252+
1253+
try {
1254+
destroyed_subsystems.emplace_back(item.second.getValue<SCP_string>());
1255+
} catch (const luacpp::LuaException& /*e*/) {
1256+
return ade_set_args(L, "b", false);
1257+
}
1258+
}
1259+
}
1260+
1261+
return ade_set_args(L, "b", render_tech_model(TECH_SHIP, x1, y1, x2, y2, zoom, true, idx, orient, "", 0, &vmd_zero_vector, tcolor, destroyed_subsystems));
12271262
}
12281263

12291264
ADE_FUNC(renderSelectModel,

0 commit comments

Comments
 (0)