Skip to content

Commit 8270a38

Browse files
committed
electrical arc upgrade, stage 1: refactor data structures
1 parent 73e82d9 commit 8270a38

File tree

10 files changed

+214
-176
lines changed

10 files changed

+214
-176
lines changed

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 ) {
@@ -1168,7 +1174,7 @@ void calc_debris_physics_properties( physics_info *pi, vec3d *mins, vec3d *maxs,
11681174
*/
11691175
void debris_render(object * obj, model_draw_list *scene)
11701176
{
1171-
int i, num, swapped;
1177+
int num, swapped;
11721178
debris *db;
11731179

11741180
swapped = -1;
@@ -1203,9 +1209,9 @@ void debris_render(object * obj, model_draw_list *scene)
12031209

12041210
// Only render electrical arcs if within 500m of the eye (for a 10m piece)
12051211
if ( vm_vec_dist_quick( &obj->pos, &Eye_position ) < obj->radius*50.0f ) {
1206-
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
1207-
if ( db->arc_timestamp[i].isValid() ) {
1208-
model_instance_add_arc( pm, pmi, db->submodel_num, &db->arc_pts[i][0], &db->arc_pts[i][1], MARC_TYPE_DAMAGED );
1212+
for (auto &arc: db->electrical_arcs) {
1213+
if ( arc.timestamp.isValid() ) {
1214+
model_instance_add_arc( pm, pmi, db->submodel_num, &arc.endpoint_1, &arc.endpoint_2, MARC_TYPE_DAMAGED );
12091215
}
12101216
}
12111217
}
@@ -1256,3 +1262,19 @@ void create_generic_debris(object* ship_objp, const vec3d* pos, float min_num_de
12561262
debris_create(ship_objp, model_num, -1, &create_pos, pos, 0, speed_mult);
12571263
}
12581264
}
1265+
1266+
debris_electrical_arc *debris_find_electrical_arc_slot(debris *db)
1267+
{
1268+
size_t i = 0;
1269+
for (auto& ii : db->electrical_arcs)
1270+
{
1271+
if (!ii.timestamp.isValid())
1272+
break;
1273+
i++;
1274+
}
1275+
1276+
if (i == MAX_DEBRIS_ARCS)
1277+
return nullptr;
1278+
1279+
return &db->electrical_arcs[i];
1280+
}

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
@@ -1381,18 +1381,16 @@ void obj_move_all_post(object *objp, float frametime)
13811381
// Make any electrical arcs on ships cast light
13821382
if (Arc_light) {
13831383
if ( (Detail.lighting > 3) && (objp != Viewer_obj) ) {
1384-
int i;
1385-
ship *shipp;
1386-
shipp = &Ships[objp->instance];
1384+
auto shipp = &Ships[objp->instance];
13871385

1388-
for (i=0; i<MAX_ARC_EFFECTS; i++ ) {
1389-
if ( shipp->arc_timestamp[i].isValid() ) {
1386+
for (auto &arc: shipp->electrical_arcs) {
1387+
if ( arc.timestamp.isValid() ) {
13901388
// Move arc endpoints into world coordinates
13911389
vec3d tmp1, tmp2;
1392-
vm_vec_unrotate(&tmp1,&shipp->arc_pts[i][0],&objp->orient);
1390+
vm_vec_unrotate(&tmp1,&arc.endpoint_1,&objp->orient);
13931391
vm_vec_add2(&tmp1,&objp->pos);
13941392

1395-
vm_vec_unrotate(&tmp2,&shipp->arc_pts[i][1],&objp->orient);
1393+
vm_vec_unrotate(&tmp2,&arc.endpoint_2,&objp->orient);
13961394
vm_vec_add2(&tmp2,&objp->pos);
13971395

13981396
light_add_point( &tmp1, 10.0f, 20.0f, frand(), 1.0f, 1.0f, 1.0f);
@@ -1478,19 +1476,17 @@ void obj_move_all_post(object *objp, float frametime)
14781476
// Make any electrical arcs on debris cast light
14791477
if (Arc_light) {
14801478
if ( Detail.lighting > 3 ) {
1481-
int i;
1482-
debris *db;
1483-
db = &Debris[objp->instance];
1479+
auto db = &Debris[objp->instance];
14841480

14851481
if (db->arc_frequency > 0) {
1486-
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
1487-
if ( db->arc_timestamp[i].isValid() ) {
1482+
for (auto &arc: db->electrical_arcs) {
1483+
if ( arc.timestamp.isValid() ) {
14881484
// Move arc endpoints into world coordinates
14891485
vec3d tmp1, tmp2;
1490-
vm_vec_unrotate(&tmp1,&db->arc_pts[i][0],&objp->orient);
1486+
vm_vec_unrotate(&tmp1,&arc.endpoint_1,&objp->orient);
14911487
vm_vec_add2(&tmp1,&objp->pos);
14921488

1493-
vm_vec_unrotate(&tmp2,&db->arc_pts[i][1],&objp->orient);
1489+
vm_vec_unrotate(&tmp2,&arc.endpoint_2,&objp->orient);
14941490
vm_vec_add2(&tmp2,&objp->pos);
14951491

14961492
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)