Skip to content

Commit 05b44cd

Browse files
committed
electrical arc upgrade, stage 1: refactor data structures
1 parent 8102feb commit 05b44cd

10 files changed

Lines changed: 214 additions & 176 deletions

File tree

code/debris/debris.cpp

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +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);
6264

6365
/**
6466
* Start the sequence of a piece of debris writhing in unholy agony!!!
@@ -286,36 +288,36 @@ void debris_process_post(object * obj, float frame_time)
286288

287289
// Create the spark effects
288290
for (int i=0; i<MAX_DEBRIS_ARCS; ++i) {
289-
if ( !db->arc_timestamp[i].isValid() ) {
291+
auto arc = &db->electrical_arcs[i];
292+
if ( !arc->timestamp.isValid() ) {
290293

291-
db->arc_timestamp[i] = _timestamp(lifetime); // live up to a second
294+
arc->timestamp = _timestamp(lifetime); // live up to a second
292295

293296
switch( n ) {
294297
case 0:
295-
db->arc_pts[i][0] = v1;
296-
db->arc_pts[i][1] = v2;
298+
arc->endpoint_1 = v1;
299+
arc->endpoint_2 = v2;
297300
break;
298301
case 1:
299-
db->arc_pts[i][0] = v2;
300-
db->arc_pts[i][1] = v3;
302+
arc->endpoint_1 = v2;
303+
arc->endpoint_2 = v3;
301304
break;
302305

303306
case 2:
304-
db->arc_pts[i][0] = v2;
305-
db->arc_pts[i][1] = v4;
307+
arc->endpoint_1 = v2;
308+
arc->endpoint_2 = v4;
306309
break;
307310

308311
default:
309312
Int3();
310313
}
311-
314+
312315
n++;
313316
if ( n == n_arcs )
314317
break; // Don't need to create anymore
315318
}
316319
}
317320

318-
319321
// rotate v2 out of local coordinates into world.
320322
// Use v2 since it is used in every bolt. See above switch().
321323
vec3d snd_pos;
@@ -342,16 +344,20 @@ void debris_process_post(object * obj, float frame_time)
342344
}
343345
}
344346

345-
for (int i=0; i<MAX_DEBRIS_ARCS; ++i) {
346-
if ( db->arc_timestamp[i].isValid() ) {
347-
if ( timestamp_elapsed( db->arc_timestamp[i] ) ) {
347+
for (auto &arc: db->electrical_arcs) {
348+
if (arc.timestamp.isValid()) {
349+
if (timestamp_elapsed(arc.timestamp)) {
348350
// Kill off the spark
349-
db->arc_timestamp[i] = TIMESTAMP::invalid();
351+
arc.timestamp = TIMESTAMP::invalid();
350352
} else {
351353
// Maybe move a vertex.... 20% of the time maybe?
352354
int mr = Random::next();
353355
if ( mr < Random::MAX_VALUE/5 ) {
354-
db->arc_pts[i][mr % 2] = submodel_get_random_point(db->model_num, db->submodel_num);
356+
auto pt = submodel_get_random_point(db->model_num, db->submodel_num);
357+
if (mr % 2 == 0)
358+
arc.endpoint_1 = pt;
359+
else
360+
arc.endpoint_2 = pt;
355361
}
356362
}
357363
}
@@ -602,7 +608,7 @@ object *debris_create_only(int parent_objnum, int parent_ship_class, int alt_typ
602608
db->damage_mult = 1.0f;
603609

604610
for (int i=0; i<MAX_DEBRIS_ARCS; ++i) { // NOLINT
605-
db->arc_timestamp[i] = TIMESTAMP::invalid();
611+
db->electrical_arcs[i].timestamp = TIMESTAMP::invalid();
606612
}
607613

608614
if ( db->is_hull ) {
@@ -1162,7 +1168,7 @@ void calc_debris_physics_properties( physics_info *pi, vec3d *mins, vec3d *maxs,
11621168
*/
11631169
void debris_render(object * obj, model_draw_list *scene)
11641170
{
1165-
int i, num, swapped;
1171+
int num, swapped;
11661172
debris *db;
11671173

11681174
swapped = -1;
@@ -1197,9 +1203,9 @@ void debris_render(object * obj, model_draw_list *scene)
11971203

11981204
// Only render electrical arcs if within 500m of the eye (for a 10m piece)
11991205
if ( vm_vec_dist_quick( &obj->pos, &Eye_position ) < obj->radius*50.0f ) {
1200-
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
1201-
if ( db->arc_timestamp[i].isValid() ) {
1202-
model_instance_add_arc( pm, pmi, db->submodel_num, &db->arc_pts[i][0], &db->arc_pts[i][1], MARC_TYPE_DAMAGED );
1206+
for (auto &arc: db->electrical_arcs) {
1207+
if ( arc.timestamp.isValid() ) {
1208+
model_instance_add_arc( pm, pmi, db->submodel_num, &arc.endpoint_1, &arc.endpoint_2, MARC_TYPE_DAMAGED );
12031209
}
12041210
}
12051211
}
@@ -1250,3 +1256,19 @@ void create_generic_debris(object* ship_objp, const vec3d* pos, float min_num_de
12501256
debris_create(ship_objp, model_num, -1, &create_pos, pos, 0, speed_mult);
12511257
}
12521258
}
1259+
1260+
debris_electrical_arc *debris_find_electrical_arc_slot(debris *db)
1261+
{
1262+
size_t i = 0;
1263+
for (auto& ii : db->electrical_arcs)
1264+
{
1265+
if (!ii.timestamp.isValid())
1266+
break;
1267+
i++;
1268+
}
1269+
1270+
if (i == MAX_DEBRIS_ARCS)
1271+
return nullptr;
1272+
1273+
return &db->electrical_arcs[i];
1274+
}

code/debris/debris.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ FLAG_LIST(Debris_Flags) {
3030
NUM_VALUES
3131
};
3232

33+
struct debris_electrical_arc
34+
{
35+
vec3d endpoint_1;
36+
vec3d endpoint_2;
37+
TIMESTAMP timestamp; // When this times out, the spark goes away. Invalid is not used
38+
};
3339

3440
typedef struct debris {
3541
flagset<Debris_Flags> flags; // See DEBRIS_??? defines
@@ -50,8 +56,7 @@ typedef struct debris {
5056
TIMESTAMP sound_delay; // timestamp to signal when sound should start
5157
fix time_started; // time when debris was created
5258

53-
vec3d arc_pts[MAX_DEBRIS_ARCS][2]; // The endpoints of each arc
54-
TIMESTAMP arc_timestamp[MAX_DEBRIS_ARCS]; // When this times out, the spark goes away. Invalid is not used
59+
debris_electrical_arc electrical_arcs[MAX_DEBRIS_ARCS];
5560
int arc_frequency; // Starts at 1000, gets bigger
5661

5762
int parent_alt_name;

code/model/model.h

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,23 @@ extern const char *Subsystem_types[SUBSYSTEM_MAX];
9696

9797
#define MAX_SPLIT_PLANE 5 // number of artist specified split planes (used in big ship explosions)
9898

99+
// Electrical Arc Effect Info
100+
// Sets a spark for this submodel between vertex v1 and v2
101+
struct electrical_arc
102+
{
103+
color primary_color_1;
104+
color primary_color_2;
105+
color secondary_color;
106+
float width; // only used for MARC_TYPE_SHIP and MARC_TYPE_SCRIPTED
107+
vec3d endpoint_1;
108+
vec3d endpoint_2;
109+
ubyte type; // see MARC_TYPE_* defines
110+
};
111+
112+
struct model_electrical_arc : electrical_arc
113+
{
114+
};
115+
99116
// Data specific to a particular instance of a submodel.
100117
struct submodel_instance
101118
{
@@ -127,30 +144,16 @@ struct submodel_instance
127144
vec3d canonical_offset = vmd_zero_vector;
128145
vec3d canonical_prev_offset = vmd_zero_vector;
129146

130-
// --- these fields used to be in bsp_info ---
131-
132-
// Electrical Arc Effect Info
133-
// Sets a spark for this submodel between vertex v1 and v2
134-
int num_arcs = 0; // See model_add_arc for more info
135-
color arc_primary_color_1[MAX_ARC_EFFECTS];
136-
color arc_primary_color_2[MAX_ARC_EFFECTS];
137-
color arc_secondary_color[MAX_ARC_EFFECTS];
138-
float arc_width[MAX_ARC_EFFECTS]; // only used for MARC_TYPE_SHIP and MARC_TYPE_SCRIPTED
139-
vec3d arc_pts[MAX_ARC_EFFECTS][2];
140-
ubyte arc_type[MAX_ARC_EFFECTS]; // see MARC_TYPE_* defines
147+
int num_arcs = 0; // See model_add_arc for more info
148+
model_electrical_arc electrical_arcs[MAX_ARC_EFFECTS];
141149

142150
//SMI-Specific movement axis. Only valid in MOVEMENT_TYPE_TRIGGERED.
143-
vec3d rotation_axis;
144-
vec3d translation_axis;
151+
vec3d rotation_axis = vmd_zero_vector;
152+
vec3d translation_axis = vmd_zero_vector;
145153

146154
submodel_instance()
147155
{
148-
memset(&arc_pts, 0, MAX_ARC_EFFECTS * 2 * sizeof(vec3d));
149-
memset(&arc_primary_color_1, 0, MAX_ARC_EFFECTS * sizeof(color));
150-
memset(&arc_primary_color_2, 0, MAX_ARC_EFFECTS * sizeof(color));
151-
memset(&arc_secondary_color, 0, MAX_ARC_EFFECTS * sizeof(color));
152-
memset(&arc_type, 0, MAX_ARC_EFFECTS * sizeof(ubyte));
153-
memset(&arc_width, 0, MAX_ARC_EFFECTS * sizeof(float));
156+
memset(electrical_arcs, 0, MAX_ARC_EFFECTS * sizeof(model_electrical_arc));
154157
}
155158
};
156159

code/model/modelread.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5221,15 +5221,16 @@ void model_instance_add_arc(polymodel *pm, polymodel_instance *pmi, int sub_mode
52215221
auto smi = &pmi->submodel[sub_model_num];
52225222

52235223
if ( smi->num_arcs < MAX_ARC_EFFECTS ) {
5224-
smi->arc_type[smi->num_arcs] = (ubyte)arc_type;
5225-
smi->arc_pts[smi->num_arcs][0] = *v1;
5226-
smi->arc_pts[smi->num_arcs][1] = *v2;
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;
52275228

52285229
if (arc_type == MARC_TYPE_SHIP || arc_type == MARC_TYPE_SCRIPTED) {
5229-
smi->arc_primary_color_1[smi->num_arcs] = *primary_color_1;
5230-
smi->arc_primary_color_2[smi->num_arcs] = *primary_color_2;
5231-
smi->arc_secondary_color[smi->num_arcs] = *secondary_color;
5232-
smi->arc_width[smi->num_arcs] = width;
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;
52335234
}
52345235

52355236
smi->num_arcs++;

code/model/modelrender.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -826,8 +826,10 @@ void model_render_add_lightning(model_draw_list *scene, const model_render_param
826826
}
827827

828828
for ( i = 0; i < smi->num_arcs; i++ ) {
829+
auto &arc = smi->electrical_arcs[i];
830+
829831
// pick a color based upon arc type
830-
switch ( smi->arc_type[i] ) {
832+
switch ( arc.type ) {
831833
// "normal", FreeSpace 1 style arcs
832834
case MARC_TYPE_DAMAGED:
833835
if ( Random::flip_coin() ) {
@@ -853,14 +855,14 @@ void model_render_add_lightning(model_draw_list *scene, const model_render_param
853855
case MARC_TYPE_SCRIPTED:
854856
case MARC_TYPE_SHIP:
855857
if ( Random::flip_coin() ) {
856-
primary = smi->arc_primary_color_1[i];
858+
primary = arc.primary_color_1;
857859
} else {
858-
primary = smi->arc_primary_color_2[i];
860+
primary = arc.primary_color_2;
859861
}
860862

861-
secondary = smi->arc_secondary_color[i];
863+
secondary = arc.secondary_color;
862864

863-
width = smi->arc_width[i];
865+
width = arc.width;
864866

865867
break;
866868

@@ -887,12 +889,12 @@ void model_render_add_lightning(model_draw_list *scene, const model_render_param
887889
break;
888890

889891
default:
890-
UNREACHABLE("Unknown arc type of %d found in model_render_add_lightning(), please contact an SCP coder!", smi->arc_type[i]);
892+
UNREACHABLE("Unknown arc type of %d found in model_render_add_lightning(), please contact an SCP coder!", arc.type);
891893
}
892894

893895
// render the actual arc segment
894896
if (width > 0.0f)
895-
scene->add_arc(&smi->arc_pts[i][0], &smi->arc_pts[i][1], &primary, &secondary, width);
897+
scene->add_arc(&arc.endpoint_1, &arc.endpoint_2, &primary, &secondary, width);
896898
}
897899
}
898900

code/object/object.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,18 +1334,16 @@ void obj_move_all_post(object *objp, float frametime)
13341334
// Make any electrical arcs on ships cast light
13351335
if (Arc_light) {
13361336
if ( (Detail.lighting > 3) && (objp != Viewer_obj) ) {
1337-
int i;
1338-
ship *shipp;
1339-
shipp = &Ships[objp->instance];
1337+
auto shipp = &Ships[objp->instance];
13401338

1341-
for (i=0; i<MAX_ARC_EFFECTS; i++ ) {
1342-
if ( shipp->arc_timestamp[i].isValid() ) {
1339+
for (auto &arc: shipp->electrical_arcs) {
1340+
if ( arc.timestamp.isValid() ) {
13431341
// Move arc endpoints into world coordinates
13441342
vec3d tmp1, tmp2;
1345-
vm_vec_unrotate(&tmp1,&shipp->arc_pts[i][0],&objp->orient);
1343+
vm_vec_unrotate(&tmp1,&arc.endpoint_1,&objp->orient);
13461344
vm_vec_add2(&tmp1,&objp->pos);
13471345

1348-
vm_vec_unrotate(&tmp2,&shipp->arc_pts[i][1],&objp->orient);
1346+
vm_vec_unrotate(&tmp2,&arc.endpoint_2,&objp->orient);
13491347
vm_vec_add2(&tmp2,&objp->pos);
13501348

13511349
light_add_point( &tmp1, 10.0f, 20.0f, frand(), 1.0f, 1.0f, 1.0f);
@@ -1431,19 +1429,17 @@ void obj_move_all_post(object *objp, float frametime)
14311429
// Make any electrical arcs on debris cast light
14321430
if (Arc_light) {
14331431
if ( Detail.lighting > 3 ) {
1434-
int i;
1435-
debris *db;
1436-
db = &Debris[objp->instance];
1432+
auto db = &Debris[objp->instance];
14371433

14381434
if (db->arc_frequency > 0) {
1439-
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
1440-
if ( db->arc_timestamp[i].isValid() ) {
1435+
for (auto &arc: db->electrical_arcs) {
1436+
if ( arc.timestamp.isValid() ) {
14411437
// Move arc endpoints into world coordinates
14421438
vec3d tmp1, tmp2;
1443-
vm_vec_unrotate(&tmp1,&db->arc_pts[i][0],&objp->orient);
1439+
vm_vec_unrotate(&tmp1,&arc.endpoint_1,&objp->orient);
14441440
vm_vec_add2(&tmp1,&objp->pos);
14451441

1446-
vm_vec_unrotate(&tmp2,&db->arc_pts[i][1],&objp->orient);
1442+
vm_vec_unrotate(&tmp2,&arc.endpoint_2,&objp->orient);
14471443
vm_vec_add2(&tmp2,&objp->pos);
14481444

14491445
light_add_point( &tmp1, 10.0f, 20.0f, frand(), 1.0f, 1.0f, 1.0f );

code/scripting/api/objs/ship.cpp

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2773,24 +2773,24 @@ ADE_FUNC(AddElectricArc, l_Ship, "vector firstPoint, vector secondPoint, number
27732773
auto shipp = &Ships[objh->objp()->instance];
27742774

27752775
// spawn the arc in the first unused slot
2776-
for (int i = 0; i < MAX_ARC_EFFECTS; i++) {
2777-
if (!shipp->arc_timestamp[i].isValid()) {
2778-
shipp->arc_timestamp[i] = _timestamp(fl2i(duration * MILLISECONDS_PER_SECOND));
2776+
auto arc = ship_find_electrical_arc_slot(shipp);
2777+
if (arc)
2778+
{
2779+
arc->timestamp = _timestamp(fl2i(duration * MILLISECONDS_PER_SECOND));
27792780

2780-
shipp->arc_pts[i][0] = *v1;
2781-
shipp->arc_pts[i][1] = *v2;
2781+
arc->endpoint_1 = *v1;
2782+
arc->endpoint_2 = *v2;
27822783

2783-
//Set the arc colors
2784-
shipp->arc_primary_color_1[i] = Arc_color_damage_p1;
2785-
shipp->arc_primary_color_2[i] = Arc_color_damage_p2;
2786-
shipp->arc_secondary_color[i] = Arc_color_damage_s1;
2784+
//Set the arc colors
2785+
arc->primary_color_1 = Arc_color_damage_p1;
2786+
arc->primary_color_2 = Arc_color_damage_p2;
2787+
arc->secondary_color = Arc_color_damage_s1;
27872788

2788-
shipp->arc_type[i] = MARC_TYPE_SCRIPTED;
2789+
arc->type = MARC_TYPE_SCRIPTED;
27892790

2790-
shipp->arc_width[i] = width;
2791+
arc->width = width;
27912792

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

27962796
return ade_set_args(L, "i", 0);
@@ -2815,7 +2815,7 @@ ADE_FUNC(DeleteElectricArc, l_Ship, "number index",
28152815
index--; // Lua -> FS2
28162816
if (index >= 0 && index < MAX_ARC_EFFECTS)
28172817
{
2818-
shipp->arc_timestamp[index] = TIMESTAMP::invalid();
2818+
shipp->electrical_arcs[index].timestamp = TIMESTAMP::invalid();
28192819
}
28202820

28212821
return ADE_RETURN_NIL;
@@ -2844,11 +2844,12 @@ ADE_FUNC(ModifyElectricArc, l_Ship, "number index, vector firstPoint, vector sec
28442844
index--; // Lua -> FS2
28452845
if (index >= 0 && index < MAX_ARC_EFFECTS)
28462846
{
2847-
shipp->arc_pts[index][0] = *v1;
2848-
shipp->arc_pts[index][1] = *v2;
2847+
auto &arc = shipp->electrical_arcs[index];
2848+
arc.endpoint_1 = *v1;
2849+
arc.endpoint_2 = *v2;
28492850

28502851
if (args == 5)
2851-
shipp->arc_width[index] = width;
2852+
arc.width = width;
28522853
}
28532854

28542855
return ADE_RETURN_NIL;

0 commit comments

Comments
 (0)