Skip to content

Commit

Permalink
Merge pull request scp-fs2open#6114 from Goober5000/dynamic_fireballs
Browse files Browse the repository at this point in the history
make fireball types dynamic
  • Loading branch information
Goober5000 authored May 6, 2024
2 parents 209f563 + 3851832 commit 322f807
Show file tree
Hide file tree
Showing 14 changed files with 109 additions and 94 deletions.
10 changes: 3 additions & 7 deletions code/asteroid/asteroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1593,9 +1593,8 @@ static float asteroid_create_explosion(object *objp)
fireball_type = FIREBALL_ASTEROID;
}

if (fireball_type >= Num_fireball_types) {
Warning(LOCATION, "Invalid fireball type %i specified for an asteroid, only %i fireball types are defined.", fireball_type, Num_fireball_types);

if (fireball_type >= static_cast<int>(Fireball_info.size())) {
Warning(LOCATION, "Invalid fireball type %i specified for an asteroid; only " SIZE_T_ARG " fireball types are defined.", fireball_type, Fireball_info.size());
return 0;
}

Expand Down Expand Up @@ -2251,10 +2250,7 @@ static void asteroid_parse_section()
}

if(optional_string("$Explosion Animations:")){
int temp[MAX_FIREBALL_TYPES];
auto parsed_ints = stuff_int_list(temp, MAX_FIREBALL_TYPES, RAW_INTEGER_TYPE);
asteroid_p->explosion_bitmap_anims.clear();
asteroid_p->explosion_bitmap_anims.insert(asteroid_p->explosion_bitmap_anims.begin(), temp, temp + parsed_ints);
stuff_fireball_index_list(asteroid_p->explosion_bitmap_anims, asteroid_p->name);
}

