made the game more responsive when it's the AI or another player's turn.

Added two new AI parameters: recruitment_ignore_bad_movement and
recruitment_ignore_bad_combat
This commit is contained in:
Dave White 2004-05-05 22:07:20 +00:00
parent 6b9abaf6d9
commit c36cea09c4
26 changed files with 265 additions and 328 deletions

View file

@ -77,6 +77,16 @@ Defeat:
#enddef
#endif
#macro which tells the AI not to start thinking about
#whether it's a bad idea to send trolls into the forest
#against elves, and just do it
#define EBESIEGED_RECRUITMENT
[ai]
recruitment_ignore_bad_movement=yes
recruitment_ignore_bad_combat=yes
[/ai]
#enddef
[side]
type=Orcish Warlord
description=Urug-Telfar
@ -88,6 +98,7 @@ Defeat:
#ifdef HARD
{HIGH_PRIORITY_TARGETS}
#endif
{EBESIEGED_RECRUITMENT}
team_name=orcs
[/side]
@ -97,6 +108,7 @@ Defeat:
side=3
canrecruit=1
recruit=Orcish Warrior,Wolf Rider,Orcish Crossbow,Orcish Assassin,Troll
{EBESIEGED_RECRUITMENT}
team_name=orcs
#ifdef EASY
gold=200
@ -120,6 +132,7 @@ Defeat:
side=4
canrecruit=1
recruit=Orcish Warrior,Wolf Rider,Orcish Crossbow,Troll Warrior,Orcish Slayer
{EBESIEGED_RECRUITMENT}
team_name=orcs
#ifdef EASY
gold=200

View file

@ -47,7 +47,7 @@ void show_about(display& disp)
map_rect.h = map_image->h;
gui::button close(disp,string_table["close_button"]);
close.set_xy((disp.x()/2)-(close.width()/2), map_rect.y+map_rect.h+15);
close.set_location((disp.x()/2)-(close.width()/2), map_rect.y+map_rect.h+15);
std::vector<std::string> text;

View file

