@@ -432,7 +432,18 @@ void briefing_editor_dlg::update_data(int update)
432432
433433 if (m_last_icon >= 0 ) {
434434 valid = (m_id != ptr->icons [m_last_icon].id );
435- if (m_id >= 0 ) {
435+ if (m_id < 0 ) {
436+ // briefing icon ids must never be negative; revert to the previous id
437+ if (valid) {
438+ char msg[1024 ];
439+
440+ sprintf (msg, " Icon ID #%d is invalid. Briefing icon IDs cannot be negative.\n "
441+ " Icon ID has been reset back to %d" , m_id, ptr->icons [m_last_icon].id );
442+
443+ m_id = ptr->icons [m_last_icon].id ;
444+ MessageBox (msg);
445+ }
446+ } else {
436447 if (valid && !m_change_local) {
437448 for (i=m_last_stage+1 ; i<Briefing->num_stages ; i++) {
438449 if (find_icon (m_id, i) >= 0 ) {
@@ -473,7 +484,7 @@ void briefing_editor_dlg::update_data(int update)
473484
474485 string_copy (buf, m_icon_label, MAX_LABEL_LEN - 1 );
475486 lcl_fred_replace_stuff (buf, MAX_LABEL_LEN - 1 );
476- if (stricmp (ptr->icons [m_last_icon].label , buf) && !m_change_local) {
487+ if (strcmp (ptr->icons [m_last_icon].label , buf) && !m_change_local) {
477488 set_modified ();
478489 reset_icon_loop (m_last_stage);
479490 while (get_next_icon (m_id))
@@ -483,36 +494,41 @@ void briefing_editor_dlg::update_data(int update)
483494
484495 string_copy (buf, m_icon_closeup_label, MAX_LABEL_LEN - 1 );
485496 lcl_fred_replace_stuff (buf, MAX_LABEL_LEN - 1 );
486- if (stricmp (ptr->icons [m_last_icon].closeup_label , buf) && !m_change_local) {
497+ if (strcmp (ptr->icons [m_last_icon].closeup_label , buf) && !m_change_local) {
487498 set_modified ();
488499 reset_icon_loop (m_last_stage);
489500 while (get_next_icon (m_id))
490501 strcpy_s (iconp->closeup_label , buf);
491502 }
492503 strcpy_s (ptr->icons [m_last_icon].closeup_label , buf);
493504
494- if (m_icon_scale > 0 )
495- ptr->icons [m_last_icon].scale_factor = m_icon_scale / 100 .0f ;
496-
497- if ( m_hilight )
498- ptr->icons [m_last_icon].flags |= BI_HIGHLIGHT ;
499- else
500- ptr->icons [m_last_icon].flags &= ~BI_HIGHLIGHT ;
501-
502- if (m_flipicon)
503- ptr->icons [m_last_icon].flags |= BI_MIRROR_ICON ;
504- else
505- ptr->icons [m_last_icon].flags &= ~BI_MIRROR_ICON ;
505+ if (m_icon_scale > 0 ) {
506+ float new_scale = m_icon_scale / 100 .0f ;
507+ if ((ptr->icons [m_last_icon].scale_factor != new_scale) && !m_change_local) {
508+ set_modified ();
509+ reset_icon_loop (m_last_stage);
510+ while (get_next_icon (m_id))
511+ iconp->scale_factor = new_scale;
512+ }
513+ ptr->icons [m_last_icon].scale_factor = new_scale;
514+ }
506515
507- if (m_use_wing)
508- ptr->icons [m_last_icon].flags |= BI_USE_WING_ICON ;
509- else
510- ptr->icons [m_last_icon].flags &= ~BI_USE_WING_ICON ;
516+ // build the new flags for this icon from the checkboxes, preserving any non-editable bits
517+ const int editable_flags = BI_HIGHLIGHT | BI_MIRROR_ICON | BI_USE_WING_ICON | BI_USE_CARGO_ICON ;
518+ int new_flags = ptr->icons [m_last_icon].flags ;
519+ if (m_hilight) new_flags |= BI_HIGHLIGHT ; else new_flags &= ~BI_HIGHLIGHT ;
520+ if (m_flipicon) new_flags |= BI_MIRROR_ICON ; else new_flags &= ~BI_MIRROR_ICON ;
521+ if (m_use_wing) new_flags |= BI_USE_WING_ICON ; else new_flags &= ~BI_USE_WING_ICON ;
522+ if (m_use_cargo) new_flags |= BI_USE_CARGO_ICON ; else new_flags &= ~BI_USE_CARGO_ICON ;
511523
512- if (m_use_cargo)
513- ptr->icons [m_last_icon].flags |= BI_USE_CARGO_ICON ;
514- else
515- ptr->icons [m_last_icon].flags &= ~BI_USE_CARGO_ICON ;
524+ if ((ptr->icons [m_last_icon].flags != new_flags) && !m_change_local) {
525+ set_modified ();
526+ reset_icon_loop (m_last_stage);
527+ // apply only the editable bits to later icons, preserving their other flags
528+ while (get_next_icon (m_id))
529+ iconp->flags = (iconp->flags & ~editable_flags) | (new_flags & editable_flags);
530+ }
531+ ptr->icons [m_last_icon].flags = new_flags;
516532
517533 if ((ptr->icons [m_last_icon].type != m_icon_image) && !m_change_local) {
518534 set_modified ();
@@ -942,6 +958,7 @@ void briefing_editor_dlg::copy_stage(int from, int to)
942958 Briefing->stages [to].camera_time = 500 ;
943959 Briefing->stages [to].num_icons = 0 ;
944960 Briefing->stages [to].formula = Locked_sexp_true;
961+ Briefing->stages [to].draw_grid = true ;
945962 Briefing->stages [to].grid_color = Color_briefing_grid;
946963 return ;
947964 }
@@ -956,6 +973,7 @@ void briefing_editor_dlg::copy_stage(int from, int to)
956973 Briefing->stages [to].num_icons = Briefing->stages [from].num_icons ;
957974 Briefing->stages [to].num_lines = Briefing->stages [from].num_lines ;
958975 Briefing->stages [to].formula = Briefing->stages [from].formula ;
976+ Briefing->stages [to].draw_grid = Briefing->stages [from].draw_grid ;
959977 // For now let's just always set this back to default. Eventually when we have a UI color picker in qtFRED, we can copy from stage to stage
960978 Briefing->stages [to].grid_color = Color_briefing_grid;
961979
@@ -1089,12 +1107,13 @@ void briefing_editor_dlg::OnMakeIcon()
10891107
10901108 strncpy (biconp->label , name, len);
10911109 biconp->label [len] = 0 ;
1110+ biconp->closeup_label [0 ] = 0 ;
10921111// iconp->text[0] = 0;
10931112 biconp->type = 0 ;
10941113 biconp->team = team;
10951114 biconp->pos = pos;
10961115 biconp->flags = 0 ;
1097- biconp->id = Cur_brief_id++ ;
1116+ biconp->id = get_unused_briefing_icon_id () ;
10981117 biconp->scale_factor = 1 .0f ;
10991118
11001119 biconp->modelnum = -1 ;
@@ -1300,10 +1319,13 @@ int briefing_editor_dlg::check_mouse_hit(int x, int y)
13001319 return -1 ;
13011320}
13021321
1303- void briefing_editor_dlg::OnPropagateIcons ()
1322+ void briefing_editor_dlg::OnPropagateIcons ()
13041323{
13051324 object *ptr;
13061325
1326+ // commit any pending edits in the icon fields before propagating the icons forward
1327+ update_data (1 );
1328+
13071329 ptr = GET_FIRST (&obj_used_list);
13081330 while (ptr != END_OF_LIST (&obj_used_list)) {
13091331 if ((ptr->type == OBJ_POINT ) && (ptr->flags [Object::Object_Flags::Marked])) {
@@ -1343,6 +1365,26 @@ int briefing_editor_dlg::find_icon(int id, int stage)
13431365 return -1 ;
13441366}
13451367
1368+ // is the given id already used by any icon in any stage of the current briefing?
1369+ bool briefing_editor_dlg::briefing_icon_id_used (int id)
1370+ {
1371+ for (int s=0 ; s<Briefing->num_stages ; s++)
1372+ if (find_icon (id, s) >= 0 )
1373+ return true ;
1374+
1375+ return false ;
1376+ }
1377+
1378+ // find an id that isn't already used by an icon in the current briefing, advancing
1379+ // Cur_brief_id past any values that are already taken (e.g. from manual id edits)
1380+ int briefing_editor_dlg::get_unused_briefing_icon_id ()
1381+ {
1382+ while (briefing_icon_id_used (Cur_brief_id))
1383+ Cur_brief_id++;
1384+
1385+ return Cur_brief_id++;
1386+ }
1387+
13461388void briefing_editor_dlg::reset_icon_loop (int stage)
13471389{
13481390 stage_loop = stage + 1 ;
@@ -1355,7 +1397,7 @@ int briefing_editor_dlg::get_next_icon(int id)
13551397 icon_loop++;
13561398 if (icon_loop >= Briefing->stages [stage_loop].num_icons ) {
13571399 stage_loop++;
1358- if (stage_loop > Briefing->num_stages )
1400+ if (stage_loop >= Briefing->num_stages )
13591401 return 0 ;
13601402
13611403 icon_loop = -1 ;
0 commit comments