// displays (renders) the training objectives list void training_obj_display() { char buf[256], *second_line; int i, t, x, y, z, height, end, offset, bx, by, y_count; color *c; if (!Training_obj_num_lines){ return; } if ( !hud_gauge_active(HUD_DIRECTIVES_VIEW) ) { // Always draw the directives display if this is a training mission if ( !(The_mission.game_type & MISSION_TYPE_TRAINING) ) { return; } } // don't ever display directives display in multiplayer missions // if ( Game_mode & GM_MULTIPLAYER ){ // return; // } height = gr_get_font_height(); offset = 0; end = Training_obj_num_lines; if (end > TRAINING_OBJ_DISPLAY_LINES) { end = TRAINING_OBJ_DISPLAY_LINES; offset = Training_obj_num_lines - end; } // draw top of objective display // hud_set_default_color(); hud_set_gauge_color(HUD_DIRECTIVES_VIEW); GR_AABITMAP(Directive_gauge[0].first_frame, Directive_coords[gr_screen.res][DIRECTIVE_COORDS_TOP][0]+fl2i(HUD_offset_x), Directive_coords[gr_screen.res][DIRECTIVE_COORDS_TOP][1]+fl2i(HUD_offset_y)); // gr_set_bitmap(Directive_gauge[0].first_frame); // gr_aabitmap(Directive_coords[DIRECTIVE_COORDS_TOP][0]+fl2i(HUD_offset_x), Directive_coords[DIRECTIVE_COORDS_TOP][1]+fl2i(HUD_offset_y)); // print out title emp_hud_printf(Directive_coords[gr_screen.res][DIRECTIVE_COORDS_TITLE][0]+fl2i(HUD_offset_x), Directive_coords[gr_screen.res][DIRECTIVE_COORDS_TITLE][1]+fl2i(HUD_offset_y), EG_OBJ_TITLE, XSTR( "Directives", 422)); // gr_printf(Directive_coords[DIRECTIVE_COORDS_TITLE][0]+fl2i(HUD_offset_x), Directive_coords[DIRECTIVE_COORDS_TITLE][1]+fl2i(HUD_offset_y), XSTR( "directives", 422)); bx = DIRECTIVE_X+fl2i(HUD_offset_x); by = Directive_coords[gr_screen.res][DIRECTIVE_COORDS_MIDDLE][1]+fl2i(HUD_offset_y); y_count = 0; for (i=0; i<end; i++) { x = DIRECTIVE_X + 5 + fl2i(HUD_offset_x); y = Training_obj_window_coords[gr_screen.res][1] + fl2i(HUD_offset_y) + y_count * height + height / 2 + 1; z = TRAINING_OBJ_LINES_MASK(i + offset); c = &Color_normal; if (Training_obj_lines[i + offset] & TRAINING_OBJ_LINES_KEY) { message_translate_tokens(buf, Mission_events[z].objective_key_text); // remap keys // gr_set_color_fast(&Color_normal); c = &Color_bright_green; } else { strcpy(buf, Mission_events[z].objective_text); if (Mission_events[z].count){ sprintf(buf + strlen(buf), NOX(" [%d]"), Mission_events[z].count); } #ifndef NO_NETWORK // if this is a multiplayer tvt game, and this is event is not for my team, don't display it if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_TEAM) && (Net_player != NULL)){ if((Mission_events[z].team != -1) && (Net_player->p_info.team != Mission_events[z].team)){ continue; } } #endif switch (mission_get_event_status(z)) { case EVENT_CURRENT: // gr_set_color_fast(&Color_bright_white); c = &Color_bright_white; break; case EVENT_FAILED: // gr_set_color_fast(&Color_bright_red); c = &Color_bright_red; break; case EVENT_SATISFIED: // gr_set_color_fast(&Color_bright_blue); t = Mission_events[z].satisfied_time; if (t + i2f(2) > Missiontime) { if (Missiontime % fl2f(.4f) < fl2f(.2f)){ c = &Color_bright_blue; } else { c = &Color_bright_white; } } else { c = &Color_bright_blue; } break; } } // maybe split the directives line second_line = split_str_once(buf, 167); // blit the background frames // hud_set_default_color(); hud_set_gauge_color(HUD_DIRECTIVES_VIEW); GR_AABITMAP(Directive_gauge[1].first_frame, bx, by); // gr_set_bitmap(Directive_gauge[1].first_frame); // gr_aabitmap(bx, by); by += DIRECTIVE_H; if ( second_line ) { GR_AABITMAP(Directive_gauge[1].first_frame, bx, by); // gr_set_bitmap(Directive_gauge[1].first_frame); // gr_aabitmap(bx, by); by += DIRECTIVE_H; } // blit the text gr_set_color_fast(c); emp_hud_string(x, y, EG_OBJ1 + i, buf); // gr_printf(x, y, buf); y_count++; if ( second_line ) { y = Training_obj_window_coords[gr_screen.res][1] + fl2i(HUD_offset_y) + y_count * height + height / 2 + 1; emp_hud_string(x+12, y, EG_OBJ1 + i + 1, second_line); // gr_printf(x+12, y, second_line); y_count++; } } // draw the bottom of objective display // hud_set_default_color(); hud_set_gauge_color(HUD_DIRECTIVES_VIEW); GR_AABITMAP(Directive_gauge[2].first_frame, bx, by); // gr_set_bitmap(Directive_gauge[2].first_frame); // gr_aabitmap(bx, by); }
void sort_training_objectives() { int i, event_status, offset; // start by sorting on born on date qsort(Training_obj_lines, Training_obj_num_lines, sizeof(int), comp_training_lines_by_born_on_date); // get the index of the first directive that will be displayed // if less than 0, display all lines offset = Training_obj_num_lines - TRAINING_OBJ_DISPLAY_LINES; if (offset <= 0) { return; } // go through lines 0 to offset-1 and check if there are any CURRENT or RECENTLY_KNOWN events that should be shown int num_offset_events = 0; for (i=0; i<offset; i++) { event_status = mission_get_event_status(TRAINING_OBJ_LINES_MASK(i)); if (event_status == EVENT_CURRENT) { Training_obj_lines[i] |= TRAINING_OBJ_STATUS_UNKNOWN; num_offset_events++; } else if (event_status == EVENT_SATISFIED) { if (f2i(Missiontime - Mission_events[TRAINING_OBJ_LINES_MASK(i)].satisfied_time) < MIN_SATISFIED_TIME) { Training_obj_lines[i] |= TRAINING_OBJ_STATUS_UNKNOWN; num_offset_events++; } else { Training_obj_lines[i] |= TRAINING_OBJ_STATUS_KNOWN; } } else if (event_status == EVENT_FAILED) { if (f2i(Missiontime - Mission_events[TRAINING_OBJ_LINES_MASK(i)].satisfied_time) < MIN_FAILED_TIME) { Training_obj_lines[i] |= TRAINING_OBJ_STATUS_UNKNOWN; num_offset_events++; } else { Training_obj_lines[i] |= TRAINING_OBJ_STATUS_KNOWN; } } } // if there are no directives which should be moved, we're done if (num_offset_events == 0) { return; } // go through lines offset to Training_obj_num_lines to check which should be shown, since some will need to be bumped for (i=offset; i<Training_obj_num_lines; i++) { event_status = mission_get_event_status(TRAINING_OBJ_LINES_MASK(i)); if (event_status == EVENT_CURRENT) { Training_obj_lines[i] |= TRAINING_OBJ_STATUS_UNKNOWN; } else if (event_status == EVENT_SATISFIED) { if (f2i(Missiontime - Mission_events[TRAINING_OBJ_LINES_MASK(i)].satisfied_time) < MIN_SATISFIED_TIME) { Training_obj_lines[i] |= TRAINING_OBJ_STATUS_UNKNOWN; } else { Training_obj_lines[i] |= TRAINING_OBJ_STATUS_KNOWN; } } else if (event_status == EVENT_FAILED) { if (f2i(Missiontime - Mission_events[TRAINING_OBJ_LINES_MASK(i)].satisfied_time) < MIN_FAILED_TIME) { Training_obj_lines[i] |= TRAINING_OBJ_STATUS_UNKNOWN; } else { Training_obj_lines[i] |= TRAINING_OBJ_STATUS_UNKNOWN; } } } int slot_idx, unkn_vis; // go through list and bump as needed for (i=0; i<num_offset_events; i++) { // find most recent directive that would not be shown for (unkn_vis=offset-1; unkn_vis>=0; unkn_vis--) { if (Training_obj_lines[unkn_vis] & TRAINING_OBJ_STATUS_UNKNOWN) { break; } } // find first slot that can be bumped // look at the last (N-4 to N) positions for (slot_idx=0; slot_idx<TRAINING_OBJ_DISPLAY_LINES; slot_idx++) { if ( Training_obj_lines[i+offset] & TRAINING_OBJ_STATUS_KNOWN ) { break; } } // shift and replace (mark old one as STATUS_KNOWN) for (int j=slot_idx; j>0; j--) { Training_obj_lines[j+offset-1] = Training_obj_lines[j+offset-2]; } Training_obj_lines[offset] = Training_obj_lines[unkn_vis]; Training_obj_lines[unkn_vis] &= ~TRAINING_OBJ_LINES_EVENT_STATUS_MASK; Training_obj_lines[unkn_vis] |= TRAINING_OBJ_STATUS_KNOWN; } // remove event status for (i=0; i<Training_obj_num_lines; i++) { Training_obj_lines[i] &= ~TRAINING_OBJ_LINES_EVENT_STATUS_MASK; } }
void HudGaugeDirectives::render(float frametime) { char buf[256], *second_line; int i, t, x, y, z, end, offset, bx, by, y_count; color *c; if (!Training_obj_num_lines){ return; } offset = 0; end = Training_obj_num_lines; if (end > Max_directives) { end = Max_directives; offset = Training_obj_num_lines - end; } // draw top of objective display setGaugeColor(); renderBitmap(directives_top.first_frame, position[0], position[1]); // print out title renderPrintf(position[0] + header_offsets[0], position[1] + header_offsets[1], EG_OBJ_TITLE, XSTR( "directives", 422)); bx = position[0]; by = position[1] + middle_frame_offset_y; y_count = 0; for (i=0; i<end; i++) { x = position[0] + text_start_offsets[0]; y = position[1] + text_start_offsets[1] + y_count * text_h; z = TRAINING_OBJ_LINES_MASK(i + offset); c = &Color_normal; if (Training_obj_lines[i + offset] & TRAINING_OBJ_LINES_KEY) { message_translate_tokens(buf, Mission_events[z].objective_key_text); // remap keys c = &Color_bright_green; } else { strcpy_s(buf, Mission_events[z].objective_text); if (Mission_events[z].count){ sprintf(buf + strlen(buf), NOX(" [%d]"), Mission_events[z].count); } // if this is a multiplayer tvt game, and this is event is not for my team, don't display it if((MULTI_TEAM) && (Net_player != NULL)){ if((Mission_events[z].team != -1) && (Net_player->p_info.team != Mission_events[z].team)){ continue; } } switch (mission_get_event_status(z)) { case EVENT_CURRENT: c = &Color_bright_white; break; case EVENT_FAILED: c = &Color_bright_red; break; case EVENT_SATISFIED: t = Mission_events[z].satisfied_time; if (t + i2f(2) > Missiontime) { if (Missiontime % fl2f(.4f) < fl2f(.2f)){ c = &Color_bright_blue; } else { c = &Color_bright_white; } } else { c = &Color_bright_blue; } break; } } // maybe split the directives line second_line = split_str_once(buf, max_line_width); Assert( second_line != buf ); // blit the background frames setGaugeColor(); renderBitmap(directives_middle.first_frame, bx, by); by += text_h; if ( second_line ) { renderBitmap(directives_middle.first_frame, bx, by); by += text_h; } // blit the text gr_set_color_fast(c); renderString(x, y, EG_OBJ1 + i, buf); y_count++; if ( second_line ) { y = position[1] + text_start_offsets[1] + y_count * text_h; renderString(x+12, y, EG_OBJ1 + i + 1, second_line); y_count++; } } // draw the bottom of objective display setGaugeColor(); renderBitmap(directives_bottom.first_frame, bx, by + bottom_bg_offset); }