if (optional_string("$Explosion Radius Mult:")) {
Expand Down
72 changes: 38 additions & 34 deletions code/fireball/fireballs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,7 @@ constexpr int INTITIAL_FIREBALL_CONTAINTER_SIZE = 256;
SCP_vector<fireball> Fireballs;
SCP_vector<int> Unused_fireball_indices;

fireball_info Fireball_info[MAX_FIREBALL_TYPES];

int fireball_used[MAX_FIREBALL_TYPES];

int Num_fireball_types = 0;
SCP_vector<fireball_info> Fireball_info;

bool fireballs_inited = false;
bool fireballs_parsed = false;
Expand Down Expand Up @@ -120,7 +116,7 @@ void fireball_play_warphole_close_sound(fireball *fb)

static void fireball_generate_unique_id(char *unique_id, int buffer_len, int fireball_index)
{
Assert((fireball_index >= 0) && (fireball_index < MAX_FIREBALL_TYPES));
Assertion(SCP_vector_inbounds(Fireball_info, fireball_index), "fireball_index is out of bounds!");

switch (fireball_index)
{
Expand Down Expand Up @@ -164,7 +160,7 @@ static void fireball_generate_unique_id(char *unique_id, int buffer_len, int fir
*/
static void fireball_set_default_color(int idx)
{
Assert((idx >= 0) && (idx < MAX_FIREBALL_TYPES));
Assertion(SCP_vector_inbounds(Fireball_info, idx), "idx is out of bounds!");

switch (idx)
{
Expand Down Expand Up @@ -200,7 +196,7 @@ static void fireball_set_default_color(int idx)

static void fireball_set_default_warp_attributes(int idx)
{
Assert((idx >= 0) && (idx < MAX_FIREBALL_TYPES));
Assertion(SCP_vector_inbounds(Fireball_info, idx), "idx is out of bounds!");

switch (idx)
{
Expand Down Expand Up @@ -232,9 +228,9 @@ void fireball_info_clear(fireball_info *fb)

int fireball_info_lookup(const char *unique_id)
{
for (int i = 0; i < Num_fireball_types; ++i)
for (size_t i = 0; i < Fireball_info.size(); ++i)
if (!stricmp(Fireball_info[i].unique_id, unique_id))
return i;
return static_cast<int>(i);

return -1;
}
Expand Down Expand Up @@ -308,25 +304,19 @@ static void parse_fireball_tbl(const char *table_filename)
// we are creating a new entry, so set some defaults
else
{
// make sure we don't exceed the max
if (Num_fireball_types >= MAX_FIREBALL_TYPES)
{
error_display(0, "Too many fireball entries! Max is %d", MAX_FIREBALL_TYPES);
return;
}

fi = &Fireball_info[Num_fireball_types];
int new_fireball_index = static_cast<int>(Fireball_info.size());
Fireball_info.emplace_back();
fi = &Fireball_info.back();
fireball_info_clear(fi);

// If the table didn't specify a unique ID, generate one. This will be assigned a few lines later.
if (strlen(unique_id) == 0)
fireball_generate_unique_id(unique_id, NAME_LENGTH, Num_fireball_types);
fireball_generate_unique_id(unique_id, NAME_LENGTH, new_fireball_index);

// Set remaining fireball defaults
fireball_set_default_color(Num_fireball_types);
fireball_set_default_warp_attributes(Num_fireball_types);
fireball_set_default_color(new_fireball_index);
fireball_set_default_warp_attributes(new_fireball_index);

Num_fireball_types++;
first_time = true;
}

Expand Down Expand Up @@ -399,9 +389,9 @@ void fireball_parse_tbl()
if (fireballs_parsed)
return;

// every newly parsed fireball_info will get cleared before being added
// must do this outside of parse_fireball_tbl because it's called twice
Num_fireball_types = 0;
// every newly parsed fireball_info will get cleared before being added;
// must clear the vector outside of parse_fireball_tbl because it's called more than once
Fireball_info.clear();

parse_fireball_tbl("fireball.tbl");

Expand Down Expand Up @@ -436,10 +426,11 @@ void fireball_parse_tbl()

void fireball_load_data()
{
int i, idx;
int i, n, idx;
fireball_info *fd;

for ( i = 0; i < Num_fireball_types; i++ ) {
n = static_cast<int>(Fireball_info.size());
for ( i = 0; i < n; i++ ) {
fd = &Fireball_info[i];

for(idx=0; idx<fd->lod_count; idx++){
Expand Down Expand Up @@ -798,8 +789,7 @@ int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_o
object *obj;
fireball_info *fd;
fireball_lod *fl;
Assert( fireball_type > -1 );
Assert( fireball_type < Num_fireball_types );
Assertion(SCP_vector_inbounds(Fireball_info, fireball_type), "fireball_type is out of bounds!");

fd = &Fireball_info[fireball_type];

Expand Down Expand Up @@ -946,13 +936,14 @@ void fireball_close()

void fireballs_page_in()
{
int i, idx;
int i, n, idx;
fireball_info *fd;

for ( i = 0; i < Num_fireball_types; i++ ) {
n = static_cast<int>(Fireball_info.size());
for ( i = 0; i < n; i++ ) {
fd = &Fireball_info[i];

if((i < NUM_DEFAULT_FIREBALLS) || fireball_used[i]) {
if ((i < NUM_DEFAULT_FIREBALLS) || fd->fireball_used) {
// if this is a Knossos ani, only load if Knossos_warp_ani_used is true
if ( (i == FIREBALL_KNOSSOS) && !Knossos_warp_ani_used)
continue;
Expand Down Expand Up @@ -984,8 +975,8 @@ void fireball_get_color(int idx, float *red, float *green, float *blue)
{
Assert( red && blue && green );

if ( (idx < 0) || (idx >= Num_fireball_types) ) {
Int3();
if (!SCP_vector_inbounds(Fireball_info, idx)) {
UNREACHABLE("idx is out of bounds!");

*red = 1.0f;
*green = 1.0f;
Expand Down Expand Up @@ -1120,3 +1111,16 @@ int fireball_get_count()

return count;
}

void stuff_fireball_index_list(SCP_vector<int> &list, const char *name)
{
stuff_int_list(list, RAW_INTEGER_TYPE);

list.erase(std::remove_if(list.begin(), list.end(), [&](int index) {
if (!SCP_vector_inbounds(Fireball_info, index)) {
Warning(LOCATION, "Fireball index %d for %s was out of bounds. Removing this index.", index, name);
return true;
}
return false;
}), list.end());
}
10 changes: 5 additions & 5 deletions code/fireball/fireballs.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,12 @@ class asteroid_info;
#define FIREBALL_EXPLOSION_LARGE1 4 // Used for the big explosion when a ship breaks into pieces
#define FIREBALL_EXPLOSION_LARGE2 5 // Used for the big explosion when a ship breaks into pieces

#define MAX_FIREBALL_TYPES 32 // The maximum number of fireballs that can be defined
#define NUM_DEFAULT_FIREBALLS 6

#define MAX_FIREBALL_LOD 4

#define FIREBALL_NUM_LARGE_EXPLOSIONS 2

extern int fireball_used[MAX_FIREBALL_TYPES];

// all this moved here by Goober5000 because it makes more sense in the H file
typedef struct fireball_lod {
char filename[MAX_FILENAME_LEN];
Expand All @@ -57,6 +54,7 @@ typedef struct fireball_info {
float exp_color[3]; // red, green, blue

bool use_3d_warp;
bool fireball_used;

char warp_glow[NAME_LENGTH];
int warp_glow_bitmap;
Expand All @@ -66,8 +64,7 @@ typedef struct fireball_info {
int warp_model_id;
} fireball_info;

extern fireball_info Fireball_info[MAX_FIREBALL_TYPES];
extern int Num_fireball_types;
extern SCP_vector<fireball_info> Fireball_info;

// flag values for fireball struct flags member
#define FBF_WARP_CLOSE_SOUND_PLAYED (1<<0)
Expand Down Expand Up @@ -153,4 +150,7 @@ extern bool Fireball_warp_flash;
// Cyborg - get a count of how many valid fireballs are in the mission.
int fireball_get_count();

// Goober5000 - stuffs fireballs and checks that indexes are in bounds
void stuff_fireball_index_list(SCP_vector<int> &list, const char *name);

#endif /* _FIREBALLS_H */
4 changes: 2 additions & 2 deletions code/hud/hudartillery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ void parse_ssm(const char *filename)
{
int temp = atoi(unique_id);

if ((temp < 0) || (temp >= Num_fireball_types))
error_display(0, "Fireball index [%d] out of range (should be 0-%d) for SSM strike [%s]", temp, Num_fireball_types - 1, s->name);
if (!SCP_vector_inbounds(Fireball_info, temp))
error_display(0, "Fireball index [%d] out of range (should be 0-%d) for SSM strike [%s]", temp, static_cast<int>(Fireball_info.size()) - 1, s->name);
else
s->fireball_type = temp;
}
Expand Down
35 changes: 28 additions & 7 deletions code/parse/parselo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3064,13 +3064,16 @@ const char* get_lookup_type_name(int lookup_type)
return "Unknown lookup type, tell a coder!";
}

// Stuffs an integer list.
// This is of the form ( i* )
// where i is an integer.
// For example, (1) () (1 2 3) ( 1 ) are legal integer lists.
size_t stuff_int_list(int *ilp, size_t max_ints, int lookup_type)
// use a functor here so that we don't need to re-roll the parsing function for both variants of stuff_int_lists
struct StuffIntListParser
{
return stuff_token_list(ilp, max_ints, [&](int *buf)->bool {
int lookup_type;

StuffIntListParser(int _lookup_type)
: lookup_type(_lookup_type)
{}

bool operator()(int* buf) {
if (*Mp == '"') {
int num = 0;
bool valid_negative = false;
Expand Down Expand Up @@ -3123,7 +3126,25 @@ size_t stuff_int_list(int *ilp, size_t max_ints, int lookup_type)
}

return true;
}, get_lookup_type_name(lookup_type));
}
};

// Stuffs an integer list.
// This is of the form ( i* )
// where i is an integer.
// For example, (1) () (1 2 3) ( 1 ) are legal integer lists.
size_t stuff_int_list(int *ilp, size_t max_ints, int lookup_type)
{
return stuff_token_list(ilp, max_ints, StuffIntListParser(lookup_type), get_lookup_type_name(lookup_type));
}

// Stuffs an integer list.
// This is of the form ( i* )
// where i is an integer.
// For example, (1) () (1 2 3) ( 1 ) are legal integer lists.
void stuff_int_list(SCP_vector<int> &ilp, int lookup_type)
{
stuff_token_list(ilp, StuffIntListParser(lookup_type), get_lookup_type_name(lookup_type));
}

// Karajorma/Goober5000 - Stuffs a loadout list by parsing a list of ship or weapon choices.
Expand Down
1 change: 1 addition & 0 deletions code/parse/parselo.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ void stuff_flagset(T *dest) {
}

extern size_t stuff_int_list(int *ilp, size_t max_ints, int lookup_type = RAW_INTEGER_TYPE);
extern void stuff_int_list(SCP_vector<int> &ilp, int lookup_type = RAW_INTEGER_TYPE);
extern size_t stuff_float_list(float* flp, size_t max_floats);
extern void stuff_float_list(SCP_vector<float>& flp);
extern size_t stuff_vec3d_list(vec3d *vlp, size_t max_vecs);
Expand Down
6 changes: 3 additions & 3 deletions code/parse/sexp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3995,7 +3995,7 @@ int check_sexp_syntax(int node, int return_type, int recursive, int *bad_node, s
if (type2 == SEXP_ATOM_NUMBER || can_construe_as_integer(CTEXT(node)))
{
int num = atoi(CTEXT(node));
if (num < 0 || num >= Num_fireball_types)
if (!SCP_vector_inbounds(Fireball_info, num))
{
return SEXP_CHECK_NUM_RANGE_INVALID;
}
Expand Down Expand Up @@ -14234,7 +14234,7 @@ void sexp_explosion_effect(int n)
{
fireball_type = FIREBALL_EXPLOSION_LARGE2;
}
else if (num >= Num_fireball_types)
else if (!SCP_vector_inbounds(Fireball_info, num))
{
Warning(LOCATION, "explosion-effect fireball type is out of range; quitting the explosion...\n");
return;
Expand Down Expand Up @@ -14431,7 +14431,7 @@ void sexp_warp_effect(int n)
{
fireball_type = FIREBALL_KNOSSOS;
}
else if (num >= Num_fireball_types)
else if (!SCP_vector_inbounds(Fireball_info, num))
{
Warning(LOCATION, "warp-effect fireball type is out of range; quitting the warp...\n");
return;
Expand Down
2 changes: 1 addition & 1 deletion code/scripting/api/libs/tables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ ADE_FUNC(__len, l_Tables_FireballClasses, NULL, "Number of fireball classes", "n
if (!fireballs_inited)
return ade_set_args(L, "i", 0);

return ade_set_args(L, "i", Num_fireball_types);
return ade_set_args(L, "i", static_cast<int>(Fireball_info.size()));
}

//*****SUBLIBRARY: Tables/SimulatedSpeechOverrides
Expand Down
Loading

0 comments on commit 322f807

Please sign in to comment.