Compare commits

...
Author SHA1 Message Date
SirKnightly 52200d9668 Automated build commit 2021-01-08 09:49:08 +00:00
m!m 85a2a8f11e Merge pull request #3092 from Goober5000/strtof_patch
interim patch for get_user_vec3d_value
2021-01-08 10:47:42 +01:00
Goober5000 e76fdea8b9 interim patch for get_user_vec3d_value
As described in #3079, the old parsing of fvec and uvec used strtod and some POFs rely on this format.  This is a quickfix that uses the new parsing method for only `get_user_vec3d_value`.
2021-01-07 18:08:27 -05:00
Goober5000 726ce953c7 Merge pull request #3089 from Goober5000/fix_submodel_debris
de-parent live debris
2021-01-07 15:24:49 -05:00
JohnAFernandez a545a4ec27 Merge pull request #3087 from Baezon/lock-restriction-safety
Safety for lock restriction handling
2021-01-07 15:01:31 -05:00
Fabian Woltermann fc0662a9c4 Merge pull request #3080 from JohnAFernandez/Vectorize-Tech-Lists
Vectorize tech lists
2021-01-07 15:16:09 +01:00
JohnAFernandez e5685ded86 Keep the lists from being cleared early by removing unneeded the loops. 2021-01-07 00:33:21 -05:00
JohnAFernandez 226cbf1204 The true fix, check the correct value 2021-01-07 00:32:52 -05:00
Goober5000 043466309a de-parent live debris
It appears that live debris is not supposed to have a parent submodel; see the retail NTF Boadicea.  This removes the parent from any live debris that might have it.

This should fix #3078.
2021-01-07 00:02:49 -05:00
Baezon 766624600d update name 2021-01-06 18:04:59 -05:00
Baezon dab9a41f45 remove redundant check 2021-01-06 17:45:32 -05:00
m!m 51d8ab13d8 Merge pull request #3088 from EatThePath/fix-empty-secondaries-locking
off-by-one fix in early exit update_aspect_lock_information()
2021-01-06 23:25:53 +01:00
Baezon b93d30e12b unused variable 2021-01-06 14:46:44 -05:00
David Gibson 945db25578 corrected off-by-one issue in the early exit condition of update_aspect_lock_information() 2021-01-06 13:46:05 -06:00
Baezon 67de007ecb lock restrictions safety 2021-01-06 14:28:27 -05:00
JohnAFernandez e9a9b3b978 Merge pull request #3085 from Baezon/docking-collision-bugfix
Safety for check_for_docking_collision
2021-01-06 14:03:00 -05:00
Baezon e10522a2c7 safety for check_for_docking_collision 2021-01-06 13:18:27 -05:00
JohnAFernandez 9f33b432fc Simply this check 2021-01-05 00:07:07 -05:00
JohnAFernandez 7a0578a797 Ok CI, I'll use nullptr 2021-01-04 22:14:36 -05:00
JohnAFernandez b81825326c Signed Vs Unsigned
AKA C'Mon CI!
2021-01-03 21:54:31 -05:00
JohnAFernandez b8c2c975c0 Change to a pointer
So that we can release bitmaps and animations properly.
2021-01-03 21:36:50 -05:00
JohnAFernandez dc0272e664 Fixes Part 1 2021-01-03 20:56:30 -05:00
JohnAFernandez 3e329d64dd Check the correct value in the animation code 2021-01-03 15:15:51 -05:00
JohnAFernandez 882ac2b1a1 Possibly Fix Memory Corruption Issue
Remove Unused Var
2021-01-03 15:14:11 -05:00
10 changed files with 198 additions and 225 deletions

No files matched your search