@ -817,7 +817,7 @@ int ai::compare_unit_types(const unit_type& a, const unit_type& b) const
void ai::analyze_potential_recruit_combat()
{
if(unit_combat_scores_.empty() == false) {
if(unit_combat_scores_.empty() == false || current_team().ai_parameters()["recruitment_ignore_bad_combat"] == "yes") {
return;
}
@ -890,7 +890,7 @@ private:
void ai::analyze_potential_recruit_movements()
{
if(unit_movement_scores_.empty() == false) {
if(unit_movement_scores_.empty() == false || current_team().ai_parameters()["recruitment_ignore_bad_movement"] == "yes") {
return;
}

View file

@ -2065,7 +2065,7 @@ void display::create_buttons()
for(std::vector<theme::menu>::const_iterator i = buttons.begin(); i != buttons.end(); ++i) {
gui::button b(*this,i->title(),gui::button::TYPE_PRESS,i->image());
const SDL_Rect& loc = i->location(screen_area());
b.set_xy(loc.x,loc.y);
b.set_location(loc.x,loc.y);
buttons_.push_back(b);
}
}

View file

@ -83,8 +83,8 @@ map_editor::map_editor(display &gui, gamemap &map, config &theme, config &game_c
// Set size specs.
adjust_sizes(gui_, size_specs_, palette_.num_terrains());
tup_.set_xy(gui.mapx() + size_specs_.button_x, size_specs_.top_button_y);
tdown_.set_xy(gui.mapx() + size_specs_.button_x, size_specs_.bot_button_y);
tup_.set_location(gui.mapx() + size_specs_.button_x, size_specs_.top_button_y);
tdown_.set_location(gui.mapx() + size_specs_.button_x, size_specs_.bot_button_y);
// Clear the current hotkeys. Alot of hotkeys are already set
// through other configuration files (e.g. english.cfg) and we need

View file

@ -81,16 +81,13 @@ std::string new_map_dialog(display& disp, gamemap::TERRAIN fill_terrain,
gui::button random_map_setting_button(disp,"Random Generator Setting");
gui::button cancel_button(disp,"Cancel");
new_map_button.set_x(xpos + horz_margin);
new_map_button.set_y(height_rect.y + height_rect.h + vertical_margin);
random_map_button.set_x(xpos + horz_margin);
random_map_button.set_y(ypos + height - random_map_button.height()-14*2-vertical_margin);
random_map_setting_button.set_x(random_map_button.get_x() + random_map_button.width()
+ horz_margin);
random_map_setting_button.set_y(ypos + height - random_map_setting_button.height()
- 14*2 - vertical_margin);
cancel_button.set_x(xpos + width - cancel_button.width() - horz_margin);
cancel_button.set_y(ypos + height - cancel_button.height()-14);
new_map_button.set_location(xpos + horz_margin,height_rect.y + height_rect.h + vertical_margin);
random_map_button.set_location(xpos + horz_margin,ypos + height - random_map_button.height()-14*2-vertical_margin);
random_map_setting_button.set_location(random_map_button.location().x + random_map_button.width() + horz_margin,
ypos + height - random_map_setting_button.height()
- 14*2 - vertical_margin);
cancel_button.set_location(xpos + width - cancel_button.width() - horz_margin,
ypos + height - cancel_button.height()-14);
const int right_space = 100;

View file

@ -89,10 +89,8 @@ bool show_intro_part(display& screen, const config& part,
gui::button next_button(screen,string_table["next_button"] + ">>>");
gui::button skip_button(screen,string_table["skip_button"]);
next_button.set_x(screen.x()-200);
next_button.set_y(screen.y()-150);
skip_button.set_x(screen.x()-200);
skip_button.set_y(screen.y()-100);
next_button.set_location(screen.x()-200,screen.y()-150);
skip_button.set_location(screen.x()-200,screen.y()-100);
gui::draw_solid_tinted_rectangle(0,0,screen.x()-1,screen.y()-1,
0,0,0,1.0,screen.video().getSurface());
@ -122,10 +120,8 @@ bool show_intro_part(display& screen, const config& part,
textx = dstrect.x;
texty = dstrect.y + dstrect.h + 10;
next_button.set_x(dstrect.x+dstrect.w-40);
next_button.set_y(dstrect.y+dstrect.h+20);
skip_button.set_x(dstrect.x+dstrect.w-40);
skip_button.set_y(dstrect.y+dstrect.h+70);
next_button.set_location(dstrect.x+dstrect.w-40,dstrect.y+dstrect.h+20);
skip_button.set_location(dstrect.x+dstrect.w-40,dstrect.y+dstrect.h+70);
}
next_button.draw();
@ -145,7 +141,7 @@ bool show_intro_part(display& screen, const config& part,
int xpos = textx, ypos = texty;
//the maximum position that text can reach before wrapping
const int max_xpos = next_button.get_x() - 10;
const int max_xpos = next_button.location().x - 10;
size_t height = 0;
std::string buf;
for(;;) {

View file

@ -73,8 +73,8 @@ void default_map_generator::user_config(display& disp)
gui::button close_button(disp,string_table["close_window"]);
close_button.set_x(xpos + width/2 - close_button.width()/2);
close_button.set_y(ypos + height - close_button.height()-14);
close_button.set_location(xpos + width/2 - close_button.width()/2,
ypos + height - close_button.height()-14);
const std::string& players_label = string_table["num_players"] + ":";
const std::string& width_label = string_table["map_width"] + ":";

View file

@ -167,7 +167,7 @@ void multiplayer_game_setup_dialog::set_area(const SDL_Rect& area)
ypos += font::draw_text(&disp_,disp_.screen_area(),12,font::GOOD_COLOUR,
string_table["name_of_game"] + ":",xpos,ypos).h + border_size;
name_entry_.assign(new gui::textbox(disp_,width-20,string_table["game_prefix"] + preferences::login() + string_table["game_postfix"]));
name_entry_->set_position(xpos,ypos);
name_entry_->set_location(xpos,ypos);
ypos += name_entry_->location().h + border_size;
@ -230,38 +230,38 @@ void multiplayer_game_setup_dialog::set_area(const SDL_Rect& area)
//FOG of war
rect.y += rect.h + border_size*2;
fog_game_->set_xy(rect.x,rect.y);
fog_game_->set_location(rect.x,rect.y);
rect.y += fog_game_->location().h + border_size;
std::cerr << "g\n";
//Shroud
shroud_game_->set_xy(rect.x,rect.y);
shroud_game_->set_location(rect.x,rect.y);
rect.y += shroud_game_->location().h + border_size;
//Observers
observers_game_->set_xy(rect.x,rect.y);
observers_game_->set_location(rect.x,rect.y);
rect.y += observers_game_->location().h + border_size;
std::cerr << "h\n";
//Buttons
cancel_game_->set_xy(right - cancel_game_->width() - gui::ButtonHPadding,
cancel_game_->set_location(right - cancel_game_->width() - gui::ButtonHPadding,
bottom - cancel_game_->height() - gui::ButtonVPadding);
launch_game_->set_xy(right - cancel_game_->width() - launch_game_->width() - gui::ButtonHPadding*2,
launch_game_->set_location(right - cancel_game_->width() - launch_game_->width() - gui::ButtonHPadding*2,
bottom - launch_game_->height() - gui::ButtonVPadding);
regenerate_map_->set_xy(rect.x,rect.y);
regenerate_map_->backup_background();
regenerate_map_->set_location(rect.x,rect.y);
regenerate_map_->bg_backup();
rect.y += regenerate_map_->location().h + border_size;
generator_settings_->set_xy(rect.x,rect.y);
generator_settings_->backup_background();
generator_settings_->set_location(rect.x,rect.y);
generator_settings_->bg_backup();
std::cerr << "i\n";
@ -275,7 +275,7 @@ void multiplayer_game_setup_dialog::set_area(const SDL_Rect& area)
std::cerr << "j\n";
era_combo_->set_xy(era_rect.x+era_rect.w+border_size,era_rect.y);
era_combo_->set_location(era_rect.x+era_rect.w+border_size,era_rect.y);
SDL_Rect minimap_rect = {xpos,ypos,minimap_width,minimap_width};
minimap_restorer_ = surface_restorer(&disp_.video(),minimap_rect);
@ -409,13 +409,8 @@ lobby::RESULT multiplayer_game_setup_dialog::process()
}
if(map_changed) {
if(generator_ != NULL) {
generator_settings_->draw();
regenerate_map_->draw();
} else {
generator_settings_->hide();
regenerate_map_->hide();
}
generator_settings_->hide(generator_ == NULL);
regenerate_map_->hide(generator_ == NULL);
const std::string& map_data = (*level_)["map_data"];

View file

@ -126,8 +126,8 @@ public:
font::draw_text(&disp_,rect,14,font::NORMAL_COLOUR,text,rect.x,rect.y);
cancel_button_.assign(new gui::button(disp_,string_table["cancel"]));
cancel_button_->set_xy(area.x+area.w - cancel_button_->width() - gui::ButtonHPadding,
area.y+area.h - cancel_button_->height() - gui::ButtonVPadding);
cancel_button_->set_location(area.x+area.w - cancel_button_->width() - gui::ButtonHPadding,
area.y+area.h - cancel_button_->height() - gui::ButtonVPadding);
cancel_button_->draw();
}

View file

@ -333,10 +333,10 @@ void mp_connect::set_area(const SDL_Rect& rect)
//gui::draw_dialog_background(left, right, width, height, *disp_, "menu");
//Buttons
cancel_.set_xy(right - cancel_.width() - gui::ButtonHPadding,bottom-cancel_.height()-gui::ButtonVPadding);
launch_.set_xy(right - cancel_.width() - launch_.width() - gui::ButtonHPadding*2,bottom-launch_.height()-gui::ButtonVPadding);
cancel_.set_location(right - cancel_.width() - gui::ButtonHPadding,bottom-cancel_.height()-gui::ButtonVPadding);
launch_.set_location(right - cancel_.width() - launch_.width() - gui::ButtonHPadding*2,bottom-launch_.height()-gui::ButtonVPadding);
ai_.set_xy(left+30,bottom-60);
ai_.set_location(left+30,bottom-60);
//Title and labels
gui::draw_dialog_title(left,top,disp_,string_table["game_lobby"]);
@ -385,20 +385,20 @@ void mp_connect::set_area(const SDL_Rect& rect)
//Player type
combos_type_.push_back(gui::combo(*disp_, player_types_));
combos_type_.back().set_xy(left+30,top+55+(30*side_num));
combos_type_.back().set_location(left+30,top+55+(30*side_num));
//Player race
combos_race_.push_back(gui::combo(*disp_, player_races_));
combos_race_.back().set_xy(left+145,top+55+(30*side_num));
combos_race_.back().set_location(left+145,top+55+(30*side_num));
//Player team
combos_team_.push_back(gui::combo(*disp_, player_teams_));
combos_team_.back().set_xy(left+260,top+55+(30*side_num));
combos_team_.back().set_location(left+260,top+55+(30*side_num));
combos_team_.back().set_selected(side_num);
//Player color
combos_color_.push_back(gui::combo(*disp_, player_colors_));
combos_color_.back().set_xy(left+375,top+55+(30*side_num));
combos_color_.back().set_location(left+375,top+55+(30*side_num));
combos_color_.back().set_selected(side_num);
SDL_Rect r;

View file

@ -205,10 +205,10 @@ RESULT enter(display& disp, config& game_data, const config& terrain_data, dialo
}
update_rect(xscale(disp,19),yscale(disp,23),xscale(disp,832),yscale(disp,520));
join_game.set_xy(xscale(disp,19),yscale(disp,545));
new_game.set_xy(xscale(disp,19)+join_game.width()+5,yscale(disp,545));
quit_game.set_xy(xscale(disp,19)+join_game.width()+5+new_game.width()+5,yscale(disp,545));
message_entry.set_position(xscale(disp,19),yscale(disp,725));
join_game.set_location(xscale(disp,19),yscale(disp,545));
new_game.set_location(xscale(disp,19)+join_game.width()+5,yscale(disp,545));
quit_game.set_location(xscale(disp,19)+join_game.width()+5+new_game.width()+5,yscale(disp,545));
message_entry.set_location(xscale(disp,19),yscale(disp,725));
message_entry.set_width(xscale(disp,832));
update_whole_screen();

View file

@ -147,16 +147,17 @@ void turn_info::turn_slice()
int mousex, mousey;
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);
tooltips::process(mousex,mousey,mouse_flags & SDL_BUTTON_LMASK);
const int scroll_threshold = 5;
const theme::menu* const m = gui_.menu_pressed(mousex,mousey,mouse_flags&SDL_BUTTON_LMASK);
const theme::menu* const m = gui_.menu_pressed(mousex,mousey,true);
if(m != NULL) {
const SDL_Rect& menu_loc = m->location(gui_.screen_area());
show_menu(m->items(),menu_loc.x+1,menu_loc.y + menu_loc.h + 1,false);
return;
}
tooltips::process(mousex,mousey,mouse_flags & SDL_BUTTON_LMASK);
const int scroll_threshold = 5;
if(key_[SDLK_UP] || mousey < scroll_threshold)
gui_.scroll(0,-preferences::scroll_speed());
@ -206,8 +207,9 @@ int turn_info::send_data(int first_command)
void turn_info::handle_event(const SDL_Event& event)
{
if(gui::in_dialog() || commands_disabled)
if(gui::in_dialog()) {
return;
}
switch(event.type) {
case SDL_KEYDOWN:
@ -271,10 +273,6 @@ void turn_info::handle_event(const SDL_Event& event)
void turn_info::mouse_motion(const SDL_MouseMotionEvent& event)
{
if(commands_disabled) {
return;
}
if(minimap_scrolling_) {
//if the game is run in a window, we could miss a LMB/MMB up event
// if it occurs outside our window.
@ -390,9 +388,6 @@ void turn_info::mouse_motion(const SDL_MouseMotionEvent& event)
void turn_info::mouse_press(const SDL_MouseButtonEvent& event)
{
if(commands_disabled)
return;
if(event.button == SDL_BUTTON_LEFT && event.state == SDL_RELEASED) {
minimap_scrolling_ = false;
} else if(event.button == SDL_BUTTON_MIDDLE && event.state == SDL_RELEASED) {
@ -516,6 +511,10 @@ gui::dialog_button_action::RESULT attack_calculations_displayer::button_pressed(
void turn_info::left_click(const SDL_MouseButtonEvent& event)
{
if(commands_disabled) {
return;
}
const team& current_team = teams_[team_num_-1];
// clicked on a hex on the minimap? then initiate minimap scrolling
@ -887,7 +886,6 @@ bool turn_info::can_execute_command(hotkey::HOTKEY_COMMAND command) const
case hotkey::HOTKEY_ZOOM_DEFAULT:
case hotkey::HOTKEY_FULLSCREEN:
case hotkey::HOTKEY_ACCELERATED:
case hotkey::HOTKEY_SAVE_GAME:
case hotkey::HOTKEY_TOGGLE_GRID:
case hotkey::HOTKEY_STATUS_TABLE:
case hotkey::HOTKEY_MUTE:
@ -899,6 +897,9 @@ bool turn_info::can_execute_command(hotkey::HOTKEY_COMMAND command) const
case hotkey::HOTKEY_SEARCH:
return true;
case hotkey::HOTKEY_SAVE_GAME:
return !commands_disabled;
case hotkey::HOTKEY_SHOW_ENEMY_MOVES:
case hotkey::HOTKEY_BEST_ENEMY_MOVES:
return enemies_visible_;
@ -907,12 +908,14 @@ bool turn_info::can_execute_command(hotkey::HOTKEY_COMMAND command) const
return network::nconnections() > 0;
case hotkey::HOTKEY_REDO:
return !browse_ && !redo_stack_.empty();
return !browse_ && !redo_stack_.empty() && !commands_disabled;
case hotkey::HOTKEY_UNDO:
return !browse_ && !undo_stack_.empty();
return !browse_ && !undo_stack_.empty() && !commands_disabled;
case hotkey::HOTKEY_CONTINUE_MOVE: {
if(browse_) return false;
if(browse_ || commands_disabled)
return false;
if(current_unit() != units_.end() && current_unit()->second.move_interrupted())
return true;
const unit_map::const_iterator i = units_.find(selected_hex_);
@ -923,7 +926,7 @@ bool turn_info::can_execute_command(hotkey::HOTKEY_COMMAND command) const
case hotkey::HOTKEY_DELAY_SHROUD:
return !browse_ && (current_team().uses_fog() || current_team().uses_shroud());
case hotkey::HOTKEY_UPDATE_SHROUD:
return !browse_ && current_team().auto_shroud_updates() == false;
return !browse_ && !commands_disabled && current_team().auto_shroud_updates() == false;
//commands we can only do if we are actually playing, not just viewing
case hotkey::HOTKEY_END_UNIT_TURN:
@ -931,7 +934,7 @@ bool turn_info::can_execute_command(hotkey::HOTKEY_COMMAND command) const
case hotkey::HOTKEY_REPEAT_RECRUIT:
case hotkey::HOTKEY_RECALL:
case hotkey::HOTKEY_ENDTURN:
return !browse_;
return !browse_ && !commands_disabled;
//commands we can only do if there is an active unit
case hotkey::HOTKEY_TERRAIN_TABLE:
@ -940,14 +943,14 @@ bool turn_info::can_execute_command(hotkey::HOTKEY_COMMAND command) const
return current_unit() != units_.end();
case hotkey::HOTKEY_RENAME_UNIT:
return current_unit() != units_.end() && current_unit()->second.side() == gui_.viewing_team()+1;
return !commands_disabled && current_unit() != units_.end() && current_unit()->second.side() == gui_.viewing_team()+1;
case hotkey::HOTKEY_LABEL_TERRAIN:
return map_.on_board(last_hex_) && !gui_.shrouded(last_hex_.x,last_hex_.y);
return !commands_disabled && map_.on_board(last_hex_) && !gui_.shrouded(last_hex_.x,last_hex_.y);
//commands we can only do if in debug mode
case hotkey::HOTKEY_CREATE_UNIT:
return game_config::debug && map_.on_board(last_hex_);
return !commands_disabled && game_config::debug && map_.on_board(last_hex_);
default:
return false;

View file

@ -531,60 +531,50 @@ void show_preferences_dialog(display& disp)
fullscreen_button.set_check(fullscreen());
fullscreen_button.set_x(slider_left);
fullscreen_button.set_y(sound_pos + 80);
fullscreen_button.set_location(slider_left,sound_pos + 80);
gui::button turbo_button(disp,string_table["speed_turbo"],
gui::button::TYPE_CHECK);
turbo_button.set_check(turbo());
turbo_button.set_x(slider_left);
turbo_button.set_y(sound_pos + 80 + 50);
turbo_button.set_location(slider_left,sound_pos + 80 + 50);
gui::button grid_button(disp,string_table["grid_button"],
gui::button::TYPE_CHECK);
grid_button.set_check(grid());
grid_button.set_x(slider_left);
grid_button.set_y(sound_pos + 80 + 100);
grid_button.set_location(slider_left,sound_pos + 80 + 100);
gui::button floating_labels_button(disp,string_table["floating_labels_button"],
gui::button::TYPE_CHECK);
floating_labels_button.set_check(show_floating_labels());
floating_labels_button.set_x(slider_left);
floating_labels_button.set_y(sound_pos + 80 + 150);
floating_labels_button.set_location(slider_left,sound_pos + 80 + 150);
gui::button resolution_button(disp,string_table["video_mode"]);
resolution_button.set_x(slider_left);
resolution_button.set_y(sound_pos + 80 + 200);
resolution_button.set_location(slider_left,sound_pos + 80 + 200);
gui::button turn_dialog_button(disp,string_table["turn_dialog_button"],
gui::button::TYPE_CHECK);
turn_dialog_button.set_check(turn_dialog());
turn_dialog_button.set_x(slider_left+fullscreen_button.width()+100);
turn_dialog_button.set_y(sound_pos + 80);
turn_dialog_button.set_location(slider_left+fullscreen_button.width()+100,sound_pos + 80);
gui::button turn_bell_button(disp,string_table["turn_bell_button"],
gui::button::TYPE_CHECK);
turn_bell_button.set_check(turn_bell());
turn_bell_button.set_x(slider_left+fullscreen_button.width()+100);
turn_bell_button.set_y(sound_pos + 80 + 50);
turn_bell_button.set_location(slider_left+fullscreen_button.width()+100,sound_pos + 80 + 50);
gui::button side_colours_button(disp,string_table["show_side_colours"],
gui::button::TYPE_CHECK);
side_colours_button.set_check(show_side_colours());
side_colours_button.set_x(slider_left + fullscreen_button.width() + 100);
side_colours_button.set_y(sound_pos + 80 + 100);
side_colours_button.set_location(slider_left + fullscreen_button.width() + 100,sound_pos + 80 + 100);
gui::button colour_cursors_button(disp,string_table["show_colour_cursors"],
gui::button::TYPE_CHECK);
colour_cursors_button.set_check(use_colour_cursors());
colour_cursors_button.set_x(slider_left + fullscreen_button.width() + 100);
colour_cursors_button.set_y(sound_pos + 80 + 150);
colour_cursors_button.set_location(slider_left + fullscreen_button.width() + 100,sound_pos + 80 + 150);
gui::button hotkeys_button (disp,string_table["hotkeys_button"]);
hotkeys_button.set_x(slider_left + fullscreen_button.width() + 100);
hotkeys_button.set_y(sound_pos + 80 + 200);
hotkeys_button.set_location(slider_left + fullscreen_button.width() + 100,sound_pos + 80 + 200);
bool redraw_all = true;
@ -791,14 +781,10 @@ void show_hotkeys_dialog (display & disp)
menu_.set_loc (xpos + 20, ypos);
gui::button change_button (disp, string_table["change_hotkey_button"]);
change_button.set_x (xpos + width -
change_button.width () -30);
change_button.set_y (ypos + 80);
change_button.set_location(xpos + width - change_button.width () -30,ypos + 80);
gui::button save_button (disp, string_table["save_hotkeys_button"]);
save_button.set_x (xpos + width -
save_button.width () -30);
save_button.set_y (ypos + 130);
save_button.set_location(xpos + width - save_button.width () - 30,ypos + 130);
bool redraw_all = true;

View file

@ -222,7 +222,7 @@ void draw_dialog(int x, int y, int w, int h, display& disp, const std::string& t
if(buttons != NULL) {
for(std::vector<button*>::const_iterator b = buttons->begin(); b != buttons->end(); ++b) {
(**b).set_xy(buttons_area.x,buttons_area.y);
(**b).set_location(buttons_area.x,buttons_area.y);
buttons_area.x += (**b).width() + ButtonHPadding;
}
}
@ -417,7 +417,7 @@ int show_dialog(display& disp, SDL_Surface* image,
for(std::vector<check_item>::const_iterator i = options->begin(); i != options->end(); ++i) {
button check_button(disp,i->label,button::TYPE_CHECK);
check_button_height += check_button.height() + button_height_padding;
check_button_width = maximum(check_button.width(),check_button_width);
check_button_width = maximum<int>(check_button.width(),check_button_width);
check_buttons.push_back(check_button);
}
@ -427,7 +427,7 @@ int show_dialog(display& disp, SDL_Surface* image,
for(std::vector<dialog_button>::const_iterator i = action_buttons->begin(); i != action_buttons->end(); ++i) {
button new_button(disp,i->label);
check_button_height += new_button.height() + button_height_padding;
check_button_width = maximum(new_button.width(),check_button_width);
check_button_width = maximum<int>(new_button.width(),check_button_width);
check_buttons.push_back(new_button);
}
@ -536,7 +536,7 @@ int show_dialog(display& disp, SDL_Surface* image,
if(use_textbox) {
const int text_widget_y_unpadded = text_widget_y + (text_widget_height - text_widget.location().h)/2;
text_widget.set_position(xloc + left_padding +
text_widget.set_location(xloc + left_padding +
text_widget_width - text_widget.location().w,
text_widget_y_unpadded);
events::raise_draw_event();
@ -550,8 +550,7 @@ int show_dialog(display& disp, SDL_Surface* image,
if(check_buttons.empty() == false) {
int options_y = text_widget_y + text_widget_height + menu_.height() + button_height_padding + menu_hpadding;
for(size_t i = 0; i != check_buttons.size(); ++i) {
check_buttons[i].set_x(xloc + total_width - padding_width - check_buttons[i].width());
check_buttons[i].set_y(options_y);
check_buttons[i].set_location(xloc + total_width - padding_width - check_buttons[i].width(),options_y);
options_y += check_buttons[i].height() + button_height_padding;

View file

@ -91,9 +91,10 @@ team::team_info::team_info(const config& cfg)
ai_algorithm = cfg["ai_algorithm"];
const config* const ai_parameters = cfg.child("ai");
if(ai_parameters != NULL) {
ai_params = *ai_parameters;
const config::child_list& ai_parameters = cfg.get_children("ai");
for(config::child_list::const_iterator aiparam = ai_parameters.begin(); aiparam != ai_parameters.end(); ++aiparam) {
ai_params.append(**aiparam);
}
const std::string& scouts_val = cfg["villages_per_scout"];

View file

@ -128,7 +128,7 @@ TITLE_RESULT show_title(display& screen)
size_t b, max_width = 0;
for(b = 0; b != nbuttons; ++b) {
buttons.push_back(button(screen,string_table[button_labels[b]]));
buttons.back().set_xy(menu_xbase + b*menu_xincr, menu_ybase + b*menu_yincr);
buttons.back().set_location(menu_xbase + b*menu_xincr, menu_ybase + b*menu_yincr);
max_width = maximum<size_t>(max_width,buttons.back().width());
}
@ -160,13 +160,13 @@ TITLE_RESULT show_title(display& screen)
}
}
screen.video().flip();
if(!last_escape && key[SDLK_ESCAPE])
return QUIT_GAME;
last_escape = key[SDLK_ESCAPE];
screen.video().flip();
events::pump();
//if the resolution has changed due to the user resizing the screen,

View file

@ -28,10 +28,9 @@ const int vertical_padding = 12;
button::button(display& disp, const std::string& label, button::TYPE type,
std::string button_image_name) :
label_(label), display_(&disp),
widget(disp), label_(label), display_(&disp),
image_(NULL), pressedImage_(NULL), activeImage_(NULL), pressedActiveImage_(NULL),
x_(0), y_(0), button_(true),
state_(UNINIT), type_(type), enabled_(true)
button_(true), state_(NORMAL), type_(type), enabled_(true), pressed_(false)
{
set_label(label);
@ -72,18 +71,18 @@ button::button(display& disp, const std::string& label, button::TYPE type,
textRect_ = font::draw_text(NULL,textRect_,font_size,
font::BUTTON_COLOUR,label_,0,0);
h_ = maximum(textRect_.h+horizontal_padding,button_image->h);
set_height(maximum(textRect_.h+horizontal_padding,button_image->h));
if(type == TYPE_PRESS) {
w_ = maximum(textRect_.w+horizontal_padding,button_image->w);
set_width(maximum(textRect_.w+horizontal_padding,button_image->w));
image_.assign(scale_surface(button_image,w_,h_));
pressedImage_.assign(scale_surface(pressed_image,w_,h_));
activeImage_.assign(scale_surface(active_image,w_,h_));
pressedActiveImage_.assign(scale_surface(pressed_active_image,w_,h_));
image_.assign(scale_surface(button_image,location().w,location().h));
pressedImage_.assign(scale_surface(pressed_image,location().w,location().h));
activeImage_.assign(scale_surface(active_image,location().w,location().h));
pressedActiveImage_.assign(scale_surface(pressed_active_image,location().w,location().h));
} else {
w_ = horizontal_padding + textRect_.w + button_image->w;
set_width(horizontal_padding + textRect_.w + button_image->w);
image_.assign(scale_surface(button_image,button_image->w,button_image->h));
pressedImage_.assign(scale_surface(pressed_image,button_image->w,button_image->h));
activeImage_.assign(scale_surface(active_image,button_image->w,button_image->h));
@ -102,22 +101,11 @@ bool button::checked() const
return state_ == PRESSED || state_ == PRESSED_ACTIVE;
}
void button::backup_background()
{
const SDL_Rect area = {x_,y_,w_,h_};
restorer_ = surface_restorer(&display_->video(),area);
}
void button::hide()
{
restorer_.restore();
}
void button::enable(bool new_val)
{
if(enabled_ != new_val) {
enabled_ = new_val;
draw();
set_dirty(true);
}
}
@ -128,18 +116,17 @@ bool button::enabled() const
void button::draw()
{
if(x_ <= 0 && y_ <= 0) {
if(location().x == 0 && location().y == 0 || hidden() || !dirty()) {
return;
}
if(type_ == TYPE_CHECK) {
hide();
backup_background();
bg_restore();
}
SDL_Surface* image = image_;
const int image_w = image_->w;
//const int image_h = image_->h;
int offset = 0;
switch(state_) {
case ACTIVE: image = activeImage_;
@ -149,19 +136,18 @@ void button::draw()
break;
case PRESSED_ACTIVE: image = pressedActiveImage_;
break;
case UNINIT:
case NORMAL:
default: break;
}
const SDL_Rect clipArea = display_->screen_area();
const int texty = y_ + h_/2 - textRect_.h/2 + offset;
const int texty = location().y + location().h/2 - textRect_.h/2 + offset;
int textx;
if(type_ == TYPE_PRESS) {
textx = x_ + image->w/2 - textRect_.w/2 + offset;
textx = location().x + image->w/2 - textRect_.w/2 + offset;
} else {
textx = x_ + image_w + horizontal_padding/2;
textx = location().x + image_w + horizontal_padding/2;
}
scoped_sdl_surface greyed_image(NULL);
@ -170,41 +156,24 @@ void button::draw()
image = greyed_image;
}
display_->blit_surface(x_,y_,image);
display_->blit_surface(location().x,location().y,image);
font::draw_text(display_,clipArea,font_size,
font::BUTTON_COLOUR,label_,textx,texty);
update_rect(x_,y_,width(),height());
update_rect(location());
set_dirty(false);
}
bool button::hit(int x, int y) const
{
if(x > x_ && x < x_ + w_ &&
y > y_ && y < y_ + h_) {
if(type_ == TYPE_CHECK)
return true;
x -= x_;
y -= y_;
int row_width = image_->w + is_odd(image_->w);
surface_lock lock(image_);
if(*(lock.pixels()+y*row_width+x) != 0)
return true;
}
return false;
return point_in_rect(x,y,location());
}
namespace {
bool not_image(const std::string& str) { return str != "" && str[0] != '&'; }
}
void button::set_x(int val) { x_ = val; }
void button::set_y(int val) { y_ = val; }
void button::set_xy(int valx, int valy) { x_ = valx; y_ = valy; }
void button::set_label(const std::string& val)
{
label_ = val;
@ -223,124 +192,80 @@ void button::set_label(const std::string& val)
font::BUTTON_COLOUR,label_,0,0);
}
int button::width() const
void button::mouse_motion(const SDL_MouseMotionEvent& event)
{
return w_;
const bool is_hit = hit(event.x,event.y);
if(state_ == NORMAL && is_hit) {
state_ = ACTIVE;
} else if(state_ == PRESSED && is_hit && type_ == TYPE_CHECK) {
state_ = PRESSED_ACTIVE;
} else if(state_ == ACTIVE && !is_hit) {
state_ = NORMAL;
} else if(state_ == PRESSED_ACTIVE && !is_hit) {
state_ = PRESSED;
} else if(state_ == PRESSED && !is_hit && type_ == TYPE_PRESS) {
state_ = NORMAL;
}
}
int button::height() const
void button::mouse_down(const SDL_MouseButtonEvent& event)
{
return h_;
const bool is_hit = hit(event.x,event.y);
if(is_hit && type_ == TYPE_PRESS) {
state_ = PRESSED;
}
}
void button::mouse_up(const SDL_MouseButtonEvent& event)
{
const bool is_hit = hit(event.x,event.y);
if(is_hit && type_ == TYPE_CHECK) {
if(state_ == ACTIVE) {
state_ = PRESSED_ACTIVE;
} else {
state_ = ACTIVE;
}
pressed_ = true;
} else if(is_hit && type_ == TYPE_PRESS && state_ == PRESSED) {
state_ = ACTIVE;
pressed_ = true;
}
}
void button::handle_event(const SDL_Event& event)
{
if(hidden() || !enabled_) {
return;
}
STATE start_state = state_;
switch(event.type) {
case SDL_MOUSEBUTTONDOWN:
mouse_down(event.button);
break;
case SDL_MOUSEBUTTONUP:
mouse_up(event.button);
break;
case SDL_MOUSEMOTION:
mouse_motion(event.motion);
break;
}
if(start_state != state_) {
set_dirty(true);
}
}
bool button::process(int mousex, int mousey, bool button)
{
if(!enabled_) {
if(state_ == UNINIT) {
state_ = NORMAL;
draw();
}
draw();
return false;
}
enum MOUSE_STATE { UNCHANGED, UP, DOWN };
MOUSE_STATE mouse_state = UNCHANGED;
if(button && !button_)
mouse_state = DOWN;
else if(!button && button_)
mouse_state = UP;
button_ = button;
const STATE start_state = state_;
if(type_ == TYPE_PRESS) {
switch(state_) {
case UNINIT:
state_ = NORMAL;
break;
case NORMAL:
if(hit(mousex,mousey))
state_ = ACTIVE;
break;
case ACTIVE:
if(mouse_state == DOWN && hit(mousex,mousey))
state_ = PRESSED;
else if(!hit(mousex,mousey))
state_ = NORMAL;
break;
case PRESSED:
if(mouse_state == UP) {
if(hit(mousex,mousey)) {
state_ = ACTIVE;
draw();
return true;
} else {
state_ = NORMAL;
}
}
case PRESSED_ACTIVE:
break;
}
} else if(type_ == TYPE_CHECK) {
const bool is_hit = hit(mousex,mousey);
switch(state_) {
case NORMAL:
if(is_hit) {
state_ = ACTIVE;
draw();
return true;
}
break;
case PRESSED:
if(is_hit) {
state_ = PRESSED_ACTIVE;
draw();
return true;
}
break;
case UNINIT:
break;
case ACTIVE:
if(!is_hit) {
state_ = NORMAL;
draw();
return true;
} else if(mouse_state == UP) {
state_ = PRESSED_ACTIVE;
draw();
return true;
}
break;
case PRESSED_ACTIVE:
if(!is_hit) {
state_ = PRESSED;
draw();
return true;
} else if(mouse_state == UP) {
state_ = ACTIVE;
draw();
return true;
}
break;
}
}
if(state_ != start_state) {
draw();
}
return false;
const bool res = pressed_;
pressed_ = false;
return res;
}
}

View file

@ -15,6 +15,8 @@
#include "SDL.h"
#include "widget.hpp"
#include "../sdl_utils.hpp"
#include <string>
@ -25,7 +27,7 @@ class display;
namespace gui {
class button
class button : public widget
{
public:
struct error {};
@ -35,39 +37,31 @@ public:
button(display& disp, const std::string& label, TYPE type=TYPE_PRESS,
std::string button_image="");
virtual ~button() {}
void set_check(bool check);
bool checked() const;
void draw();
void set_x(int val);
int get_x() {return x_;}
void set_y(int val);
void set_xy(int valx, int valy);
void set_label(const std::string& val);
SDL_Rect location() const {
const SDL_Rect pos = {x_,y_,w_,h_};
return pos;
}
int width() const;
int height() const;
bool process(int mousex, int mousey, bool button);
void backup_background();
void hide();
void enable(bool new_val);
bool enabled() const;
protected:
virtual void handle_event(const SDL_Event& event);
virtual void mouse_motion(const SDL_MouseMotionEvent& event);
virtual void mouse_down(const SDL_MouseButtonEvent& event);
virtual void mouse_up(const SDL_MouseButtonEvent& event);
private:
surface_restorer restorer_;
std::string label_;
display* display_;
shared_sdl_surface image_, pressedImage_, activeImage_, pressedActiveImage_;
int x_, y_, w_, h_;
SDL_Rect textRect_;
bool button_;
@ -79,6 +73,8 @@ private:
bool enabled_;
bool pressed_;
bool hit(int x, int y) const;
}; //end class button

View file

@ -48,9 +48,9 @@ void combo::set_items(const std::vector<std::string>& items)
items_ = items;
}
void combo::set_xy(int x, int y)
void combo::set_location(int x, int y)
{
button_.set_xy(x,y);
button_.set_location(x,y);
}
void combo::set_selected(int val)

View file

@ -26,9 +26,7 @@ public:
combo(display& disp, const std::vector<std::string>& items);
void draw();
void set_x(int val);
void set_y(int val);
void set_xy(int valx, int valy);
void set_location(int valx, int valy);
void set_selected(int val);
void set_items(const std::vector<std::string>& items);

View file

@ -115,10 +115,8 @@ void menu::set_loc(int x, int y)
scrollbar_.set_location(scroll_rect);
set_scrollbar_height();
uparrow_.set_x(x_ + menu_width);
uparrow_.set_y(y_);
downarrow_.set_x(x_+ menu_width);
downarrow_.set_y(scrollbar_.location().y + scrollbar_.location().h);
uparrow_.set_location(x_ + menu_width,y_);
downarrow_.set_location(x_+ menu_width,scrollbar_.location().y + scrollbar_.location().h);
}
}
@ -520,19 +518,8 @@ void menu::draw()
// update enabled/disabled status for up/down buttons
if(show_scrollbar()) {
if(first_item_on_screen_ == 0) {
uparrow_.enable(false);
uparrow_.hide();
} else {
uparrow_.enable(true);
}
if(first_item_on_screen_ >= items_.size() - max_items_onscreen()) {
downarrow_.enable(false);
downarrow_.hide();
} else {
downarrow_.enable(true);
}
uparrow_.hide(first_item_on_screen_ == 0);
downarrow_.hide(first_item_on_screen_ >= items_.size() - max_items_onscreen());
}
for(size_t i = 0; i != items_.size(); ++i)

View file

@ -12,6 +12,7 @@
*/
#include "scrollbar.hpp"
#include "../display.hpp"
#include "../image.hpp"
#include "../video.hpp"

View file

@ -12,6 +12,7 @@
*/
#include "slider.hpp"
#include "../display.hpp"
#include "../image.hpp"
#include "../video.hpp"

View file

@ -8,19 +8,19 @@ namespace {
namespace gui {
widget::widget(const widget &o) :
disp_(o.disp_), rect_(o.rect_), focus_(o.focus_), dirty_(o.dirty_)
disp_(o.disp_), rect_(o.rect_), focus_(o.focus_), dirty_(o.dirty_), hidden_(false)
{
bg_backup();
}
widget::widget(display& disp) :
disp_(&disp), rect_(EmptyRect), focus_(true), dirty_(true)
disp_(&disp), rect_(EmptyRect), focus_(true), dirty_(true), hidden_(false)
{
bg_backup();
}
widget::widget(display& disp, SDL_Rect& rect) :
disp_(&disp), rect_(EmptyRect), focus_(true), dirty_(true)
disp_(&disp), rect_(EmptyRect), focus_(true), dirty_(true), hidden_(false)
{
set_location(rect);
bg_backup();
@ -35,7 +35,7 @@ void widget::set_location(const SDL_Rect& rect)
draw();
}
void widget::set_position(int x, int y)
void widget::set_location(int x, int y)
{
bg_restore();
SDL_Rect rect = {x,y,location().w,location().h};
@ -65,6 +65,16 @@ void widget::set_height(int h)
draw();
}
size_t widget::width() const
{
return rect_.w;
}
size_t widget::height() const
{
return rect_.h;
}
const SDL_Rect& widget::location() const
{
return rect_;
@ -86,6 +96,24 @@ bool widget::focus() const
return events::has_focus(this) && focus_;
}
void widget::hide(bool value)
{
if(value != hidden_) {
if(value) {
restorer_.restore();
} else {
set_dirty(true);
}
hidden_ = value;
}
}
bool widget::hidden() const
{
return hidden_;
}
void widget::set_dirty(bool dirty)
{
dirty_ = dirty;

View file

@ -2,10 +2,13 @@
#define WIDGET_HPP_INCLUDED
#include "../events.hpp"
#include "../display.hpp"
#include "../sdl_utils.hpp"
#include "SDL.h"
class display;
namespace gui {
class widget : public events::handler
@ -13,13 +16,21 @@ class widget : public events::handler
public:
const SDL_Rect& location() const;
void set_location(const SDL_Rect& rect);
void set_position(int x, int y);
void set_location(int x, int y);
void set_width(int w);
void set_height(int h);
size_t width() const;
size_t height() const;
virtual bool focus() const;
void set_focus(bool focus);
void hide(bool value=true);
bool hidden() const;
void bg_backup();
protected:
widget(const widget &o);
widget(display& disp);
@ -32,6 +43,8 @@ protected:
display& disp() const { return *disp_; }
virtual void handle_event(const SDL_Event& event);
private:
mutable display* disp_;
mutable surface_restorer restorer_;
@ -39,9 +52,7 @@ private:
bool focus_; // Should user input be ignored?
bool dirty_; // Does the widget need drawn?
void bg_backup();
virtual void handle_event(const SDL_Event& event);
bool hidden_;
};
}