Skip to content

Commit 305af2a

Browse files
committed
electrical arc upgrade, stage 2: make arrays dynamic
1 parent 5732183 commit 305af2a

File tree

10 files changed

+70
-98
lines changed

10 files changed

+70
-98
lines changed

code/debris/debris.cpp

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ particle::ParticleEffectHandle Debris_hit_particle;
5959

6060
#define DEBRIS_INDEX(dp) (int)(dp-Debris.data())
6161

62-
// Find the first available arc slot.
63-
debris_electrical_arc *debris_find_electrical_arc_slot(debris *db);
62+
// Find the first available arc slot. If none is available, and no_create is false, add one.
63+
debris_electrical_arc *debris_find_or_create_electrical_arc_slot(debris *db, bool no_create);
6464

6565
/**
6666
* Start the sequence of a piece of debris writhing in unholy agony!!!
@@ -275,22 +275,19 @@ void debris_process_post(object * obj, float frame_time)
275275

276276
if (db->is_hull) {
277277

278-
int n, n_arcs = Random::next(1, 3); // Create 1-3 sparks
278+
int n_arcs = Random::next(1, 3); // Create 1-3 sparks
279279

280280
vec3d v1 = submodel_get_random_point(db->model_num, db->submodel_num);
281281
vec3d v2 = submodel_get_random_point(db->model_num, db->submodel_num);
282282
vec3d v3 = submodel_get_random_point(db->model_num, db->submodel_num);
283283
vec3d v4 = submodel_get_random_point(db->model_num, db->submodel_num);
284284

285-
n = 0;
286-
287285
int lifetime = Random::next(100, 1000);
288286

289287
// Create the spark effects
290-
for (int i=0; i<MAX_DEBRIS_ARCS; ++i) {
291-
auto arc = &db->electrical_arcs[i];
292-
if ( !arc->timestamp.isValid() ) {
293-
288+
for (int n = 0; n < n_arcs; n++) {
289+
auto arc = debris_find_or_create_electrical_arc_slot(db, db->electrical_arcs.size() >= MAX_DEBRIS_ARCS);
290+
if (arc) {
294291
arc->timestamp = _timestamp(lifetime); // live up to a second
295292

296293
switch( n ) {
@@ -310,10 +307,6 @@ void debris_process_post(object * obj, float frame_time)
310307
default:
311308
UNREACHABLE("Unhandled case %d for electrical arc creation in debris_process_post()!", n);
312309
}
313-
314-
n++;
315-
if ( n == n_arcs )
316-
break; // Don't need to create anymore
317310
}
318311
}
319312

@@ -606,9 +599,7 @@ object *debris_create_only(int parent_objnum, int parent_ship_class, int alt_typ
606599
db->parent_alt_name = alt_type_index;
607600
db->damage_mult = 1.0f;
608601

609-
for (int i=0; i<MAX_DEBRIS_ARCS; ++i) { // NOLINT
610-
db->electrical_arcs[i].timestamp = TIMESTAMP::invalid();
611-
}
602+
db->electrical_arcs.clear();
612603

613604
if ( db->is_hull ) {
614605
// Percent of debris pieces with arcs controlled via table (default 50%)
@@ -1262,7 +1253,7 @@ void create_generic_debris(object* ship_objp, const vec3d* pos, float min_num_de
12621253
}
12631254
}
12641255

1265-
debris_electrical_arc *debris_find_electrical_arc_slot(debris *db)
1256+
debris_electrical_arc *debris_find_or_create_electrical_arc_slot(debris *db, bool no_create)
12661257
{
12671258
size_t i = 0;
12681259
for (auto& ii : db->electrical_arcs)
@@ -1272,8 +1263,12 @@ debris_electrical_arc *debris_find_electrical_arc_slot(debris *db)
12721263
i++;
12731264
}
12741265

1275-
if (i == MAX_DEBRIS_ARCS)
1276-
return nullptr;
1266+
if (i == db->electrical_arcs.size())
1267+
{
1268+
if (no_create)
1269+
return nullptr;
1270+
db->electrical_arcs.emplace_back();
1271+
}
12771272

12781273
return &db->electrical_arcs[i];
12791274
}

code/debris/debris.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class object;
2020
struct CFILE;
2121
class model_draw_list;
2222

23-
#define MAX_DEBRIS_ARCS 8 // Must be less than MAX_ARC_EFFECTS in model.h
23+
#define MAX_DEBRIS_ARCS 8
2424

2525
FLAG_LIST(Debris_Flags) {
2626
Used,
@@ -56,7 +56,7 @@ typedef struct debris {
5656
TIMESTAMP sound_delay; // timestamp to signal when sound should start
5757
fix time_started; // time when debris was created
5858

59-
debris_electrical_arc electrical_arcs[MAX_DEBRIS_ARCS];
59+
SCP_vector<debris_electrical_arc> electrical_arcs;
6060
int arc_frequency; // Starts at 1000, gets bigger
6161

6262
int parent_alt_name;

code/model/model.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,17 +144,11 @@ struct submodel_instance
144144
vec3d canonical_offset = vmd_zero_vector;
145145
vec3d canonical_prev_offset = vmd_zero_vector;
146146

147-
int num_arcs = 0; // See model_add_arc for more info
148-
model_electrical_arc electrical_arcs[MAX_ARC_EFFECTS];
147+
SCP_vector<model_electrical_arc> electrical_arcs;
149148

150149
//SMI-Specific movement axis. Only valid in MOVEMENT_TYPE_TRIGGERED.
151150
vec3d rotation_axis = vmd_zero_vector;
152151
vec3d translation_axis = vmd_zero_vector;
153-
154-
submodel_instance()
155-
{
156-
memset(electrical_arcs, 0, MAX_ARC_EFFECTS * sizeof(model_electrical_arc));
157-
}
158152
};
159153

160154
#define TM_BASE_TYPE 0 // the standard base map

code/model/modelinterp.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -785,20 +785,15 @@ void model_draw_bay_paths_htl(int model_num)
785785
gr_set_cull(cull);
786786
}
787787

788-
static const int MAX_ARC_SEGMENT_POINTS = 50;
789-
int Num_arc_segment_points = 0;
790-
vec3d Arc_segment_points[MAX_ARC_SEGMENT_POINTS];
788+
SCP_vector<vec3d> Arc_segment_points;
791789

792790
void interp_render_arc_segment(const vec3d *v1, const vec3d *v2, int depth )
793791
{
794792
float d = vm_vec_dist_quick( v1, v2 );
795793
const float scaler = 0.30f;
796794

797795
if ( (d < scaler) || (depth > 4) ) {
798-
// the real limit appears to be 33, so we should never hit this unless the code changes
799-
Assert( Num_arc_segment_points < MAX_ARC_SEGMENT_POINTS );
800-
801-
memcpy( &Arc_segment_points[Num_arc_segment_points++], v2, sizeof(vec3d) );
796+
Arc_segment_points.push_back(*v2);
802797
} else {
803798
// divide in half
804799
vec3d tmp;

code/model/modelread.cpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5200,7 +5200,7 @@ void model_instance_clear_arcs(polymodel *pm, polymodel_instance *pmi)
52005200
Assert(pm->id == pmi->model_num);
52015201

52025202
for (int i = 0; i < pm->n_models; ++i) {
5203-
pmi->submodel[i].num_arcs = 0; // Turn off any electric arcing effects
5203+
pmi->submodel[i].electrical_arcs.clear(); // Turn off any electric arcing effects
52045204
}
52055205
}
52065206

@@ -5220,20 +5220,18 @@ void model_instance_add_arc(polymodel *pm, polymodel_instance *pmi, int sub_mode
52205220
if ( sub_model_num >= pm->n_models ) return;
52215221
auto smi = &pmi->submodel[sub_model_num];
52225222

5223-
if ( smi->num_arcs < MAX_ARC_EFFECTS ) {
5224-
auto &new_arc = smi->electrical_arcs[smi->num_arcs];
5225-
new_arc.type = static_cast<ubyte>(arc_type);
5226-
new_arc.endpoint_1 = *v1;
5227-
new_arc.endpoint_2 = *v2;
5228-
5229-
if (arc_type == MARC_TYPE_SHIP || arc_type == MARC_TYPE_SCRIPTED) {
5230-
new_arc.primary_color_1 = *primary_color_1;
5231-
new_arc.primary_color_2 = *primary_color_2;
5232-
new_arc.secondary_color = *secondary_color;
5233-
new_arc.width = width;
5234-
}
5223+
smi->electrical_arcs.emplace_back();
5224+
auto &new_arc = smi->electrical_arcs.back();
5225+
5226+
new_arc.type = static_cast<ubyte>(arc_type);
5227+
new_arc.endpoint_1 = *v1;
5228+
new_arc.endpoint_2 = *v2;
52355229

5236-
smi->num_arcs++;
5230+
if (arc_type == MARC_TYPE_SHIP || arc_type == MARC_TYPE_SCRIPTED) {
5231+
new_arc.primary_color_1 = *primary_color_1;
5232+
new_arc.primary_color_2 = *primary_color_2;
5233+
new_arc.secondary_color = *secondary_color;
5234+
new_arc.width = width;
52375235
}
52385236
}
52395237

code/model/modelrender.cpp

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ extern int Model_polys;
4040
extern int tiling;
4141
extern float model_radius;
4242

43-
extern const int MAX_ARC_SEGMENT_POINTS;
44-
extern int Num_arc_segment_points;
45-
extern vec3d Arc_segment_points[];
43+
extern SCP_vector<vec3d> Arc_segment_points;
4644

4745
extern bool Scene_framebuffer_in_frame;
4846
color Wireframe_color;
@@ -810,12 +808,9 @@ model_draw_list::~model_draw_list() {
810808

811809
void model_render_add_lightning(model_draw_list *scene, const model_render_params* interp, const polymodel *pm, const submodel_instance *smi )
812810
{
813-
int i;
814811
float width = 0.9f;
815812
color primary, secondary;
816813

817-
Assert( smi->num_arcs > 0 );
818-
819814
if ( interp->get_model_flags() & MR_SHOW_OUTLINE_PRESET ) {
820815
return;
821816
}
@@ -825,9 +820,7 @@ void model_render_add_lightning(model_draw_list *scene, const model_render_param
825820
return;
826821
}
827822

828-
for ( i = 0; i < smi->num_arcs; i++ ) {
829-
auto &arc = smi->electrical_arcs[i];
830-
823+
for (auto &arc: smi->electrical_arcs) {
831824
// pick a color based upon arc type
832825
switch ( arc.type ) {
833826
// "normal", FreeSpace 1 style arcs
@@ -1305,7 +1298,7 @@ void model_render_children_buffers(model_draw_list* scene, model_material *rende
13051298
}
13061299
}
13071300

1308-
if ( smi != nullptr && smi->num_arcs > 0 ) {
1301+
if ( smi != nullptr && !smi->electrical_arcs.empty() ) {
13091302
model_render_add_lightning( scene, interp, pm, smi );
13101303
}
13111304

@@ -1625,7 +1618,7 @@ void submodel_render_queue(const model_render_params *render_info, model_draw_li
16251618
}
16261619
}
16271620

1628-
if ( pmi && pmi->submodel[submodel_num].num_arcs > 0 ) {
1621+
if ( pmi && !pmi->submodel[submodel_num].electrical_arcs.empty() ) {
16291622
model_render_add_lightning( scene, render_info, pm, &pmi->submodel[submodel_num] );
16301623
}
16311624

@@ -2079,8 +2072,8 @@ void model_render_glow_points(const polymodel *pm, const polymodel_instance *pmi
20792072
Assert( bank->points != nullptr );
20802073
int flick;
20812074

2082-
if (pmi != nullptr && pmi->submodel[pm->detail[0]].num_arcs > 0) {
2083-
flick = static_rand( timestamp() % 20 ) % (pmi->submodel[pm->detail[0]].num_arcs + j); //the more damage, the more arcs, the more likely the lights will fail
2075+
if (pmi != nullptr && !pmi->submodel[pm->detail[0]].electrical_arcs.empty()) {
2076+
flick = static_rand( timestamp() % 20 ) % (pmi->submodel[pm->detail[0]].electrical_arcs.size() + j); //the more damage, the more arcs, the more likely the lights will fail
20842077
} else {
20852078
flick = 1;
20862079
}
@@ -2502,21 +2495,21 @@ void model_render_insignias(const insignia_draw_data *insignia_data)
25022495

25032496
void model_render_arc(const vec3d *v1, const vec3d *v2, const color *primary, const color *secondary, float arc_width)
25042497
{
2505-
Num_arc_segment_points = 0;
2498+
Arc_segment_points.clear();
25062499

2507-
// need need to add the first point
2508-
memcpy( &Arc_segment_points[Num_arc_segment_points++], v1, sizeof(vec3d) );
2500+
// need to add the first point
2501+
Arc_segment_points.push_back(*v1);
25092502

25102503
// this should fill in all of the middle, and the last, points
25112504
interp_render_arc_segment(v1, v2, 0);
25122505

25132506
// use primary color for fist pass
25142507
Assert( primary );
25152508

2516-
g3_render_rod(primary, Num_arc_segment_points, Arc_segment_points, arc_width);
2509+
g3_render_rod(primary, static_cast<int>(Arc_segment_points.size()), Arc_segment_points.data(), arc_width);
25172510

25182511
if (secondary) {
2519-
g3_render_rod(secondary, Num_arc_segment_points, Arc_segment_points, arc_width * 0.33f);
2512+
g3_render_rod(secondary, static_cast<int>(Arc_segment_points.size()), Arc_segment_points.data(), arc_width * 0.33f);
25202513
}
25212514
}
25222515

@@ -2921,7 +2914,7 @@ void model_render_queue(const model_render_params* interp, model_draw_list* scen
29212914
} else {
29222915
model_render_buffers(scene, &rendering_material, interp, &pm->submodel[detail_model_num].buffer, pm, detail_model_num, detail_level, tmap_flags);
29232916

2924-
if ( pmi != nullptr && pmi->submodel[detail_model_num].num_arcs > 0 ) {
2917+
if ( pmi != nullptr && !pmi->submodel[detail_model_num].electrical_arcs.empty() ) {
29252918
model_render_add_lightning( scene, interp, pm, &pmi->submodel[detail_model_num] );
29262919
}
29272920
}

code/scripting/api/objs/ship.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2772,8 +2772,8 @@ ADE_FUNC(AddElectricArc, l_Ship, "vector firstPoint, vector secondPoint, number
27722772

27732773
auto shipp = &Ships[objh->objp()->instance];
27742774

2775-
// spawn the arc in the first unused slot
2776-
auto arc = ship_find_electrical_arc_slot(shipp);
2775+
// spawn the arc in the first unused slot, or in a new slot if there are no unused ones
2776+
auto arc = ship_find_or_create_electrical_arc_slot(shipp, false);
27772777
if (arc)
27782778
{
27792779
arc->timestamp = _timestamp(fl2i(duration * MILLISECONDS_PER_SECOND));
@@ -2790,7 +2790,7 @@ ADE_FUNC(AddElectricArc, l_Ship, "vector firstPoint, vector secondPoint, number
27902790

27912791
arc->width = width;
27922792

2793-
return ade_set_args(L, "i", static_cast<int>(arc - shipp->electrical_arcs) + 1); // FS2 -> Lua
2793+
return ade_set_args(L, "i", static_cast<int>(arc - shipp->electrical_arcs.data()) + 1); // FS2 -> Lua
27942794
}
27952795

27962796
return ade_set_args(L, "i", 0);
@@ -2813,7 +2813,7 @@ ADE_FUNC(DeleteElectricArc, l_Ship, "number index",
28132813
auto shipp = &Ships[objh->objp()->instance];
28142814

28152815
index--; // Lua -> FS2
2816-
if (index >= 0 && index < MAX_ARC_EFFECTS)
2816+
if (SCP_vector_inbounds(shipp->electrical_arcs, index))
28172817
{
28182818
shipp->electrical_arcs[index].timestamp = TIMESTAMP::invalid();
28192819
}
@@ -2842,7 +2842,7 @@ ADE_FUNC(ModifyElectricArc, l_Ship, "number index, vector firstPoint, vector sec
28422842
auto shipp = &Ships[objh->objp()->instance];
28432843

28442844
index--; // Lua -> FS2
2845-
if (index >= 0 && index < MAX_ARC_EFFECTS)
2845+
if (SCP_vector_inbounds(shipp->electrical_arcs, index))
28462846
{
28472847
auto &arc = shipp->electrical_arcs[index];
28482848
arc.endpoint_1 = *v1;

code/ship/ship.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7029,9 +7029,7 @@ void ship::clear()
70297029
for (int i = 0; i < NUM_SUB_EXPL_HANDLES; i++)
70307030
sub_expl_sound_handle[i] = sound_handle::invalid();
70317031

7032-
memset(&electrical_arcs, 0, MAX_ARC_EFFECTS * sizeof(ship_electrical_arc));
7033-
for (int i = 0; i < MAX_ARC_EFFECTS; i++)
7034-
electrical_arcs[i].timestamp = TIMESTAMP::invalid();
7032+
electrical_arcs.clear();
70357033
arc_next_time = TIMESTAMP::invalid();
70367034

70377035
emp_intensity = -1.0f;
@@ -21835,7 +21833,7 @@ int ship_check_visibility(const ship* viewed, ship* viewer)
2183521833
return ship_is_visible;
2183621834
}
2183721835

21838-
ship_electrical_arc *ship_find_electrical_arc_slot(ship *shipp)
21836+
ship_electrical_arc *ship_find_or_create_electrical_arc_slot(ship *shipp, bool no_create)
2183921837
{
2184021838
size_t i = 0;
2184121839
for (auto &ii : shipp->electrical_arcs)
@@ -21845,8 +21843,12 @@ ship_electrical_arc *ship_find_electrical_arc_slot(ship *shipp)
2184521843
i++;
2184621844
}
2184721845

21848-
if (i == MAX_ARC_EFFECTS)
21849-
return nullptr;
21846+
if (i == shipp->electrical_arcs.size())
21847+
{
21848+
if (no_create)
21849+
return nullptr;
21850+
shipp->electrical_arcs.emplace_back();
21851+
}
2185021852

2185121853
return &shipp->electrical_arcs[i];
2185221854
}

code/ship/ship.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ class ship
733733
std::array<sound_handle, NUM_SUB_EXPL_HANDLES> sub_expl_sound_handle;
734734

735735
// Stuff for showing electrical arcs on damaged ships
736-
ship_electrical_arc electrical_arcs[MAX_ARC_EFFECTS];
736+
SCP_vector<ship_electrical_arc> electrical_arcs;
737737
TIMESTAMP arc_next_time; // When the next damage/emp arc will be created.
738738
SCP_vector<TIMESTAMP> passive_arc_next_times; // When the next passive ship arc will be created.
739739

@@ -2113,7 +2113,7 @@ bool ship_secondary_has_ammo(ship_weapon* swp, int bank_index);
21132113
// Used to check if one ship can see the other on radar
21142114
int ship_check_visibility(const ship* viewed, ship* viewer);
21152115

2116-
// Find the first available arc slot.
2117-
ship_electrical_arc *ship_find_electrical_arc_slot(ship *shipp);
2116+
// Find the first available arc slot. If none is available, and no_create is false, add one.
2117+
ship_electrical_arc *ship_find_or_create_electrical_arc_slot(ship *shipp, bool no_create);
21182118

21192119
#endif

0 commit comments

Comments
 (0)