added basic implementation of menus to theming system.
fixed problem where enemy energy bars would always display as full yellow (CVS internal)
This commit is contained in:
parent
8868fa0241
commit
dcdaa8c3bc
20 changed files with 446 additions and 171 deletions
|
@ -133,6 +133,7 @@ char=S
|
|||
red=255
|
||||
green=255
|
||||
blue=255
|
||||
light=true
|
||||
[/terrain]
|
||||
|
||||
[terrain]
|
||||
|
@ -142,6 +143,7 @@ name=snow village
|
|||
char=V
|
||||
aliasof=t
|
||||
no_overlay=true
|
||||
light=true
|
||||
[/terrain]
|
||||
|
||||
[terrain]
|
||||
|
@ -158,6 +160,7 @@ name=mountains
|
|||
char=m
|
||||
red=150
|
||||
green=150
|
||||
light=true
|
||||
[/terrain]
|
||||
|
||||
[terrain]
|
||||
|
@ -183,6 +186,7 @@ name=keep
|
|||
char=K
|
||||
unit_height_adjust=8
|
||||
aliasof=C
|
||||
light=true
|
||||
[/terrain]
|
||||
|
||||
[terrain]
|
||||
|
@ -192,6 +196,7 @@ char=W
|
|||
red=50
|
||||
green=50
|
||||
blue=20
|
||||
light=true
|
||||
[/terrain]
|
||||
|
||||
[terrain]
|
||||
|
|
|
@ -25,6 +25,15 @@ height=600
|
|||
xanchor=right
|
||||
yanchor=top
|
||||
[/panel]
|
||||
[menu]
|
||||
is_context_menu=true
|
||||
items=objectives,recruit,recall,preferences,statustable,undo,redo,createunit,endturn,describeunit
|
||||
[/menu]
|
||||
[menu]
|
||||
title=action_endturn
|
||||
items=endturn
|
||||
rect=900,700
|
||||
[/menu]
|
||||
|
||||
[status]
|
||||
#the time of day image
|
||||
|
|
|
@ -245,7 +245,6 @@ location="Location"
|
|||
level="level"
|
||||
|
||||
message="Message"
|
||||
speak="Speak"
|
||||
describe_unit="Describe Unit"
|
||||
rename_unit="Rename Unit"
|
||||
scenario_objectives="Scenario Objectives"
|
||||
|
@ -267,6 +266,12 @@ full_screen="Full Screen"
|
|||
windowed="Windowed"
|
||||
|
||||
hotkeys_button="Hotkeys"
|
||||
action_quit="Quit Game"
|
||||
action_unitlist="Unit List"
|
||||
action_objectives="Scenario Objectives"
|
||||
action_preferences="Preferences"
|
||||
action_createunit="Create Unit (Debug!)"
|
||||
action_speak="Speak"
|
||||
action_zoomin="Zoom In"
|
||||
action_zoomout="Zoom Out"
|
||||
action_zoomdefault="Default Zoom"
|
||||
|
@ -281,6 +286,7 @@ action_redo="Redo"
|
|||
action_terraintable="Terrain Table"
|
||||
action_resistance="Attack Resistance"
|
||||
action_describeunit="Unit Description"
|
||||
action_renameunit="Rename Unit"
|
||||
action_save="Save Game"
|
||||
action_togglegrid="Toggle Grid"
|
||||
action_statustable="Status Table"
|
||||
|
@ -290,9 +296,9 @@ action_repeatrecruit="Repeat Recruit"
|
|||
action_mute="Mute"
|
||||
save_hotkeys_button="Save Hotkeys"
|
||||
change_hotkey_button="Change Hotkey"
|
||||
hotkeys_dialog="Hotkeys Setting"
|
||||
hotkeys_dialog="Hotkey Settings"
|
||||
set_hotkey="Press desired HotKey"
|
||||
hotkey_already_used="This HotKey is already used. Nothing done."
|
||||
hotkey_already_used="This HotKey is already in use."
|
||||
|
||||
speed="Speed:"
|
||||
speed_normal="Normal"
|
||||
|
@ -339,7 +345,7 @@ versus="vs"
|
|||
cancel="Cancel"
|
||||
|
||||
terrain_info="Terrain Modifiers"
|
||||
movement="Movement"
|
||||
movement="Moves"
|
||||
defense="Defense"
|
||||
|
||||
attack_resistance="Resistance"
|
||||
|
|
|
@ -26,7 +26,7 @@ get_hit_sound=groan.wav
|
|||
name=wail
|
||||
type=cold
|
||||
range=long
|
||||
damage=2
|
||||
damage=3
|
||||
number=3
|
||||
[/attack]
|
||||
[/unit]
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 374 B After Width: | Height: | Size: 791 B |
|
@ -101,6 +101,8 @@ display::display(unit_map& units, CVideo& video, const gamemap& map,
|
|||
turbo_(false), grid_(false), sidebarScaling_(1.0),
|
||||
theme_(theme_cfg,screen_area())
|
||||
{
|
||||
create_buttons();
|
||||
|
||||
std::fill(reportRects_,reportRects_+reports::NUM_REPORTS,empty_rect);
|
||||
|
||||
new_turn();
|
||||
|
@ -438,6 +440,7 @@ void display::redraw_everything()
|
|||
tooltips::clear_tooltips();
|
||||
|
||||
theme_.set_resolution(screen_area());
|
||||
create_buttons();
|
||||
|
||||
panelsDrawn_ = false;
|
||||
invalidate_all();
|
||||
|
@ -500,6 +503,10 @@ void display::draw(bool update,bool force)
|
|||
for(std::vector<theme::label>::const_iterator i = labels.begin(); i != labels.end(); ++i) {
|
||||
draw_label(*this,screen,*i);
|
||||
}
|
||||
|
||||
for(std::vector<gui::button>::iterator b = buttons_.begin(); b != buttons_.end(); ++b) {
|
||||
b->draw();
|
||||
}
|
||||
|
||||
panelsDrawn_ = true;
|
||||
}
|
||||
|
@ -1550,14 +1557,19 @@ void display::draw_footstep(const gamemap::location& loc, int xloc, int yloc)
|
|||
draw_unit(xloc,yloc,image,hflip,vflip,0.5);
|
||||
|
||||
if(show_time && route_.move_left > 0 && route_.move_left < 10) {
|
||||
//draw number in yellow if terrain is light, else draw in black
|
||||
gamemap::TERRAIN terrain = map_.get_terrain(loc);
|
||||
bool tile_is_light = map_.get_terrain_info (terrain).is_light ();;
|
||||
SDL_Color text_colour = tile_is_light ? font::DARK_COLOUR : font::YELLOW_COLOUR;
|
||||
|
||||
const SDL_Rect& rect = map_area();
|
||||
static std::string str(1,'x');
|
||||
str[0] = '0' + route_.move_left + 1;
|
||||
const SDL_Rect& text_area =
|
||||
font::draw_text(NULL,rect,18,font::BUTTON_COLOUR,str,0,0);
|
||||
font::draw_text(NULL,rect,18,text_colour,str,0,0);
|
||||
const int x = xloc + int(zoom_/2.0) - text_area.w/2;
|
||||
const int y = yloc + int(zoom_/2.0) - text_area.h/2;
|
||||
font::draw_text(this,rect,18,font::BUTTON_COLOUR,str,x,y);
|
||||
font::draw_text(this,rect,18,text_colour,str,x,y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2618,4 +2630,36 @@ size_t display::viewing_team() const
|
|||
size_t display::playing_team() const
|
||||
{
|
||||
return activeTeam_;
|
||||
}
|
||||
}
|
||||
|
||||
const theme& display::get_theme() const
|
||||
{
|
||||
return theme_;
|
||||
}
|
||||
|
||||
const theme::menu* display::menu_pressed(int mousex, int mousey, bool button_pressed)
|
||||
{
|
||||
|
||||
for(std::vector<gui::button>::iterator i = buttons_.begin(); i != buttons_.end(); ++i) {
|
||||
if(i->process(mousex,mousey,button_pressed)) {
|
||||
const size_t index = i - buttons_.begin();
|
||||
assert(index < theme_.menus().size());
|
||||
return &theme_.menus()[index];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void display::create_buttons()
|
||||
{
|
||||
buttons_.clear();
|
||||
|
||||
const std::vector<theme::menu>& buttons = theme_.menus();
|
||||
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);
|
||||
buttons_.push_back(b);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "theme.hpp"
|
||||
#include "unit.hpp"
|
||||
#include "video.hpp"
|
||||
#include "widgets/button.hpp"
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
|
@ -261,6 +262,10 @@ public:
|
|||
size_t viewing_team() const;
|
||||
size_t playing_team() const;
|
||||
|
||||
const theme& get_theme() const;
|
||||
|
||||
const theme::menu* menu_pressed(int mousex, int mousey, bool button_pressed);
|
||||
|
||||
private:
|
||||
display(const display&);
|
||||
void operator=(const display&);
|
||||
|
@ -382,6 +387,9 @@ private:
|
|||
|
||||
theme theme_;
|
||||
|
||||
void create_buttons();
|
||||
std::vector<gui::button> buttons_;
|
||||
|
||||
//for debug mode
|
||||
static std::map<gamemap::location,double> debugHighlights_;
|
||||
};
|
||||
|
|
|
@ -110,6 +110,8 @@ const SDL_Color NORMAL_COLOUR = {0xDD,0xDD,0xDD,0},
|
|||
GOOD_COLOUR = {0x00,0xFF,0x00,0},
|
||||
BAD_COLOUR = {0xFF,0x00,0x00,0},
|
||||
BLACK_COLOUR = {0x00,0x00,0x00,0},
|
||||
DARK_COLOUR = {0x00,0x00,0x66,0},
|
||||
YELLOW_COLOUR = {0xFF,0xFF,0x00,0},
|
||||
BUTTON_COLOUR = {0xFF,0xFF,0x00,0};
|
||||
|
||||
const SDL_Color& get_side_colour(int side)
|
||||
|
|
|
@ -34,7 +34,7 @@ const SDL_Color& get_side_colour(int side);
|
|||
|
||||
//various standard colours
|
||||
extern const SDL_Color NORMAL_COLOUR, GOOD_COLOUR, BAD_COLOUR, BLACK_COLOUR,
|
||||
BUTTON_COLOUR;
|
||||
DARK_COLOUR, YELLOW_COLOUR, BUTTON_COLOUR;
|
||||
|
||||
enum MARKUP { USE_MARKUP, NO_MARKUP };
|
||||
|
||||
|
|
|
@ -57,6 +57,12 @@ HOTKEY_COMMAND string_to_command(const std::string& str)
|
|||
m.insert(val("togglegrid",HOTKEY_TOGGLE_GRID));
|
||||
m.insert(val("statustable",HOTKEY_STATUS_TABLE));
|
||||
m.insert(val("mute",HOTKEY_MUTE));
|
||||
m.insert(val("speak",HOTKEY_SPEAK));
|
||||
m.insert(val("createunit",HOTKEY_CREATE_UNIT));
|
||||
m.insert(val("preferences",HOTKEY_PREFERENCES));
|
||||
m.insert(val("objectives",HOTKEY_OBJECTIVES));
|
||||
m.insert(val("unitlist",HOTKEY_UNIT_LIST));
|
||||
m.insert(val("quit",HOTKEY_QUIT_GAME));
|
||||
}
|
||||
|
||||
const std::map<std::string,HOTKEY_COMMAND>::const_iterator i = m.find(str);
|
||||
|
@ -68,10 +74,12 @@ HOTKEY_COMMAND string_to_command(const std::string& str)
|
|||
|
||||
std::string command_to_string(const HOTKEY_COMMAND &command)
|
||||
{
|
||||
for(std::map<std::string,HOTKEY_COMMAND>::iterator i = m.begin();
|
||||
i!=m.end();i++)
|
||||
if (i!=m.end())
|
||||
if (i->second == command) return i->first;
|
||||
for(std::map<std::string,HOTKEY_COMMAND>::iterator i = m.begin(); i != m.end(); ++i) {
|
||||
if(i->second == command) {
|
||||
return i->first;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "\n command_to_string: No matching command found...";
|
||||
return "";
|
||||
}
|
||||
|
@ -210,11 +218,8 @@ std::string get_hotkey_name(hotkey_item i)
|
|||
return str.str();
|
||||
}
|
||||
|
||||
void key_event(display& disp, const SDL_KeyboardEvent& event,
|
||||
command_executor* executor)
|
||||
void key_event(display& disp, const SDL_KeyboardEvent& event, command_executor* executor)
|
||||
{
|
||||
const double zoom_amount = 5.0;
|
||||
|
||||
if(event.keysym.sym == SDLK_ESCAPE) {
|
||||
const int res = gui::show_dialog(disp,NULL,"",
|
||||
string_table["quit_message"],gui::YES_NO);
|
||||
|
@ -225,13 +230,22 @@ void key_event(display& disp, const SDL_KeyboardEvent& event,
|
|||
}
|
||||
}
|
||||
|
||||
const std::vector<hotkey_item>::iterator i =
|
||||
std::find_if(hotkeys.begin(),hotkeys.end(),hotkey_pressed(event));
|
||||
const std::vector<hotkey_item>::iterator i = std::find_if(hotkeys.begin(),hotkeys.end(),hotkey_pressed(event));
|
||||
|
||||
if(i == hotkeys.end())
|
||||
return;
|
||||
|
||||
switch(i->action) {
|
||||
execute_command(disp,i->action,executor);
|
||||
}
|
||||
|
||||
void execute_command(display& disp, HOTKEY_COMMAND command, command_executor* executor)
|
||||
{
|
||||
const double zoom_amount = 5.0;
|
||||
|
||||
if(executor != NULL && executor->can_execute_command(command) == false)
|
||||
return;
|
||||
|
||||
switch(command) {
|
||||
case HOTKEY_ZOOM_IN:
|
||||
disp.zoom(zoom_amount);
|
||||
break;
|
||||
|
@ -314,6 +328,35 @@ void key_event(display& disp, const SDL_KeyboardEvent& event,
|
|||
if(executor)
|
||||
executor->repeat_recruit();
|
||||
break;
|
||||
case HOTKEY_SPEAK:
|
||||
if(executor)
|
||||
executor->speak();
|
||||
break;
|
||||
case HOTKEY_CREATE_UNIT:
|
||||
if(executor)
|
||||
executor->create_unit();
|
||||
break;
|
||||
case HOTKEY_PREFERENCES:
|
||||
if(executor)
|
||||
executor->preferences();
|
||||
break;
|
||||
case HOTKEY_OBJECTIVES:
|
||||
if(executor)
|
||||
executor->objectives();
|
||||
break;
|
||||
case HOTKEY_UNIT_LIST:
|
||||
if(executor)
|
||||
executor->unit_list();
|
||||
break;
|
||||
case HOTKEY_QUIT_GAME: {
|
||||
const int res = gui::show_dialog(disp,NULL,"",string_table["quit_message"],gui::YES_NO);
|
||||
if(res == 0) {
|
||||
throw end_level_exception(QUIT);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ enum HOTKEY_COMMAND { HOTKEY_CYCLE_UNITS, HOTKEY_END_UNIT_TURN, HOTKEY_LEADER,
|
|||
HOTKEY_UNIT_DESCRIPTION, HOTKEY_RENAME_UNIT, HOTKEY_SAVE_GAME,
|
||||
HOTKEY_RECRUIT, HOTKEY_REPEAT_RECRUIT, HOTKEY_RECALL, HOTKEY_ENDTURN,
|
||||
HOTKEY_TOGGLE_GRID, HOTKEY_STATUS_TABLE, HOTKEY_MUTE,
|
||||
HOTKEY_SPEAK, HOTKEY_CREATE_UNIT, HOTKEY_PREFERENCES,
|
||||
HOTKEY_OBJECTIVES, HOTKEY_UNIT_LIST, HOTKEY_QUIT_GAME,
|
||||
HOTKEY_NULL };
|
||||
|
||||
struct hotkey_item {
|
||||
|
@ -60,12 +62,13 @@ void change_hotkey(hotkey_item& item);
|
|||
void save_hotkeys(config& cfg);
|
||||
|
||||
// return list of current hotkeys
|
||||
std::vector<hotkey_item> &get_hotkeys();
|
||||
std::vector<hotkey_item>& get_hotkeys();
|
||||
|
||||
// Return "name" of hotkey for example :"ctrl+alt+g"
|
||||
std::string get_hotkey_name(hotkey_item item);
|
||||
|
||||
std::string command_to_string(const HOTKEY_COMMAND &command);
|
||||
HOTKEY_COMMAND string_to_command(const std::string& str);
|
||||
|
||||
//abstract base class for objects that implement the ability
|
||||
//to execute hotkey commands.
|
||||
|
@ -88,14 +91,22 @@ public:
|
|||
virtual void recall() = 0;
|
||||
virtual void recruit() = 0;
|
||||
virtual void repeat_recruit() = 0;
|
||||
virtual void speak() = 0;
|
||||
virtual void create_unit() = 0;
|
||||
virtual void preferences() = 0;
|
||||
virtual void objectives() = 0;
|
||||
virtual void unit_list() = 0;
|
||||
|
||||
virtual bool can_execute_command(HOTKEY_COMMAND command) const = 0;
|
||||
};
|
||||
|
||||
//function to be called every time a key event is intercepted. Will
|
||||
//call the relevant function in executor if the keyboard event is
|
||||
//not NULL. Also handles some events in the function itself, and so
|
||||
//is still meaningful to call with executor=NULL
|
||||
void key_event(display& disp, const SDL_KeyboardEvent& event,
|
||||
command_executor* executor);
|
||||
void key_event(display& disp, const SDL_KeyboardEvent& event, command_executor* executor);
|
||||
|
||||
void execute_command(display& disp, HOTKEY_COMMAND command, command_executor* executor);
|
||||
|
||||
//object which will ensure that basic keyboard events like escape
|
||||
//are handled properly for the duration of its lifetime
|
||||
|
|
353
src/playturn.cpp
353
src/playturn.cpp
|
@ -151,6 +151,11 @@ void turn_info::turn_slice()
|
|||
|
||||
const int scroll_threshold = 5;
|
||||
|
||||
const theme::menu* const m = gui_.menu_pressed(mousex,mousey,mouse_flags&SDL_BUTTON_LMASK);
|
||||
if(m != NULL) {
|
||||
show_menu(m->items());
|
||||
}
|
||||
|
||||
if(key_[SDLK_UP] || mousey < scroll_threshold)
|
||||
gui_.scroll(0.0,-preferences::scroll_speed());
|
||||
|
||||
|
@ -316,7 +321,13 @@ void turn_info::mouse_press(const SDL_MouseButtonEvent& event)
|
|||
current_route_.steps.clear();
|
||||
gui_.set_route(NULL);
|
||||
} else {
|
||||
show_menu();
|
||||
const theme::menu* const m = gui_.get_theme().context_menu();
|
||||
if(m != NULL) {
|
||||
std::cerr << "found context menu\n";
|
||||
show_menu(m->items());
|
||||
} else {
|
||||
std::cerr << "no context menu found...\n";
|
||||
}
|
||||
}
|
||||
} else if(event.button == SDL_BUTTON_MIDDLE && event.state == SDL_PRESSED) {
|
||||
const SDL_Rect& rect = gui_.map_area();
|
||||
|
@ -593,154 +604,94 @@ void turn_info::show_attack_options(unit_map::const_iterator u)
|
|||
}
|
||||
}
|
||||
|
||||
void turn_info::show_menu()
|
||||
bool turn_info::can_execute_command(hotkey::HOTKEY_COMMAND command) const
|
||||
{
|
||||
const unit_map::const_iterator un = units_.find(last_hex_);
|
||||
switch(command) {
|
||||
|
||||
//commands we can always do
|
||||
case hotkey::HOTKEY_LEADER:
|
||||
case hotkey::HOTKEY_CYCLE_UNITS:
|
||||
case hotkey::HOTKEY_ZOOM_IN:
|
||||
case hotkey::HOTKEY_ZOOM_OUT:
|
||||
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:
|
||||
case hotkey::HOTKEY_SPEAK:
|
||||
case hotkey::HOTKEY_PREFERENCES:
|
||||
case hotkey::HOTKEY_OBJECTIVES:
|
||||
case hotkey::HOTKEY_UNIT_LIST:
|
||||
return true;
|
||||
|
||||
case hotkey::HOTKEY_REDO:
|
||||
return !browse_ && !redo_stack_.empty();
|
||||
case hotkey::HOTKEY_UNDO:
|
||||
return !browse_ && !undo_stack_.empty();
|
||||
|
||||
//commands we can only do if we are actually playing, not just viewing
|
||||
case hotkey::HOTKEY_END_UNIT_TURN:
|
||||
case hotkey::HOTKEY_RECRUIT:
|
||||
case hotkey::HOTKEY_REPEAT_RECRUIT:
|
||||
case hotkey::HOTKEY_RECALL:
|
||||
case hotkey::HOTKEY_ENDTURN:
|
||||
return !browse_;
|
||||
|
||||
//commands we can only do if there is an active unit
|
||||
case hotkey::HOTKEY_TERRAIN_TABLE:
|
||||
case hotkey::HOTKEY_ATTACK_RESISTANCE:
|
||||
case hotkey::HOTKEY_UNIT_DESCRIPTION:
|
||||
case hotkey::HOTKEY_RENAME_UNIT:
|
||||
return current_unit() != units_.end();
|
||||
|
||||
//commands we can only do if in debug mode
|
||||
case hotkey::HOTKEY_CREATE_UNIT:
|
||||
return game_config::debug;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct cannot_execute {
|
||||
cannot_execute(const turn_info& info) : info_(info) {}
|
||||
bool operator()(const std::string& str) const {
|
||||
return !info_.can_execute_command(hotkey::string_to_command(str));
|
||||
}
|
||||
private:
|
||||
const turn_info& info_;
|
||||
};
|
||||
}
|
||||
|
||||
void turn_info::show_menu(const std::vector<std::string>& items_arg)
|
||||
{
|
||||
std::vector<std::string> items = items_arg;
|
||||
items.erase(std::remove_if(items.begin(),items.end(),cannot_execute(*this)),items.end());
|
||||
if(items.empty())
|
||||
return;
|
||||
|
||||
//if just one item is passed in, that means we should execute that item
|
||||
if(items.size() == 1 && items_arg.size() == 1) {
|
||||
hotkey::execute_command(gui_,hotkey::string_to_command(items.front()),this);
|
||||
return;
|
||||
}
|
||||
|
||||
static const std::string menu_items[] =
|
||||
{"scenario_objectives","recruit",
|
||||
"recall","unit_list","status_table",
|
||||
"save_game","preferences","end_turn",""};
|
||||
static const std::string browse_menu_items[] =
|
||||
{"scenario_objectives",
|
||||
"status_table","save_game","preferences",
|
||||
""};
|
||||
std::vector<std::string> menu;
|
||||
|
||||
const std::string* items = browse_ ? browse_menu_items : menu_items;
|
||||
for(; items->empty() == false; ++items) {
|
||||
menu.push_back(string_table[*items]);
|
||||
for(std::vector<std::string>::const_iterator i = items.begin(); i != items.end(); ++i) {
|
||||
menu.push_back(translate_string("action_" + *i));
|
||||
}
|
||||
|
||||
static const std::string create_unit_debug = "Create Unit (debug)";
|
||||
if(game_config::debug && map_.on_board(last_hex_)) {
|
||||
menu.push_back(create_unit_debug);
|
||||
}
|
||||
|
||||
const unit_map::iterator leader = find_leader(units_,gui_.viewing_team()+1);
|
||||
if(network::nconnections() > 0 && leader != units_.end()) {
|
||||
menu.push_back(string_table["speak"]);
|
||||
}
|
||||
|
||||
if(un != units_.end()) {
|
||||
menu.push_back(string_table["describe_unit"]);
|
||||
|
||||
//if the unit is on our side, we can rename it
|
||||
if(un->second.side() == gui_.viewing_team()+1)
|
||||
menu.push_back(string_table["rename_unit"]);
|
||||
}
|
||||
|
||||
const int res = gui::show_dialog(gui_,NULL,"",
|
||||
string_table["options"]+":\n",
|
||||
const int res = gui::show_dialog(gui_,NULL,"",string_table["options"]+":\n",
|
||||
gui::MESSAGE,&menu);
|
||||
if(res == -1)
|
||||
return;
|
||||
|
||||
const std::string result = res != -1 ? menu[res] : "";
|
||||
|
||||
if(un != units_.end()) {
|
||||
menu.pop_back();
|
||||
}
|
||||
|
||||
if(result == string_table["speak"]) {
|
||||
std::string message;
|
||||
const int res = gui::show_dialog(gui_,NULL,"",string_table["speak"],gui::OK_CANCEL,NULL,NULL,
|
||||
string_table["message"] + ":", &message);
|
||||
if(res == 0) {
|
||||
config cfg;
|
||||
cfg["description"] = leader->second.description();
|
||||
cfg["message"] = message;
|
||||
char buf[50];
|
||||
sprintf(buf,"%d",leader->second.side());
|
||||
cfg["side"] = buf;
|
||||
|
||||
recorder.speak(cfg);
|
||||
dialogs::unit_speak(cfg,gui_,units_);
|
||||
|
||||
//speaking is an unretractable operation
|
||||
undo_stack_.clear();
|
||||
redo_stack_.clear();
|
||||
}
|
||||
} else if(result == create_unit_debug) {
|
||||
std::vector<std::string> options;
|
||||
std::vector<unit> unit_choices;
|
||||
for(game_data::unit_type_map::const_iterator i = gameinfo_.unit_types.begin();
|
||||
i != gameinfo_.unit_types.end(); ++i) {
|
||||
options.push_back(i->first);
|
||||
unit_choices.push_back(unit(&i->second,1,false));
|
||||
}
|
||||
|
||||
const int choice = gui::show_dialog(gui_,NULL,"","Create unit (debug):",
|
||||
gui::OK_CANCEL,&options,&unit_choices);
|
||||
if(choice >= 0 && choice < unit_choices.size()) {
|
||||
units_.erase(last_hex_);
|
||||
units_.insert(std::pair<gamemap::location,unit>(last_hex_,unit_choices[choice]));
|
||||
gui_.invalidate(last_hex_);
|
||||
gui_.invalidate_unit();
|
||||
}
|
||||
} else if(result == string_table["describe_unit"]) {
|
||||
unit_description();
|
||||
} else if(result == string_table["rename_unit"]) {
|
||||
rename_unit();
|
||||
} else if(result == string_table["preferences"]) {
|
||||
preferences::show_preferences_dialog(gui_);
|
||||
gui_.redraw_everything();
|
||||
} else if(result == string_table["end_turn"]) {
|
||||
end_turn();
|
||||
} else if(result == string_table["scenario_objectives"]) {
|
||||
dialogs::show_objectives(gui_,*level_);
|
||||
} else if(result == string_table["recall"]) {
|
||||
recall();
|
||||
} else if(result == string_table["recruit"]) {
|
||||
recruit();
|
||||
} else if(result == string_table["status_table"]) {
|
||||
status_table();
|
||||
} else if(result == string_table["unit_list"]) {
|
||||
const std::string heading = string_table["type"] + "," +
|
||||
string_table["name"] + "," +
|
||||
string_table["hp"] + "," +
|
||||
string_table["xp"] + "," +
|
||||
string_table["moves"] + "," +
|
||||
string_table["location"];
|
||||
|
||||
std::vector<std::string> items;
|
||||
items.push_back(heading);
|
||||
|
||||
std::vector<unit> units_list;
|
||||
for(unit_map::const_iterator i = units_.begin();
|
||||
i != units_.end(); ++i) {
|
||||
if(i->second.side() != team_num_)
|
||||
continue;
|
||||
|
||||
std::stringstream row;
|
||||
row << i->second.type().language_name() << ","
|
||||
<< i->second.description() << ","
|
||||
<< i->second.hitpoints()
|
||||
<< "/" << i->second.max_hitpoints() << ","
|
||||
<< i->second.experience() << "/";
|
||||
|
||||
if(i->second.type().advances_to().empty())
|
||||
row << "-";
|
||||
else
|
||||
row << i->second.max_experience();
|
||||
|
||||
row << ","
|
||||
<< i->second.movement_left() << "/"
|
||||
<< i->second.total_movement() << ","
|
||||
<< (i->first.x+1) << "-" << (i->first.y+1);
|
||||
|
||||
items.push_back(row.str());
|
||||
|
||||
//extra unit for the first row to make up the heading
|
||||
if(units_list.empty())
|
||||
units_list.push_back(i->second);
|
||||
|
||||
units_list.push_back(i->second);
|
||||
}
|
||||
|
||||
gui::show_dialog(gui_,NULL,string_table["unit_list"],"",
|
||||
gui::OK_ONLY,&items,&units_list);
|
||||
} else if(result == string_table["save_game"]) {
|
||||
save_game();
|
||||
}
|
||||
const hotkey::HOTKEY_COMMAND cmd = hotkey::string_to_command(items[res]);
|
||||
hotkey::execute_command(gui_,cmd,this);
|
||||
}
|
||||
|
||||
void turn_info::cycle_units()
|
||||
|
@ -1010,8 +961,9 @@ void turn_info::attack_resistance()
|
|||
void turn_info::unit_description()
|
||||
{
|
||||
const unit_map::const_iterator un = current_unit();
|
||||
if(un == units_.end())
|
||||
if(un == units_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string description = un->second.type().unit_description()
|
||||
+ "\n\n" + string_table["see_also"];
|
||||
|
@ -1330,6 +1282,111 @@ void turn_info::recall()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void turn_info::speak()
|
||||
{
|
||||
const unit_map::const_iterator leader = find_leader(units_,gui_.viewing_team()+1);
|
||||
if(leader == units_.end())
|
||||
return;
|
||||
|
||||
std::string message;
|
||||
const int res = gui::show_dialog(gui_,NULL,"",string_table["speak"],gui::OK_CANCEL,NULL,NULL,
|
||||
string_table["message"] + ":", &message);
|
||||
if(res == 0) {
|
||||
config cfg;
|
||||
cfg["description"] = leader->second.description();
|
||||
cfg["message"] = message;
|
||||
char buf[50];
|
||||
sprintf(buf,"%d",leader->second.side());
|
||||
cfg["side"] = buf;
|
||||
|
||||
recorder.speak(cfg);
|
||||
dialogs::unit_speak(cfg,gui_,units_);
|
||||
|
||||
//speaking is an unretractable operation
|
||||
undo_stack_.clear();
|
||||
redo_stack_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void turn_info::create_unit()
|
||||
{
|
||||
std::vector<std::string> options;
|
||||
std::vector<unit> unit_choices;
|
||||
for(game_data::unit_type_map::const_iterator i = gameinfo_.unit_types.begin();
|
||||
i != gameinfo_.unit_types.end(); ++i) {
|
||||
options.push_back(i->first);
|
||||
unit_choices.push_back(unit(&i->second,1,false));
|
||||
}
|
||||
|
||||
const int choice = gui::show_dialog(gui_,NULL,"","Create unit (debug):",
|
||||
gui::OK_CANCEL,&options,&unit_choices);
|
||||
if(choice >= 0 && choice < unit_choices.size()) {
|
||||
units_.erase(last_hex_);
|
||||
units_.insert(std::pair<gamemap::location,unit>(last_hex_,unit_choices[choice]));
|
||||
gui_.invalidate(last_hex_);
|
||||
gui_.invalidate_unit();
|
||||
}
|
||||
}
|
||||
|
||||
void turn_info::preferences()
|
||||
{
|
||||
preferences::show_preferences_dialog(gui_);
|
||||
gui_.redraw_everything();
|
||||
}
|
||||
|
||||
void turn_info::objectives()
|
||||
{
|
||||
dialogs::show_objectives(gui_,*level_);
|
||||
}
|
||||
|
||||
void turn_info::unit_list()
|
||||
{
|
||||
const std::string heading = string_table["type"] + "," +
|
||||
string_table["name"] + "," +
|
||||
string_table["hp"] + "," +
|
||||
string_table["xp"] + "," +
|
||||
string_table["moves"] + "," +
|
||||
string_table["location"];
|
||||
|
||||
std::vector<std::string> items;
|
||||
items.push_back(heading);
|
||||
|
||||
std::vector<unit> units_list;
|
||||
for(unit_map::const_iterator i = units_.begin(); i != units_.end(); ++i) {
|
||||
if(i->second.side() != team_num_)
|
||||
continue;
|
||||
|
||||
std::stringstream row;
|
||||
row << i->second.type().language_name() << ","
|
||||
<< i->second.description() << ","
|
||||
<< i->second.hitpoints()
|
||||
<< "/" << i->second.max_hitpoints() << ","
|
||||
<< i->second.experience() << "/";
|
||||
|
||||
if(i->second.type().advances_to().empty())
|
||||
row << "-";
|
||||
else
|
||||
row << i->second.max_experience();
|
||||
|
||||
row << ","
|
||||
<< i->second.movement_left() << "/"
|
||||
<< i->second.total_movement() << ","
|
||||
<< (i->first.x+1) << "-" << (i->first.y+1);
|
||||
|
||||
items.push_back(row.str());
|
||||
|
||||
//extra unit for the first row to make up the heading
|
||||
if(units_list.empty())
|
||||
units_list.push_back(i->second);
|
||||
|
||||
units_list.push_back(i->second);
|
||||
}
|
||||
|
||||
gui::show_dialog(gui_,NULL,string_table["unit_list"],"",
|
||||
gui::OK_ONLY,&items,&units_list);
|
||||
}
|
||||
|
||||
unit_map::iterator turn_info::current_unit()
|
||||
{
|
||||
unit_map::iterator i = units_.find(last_hex_);
|
||||
|
@ -1339,3 +1396,13 @@ unit_map::iterator turn_info::current_unit()
|
|||
|
||||
return i;
|
||||
}
|
||||
|
||||
unit_map::const_iterator turn_info::current_unit() const
|
||||
{
|
||||
unit_map::const_iterator i = units_.find(last_hex_);
|
||||
if(i == units_.end()) {
|
||||
i = units_.find(selected_hex_);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
|
||||
undo_list& undos() { return undo_stack_; }
|
||||
|
||||
bool can_execute_command(hotkey::HOTKEY_COMMAND command) const;
|
||||
|
||||
private:
|
||||
|
||||
void write_game_snapshot(config& cfg) const;
|
||||
|
@ -89,6 +91,11 @@ private:
|
|||
void recruit();
|
||||
void repeat_recruit();
|
||||
void recall();
|
||||
void speak();
|
||||
void create_unit();
|
||||
void preferences();
|
||||
void objectives();
|
||||
void unit_list();
|
||||
|
||||
void do_recruit(const std::string& name);
|
||||
|
||||
|
@ -97,11 +104,12 @@ private:
|
|||
void mouse_press(const SDL_MouseButtonEvent& event);
|
||||
|
||||
void left_click(const SDL_MouseButtonEvent& event);
|
||||
void show_menu();
|
||||
void show_menu(const std::vector<std::string>& items);
|
||||
|
||||
void show_attack_options(unit_map::const_iterator u);
|
||||
|
||||
unit_map::iterator current_unit();
|
||||
unit_map::const_iterator current_unit() const;
|
||||
|
||||
game_data& gameinfo_;
|
||||
game_state& state_of_game_;
|
||||
|
|
|
@ -645,8 +645,7 @@ void show_hotkeys_dialog (display & disp)
|
|||
|
||||
std::vector < hotkey::hotkey_item > hotkeys =
|
||||
hotkey::get_hotkeys ();
|
||||
for (std::vector < hotkey::hotkey_item >::iterator i =
|
||||
hotkeys.begin (); i != hotkeys.end (); i++)
|
||||
for (std::vector<hotkey::hotkey_item>::iterator i = hotkeys.begin(); i != hotkeys.end(); ++i)
|
||||
{
|
||||
std::stringstream str,name;
|
||||
name << "action_"<< hotkey::command_to_string(i->action);
|
||||
|
|
|
@ -45,6 +45,7 @@ terrain_type::terrain_type(const config& cfg)
|
|||
submerge_ = atof(cfg["submerge"].c_str());
|
||||
|
||||
equal_precedence_ = cfg["no_overlay"] == "true";
|
||||
is_light_ = cfg["light"] == "true";
|
||||
}
|
||||
|
||||
const std::string& terrain_type::image(int x, int y) const
|
||||
|
@ -85,6 +86,11 @@ pixel_data terrain_type::get_rgb() const
|
|||
return colour_;
|
||||
}
|
||||
|
||||
bool terrain_type::is_light() const
|
||||
{
|
||||
return is_light_;
|
||||
}
|
||||
|
||||
bool terrain_type::is_alias() const
|
||||
{
|
||||
return type_ != letter_;
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
|
||||
pixel_data get_rgb() const;
|
||||
|
||||
bool is_light() const;
|
||||
bool is_alias() const;
|
||||
|
||||
int unit_height_adjust() const;
|
||||
|
@ -59,6 +60,7 @@ private:
|
|||
double submerge_;
|
||||
|
||||
bool equal_precedence_;
|
||||
bool is_light_;
|
||||
};
|
||||
|
||||
void create_terrain_maps(const std::vector<config*>& cfgs,
|
||||
|
|
|
@ -194,6 +194,23 @@ const std::string& theme::panel::image() const
|
|||
return image_;
|
||||
}
|
||||
|
||||
theme::menu::menu() : context_(false)
|
||||
{}
|
||||
|
||||
theme::menu::menu(const config& cfg) : object(cfg), context_(cfg["is_context_menu"] == "true"),
|
||||
title_(translate_string(cfg["title"]) + cfg["title_literal"]),
|
||||
image_(cfg["image"]),
|
||||
items_(config::split(cfg["items"]))
|
||||
{}
|
||||
|
||||
bool theme::menu::is_context() const { return context_; }
|
||||
|
||||
const std::string& theme::menu::title() const { return title_; }
|
||||
|
||||
const std::string& theme::menu::image() const { return image_; }
|
||||
|
||||
const std::vector<std::string>& theme::menu::items() const { return items_; }
|
||||
|
||||
theme::theme(const config& cfg, const SDL_Rect& screen) : cfg_(cfg)
|
||||
{
|
||||
set_resolution(screen);
|
||||
|
@ -261,6 +278,16 @@ bool theme::set_resolution(const SDL_Rect& screen)
|
|||
labels_.push_back(label(**lb));
|
||||
}
|
||||
|
||||
const config::child_list& menu_list = cfg.get_children("menu");
|
||||
for(config::child_list::const_iterator m = menu_list.begin(); m != menu_list.end(); ++m) {
|
||||
const menu new_menu(**m);
|
||||
std::cerr << "adding menu: " << (new_menu.is_context() ? "is context" : "not context") << "\n";
|
||||
if(new_menu.is_context())
|
||||
context_ = new_menu;
|
||||
else
|
||||
menus_.push_back(new_menu);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -274,6 +301,16 @@ const std::vector<theme::label>& theme::labels() const
|
|||
return labels_;
|
||||
}
|
||||
|
||||
const std::vector<theme::menu>& theme::menus() const
|
||||
{
|
||||
return menus_;
|
||||
}
|
||||
|
||||
const theme::menu* theme::context_menu() const
|
||||
{
|
||||
return context_.is_context() ? &context_ : NULL;
|
||||
}
|
||||
|
||||
const theme::status_item* theme::get_status_item(const std::string& key) const
|
||||
{
|
||||
const std::map<std::string,status_item>::const_iterator i = status_.find(key);
|
||||
|
|
|
@ -103,11 +103,35 @@ public:
|
|||
std::string image_;
|
||||
};
|
||||
|
||||
class menu : private object
|
||||
{
|
||||
public:
|
||||
menu();
|
||||
explicit menu(const config& cfg);
|
||||
|
||||
using object::location;
|
||||
|
||||
bool is_context() const;
|
||||
|
||||
const std::string& title() const;
|
||||
|
||||
const std::string& image() const;
|
||||
|
||||
const std::vector<std::string>& items() const;
|
||||
private:
|
||||
bool context_;
|
||||
std::string title_, image_;
|
||||
std::vector<std::string> items_;
|
||||
};
|
||||
|
||||
explicit theme(const config& cfg, const SDL_Rect& screen);
|
||||
bool set_resolution(const SDL_Rect& screen);
|
||||
|
||||
const std::vector<panel>& panels() const;
|
||||
const std::vector<label>& labels() const;
|
||||
const std::vector<menu>& menus() const;
|
||||
|
||||
const menu* context_menu() const;
|
||||
|
||||
const status_item* get_status_item(const std::string& item) const;
|
||||
|
||||
|
@ -118,6 +142,9 @@ private:
|
|||
const config& cfg_;
|
||||
std::vector<panel> panels_;
|
||||
std::vector<label> labels_;
|
||||
std::vector<menu> menus_;
|
||||
|
||||
menu context_;
|
||||
|
||||
std::map<std::string,status_item> status_;
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
|
||||
#include "button.hpp"
|
||||
#include "../display.hpp"
|
||||
#include "../game.hpp"
|
||||
#include "../font.hpp"
|
||||
#include "../image.hpp"
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
|
||||
#include "SDL.h"
|
||||
|
||||
#include "../display.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class display;
|
||||
|
||||
namespace gui {
|
||||
|
||||
class button
|
||||
|
|
Loading…
Add table
Reference in a new issue