+2 -2
View File
@@ -7840,7 +7840,7 @@ void update_aspect_lock_information(ai_info *aip, vec3d *vec_to_enemy, float dis
object *aiobjp = &Objects[shipp->objnum];
// AL 3-7-98: This probably should never happen, but check to ensure that current_secondary_bank is valid
if ( (swp->current_secondary_bank < 0) || (swp->current_secondary_bank > swp->num_secondary_banks) ) {
if ( (swp->current_secondary_bank < 0) || (swp->current_secondary_bank >= swp->num_secondary_banks) ) {
return;
}
@@ -9065,7 +9065,7 @@ void ai_chase()
}
}
if (timestamp_elapsed(swp->next_secondary_fire_stamp[current_bank]) && weapon_can_lock_on_ship(swip, En_objp->instance)) {
if (timestamp_elapsed(swp->next_secondary_fire_stamp[current_bank]) && weapon_target_satisfies_lock_restrictions(swip, En_objp)) {
if (current_bank >= 0) {
float firing_range;
+3 -3
View File
@@ -924,7 +924,7 @@ void hud_lock_acquire_uncaged_target(lock_info *current_lock, weapon_info *wip)
continue;
}*/
if (!weapon_can_lock_on_ship(wip, A->instance)) {
if (!weapon_target_satisfies_lock_restrictions(wip, A)) {
continue;
}
@@ -1042,7 +1042,7 @@ void hud_lock_determine_lock_target(lock_info *lock_slot, weapon_info *wip)
return;
}
if ( !weapon_can_lock_on_ship(wip, lock_slot->obj->instance) ) {
if ( !weapon_target_satisfies_lock_restrictions(wip, lock_slot->obj) ) {
ship_clear_lock(lock_slot);
return;
}
@@ -1110,7 +1110,7 @@ void hud_lock_determine_lock_target(lock_info *lock_slot, weapon_info *wip)
return;
}
if ( !weapon_can_lock_on_ship(wip, lock_slot->obj->instance) ) {
if ( !weapon_target_satisfies_lock_restrictions(wip, lock_slot->obj) ) {
ship_clear_lock(lock_slot);
return;
}
+115 -195
View File
@@ -5,7 +5,8 @@
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
*/
@@ -235,14 +236,10 @@ typedef struct {
int textures_loaded; // if the model has textures loaded for it or not (hacky mem management)
} tech_list_entry;
static tech_list_entry *Ship_list = nullptr;
static int Ship_list_size = 0;
static tech_list_entry *Weapon_list = nullptr;
static int Weapon_list_size = 0;
static tech_list_entry *Intel_list = nullptr;
static int Intel_list_size = 0;
static tech_list_entry *Current_list; // points to currently valid display list
static int Current_list_size = 0;
static SCP_vector<tech_list_entry> Ship_list;
static SCP_vector<tech_list_entry> Weapon_list;
static SCP_vector<tech_list_entry> Intel_list;
static SCP_vector<tech_list_entry>* Current_list = &Ship_list; // A pointer to the current display list
// slider stuff
static UI_SLIDER2 Tech_slider;
@@ -274,64 +271,63 @@ void techroom_init_desc(const char *src, int w)
void techroom_unload_animation()
{
int i;
//clear everything, just in case, it will get loaded when needed later
if (Weapon_list != NULL) {
for (i = 0; i < Weapon_list_size; i++) {
if (Weapon_list[i].animation.num_frames != 0) {
generic_anim_unload(&Weapon_list[i].animation);
}
for (auto& list_entry : Weapon_list) {
if (list_entry.animation.type != BM_TYPE_NONE && list_entry.has_anim != 0) {
generic_anim_unload(&list_entry.animation);
}
if (Weapon_list[i].bitmap >= 0) {
bm_release(Weapon_list[i].bitmap);
Weapon_list[i].bitmap = -1;
}
if (list_entry.bitmap >= 0) {
bm_release(list_entry.bitmap);
list_entry.bitmap = -1;
}
}
for (i = 0; i < Intel_list_size; i++) {
if (Intel_list[i].animation.num_frames != 0) {
generic_anim_unload(&Intel_list[i].animation);
for (auto & intel_entry : Intel_list) {
if (intel_entry.animation.type != BM_TYPE_NONE && intel_entry.has_anim != 0) {
generic_anim_unload(&intel_entry.animation);
}
if (Intel_list[i].bitmap >= 0) {
bm_release(Intel_list[i].bitmap);
Intel_list[i].bitmap = -1;
if (intel_entry.bitmap >= 0) {
bm_release(intel_entry.bitmap);
intel_entry.bitmap = -1;
}
}
}
void techroom_select_new_entry()
{
Assert(Current_list != NULL);
if (Current_list == NULL || Current_list_size <= 0) {
if (Current_list->empty()) {
Cur_entry_index = Cur_entry = -1;
techroom_init_desc(NULL,0);
techroom_init_desc(nullptr,0);
return;
}
Cur_entry_index = Current_list[Cur_entry].index;
Assert(Cur_entry < static_cast<int>(Current_list->size()));
Cur_entry_index = Current_list->at(Cur_entry).index;
Assert( Cur_entry_index >= 0 );
// if we are in the ships tab, load the ship model
if (Tab == SHIPS_DATA_TAB) {
ship_info *sip = &Ship_info[Cur_entry_index];
int i = 0;
// little memory management, kinda hacky but it should keep the techroom at around
// 100meg rather than the 700+ it can get to with all ships loaded - taylor
for (int i=0; i<Current_list_size; i++) {
if ((Current_list[i].model_num > -1) && (Current_list[i].textures_loaded)) {
for (auto & list_entry : *Current_list) {
if ((list_entry.model_num > -1) && (list_entry.textures_loaded)) {
// don't unload any spot within 5 of current
if ( (i < Cur_entry + 5) && (i > Cur_entry - 5) )
if ((i < Cur_entry + 5) && (i > Cur_entry - 5) )
continue;
mprintf(("TECH ROOM: Dumping excess ship textures...\n"));
model_page_out_textures(Current_list[i].model_num);
model_page_out_textures(list_entry.model_num);
Current_list[i].textures_loaded = 0;
list_entry.textures_loaded = 0;
}
i++;
}
Techroom_ship_modelnum = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
@@ -341,12 +337,12 @@ void techroom_select_new_entry()
}
Techroom_ship_model_instance = model_create_instance(true, Techroom_ship_modelnum);
Current_list[Cur_entry].model_num = Techroom_ship_modelnum;
Current_list->at(Cur_entry).model_num = Techroom_ship_modelnum;
// page in ship textures properly (takes care of nondimming pixels)
model_page_in_textures(Techroom_ship_modelnum, Cur_entry_index);
Current_list[Cur_entry].textures_loaded = 1;
Current_list->at(Cur_entry).textures_loaded = 1;
} else {
Techroom_ship_modelnum = -1;
@@ -358,19 +354,19 @@ void techroom_select_new_entry()
Trackball_mode = 0;
// load animation here, we now only have one loaded
int stream_result = generic_anim_init_and_stream(&Current_list[Cur_entry].animation, Current_list[Cur_entry].tech_anim_filename, bm_get_type(Tech_background_bitmap), true);
int stream_result = generic_anim_init_and_stream(&Current_list->at(Cur_entry).animation, Current_list->at(Cur_entry).tech_anim_filename, bm_get_type(Tech_background_bitmap), true);
if (stream_result >= 0) {
Current_list[Cur_entry].has_anim = 1;
Current_list->at(Cur_entry).has_anim = 1;
} else {
// we've failed to load any animation
// load an image and treat it like a 1 frame animation
Current_list[Cur_entry].bitmap = bm_load(Current_list[Cur_entry].tech_anim_filename);
Current_list->at(Cur_entry).bitmap = bm_load(Current_list->at(Cur_entry).tech_anim_filename);
}
}
techroom_init_desc(Current_list[Cur_entry].desc, Tech_desc_coords[gr_screen.res][SHIP_W_COORD]);
fsspeech_play(FSSPEECH_FROM_TECHROOM, Current_list[Cur_entry].desc);
techroom_init_desc(Current_list->at(Cur_entry).desc, Tech_desc_coords[gr_screen.res][SHIP_W_COORD]);
fsspeech_play(FSSPEECH_FROM_TECHROOM, Current_list->at(Cur_entry).desc);
}
// write out the current description in the bottom window
@@ -432,7 +428,7 @@ void tech_common_render()
y = 0;
z = List_offset;
while (y + font_height <= Tech_list_coords[gr_screen.res][SHIP_H_COORD]) {
if (z >= Current_list_size) {
if (z >= static_cast<int>(Current_list->size())) {
break;
}
@@ -445,7 +441,7 @@ void tech_common_render()
}
memset( buf, 0, sizeof(buf) );
strncpy(buf, Current_list[z].name, sizeof(buf) - 1);
strncpy(buf, Current_list->at(z).name, sizeof(buf) - 1);
if (Lcl_gr && !Disable_built_in_translations)
lcl_translate_ship_name_gr(buf);
@@ -626,7 +622,7 @@ void tech_prev_entry()
Cur_entry--;
if (Cur_entry < 0) {
Cur_entry = Current_list_size - 1;
Cur_entry = static_cast<int>(Current_list->size() - 1);
// scroll to end of list
List_offset = Cur_entry - Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() + 1;
@@ -654,7 +650,7 @@ void tech_next_entry()
techroom_unload_animation();
Cur_entry++;
if (Cur_entry >= Current_list_size) {
if (Cur_entry >= static_cast<int>(Current_list->size())) {
Cur_entry = 0;
// scroll to beginning of list
@@ -710,7 +706,7 @@ void tech_scroll_list_up()
void tech_scroll_list_down()
{
if (List_offset + Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() < Current_list_size) {
if (List_offset + Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() < static_cast<int>(Current_list->size())) {
List_offset++;
gamesnd_play_iface(InterfaceSounds::SCROLL);
} else {
@@ -735,27 +731,27 @@ void techroom_anim_render(float frametime)
tech_common_render();
// exit now if there are no entries to show
if (Current_list_size == 0 || Cur_entry < 0)
if (Current_list->empty() || Cur_entry < 0 || Cur_entry >= static_cast<int>(Current_list->size()))
return;
// render the animation
if(Current_list[Cur_entry].animation.num_frames > 0)
if(Current_list->at(Cur_entry).animation.num_frames > 0)
{
//grab dimensions
bm_get_info((Current_list[Cur_entry].animation.streaming) ? Current_list[Cur_entry].animation.bitmap_id : Current_list[Cur_entry].animation.first_frame, &x, &y, NULL, NULL, NULL);
bm_get_info((Current_list->at(Cur_entry).animation.streaming) ? Current_list->at(Cur_entry).animation.bitmap_id : Current_list->at(Cur_entry).animation.first_frame, &x, &y, nullptr, nullptr, nullptr);
//get the centre point - adjust
x = Tech_ani_centre_coords[gr_screen.res][0] - x / 2;
y = Tech_ani_centre_coords[gr_screen.res][1] - y / 2;
generic_anim_render(&Current_list[Cur_entry].animation, frametime, x, y, true);
generic_anim_render(&Current_list->at(Cur_entry).animation, frametime, x, y, true);
}
// if our active item has a bitmap instead of an animation, draw it
else if((Cur_entry >= 0) && (Current_list[Cur_entry].bitmap >= 0)){
else if((Cur_entry >= 0) && (Current_list->at(Cur_entry).bitmap >= 0)){
//grab dimensions
bm_get_info(Current_list[Cur_entry].bitmap, &x, &y, NULL, NULL, NULL);
bm_get_info(Current_list->at(Cur_entry).bitmap, &x, &y, nullptr, nullptr, nullptr);
//get the centre point - adjust
x = Tech_ani_centre_coords[gr_screen.res][0] - x / 2;
y = Tech_ani_centre_coords[gr_screen.res][1] - y / 2;
gr_set_bitmap(Current_list[Cur_entry].bitmap);
gr_set_bitmap(Current_list->at(Cur_entry).bitmap);
gr_bitmap(x, y, GR_RESIZE_MENU);
}
}
@@ -792,50 +788,40 @@ void techroom_change_tab(int num)
// load ship info if necessary
if ( !Ships_loaded ) {
if (Ship_list == NULL) {
Ship_list = new tech_list_entry[Ship_info.size()];
if (Ship_list.empty()) {
Ship_list.reserve(Ship_info.size());
}
Ship_list_size = 0;
tech_list_entry temp_entry;
// we always initially set these values, so keep them outside the loop.
temp_entry.bitmap = -1;
temp_entry.animation.num_frames = 0; // no anim for ships
temp_entry.has_anim = 0; // no anim for ships
temp_entry.model_num = -1;
temp_entry.textures_loaded = 0;
for (auto it = Ship_info.begin(); it != Ship_info.end(); ++it)
{
if (Techroom_show_all || (it->flags & si_mask).any_set())
{
// this ship should be displayed, fill out the entry struct
Ship_list[Ship_list_size].bitmap = -1;
Ship_list[Ship_list_size].index = (int)std::distance(Ship_info.begin(), it);
Ship_list[Ship_list_size].animation.num_frames = 0; // no anim for ships
Ship_list[Ship_list_size].has_anim = 0; // no anim for ships
Ship_list[Ship_list_size].name = *it->tech_title ? it->tech_title : it->get_display_name();
Ship_list[Ship_list_size].desc = it->tech_desc;
Ship_list[Ship_list_size].model_num = -1;
Ship_list[Ship_list_size].textures_loaded = 0;
temp_entry.index = (int)std::distance(Ship_info.begin(), it);
temp_entry.name = *it->tech_title ? it->tech_title : it->get_display_name();
temp_entry.desc = it->tech_desc;
Ship_list_size++;
Ship_list.push_back(temp_entry);
}
}
// make sure that at least the default entry is cleared out if we didn't grab anything
if (!Ship_info.empty() && !Ship_list_size) {
Ship_list[0].index = -1;
Ship_list[0].desc = NULL;
Ship_list[0].name = NULL;
Ship_list[0].bitmap = -1;
Ship_list[0].has_anim = 0;
Ship_list[0].animation.num_frames = 0;
Ship_list[0].model_num = -1;
Ship_list[0].textures_loaded = 0;
}
Ships_loaded = true;
}
Current_list = Ship_list;
Current_list_size = Ship_list_size;
Current_list = &Ship_list;
font_height = gr_get_font_height();
max_num_entries_viewable = Tech_list_coords[gr_screen.res][SHIP_H_COORD] / font_height;
Tech_slider.set_numberItems(Current_list_size > max_num_entries_viewable ? Current_list_size-max_num_entries_viewable : 0);
Tech_slider.set_numberItems((int)Current_list->size() > max_num_entries_viewable ? (int)Current_list->size()-max_num_entries_viewable : 0);
// no anim to start here
break;
@@ -844,57 +830,45 @@ void techroom_change_tab(int num)
// load weapon info & anims if necessary
if ( !Weapons_loaded ) {
if (Weapon_list == NULL) {
Weapon_list = new tech_list_entry[Weapon_info.size()];
}
Weapon_list_size = 0;
Weapon_list.reserve(Weapon_info.size());
wi_mask.set(multi ? Weapon::Info_Flags::Player_allowed : Weapon::Info_Flags::In_tech_database);
wi_mask.set(Weapon::Info_Flags::Default_in_tech_database);
int i = 0;
tech_list_entry temp_entry;
// we always initially set these values, so keep them outside the loop.
temp_entry.has_anim = 1;
temp_entry.bitmap = -1;
temp_entry.animation.num_frames = 0;
temp_entry.model_num = -1;
temp_entry.textures_loaded = 0;
for (auto &wi : Weapon_info)
{
if (Techroom_show_all || (wi.wi_flags & wi_mask).any_set())
{
// we have a weapon that should be in the tech db, so fill out the entry struct
Weapon_list[Weapon_list_size].index = i;
Weapon_list[Weapon_list_size].desc = wi.tech_desc;
Weapon_list[Weapon_list_size].has_anim = 1;
Weapon_list[Weapon_list_size].name = wi.tech_title[0] ? wi.tech_title : wi.get_display_name();
Weapon_list[Weapon_list_size].bitmap = -1;
Weapon_list[Weapon_list_size].animation.num_frames = 0;
Weapon_list[Weapon_list_size].model_num = -1;
Weapon_list[Weapon_list_size].textures_loaded = 0;
// we have a weapon that should be in the tech db, so fill out specific info
temp_entry.index = i;
temp_entry.desc = wi.tech_desc;
temp_entry.name = wi.tech_title[0] ? wi.tech_title : wi.get_display_name();
// copy the weapon animation filename
strncpy(Weapon_list[Weapon_list_size].tech_anim_filename, wi.tech_anim_filename, MAX_FILENAME_LEN - 1);
++Weapon_list_size;
strncpy(temp_entry.tech_anim_filename, wi.tech_anim_filename, MAX_FILENAME_LEN - 1);
Weapon_list.push_back(temp_entry);
}
++i;
}
// make sure that at least the default entry is cleared out if we didn't grab anything
if (!Weapon_info.empty() && !Weapon_list_size) {
Weapon_list[0].index = -1;
Weapon_list[0].desc = NULL;
Weapon_list[0].name = NULL;
Weapon_list[0].bitmap = -1;
Weapon_list[0].has_anim = 0;
Weapon_list[0].animation.num_frames = 0;
Weapon_list[0].model_num = -1;
Weapon_list[0].textures_loaded = 0;
}
Weapons_loaded = true;
}
Current_list = Weapon_list;
Current_list_size = Weapon_list_size;
Current_list = &Weapon_list;
font_height = gr_get_font_height();
max_num_entries_viewable = Tech_list_coords[gr_screen.res][SHIP_H_COORD] / font_height;
Tech_slider.set_numberItems(Current_list_size > max_num_entries_viewable ? Current_list_size-max_num_entries_viewable : 0);
Tech_slider.set_numberItems(static_cast<int>(Current_list->size()) > max_num_entries_viewable ? static_cast<int>(Current_list->size())-max_num_entries_viewable : 0);
break;
@@ -902,60 +876,46 @@ void techroom_change_tab(int num)
// load intel if necessary
if ( !Intel_loaded ) {
if (Intel_list == nullptr) {
Intel_list = new tech_list_entry[Intel_info.size()];
if (Intel_list.empty()) {
Intel_list.reserve(Intel_info.size());
}
Intel_list_size = 0;
int i = 0;
tech_list_entry temp_entry;
// we always initially set these values, so keep them outside the loop.
temp_entry.has_anim = 0;
temp_entry.model_num = -1;
temp_entry.textures_loaded = 0;
for (auto &ii : Intel_info) {
if (Techroom_show_all || (ii.flags & IIF_IN_TECH_DATABASE)) {
// leave option for no animation if string == "none"
if (!strcmp(ii.anim_filename, "none")) {
Intel_list[Intel_list_size].has_anim = 0;
Intel_list[Intel_list_size].animation.num_frames = 0;
temp_entry.animation.num_frames = 0;
} else {
// try and load as an animation
Intel_list[Intel_list_size].has_anim = 0;
Intel_list[Intel_list_size].bitmap = -1;
strncpy(Intel_list[Intel_list_size].tech_anim_filename, ii.anim_filename, NAME_LENGTH - 1);
temp_entry.bitmap = -1;
strncpy(temp_entry.tech_anim_filename, ii.anim_filename, NAME_LENGTH - 1);
}
Intel_list[Intel_list_size].desc = ii.desc.c_str();
Intel_list[Intel_list_size].index = i;
Intel_list[Intel_list_size].name = ii.name;
Intel_list[Intel_list_size].model_num = -1;
Intel_list[Intel_list_size].textures_loaded = 0;
temp_entry.desc = ii.desc.c_str();
temp_entry.index = i;
temp_entry.name = ii.name;
Intel_list_size++;
Intel_list.push_back(temp_entry);
}
++i;
}
// make sure that at least the default entry is cleared out if we didn't grab anything
if (!Intel_info.empty() && !Intel_list_size) {
Intel_list[0].index = -1;
Intel_list[0].desc = NULL;
Intel_list[0].name = NULL;
Intel_list[0].bitmap = -1;
Intel_list[0].has_anim = 0;
Intel_list[0].animation.num_frames = 0;
Intel_list[0].model_num = -1;
Intel_list[0].textures_loaded = 0;
}
Intel_loaded = true;
}
// index lookup on intel is a pretty pointless, but it keeps everything
// consistent and doesn't really hurt anything
Current_list = Intel_list;
Current_list_size = Intel_list_size;
Current_list = &Intel_list;
font_height = gr_get_font_height();
max_num_entries_viewable = Tech_list_coords[gr_screen.res][SHIP_H_COORD] / font_height;
Tech_slider.set_numberItems(Current_list_size > max_num_entries_viewable ? Current_list_size-max_num_entries_viewable : 0);
Tech_slider.set_numberItems(static_cast<int>(Current_list->size()) > max_num_entries_viewable ? static_cast<int>(Current_list->size())-max_num_entries_viewable : 0);
break;
}
@@ -1123,7 +1083,7 @@ void techroom_intel_reset()
void techroom_init()
{
int i, idx;
int i;
techroom_buttons *b;
Ships_loaded = false;
@@ -1212,9 +1172,9 @@ void techroom_init()
Tech_slider.create(&Ui_window, Tech_slider_coords[gr_screen.res][SHIP_X_COORD], Tech_slider_coords[gr_screen.res][SHIP_Y_COORD], Tech_slider_coords[gr_screen.res][SHIP_W_COORD], Tech_slider_coords[gr_screen.res][SHIP_H_COORD], (int)Ship_info.size(), Tech_slider_filename[gr_screen.res], &tech_scroll_list_up, &tech_scroll_list_down, &tech_ship_scroll_capture);
// zero intel anim/bitmap stuff
for(idx=0; idx<Intel_list_size; idx++){
Intel_list[idx].animation.num_frames = 0;
Intel_list[idx].bitmap = -1;
for(auto & intel_item : Intel_list){
intel_item.animation.num_frames = 0;
intel_item.bitmap = -1;
}
mprintf(("Techroom successfully initialized, now changing tab...\n"));
@@ -1223,63 +1183,23 @@ void techroom_init()
void techroom_lists_reset()
{
int i;
//unload the current animation, we load another one for the new current entry
if(Tab != SHIPS_DATA_TAB)
if (Tab != SHIPS_DATA_TAB)
techroom_unload_animation();
Current_list = NULL;
Current_list_size = 0;
model_free_all();
Techroom_ship_modelnum = -1;
Techroom_ship_model_instance = -1;
if (Ship_list != NULL) {
delete[] Ship_list;
Ship_list = NULL;
}
Ship_list_size = 0;
// This can be cleared immediately because there are no anims or bitmaps associated.
Ship_list.clear();
Ships_loaded = false;
if (Weapon_list != NULL) {
for (i = 0; i < Weapon_list_size; i++) {
if (Weapon_list[i].animation.num_frames != 0) {
generic_anim_unload(&Weapon_list[i].animation);
}
if (Weapon_list[i].bitmap >= 0) {
bm_release(Weapon_list[i].bitmap);
Weapon_list[i].bitmap = -1;
}
}
delete[] Weapon_list;
Weapon_list = NULL;
}
Weapon_list_size = 0;
// now that we're sure all the bitmaps are released, clear the vectors.
Weapon_list.clear();
Weapons_loaded = false;
if (Intel_list != nullptr) {
for (i = 0; i < Intel_list_size; i++) {
if (Intel_list[i].animation.num_frames != 0) {
generic_anim_unload(&Intel_list[i].animation);
}
if (Intel_list[i].bitmap >= 0) {
bm_release(Intel_list[i].bitmap);
Intel_list[i].bitmap = -1;
}
}
delete[] Intel_list;
Intel_list = nullptr;
}
Intel_list_size = 0;
Intel_list.clear();
Intel_loaded = false;
}
+1 -1
View File
@@ -803,7 +803,7 @@ polymodel *model_get(int model_num);
polymodel_instance* model_get_instance(int model_instance_num);
// routine to copy susbsystems. Must be called when subsystems sets are the same -- see ship.cpp
// routine to copy subsystems. Must be called when subsystems sets are the same -- see ship.cpp
void model_copy_subsystems(int n_subsystems, model_subsystem *d_sp, model_subsystem *s_sp);
// If MR_FLAG_OUTLINE bit set this color will be used for outlines.
+55 -3
View File
@@ -462,6 +462,55 @@ void get_user_prop_value(char *buf, char *value)
*p1 = c;
}
// Stuff a floating point value pointed at by Mp.
// Advances past float characters.
int stuff_float_temp(float *f, bool optional)
{
char *str_start = Mp;
char *str_end;
// since strtof ignores white space anyway, might as well make it explicit
ignore_white_space();
auto result = strtof(Mp, &str_end);
bool success = false, comma = false;
int retval = 0;
// no float found?
if (result == 0.0f && str_end == Mp)
{
if (!optional)
error_display(1, "Expecting float, found [%.32s].\n", next_tokens());
}
else
{
*f = result;
success = true;
}
if (success)
Mp = str_end;
if (*Mp == ',')
{
comma = true;
Mp++;
}
if (optional && !success)
Mp = str_start;
if (success)
retval = 2;
else if (optional)
retval = comma ? 1 : 0;
else
skip_token();
diag_printf("Stuffed float: %f\n", *f);
return retval;
}
// routine to parse out a vec3d from a user property field of an object
bool get_user_vec3d_value(char *buf, vec3d *value, bool require_brackets)
{
@@ -494,11 +543,11 @@ bool get_user_vec3d_value(char *buf, vec3d *value, bool require_brackets)
}
// get comma-separated floats
if (stuff_float_optional(&f1) != 2)
if (stuff_float_temp(&f1, true) != 2)
break;
if (stuff_float_optional(&f2) != 2)
if (stuff_float_temp(&f2, true) != 2)
break;
if (stuff_float_optional(&f3) != 2)
if (stuff_float_temp(&f3, true) != 2)
break;
if (require_brackets)
@@ -2722,6 +2771,9 @@ int model_load(const char *filename, int n_subsystems, model_subsystem *subsyst
Assert(pm->submodel[i].num_live_debris < MAX_LIVE_DEBRIS);
pm->submodel[i].live_debris[pm->submodel[i].num_live_debris++] = j;
pm->submodel[j].is_live_debris = 1;
// make sure live debris doesn't have a parent
pm->submodel[j].parent = -1;
}
}
+4 -6
View File
@@ -69,16 +69,14 @@ static bool check_for_docking_collision(object *objp1, object *objp2)
}
if (aip1->mode == AIM_DOCK) {
if (dock_check_find_docked_object(&Objects[aip1->goal_objnum], objp2)){
if (aip1->mode == AIM_DOCK && aip1->goal_objnum >= 0 && aip1->goal_objnum < MAX_OBJECTS) {
if (dock_check_find_docked_object(&Objects[aip1->goal_objnum], objp2))
return true;
}
}
if (aip2->mode == AIM_DOCK) {
if (dock_check_find_docked_object(&Objects[aip2->goal_objnum], objp1)){
if (aip2->mode == AIM_DOCK && aip2->goal_objnum >= 0 && aip2->goal_objnum < MAX_OBJECTS) {
if (dock_check_find_docked_object(&Objects[aip2->goal_objnum], objp1))
return true;
}
}
return false;
+1 -1
View File
@@ -285,7 +285,7 @@ void shipfx_blow_off_subsystem(object *ship_objp, ship *ship_p, ship_subsys *sub
shipfx_blow_up_model(ship_objp, psub->subobj_num, 50, &subobj_pos );
// create live debris objects, if any
// TODO: some MULITPLAYER implcations here!!
// TODO: some MULTIPLAYER implcations here!!
shipfx_subsystem_maybe_create_live_debris(ship_objp, ship_p, subsys, exp_center, 1.0f);
int fireball_type = fireball_ship_explosion_type(&Ship_info[ship_p->ship_info_index]);
+2 -2
View File
@@ -676,8 +676,8 @@ void shield_impact_explosion(vec3d *hitpos, object *objp, float radius, int idx)
// Swifty - return number of max simultaneous locks
int weapon_get_max_missile_seekers(weapon_info *wip);
// return if this weapon can lock on this ship, based on its type, class, species or iff
bool weapon_can_lock_on_ship(weapon_info *wip, int ship_num);
// return if this weapon can lock on this target, based on its type, class, species or iff
bool weapon_target_satisfies_lock_restrictions(weapon_info *wip, object* target);
// return if this weapon has iff restrictions, and should ignore normal iff targeting restrictions
bool weapon_has_iff_restrictions(weapon_info* wip);
+10 -12
View File
@@ -4093,9 +4093,8 @@ void find_homing_object(object *weapon_objp, int num)
continue;
homing_object_team = obj_team(objp);
bool can_lock_on_ship = objp->type != OBJ_SHIP || weapon_can_lock_on_ship(wip, objp->instance);
bool can_attack = weapon_has_iff_restrictions(wip) || iff_x_attacks_y(wp->team, homing_object_team);
if (can_lock_on_ship && can_attack)
if (weapon_target_satisfies_lock_restrictions(wip, objp) && can_attack)
{
if ( objp->type == OBJ_SHIP )
{
@@ -5353,13 +5352,9 @@ void weapon_set_tracking_info(int weapon_objnum, int parent_objnum, int target_o
if ( parent_objp == NULL || Ships[parent_objp->instance].ai_index >= 0 ) {
int target_team = -1;
int target_ship_num = -1;
if ( target_objnum >= 0 ) {
int obj_type = Objects[target_objnum].type;
if (obj_type == OBJ_SHIP)
target_ship_num = Objects[target_objnum].instance;
if ( (obj_type == OBJ_SHIP) || (obj_type == OBJ_WEAPON) ) {
target_team = obj_team(&Objects[target_objnum]);
@@ -5381,7 +5376,7 @@ void weapon_set_tracking_info(int weapon_objnum, int parent_objnum, int target_o
targeting_same = 0;
}
bool can_lock = weapon_has_iff_restrictions(wip) && target_ship_num >= 0 ? weapon_can_lock_on_ship(wip, target_ship_num) :
bool can_lock = (weapon_has_iff_restrictions(wip) && target_objnum >= 0) ? weapon_target_satisfies_lock_restrictions(wip, &Objects[target_objnum]) :
(!targeting_same || (MULTI_DOGFIGHT && (target_team == Iff_traitor)));
// Cyborg17 - exclude all invalid object numbers here since in multi, the lock slots can get out of sync.
@@ -8691,16 +8686,19 @@ int weapon_get_max_missile_seekers(weapon_info *wip)
}
// returns whether a homing weapon can home on a particular ship
bool weapon_can_lock_on_ship(weapon_info* wip, int ship_num)
bool weapon_target_satisfies_lock_restrictions(weapon_info* wip, object* target)
{
if (target->type != OBJ_SHIP)
return true;
auto& restrictions = wip->ship_restrict;
// if you didn't specify any restrictions, you can always lock
if (restrictions.empty()) return true;
int type_num = Ship_info[Ships[ship_num].ship_info_index].class_type;
int class_num = Ships[ship_num].ship_info_index;
int species_num = Ship_info[Ships[ship_num].ship_info_index].species;
int iff_num = Ships[ship_num].team;
int type_num = Ship_info[Ships[target->instance].ship_info_index].class_type;
int class_num = Ships[target->instance].ship_info_index;
int species_num = Ship_info[Ships[target->instance].ship_info_index].species;
int iff_num = Ships[target->instance].team;
// otherwise, you're good as long as it matches one of the allowances in the restriction list
return std::any_of(restrictions.begin(), restrictions.end(),
+5
View File
@@ -0,0 +1,5 @@
set(FSO_VERSION_MAJOR 21)
set(FSO_VERSION_MINOR 0)
set(FSO_VERSION_BUILD 0)
set(FSO_VERSION_REVISION 0)
set(FSO_VERSION_REVISION_STR RC3)