mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 07:28:22 -10:00
Remove the fireball limit (#3224)
* Remove the fireball limit * Handle Feedback (Without the main PC, so really hoping I don't do any typos)
This commit is contained in:
1 parent
d716433848
commit
609ed4ed94
5 files changed
+116
-111
No files matched your search
+87
-102
@@ -31,13 +31,15 @@ int Knossos_warp_ani_used;
|
||||
|
||||
#define MAX_WARP_LOD 0
|
||||
|
||||
fireball Fireballs[MAX_FIREBALLS];
|
||||
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_fireballs = 0;
|
||||
int Num_fireball_types = 0;
|
||||
|
||||
bool fireballs_inited = false;
|
||||
@@ -435,8 +437,6 @@ void fireball_load_data()
|
||||
// This will get called at the start of each level.
|
||||
void fireball_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !fireballs_inited ) {
|
||||
// Do all the processing that happens only once
|
||||
fireball_parse_tbl();
|
||||
@@ -446,10 +446,10 @@ void fireball_init()
|
||||
}
|
||||
|
||||
// Reset everything between levels
|
||||
Num_fireballs = 0;
|
||||
for (i=0; i<MAX_FIREBALLS; i++ ) {
|
||||
Fireballs[i].objnum = -1;
|
||||
}
|
||||
Fireballs.clear();
|
||||
Fireballs.reserve(INTITIAL_FIREBALL_CONTAINTER_SIZE);
|
||||
Unused_fireball_indices.clear();
|
||||
Unused_fireball_indices.reserve(INTITIAL_FIREBALL_CONTAINTER_SIZE);
|
||||
|
||||
// Goober5000 - reset Knossos warp flag
|
||||
Knossos_warp_ani_used = 0;
|
||||
@@ -467,13 +467,15 @@ void fireball_delete( object * obj )
|
||||
fireball *fb;
|
||||
|
||||
num = obj->instance;
|
||||
// Make sure the new system works fine.
|
||||
Assert(obj->instance > -1);
|
||||
Assert(static_cast<int>(Fireballs.size()) > obj->instance);
|
||||
fb = &Fireballs[num];
|
||||
|
||||
Assert( fb->objnum == OBJ_INDEX(obj));
|
||||
|
||||
Fireballs[num].objnum = -1;
|
||||
Num_fireballs--;
|
||||
Assert( Num_fireballs >= 0 );
|
||||
Unused_fireball_indices.push_back(num);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -481,13 +483,9 @@ void fireball_delete( object * obj )
|
||||
*/
|
||||
void fireball_delete_all()
|
||||
{
|
||||
fireball *fb;
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < MAX_FIREBALLS; i++ ) {
|
||||
fb = &Fireballs[i];
|
||||
if ( fb->objnum != -1 ) {
|
||||
obj_delete(fb->objnum);
|
||||
for (auto& current_fireball : Fireballs) {
|
||||
if ( current_fireball.objnum != -1 ) {
|
||||
obj_delete(current_fireball.objnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -499,6 +497,8 @@ void fireball_set_framenum(int num)
|
||||
fireball_info *fd;
|
||||
fireball_lod *fl;
|
||||
|
||||
Assert(static_cast<int>(Fireballs.size()) > num);
|
||||
|
||||
fb = &Fireballs[num];
|
||||
fd = &Fireball_info[Fireballs[num].fireball_info_index];
|
||||
|
||||
@@ -537,6 +537,9 @@ int fireball_is_perishable(object * obj)
|
||||
|
||||
num = obj->instance;
|
||||
objnum = OBJ_INDEX(obj);
|
||||
// Make sure the new system works fine.
|
||||
Assert(obj->instance > -1);
|
||||
Assert((int)Fireballs.size() > obj->instance);
|
||||
Assert( Fireballs[num].objnum == objnum );
|
||||
|
||||
fb = &Fireballs[num];
|
||||
@@ -553,43 +556,6 @@ int fireball_is_perishable(object * obj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* There are too many fireballs, so delete the oldest small one
|
||||
* to free up a slot.
|
||||
*
|
||||
* @return The fireball slot freed.
|
||||
*/
|
||||
int fireball_free_one()
|
||||
{
|
||||
fireball *fb;
|
||||
int i;
|
||||
|
||||
int oldest_objnum = -1, oldest_slotnum = -1;
|
||||
float lifeleft, oldest_lifeleft = 0.0f;
|
||||
|
||||
for ( i = 0; i < MAX_FIREBALLS; i++ ) {
|
||||
fb = &Fireballs[i];
|
||||
|
||||
// only remove the ones that aren't warp effects
|
||||
if ( (fb->objnum >= 0) && fireball_is_perishable(&Objects[fb->objnum]) ) {
|
||||
|
||||
lifeleft = fb->total_time - fb->time_elapsed;
|
||||
if ( (oldest_objnum < 0) || (lifeleft < oldest_lifeleft) ) {
|
||||
oldest_slotnum = i;
|
||||
oldest_lifeleft = lifeleft;
|
||||
oldest_objnum = fb->objnum;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( oldest_objnum > -1 ) {
|
||||
obj_delete(oldest_objnum);
|
||||
}
|
||||
return oldest_slotnum;
|
||||
}
|
||||
|
||||
int fireball_is_warp(object * obj)
|
||||
{
|
||||
int num, objnum;
|
||||
@@ -597,6 +563,9 @@ int fireball_is_warp(object * obj)
|
||||
|
||||
num = obj->instance;
|
||||
objnum = OBJ_INDEX(obj);
|
||||
// Make sure the new system works fine.
|
||||
Assert(obj->instance > -1);
|
||||
Assert(static_cast<int>(Fireballs.size()) > obj->instance);
|
||||
Assert( Fireballs[num].objnum == objnum );
|
||||
|
||||
fb = &Fireballs[num];
|
||||
@@ -641,6 +610,9 @@ void fireball_process_post(object * obj, float frame_time)
|
||||
|
||||
num = obj->instance;
|
||||
objnum = OBJ_INDEX(obj);
|
||||
// Make sure the new system works fine.
|
||||
Assert(obj->instance > -1);
|
||||
Assert(static_cast<int>(Fireballs.size()) > obj->instance);
|
||||
Assert( Fireballs[num].objnum == objnum );
|
||||
|
||||
fb = &Fireballs[num];
|
||||
@@ -665,6 +637,10 @@ float fireball_lifeleft( object *obj )
|
||||
|
||||
num = obj->instance;
|
||||
objnum = OBJ_INDEX(obj);
|
||||
// Make sure the new system works fine.
|
||||
Assert(obj->instance > -1);
|
||||
Assert(static_cast<int>(Fireballs.size()) > obj->instance);
|
||||
|
||||
Assert( Fireballs[num].objnum == objnum );
|
||||
|
||||
fb = &Fireballs[num];
|
||||
@@ -680,6 +656,10 @@ float fireball_lifeleft_percent( object *obj )
|
||||
int num, objnum;
|
||||
fireball *fb;
|
||||
|
||||
// Make sure the new system works fine.
|
||||
Assert(obj->instance > -1);
|
||||
Assert(static_cast<int>(Fireballs.size()) > obj->instance);
|
||||
|
||||
num = obj->instance;
|
||||
objnum = OBJ_INDEX(obj);
|
||||
Assert( Fireballs[num].objnum == objnum );
|
||||
@@ -781,10 +761,8 @@ int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_o
|
||||
{
|
||||
int n, objnum, fb_lod;
|
||||
object *obj;
|
||||
fireball *fb;
|
||||
fireball_info *fd;
|
||||
fireball_lod *fl;
|
||||
|
||||
Assert( fireball_type > -1 );
|
||||
Assert( fireball_type < Num_fireball_types );
|
||||
|
||||
@@ -800,23 +778,21 @@ int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_o
|
||||
}
|
||||
}
|
||||
|
||||
if ( (Num_fireballs >= MAX_FIREBALLS) || (Num_objects >= MAX_OBJECTS) ) {
|
||||
|
||||
// out of slots, so free one up.
|
||||
n = fireball_free_one();
|
||||
if ( n < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
for ( n = 0; n < MAX_FIREBALLS; n++ ) {
|
||||
if ( Fireballs[n].objnum < 0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Assert( n != MAX_FIREBALLS );
|
||||
if (Num_objects >= MAX_OBJECTS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fb = &Fireballs[n];
|
||||
|
||||
if (!Unused_fireball_indices.empty()) {
|
||||
n = Unused_fireball_indices.back();
|
||||
Unused_fireball_indices.pop_back();
|
||||
}
|
||||
else {
|
||||
n = static_cast<int>(Fireballs.size());
|
||||
Fireballs.emplace_back();
|
||||
}
|
||||
|
||||
fireball* new_fireball = &Fireballs[n];
|
||||
|
||||
// get an lod to use
|
||||
fb_lod = fireball_get_lod(pos, fd, size);
|
||||
@@ -833,13 +809,13 @@ int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_o
|
||||
}
|
||||
fl = &fd->lod[fb_lod];
|
||||
|
||||
fb->lod = (char)fb_lod;
|
||||
new_fireball->lod = (char)fb_lod;
|
||||
|
||||
fb->flags = extra_flags;
|
||||
fb->warp_open_sound_index = warp_open_sound;
|
||||
fb->warp_close_sound_index = warp_close_sound;
|
||||
fb->warp_open_duration = (warp_open_duration < 0.0f) ? WARPHOLE_GROW_TIME : warp_open_duration;
|
||||
fb->warp_close_duration = (warp_close_duration < 0.0f) ? WARPHOLE_GROW_TIME : warp_close_duration;
|
||||
new_fireball->flags = extra_flags;
|
||||
new_fireball->warp_open_sound_index = warp_open_sound;
|
||||
new_fireball->warp_close_sound_index = warp_close_sound;
|
||||
new_fireball->warp_open_duration = (warp_open_duration < 0.0f) ? WARPHOLE_GROW_TIME : warp_open_duration;
|
||||
new_fireball->warp_close_duration = (warp_close_duration < 0.0f) ? WARPHOLE_GROW_TIME : warp_close_duration;
|
||||
|
||||
matrix orient;
|
||||
if(orient_override != NULL){
|
||||
@@ -856,58 +832,53 @@ int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_o
|
||||
default_flags.set(Object::Object_Flags::Renders);
|
||||
objnum = obj_create(OBJ_FIREBALL, parent_obj, n, &orient, pos, size, default_flags);
|
||||
|
||||
if (objnum < 0) {
|
||||
Int3(); // Get John, we ran out of objects for fireballs
|
||||
return objnum;
|
||||
}
|
||||
|
||||
obj = &Objects[objnum];
|
||||
|
||||
fb->fireball_info_index = fireball_type;
|
||||
fb->fireball_render_type = render_type;
|
||||
fb->time_elapsed = 0.0f;
|
||||
fb->objnum = objnum;
|
||||
fb->current_bitmap = -1;
|
||||
new_fireball->fireball_info_index = fireball_type;
|
||||
new_fireball->fireball_render_type = render_type;
|
||||
new_fireball->time_elapsed = 0.0f;
|
||||
new_fireball->objnum = objnum;
|
||||
new_fireball->current_bitmap = -1;
|
||||
|
||||
switch( fb->fireball_render_type ) {
|
||||
switch( new_fireball->fireball_render_type ) {
|
||||
|
||||
case FIREBALL_MEDIUM_EXPLOSION:
|
||||
fb->orient = (myrand()>>8) & 7; // 0 - 7
|
||||
new_fireball->orient = (myrand()>>8) & 7; // 0 - 7
|
||||
break;
|
||||
|
||||
case FIREBALL_LARGE_EXPLOSION:
|
||||
fb->orient = (myrand()>>8) % 360; // 0 - 359
|
||||
new_fireball->orient = (myrand()>>8) % 360; // 0 - 359
|
||||
break;
|
||||
|
||||
case FIREBALL_WARP_EFFECT:
|
||||
// Play sound effect for warp hole opening up
|
||||
fireball_play_warphole_open_sound(ship_class, fb);
|
||||
fireball_play_warphole_open_sound(ship_class, new_fireball);
|
||||
|
||||
// warp in type
|
||||
if (reverse) {
|
||||
fb->orient = 1;
|
||||
new_fireball->orient = 1;
|
||||
// if warp out, then reverse the orientation
|
||||
vm_vec_scale( &obj->orient.vec.fvec, -1.0f ); // Reverse the forward vector
|
||||
vm_vec_scale( &obj->orient.vec.rvec, -1.0f ); // Reverse the right vector
|
||||
} else {
|
||||
fb->orient = 0;
|
||||
new_fireball->orient = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Int3();
|
||||
UNREACHABLE("Bad type set in fireball_create");
|
||||
break;
|
||||
}
|
||||
|
||||
if ( fb->fireball_render_type == FIREBALL_WARP_EFFECT ) {
|
||||
if ( new_fireball->fireball_render_type == FIREBALL_WARP_EFFECT ) {
|
||||
Assert( warp_lifetime >= 4.0f ); // Warp lifetime must be at least 4 seconds!
|
||||
if ( warp_lifetime < 4.0f )
|
||||
warp_lifetime = 4.0f;
|
||||
fb->total_time = warp_lifetime; // in seconds
|
||||
new_fireball->total_time = warp_lifetime; // in seconds
|
||||
} else {
|
||||
fb->total_time = i2fl(fl->num_frames) / fl->fps; // in seconds
|
||||
new_fireball->total_time = i2fl(fl->num_frames) / fl->fps; // in seconds
|
||||
}
|
||||
|
||||
|
||||
fireball_set_framenum(n);
|
||||
|
||||
if ( velocity ) {
|
||||
@@ -923,7 +894,6 @@ int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_o
|
||||
vm_vec_zero(&obj->phys_info.max_rotvel);
|
||||
}
|
||||
|
||||
Num_fireballs++;
|
||||
return objnum;
|
||||
}
|
||||
|
||||
@@ -1058,10 +1028,14 @@ void fireball_render(object* obj, model_draw_list *scene)
|
||||
|
||||
MONITOR_INC( NumFireballsRend, 1 );
|
||||
|
||||
// Make sure the new system works fine.
|
||||
Assert(obj->instance > -1);
|
||||
Assert(static_cast<int>(Fireballs.size()) > obj->instance);
|
||||
|
||||
num = obj->instance;
|
||||
fb = &Fireballs[num];
|
||||
|
||||
if ( Fireballs[num].current_bitmap < 0 )
|
||||
if ( fb->current_bitmap < 0 )
|
||||
return;
|
||||
|
||||
g3_transfer_vertex(&p, &obj->pos);
|
||||
@@ -1069,13 +1043,13 @@ void fireball_render(object* obj, model_draw_list *scene)
|
||||
switch ( fb->fireball_render_type ) {
|
||||
|
||||
case FIREBALL_MEDIUM_EXPLOSION: {
|
||||
batching_add_volume_bitmap(Fireballs[num].current_bitmap, &p, fb->orient, obj->radius);
|
||||
batching_add_volume_bitmap(fb->current_bitmap, &p, fb->orient, obj->radius);
|
||||
}
|
||||
break;
|
||||
|
||||
case FIREBALL_LARGE_EXPLOSION: {
|
||||
// Make the big explosions rotate with the viewer.
|
||||
batching_add_volume_bitmap_rotated(Fireballs[num].current_bitmap, &p, (i2fl(fb->orient)*PI) / 180.0f, obj->radius);
|
||||
batching_add_volume_bitmap_rotated(fb->current_bitmap, &p, (i2fl(fb->orient)*PI) / 180.0f, obj->radius);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1093,3 +1067,14 @@ void fireball_render(object* obj, model_draw_list *scene)
|
||||
Int3();
|
||||
}
|
||||
}
|
||||
|
||||
// Because fireballs are only added and removed in two places, and Unused_fireball_indices is always updated in those places to contain unused indices,
|
||||
// this very simple code will give you the correct count of currently existing fireballs in use.
|
||||
int fireball_get_count()
|
||||
{
|
||||
int count = static_cast<int>(Fireballs.size()) - static_cast<int>(Unused_fireball_indices.size());
|
||||
|
||||
Assert (count >= 0);
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -95,8 +95,7 @@ typedef struct fireball {
|
||||
} fireball;
|
||||
// end move
|
||||
|
||||
extern fireball Fireballs[MAX_FIREBALLS];
|
||||
extern int Num_fireballs;
|
||||
extern SCP_vector<fireball> Fireballs;
|
||||
|
||||
extern bool fireballs_inited;
|
||||
|
||||
@@ -146,4 +145,7 @@ extern int Knossos_warp_ani_used;
|
||||
|
||||
extern bool Fireball_use_3d_warp;
|
||||
|
||||
// Cyborg - get a count of how many valid fireballs are in the mission.
|
||||
int fireball_get_count();
|
||||
|
||||
#endif /* _FIREBALLS_H */
|
||||
@@ -1201,7 +1201,6 @@ void obj_clear_weapon_group_id_list()
|
||||
|
||||
int Arc_light = 1; // If set, electrical arcs on debris cast light
|
||||
DCF_BOOL(arc_light, Arc_light)
|
||||
extern fireball Fireballs[];
|
||||
|
||||
void obj_move_all_post(object *objp, float frametime)
|
||||
{
|
||||
@@ -1313,6 +1312,9 @@ void obj_move_all_post(object *objp, float frametime)
|
||||
|
||||
if (Detail.lighting > 2) {
|
||||
float r = 0.0f, g = 0.0f, b = 0.0f;
|
||||
// Make sure the new system works fine.
|
||||
Assert(objp->instance > -1);
|
||||
Assert(static_cast<int>(Fireballs.size()) > objp->instance);
|
||||
|
||||
fireball_get_color(Fireballs[objp->instance].fireball_info_index, &r, &g, &b);
|
||||
|
||||
@@ -1332,6 +1334,9 @@ void obj_move_all_post(object *objp, float frametime)
|
||||
float intensity = 1.0f;
|
||||
if (fireball_is_warp(objp))
|
||||
{
|
||||
// Make sure the new system works fine.
|
||||
Assert(static_cast<int>(Fireballs.size()) > objp->instance);
|
||||
Assert(objp->instance > -1);
|
||||
intensity = fireball_wormhole_intensity(&Fireballs[objp->instance]); // Valathil: Get wormhole radius for lighting
|
||||
rad = objp->radius;
|
||||
}
|
||||
|
||||
@@ -705,26 +705,27 @@ ADE_INDEXER(l_Mission_Fireballs, "number Index", "Gets handle to a fireball obje
|
||||
if (!ade_get_args(L, "*i", &idx))
|
||||
return ade_set_error(L, "o", l_Fireball.Set(object_h()));
|
||||
|
||||
//Remember, Lua indices start at 0.
|
||||
//Remember, Lua indices start at 1.
|
||||
int count = 1;
|
||||
|
||||
for (int i = 0; i < MAX_FIREBALLS; i++)
|
||||
{
|
||||
if (Fireballs[i].fireball_info_index < 0 || Fireballs[i].objnum < 0 || Objects[Fireballs[i].objnum].type != OBJ_FIREBALL)
|
||||
for (auto& current_fireball : Fireballs) {
|
||||
if (current_fireball.fireball_info_index < 0 || current_fireball.objnum < 0 || Objects[current_fireball.objnum].type != OBJ_FIREBALL)
|
||||
continue;
|
||||
|
||||
if (count == idx) {
|
||||
return ade_set_args(L, "o", l_Fireball.Set(object_h(&Objects[Fireballs[i].objnum])));
|
||||
return ade_set_args(L, "o", l_Fireball.Set(object_h(&Objects[current_fireball.objnum])));
|
||||
}
|
||||
|
||||
count++;
|
||||
|
||||
}
|
||||
|
||||
return ade_set_error(L, "o", l_Fireball.Set(object_h()));
|
||||
}
|
||||
ADE_FUNC(__len, l_Mission_Fireballs, NULL, "Number of fireball objects in mission. Note that this is only accurate for one frame.", "number", "Number of fireball objects in mission")
|
||||
{
|
||||
return ade_set_args(L, "i", Num_fireballs);
|
||||
int count = fireball_get_count();
|
||||
return ade_set_args(L, "i", count);
|
||||
}
|
||||
|
||||
ADE_FUNC(addMessage, l_Mission, "string name, string text, [persona persona]", "Adds a message", "message", "The new message or invalid handle on error")
|
||||
|
||||
@@ -23,6 +23,9 @@ ADE_VIRTVAR(Class, l_Fireball, "fireballclass", "Fireball's class", "fireballcla
|
||||
if(!oh->IsValid())
|
||||
return ade_set_error(L, "o", l_Fireballclass.Set(-1));
|
||||
|
||||
if (oh->objp->instance < 0 || oh->objp->instance >= static_cast<int>(Fireballs.size()))
|
||||
return ade_set_error(L, "o", l_Fireballclass.Set(-1));
|
||||
|
||||
fireball *fb = &Fireballs[oh->objp->instance];
|
||||
|
||||
if(ADE_SETTING_VAR && nc > -1) {
|
||||
@@ -42,6 +45,9 @@ ADE_VIRTVAR(RenderType, l_Fireball, "enumeration", "Fireball's render type", "en
|
||||
if (!oh->IsValid())
|
||||
return ade_set_error(L, "o", l_Enum.Set(enum_h()));
|
||||
|
||||
if (oh->objp->instance < 0 || oh->objp->instance >= static_cast<int>(Fireballs.size()))
|
||||
return ade_set_error(L, "o", l_Enum.Set(enum_h()));
|
||||
|
||||
fireball* fb = &Fireballs[oh->objp->instance];
|
||||
|
||||
if (ADE_SETTING_VAR && type.IsValid()) {
|
||||
@@ -87,6 +93,9 @@ ADE_VIRTVAR(TimeElapsed, l_Fireball, NULL, "Time this fireball exists in seconds
|
||||
if(!oh->IsValid())
|
||||
return ade_set_error(L, "f", 0.0f);
|
||||
|
||||
if (oh->objp->instance < 0 || oh->objp->instance <= static_cast<int>(Fireballs.size()))
|
||||
return ade_set_error(L, "f", 0.0f);
|
||||
|
||||
fireball *fb = &Fireballs[oh->objp->instance];
|
||||
|
||||
return ade_set_args(L, "f", fb->time_elapsed);
|
||||
@@ -102,6 +111,9 @@ ADE_VIRTVAR(TotalTime, l_Fireball, NULL, "Total lifetime of the fireball's anima
|
||||
if (!oh->IsValid())
|
||||
return ade_set_error(L, "f", 0.0f);
|
||||
|
||||
if (oh->objp->instance < 0 || oh->objp->instance >= static_cast<int>(Fireballs.size()))
|
||||
return ade_set_error(L, "f", 0.0f);
|
||||
|
||||
fireball* fb = &Fireballs[oh->objp->instance];
|
||||
|
||||
return ade_set_args(L, "f", fb->total_time);
|
||||
|
||||
Reference in new issue
Block a user