int CVideo::set_help_string(const std::string& str) { font::remove_floating_label(help_string_); const SDL_Color color = { 0, 0, 0, 0xbb }; int size = font::SIZE_LARGE; while(size > 0) { if(font::line_width(str, size) > getx()) { size--; } else { break; } } const int border = 5; font::floating_label flabel(str); flabel.set_font_size(size); flabel.set_position(getx()/2, gety()); flabel.set_bg_color(color); flabel.set_border_size(border); help_string_ = font::add_floating_label(flabel); const SDL_Rect& rect = font::get_floating_label_rect(help_string_); font::move_floating_label(help_string_,0.0,-double(rect.h)); return help_string_; }
void terrain_label::draw() { if (text_.empty() && tooltip_.empty()) return; clear(); if ( !viewable(parent_->disp().get_disp_context()) ) return; const map_location loc_nextx(loc_.x+1,loc_.y); const map_location loc_nexty(loc_.x,loc_.y+1); const int xloc = (parent_->disp().get_location_x(loc_) + parent_->disp().get_location_x(loc_nextx)*2)/3; const int yloc = parent_->disp().get_location_y(loc_nexty) - font::SIZE_NORMAL; // If a color is specified don't allow to override it with markup. (prevents faking map labels for example) // FIXME: @todo Better detect if it's team label and not provided by // the scenario. bool use_markup = color_ == font::LABEL_COLOR; font::floating_label flabel(text_.str()); flabel.set_color(color_); flabel.set_position(xloc, yloc); flabel.set_clip_rect(parent_->disp().map_outside_area()); flabel.set_width(font::SIZE_NORMAL * 13); flabel.set_height(font::SIZE_NORMAL * 4); flabel.set_scroll_mode(font::ANCHOR_LABEL_MAP); flabel.use_markup(use_markup); handle_ = font::add_floating_label(flabel); calculate_shroud(); }
void floating_textbox::update_location(game_display& gui) { if (box_ == NULL) return; const SDL_Rect& area = gui.map_outside_area(); const int border_size = 10; const int ypos = area.y+area.h-30 - (check_ != NULL ? check_->height() + border_size : 0); if (label_ != 0) font::remove_floating_label(label_); font::floating_label flabel(label_string_); flabel.set_color(font::YELLOW_COLOR); flabel.set_position(area.x + border_size, ypos); flabel.set_alignment(font::LEFT_ALIGN); flabel.set_clip_rect(area); label_ = font::add_floating_label(flabel); if (label_ == 0) return; const SDL_Rect& label_area = font::get_floating_label_rect(label_); const int textbox_width = area.w - label_area.w - border_size*3; if(textbox_width <= 0) { font::remove_floating_label(label_); return; } if(box_ != NULL) { box_->set_volatile(true); const SDL_Rect rect = create_rect( area.x + label_area.w + border_size * 2 , ypos , textbox_width , box_->height()); box_->set_location(rect); } if(check_ != NULL) { check_->set_volatile(true); check_->set_location(box_->location().x,box_->location().y + box_->location().h + border_size); } }
void game_display::float_label(const map_location& loc, const std::string& text, const SDL_Color& color) { if(preferences::show_floating_labels() == false || fogged(loc)) { return; } font::floating_label flabel(text); flabel.set_font_size(font::SIZE_XLARGE); flabel.set_color(color); flabel.set_position(get_location_x(loc)+zoom_/2, get_location_y(loc)); flabel.set_move(0, -2 * turbo_speed()); flabel.set_lifetime(60/turbo_speed()); flabel.set_scroll_mode(font::ANCHOR_LABEL_MAP); font::add_floating_label(flabel); }
static void show_tooltip(const tooltip& tip) { if(video_ == NULL) { return; } clear_tooltip(); const SDL_Color bgcolor = {0,0,0,160}; #if defined(_KINGDOM_EXE) || !defined(_WIN32) SDL_Rect area = screen_area(); #else SDL_Rect area = create_rect(0, 0, 800, 600); #endif unsigned int border = 10; font::floating_label flabel(tip.message); flabel.set_font_size(font_size); flabel.set_color(font::NORMAL_COLOR); flabel.set_clip_rect(area); flabel.set_width(text_width); flabel.set_bg_color(bgcolor); flabel.set_border_size(border); tooltip_handle = font::add_floating_label(flabel); SDL_Rect rect = font::get_floating_label_rect(tooltip_handle); //see if there is enough room to fit it above the tip area if(tip.rect.y > rect.h) { rect.y = tip.rect.y - rect.h; } else { rect.y = tip.rect.y + tip.rect.h; } rect.x = tip.rect.x; if(rect.x < 0) { rect.x = 0; } else if(rect.x + rect.w > area.w) { rect.x = area.w - rect.w; } font::move_floating_label(tooltip_handle,rect.x,rect.y); }
static void show_tooltip(const tooltip& tip) { if(video_ == NULL) { return; } clear_tooltip(); const SDL_Color bgcolor = {0,0,0,160}; SDL_Rect area = screen_area(); unsigned int border = 10; font::floating_label flabel(tip.message, tip.foreground); flabel.use_markup(tip.markup); flabel.set_font_size(font_size); flabel.set_color(font::NORMAL_COLOR); flabel.set_clip_rect(area); flabel.set_width(text_width); flabel.set_alignment(font::LEFT_ALIGN); flabel.set_bg_color(bgcolor); flabel.set_border_size(border); tooltip_handle = font::add_floating_label(flabel); SDL_Rect rect = font::get_floating_label_rect(tooltip_handle); //see if there is enough room to fit it above the tip area if(tip.rect.y > rect.h) { rect.y = tip.rect.y - rect.h; } else { rect.y = tip.rect.y + tip.rect.h; } rect.x = tip.rect.x; if(rect.x < 0) { rect.x = 0; } else if(rect.x + rect.w > area.w) { rect.x = area.w - rect.w; } font::move_floating_label(tooltip_handle,rect.x,rect.y); }
void playmp_controller::play_human_turn(){ LOG_NG << "playmp::play_human_turn...\n"; command_disabled_resetter reset_commands; int cur_ticks = SDL_GetTicks(); show_turn_dialog(); execute_gotos(); if (!linger_ || is_host_) { end_turn_enable(true); } while(!end_turn_) { try { config cfg; const network::connection res = network::receive_data(cfg); std::deque<config> backlog; if(res != network::null_connection) { if (turn_data_->process_network_data(cfg, res, backlog, skip_replay_) == turn_info::PROCESS_RESTART_TURN) { // Clean undo stack if turn has to be restarted (losing control) if ( undo_stack_->can_undo() ) { font::floating_label flabel(_("Undoing moves not yet transmitted to the server.")); SDL_Color color = {255,255,255,255}; flabel.set_color(color); SDL_Rect rect = gui_->map_area(); flabel.set_position(rect.w/2, rect.h/2); flabel.set_lifetime(150); flabel.set_clip_rect(rect); font::add_floating_label(flabel); } while( undo_stack_->can_undo() ) undo_stack_->undo(); throw end_turn_exception(gui_->playing_side()); } } play_slice(); check_end_level(); // give a chance to the whiteboard to continue an execute_all_actions resources::whiteboard->continue_execute_all(); } catch(const end_level_exception&) { turn_data_->send_data(); throw; } if (!linger_ && (current_team().countdown_time() > 0) && gamestate_.mp_settings().mp_countdown) { SDL_Delay(1); const int ticks = SDL_GetTicks(); int new_time = current_team().countdown_time()-std::max<int>(1,(ticks - cur_ticks)); if (new_time > 0 ){ current_team().set_countdown_time(new_time); cur_ticks = ticks; if(current_team().is_human() && !beep_warning_time_) { beep_warning_time_ = new_time - WARNTIME + ticks; } if(counting_down()) { think_about_countdown(ticks); } } else { // Clock time ended // If no turn bonus or action bonus -> defeat const int action_increment = gamestate_.mp_settings().mp_countdown_action_bonus; if ( (gamestate_.mp_settings().mp_countdown_turn_bonus == 0 ) && (action_increment == 0 || current_team().action_bonus_count() == 0)) { // Not possible to end level in MP with throw end_level_exception(DEFEAT); // because remote players only notice network disconnection // Current solution end remaining turns automatically current_team().set_countdown_time(10); } else { const int maxtime = gamestate_.mp_settings().mp_countdown_reservoir_time; int secs = gamestate_.mp_settings().mp_countdown_turn_bonus; secs += action_increment * current_team().action_bonus_count(); current_team().set_action_bonus_count(0); secs = (secs > maxtime) ? maxtime : secs; current_team().set_countdown_time(1000 * secs); } turn_data_->send_data(); if (!rand_rng::has_new_seed_callback()) { throw end_turn_exception(); } } } gui_->draw(); turn_data_->send_data(); } }
void playmp_controller::play_human_turn() { LOG_NG << "playmp::play_human_turn...\n"; assert(!linger_); assert(gamestate_->init_side_done()); assert(gamestate().gamedata_.phase() == game_data::PLAY); mp_ui_alerts::turn_changed(current_team().current_player()); LOG_NG << "events::commands_disabled=" << events::commands_disabled <<"\n"; remove_blindfold(); const std::unique_ptr<countdown_clock> timer(saved_game_.mp_settings().mp_countdown ? new countdown_clock(current_team()) : nullptr); show_turn_dialog(); if(undo_stack().can_undo()) { // If we reload a networked mp game we cannot undo moves made before the save // because other players already received them if(!current_team().auto_shroud_updates()) { synced_context::run_and_store("update_shroud", replay_helper::get_update_shroud()); } undo_stack().clear(); } if (!preferences::disable_auto_moves()) { execute_gotos(); } end_turn_enable(true); while(!should_return_to_play_side()) { try { process_network_data(); check_objectives(); play_slice_catch(); if (player_type_changed_) { // Clean undo stack if turn has to be restarted (losing control) if ( undo_stack().can_undo() ) { font::floating_label flabel(_("Undoing moves not yet transmitted to the server.")); color_t color {255,255,255,SDL_ALPHA_OPAQUE}; flabel.set_color(color); SDL_Rect rect = gui_->map_area(); flabel.set_position(rect.w/2, rect.h/2); flabel.set_lifetime(150); flabel.set_clip_rect(rect); font::add_floating_label(flabel); } while( undo_stack().can_undo() ) undo_stack().undo(); } if(timer) { bool time_left = timer->update(); if(!time_left) { end_turn_ = END_TURN_REQUIRED; } } } catch(...) { turn_data_.send_data(); throw; } turn_data_.send_data(); } }
possible_end_play_signal playmp_controller::play_human_turn(){ LOG_NG << "playmp::play_human_turn...\n"; remove_blindfold(); int cur_ticks = SDL_GetTicks(); show_turn_dialog(); if (!preferences::disable_auto_moves()) { HANDLE_END_PLAY_SIGNAL(execute_gotos()); } if (!linger_ || is_host()) { end_turn_enable(true); } while(!end_turn_) { turn_info_send send_safe(turn_data_); config cfg; if(network_reader_.read(cfg)) { turn_info::PROCESS_DATA_RESULT res; HANDLE_END_PLAY_SIGNAL( res = turn_data_.process_network_data(cfg, skip_replay_) ); //PROCESS_RESTART_TURN_TEMPORARY_LOCAL should be impossible because that's means the currently active side (that's us) left. if (res == turn_info::PROCESS_RESTART_TURN || res == turn_info::PROCESS_RESTART_TURN_TEMPORARY_LOCAL) { // Clean undo stack if turn has to be restarted (losing control) if ( undo_stack_->can_undo() ) { font::floating_label flabel(_("Undoing moves not yet transmitted to the server.")); SDL_Color color = {255,255,255,255}; flabel.set_color(color); SDL_Rect rect = gui_->map_area(); flabel.set_position(rect.w/2, rect.h/2); flabel.set_lifetime(150); flabel.set_clip_rect(rect); font::add_floating_label(flabel); } while( undo_stack_->can_undo() ) undo_stack_->undo(); end_turn_struct ets = {static_cast<unsigned>(gui_->playing_side())}; return possible_end_play_signal(ets); //throw end_turn_exception(gui_->playing_side()); } else if(res == turn_info::PROCESS_END_LINGER) { if(!linger_) replay::process_error("Received unexpected next_scenario durign the game"); else { //we end the turn immidiately to prevent receiving data of the next scenario while we are not playing it. end_turn(); } } } HANDLE_END_PLAY_SIGNAL( play_slice() ); HANDLE_END_PLAY_SIGNAL( check_end_level() ); if (!linger_ && (current_team().countdown_time() > 0) && saved_game_.mp_settings().mp_countdown) { SDL_Delay(1); const int ticks = SDL_GetTicks(); int new_time = current_team().countdown_time()-std::max<int>(1,(ticks - cur_ticks)); if (new_time > 0 ){ current_team().set_countdown_time(new_time); cur_ticks = ticks; if(current_team().is_human() && !beep_warning_time_) { beep_warning_time_ = new_time - WARNTIME + ticks; } if(counting_down()) { think_about_countdown(ticks); } } else { // Clock time ended // If no turn bonus or action bonus -> defeat const int action_increment = saved_game_.mp_settings().mp_countdown_action_bonus; if ( (saved_game_.mp_settings().mp_countdown_turn_bonus == 0 ) && (action_increment == 0 || current_team().action_bonus_count() == 0)) { // Not possible to end level in MP with throw end_level_exception(DEFEAT); // because remote players only notice network disconnection // Current solution end remaining turns automatically current_team().set_countdown_time(10); } return possible_end_play_signal(end_turn_exception().to_struct()); //throw end_turn_exception(); } } gui_->draw(); } return boost::none; }
void playmp_controller::play_human_turn() { LOG_NG << "playmp::play_human_turn...\n"; assert(!linger_); remove_blindfold(); boost::scoped_ptr<countdown_clock> timer; if(saved_game_.mp_settings().mp_countdown) { timer.reset(new countdown_clock(current_team())); } show_turn_dialog(); if(undo_stack_->can_undo()) { // If we reload a networked mp game we cannot undo moves made before the save // Becasue other players already received them if(!current_team().auto_shroud_updates()) { synced_context::run_and_store("update_shroud", replay_helper::get_update_shroud()); } undo_stack_->clear(); } if (!preferences::disable_auto_moves()) { execute_gotos(); } end_turn_enable(true); while(!should_return_to_play_side()) { try { process_network_data(); if (player_type_changed_) { // Clean undo stack if turn has to be restarted (losing control) if ( undo_stack_->can_undo() ) { font::floating_label flabel(_("Undoing moves not yet transmitted to the server.")); SDL_Color color = {255,255,255,255}; flabel.set_color(color); SDL_Rect rect = gui_->map_area(); flabel.set_position(rect.w/2, rect.h/2); flabel.set_lifetime(150); flabel.set_clip_rect(rect); font::add_floating_label(flabel); } while( undo_stack_->can_undo() ) undo_stack_->undo(); } check_objectives(); play_slice_catch(); if(timer) { bool time_left = timer->update(); if(!time_left) { end_turn_ = END_TURN_REQUIRED; } } } catch(...) { turn_data_.send_data(); throw; } turn_data_.send_data(); gui_->draw(); } }
void playmp_controller::play_human_turn() { command_disabled_resetter reset_commands; int cur_ticks = SDL_GetTicks(); show_turn_dialog(); execute_gotos(); bool auto_end_turn = can_auto_end_turn(true); if (!auto_end_turn) { if (!unit::actor->is_city() && unit::actor->task() == unit::TASK_NONE) { gui_->scroll_to_tile(unit::actor->get_location(), game_display::ONSCREEN, true, true); } } else { return; } if ((!linger_) || (is_host_)) { gui_->set_theme_object_active("endturn", true); } while (!end_turn_ && !auto_end_turn) { try { play_slice(); check_end_level(); std::deque<config> backlog; std::vector<config> cfgs = received_data_cfg_; received_data_cfg_.clear(); for (std::vector<config>::const_iterator it = cfgs.begin(); it != cfgs.end(); ++ it) { const config& cfg = *it; if (turn_data_->process_network_data(cfg, lobby->transit.conn(), backlog, skip_replay_) == turn_info::PROCESS_RESTART_TURN) { // Clean undo stack if turn has to be restarted (losing control) if (!undo_stack_.empty()) { font::floating_label flabel(_("Undoing moves not yet transmitted to the server.")); SDL_Color color = {255,255,255,255}; flabel.set_color(color); SDL_Rect rect = gui_->map_area(); flabel.set_position(rect.w/2, rect.h/2); flabel.set_lifetime(150); flabel.set_clip_rect(rect); font::add_floating_label(flabel); } while(!undo_stack_.empty()) { menu_handler_.undo(gui_->get_playing_team() + 1); } throw end_turn_exception(gui_->get_playing_team() + 1); } } } catch (end_level_exception& e) { turn_data_->send_data(); throw e; } if (!linger_ && (current_team().countdown_time() > 0) && gamestate_.mp_settings().mp_countdown) { SDL_Delay(1); const int ticks = SDL_GetTicks(); int new_time = current_team().countdown_time()-std::max<int>(1,(ticks - cur_ticks)); if (new_time > 0 ){ current_team().set_countdown_time(new_time); cur_ticks = ticks; if(current_team().is_human() && !beep_warning_time_) { beep_warning_time_ = new_time - WARNTIME + ticks; } if(counting_down()) { think_about_countdown(ticks); } } else { // Clock time ended // If no turn bonus or action bonus -> defeat const int action_increment = gamestate_.mp_settings().mp_countdown_action_bonus; if ( (gamestate_.mp_settings().mp_countdown_turn_bonus == 0 ) && (action_increment == 0 || current_team().action_bonus_count() == 0)) { // Not possible to end level in MP with throw end_level_exception(DEFEAT); // because remote players only notice network disconnection // Current solution end remaining turns automatically current_team().set_countdown_time(10); } else { const int maxtime = gamestate_.mp_settings().mp_countdown_reservoir_time; int secs = gamestate_.mp_settings().mp_countdown_turn_bonus; secs += action_increment * current_team().action_bonus_count(); current_team().set_action_bonus_count(0); secs = (secs > maxtime) ? maxtime : secs; current_team().set_countdown_time(1000 * secs); } turn_data_->send_data(); throw end_turn_exception(); } } gui_->draw(); turn_data_->send_data(); auto_end_turn = can_auto_end_turn(false); } menu_handler_.clear_undo_stack(player_number_); }