Support for team only labels

This commit is contained in:
Pauli Nieminen 2007-01-01 10:32:00 +00:00
parent 8f19f11986
commit b58a67c38b
24 changed files with 724 additions and 137 deletions

View file

@ -81,6 +81,11 @@
key=" "
shift=yes
[/hotkey]
[hotkey]
command=labelteamterrain
key=l
shift=yes
[/hotkey]
[hotkey]
command=labelterrain
key=l
@ -304,6 +309,11 @@
key=" "
shift=yes
[/hotkey]
[hotkey]
command=labelteamterrain
key=l
shift=yes
[/hotkey]
[hotkey]
command=labelterrain
key=l

View file

@ -98,7 +98,7 @@ height=768
[menu]
is_context_menu=true
items=undo,redo,describeunit,renameunit,createunit,changeside,labelterrain,clearlabels,speak,continue,recruit,recall,delayshroud,updateshroud,cycle,endturn
items=undo,redo,describeunit,renameunit,createunit,changeside,labelteamterrain,labelterrain,clearlabels,speak,continue,recruit,recall,delayshroud,updateshroud,cycle,endturn
[/menu]
[mini_map]
id=mini-map

View file

@ -119,7 +119,7 @@ height=768
[menu]
is_context_menu=true
items=undo,redo,describeunit,renameunit,createunit,changeside,labelterrain,clearlabels,speak,continue,recruit,recall,delayshroud,updateshroud,cycle,endturn
items=undo,redo,describeunit,renameunit,createunit,changeside,labelteamterrain,labelterrain,clearlabels,speak,continue,recruit,recall,delayshroud,updateshroud,cycle,endturn
[/menu]
[menu]

View file

@ -89,7 +89,7 @@ height=768
[menu]
is_context_menu=true
items=undo,redo,describeunit,renameunit,createunit,changeside,labelterrain,clearlables,speak,continue,recruit,recall,delayshroud,updateshroud,cycle,endturn
items=undo,redo,describeunit,renameunit,createunit,changeside,labelteamterrain,labelterrain,clearlabels,speak,continue,recruit,recall,delayshroud,updateshroud,cycle,endturn
[/menu]
[mini_map]
id=mini-map

View file

@ -87,7 +87,7 @@ display::display(unit_map& units, CVideo& video, const gamemap& map,
currentTeam_(0), activeTeam_(0),
turbo_speed_(1), turbo_(false), grid_(false), sidebarScaling_(1.0),
theme_(theme_cfg,screen_area()), builder_(cfg, level, map),
first_turn_(true), in_game_(false), map_labels_(*this,map),
first_turn_(true), in_game_(false), map_labels_(*this,map, 0),
tod_hex_mask1(NULL), tod_hex_mask2(NULL),
diagnostic_label_(0), fps_handle_(0)
{
@ -2165,12 +2165,28 @@ void display::write_overlays(config& cfg) const
}
}
const std::string display::current_team_name() const
{
if (team_valid())
{
return teams_[currentTeam_].team_name();
}
return std::string();
}
void display::set_team(size_t team)
{
wassert(team < teams_.size());
currentTeam_ = team;
labels().recalculate_shroud();
if (!is_observer())
{
labels().set_team(&teams_[team]);
}
else
{
labels().set_team(0);
}
labels().recalculate_labels();
}
void display::set_playing_team(size_t team)

View file

@ -325,7 +325,8 @@ public:
size_t viewing_team() const;
size_t playing_team() const;
bool team_valid() const;
const std::string current_team_name() const;
theme& get_theme();
const theme::menu* menu_pressed();

View file

@ -84,7 +84,7 @@ void scenario_editor::unit_list()
{
}
void scenario_editor::label_terrain()
void scenario_editor::label_terrain(bool team_only)
{
}

View file

@ -49,7 +49,7 @@ private:
void preferences();
void objectives();
void unit_list();
void label_terrain();
void label_terrain(bool);
void edit_set_terrain();

View file

@ -330,7 +330,8 @@ const SDL_Color NORMAL_COLOUR = {0xDD,0xDD,0xDD,0},
YELLOW_COLOUR = {0xFF,0xFF,0x00,0},
BUTTON_COLOUR = {0xBC,0xB0,0x88,0},
STONED_COLOUR = {0xA0,0xA0,0xA0,0},
TITLE_COLOUR = {0xBC,0xB0,0x88,0};
TITLE_COLOUR = {0xBC,0xB0,0x88,0},
LABEL_COLOUR = {0x6B,0x8C,0xFF,0};
const SDL_Color DISABLED_COLOUR = inverse(STONED_COLOUR);
namespace {

View file

@ -46,7 +46,7 @@ void set_font_list(const std::vector<subset_descriptor>& fontlist);
//various standard colours
extern const SDL_Color NORMAL_COLOUR, GRAY_COLOUR, LOBBY_COLOUR, GOOD_COLOUR, BAD_COLOUR,
BLACK_COLOUR, DARK_COLOUR, YELLOW_COLOUR, BUTTON_COLOUR,
STONED_COLOUR, TITLE_COLOUR, DISABLED_COLOUR;
STONED_COLOUR, TITLE_COLOUR, DISABLED_COLOUR, LABEL_COLOUR;
// font sizes, to be made theme parameters
#ifdef USE_TINY_GUI

View file

@ -98,6 +98,11 @@ message_dialog::~message_dialog()
namespace game_events {
game_state* get_state_of_game()
{
return ::state_of_game;
}
bool conditional_passed(const unit_map* units,
const vconfig cond)
{
@ -1661,6 +1666,7 @@ bool event_handler::handle_event_command(const queued_event& event_info,
}
//unit serialization to and from variables
// FIXME: Check that store is automove bug safe
else if(cmd == "store_unit") {
const config empty_filter;
vconfig filter = cfg.child("filter");
@ -1942,10 +1948,14 @@ bool event_handler::handle_event_command(const queued_event& event_info,
events::pump();
}
} else if(cmd == "label") {
const gamemap::location loc(cfg);
const std::string& text = utils::interpolate_variables_into_string(
cfg.get_attribute("text"), *state_of_game);
screen->labels().set_label(loc,text);
terrain_label label(screen->labels(),cfg.get_config());
screen->labels().set_label(label.location(),
label.text(),
0,
label.team_name(),
label.colour());
}
LOG_NG << "done handling command...\n";

View file

@ -55,6 +55,7 @@ struct manager {
variable::manager variable_manager;
};
game_state* get_state_of_game();
void write_events(config& cfg);
void add_events(const config::child_list& cfgs,const std::string& id);

View file

@ -80,6 +80,7 @@ const struct {
{ hotkey::HOTKEY_UNIT_LIST, "unitlist", N_("Unit List"), false },
{ hotkey::HOTKEY_STATISTICS, "statistics", N_("Statistics"), false },
{ hotkey::HOTKEY_QUIT_GAME, "quit", N_("Quit Game"), false },
{ hotkey::HOTKEY_LABEL_TEAM_TERRAIN, "labelteamterrain", N_("Set Team Label"), false },
{ hotkey::HOTKEY_LABEL_TERRAIN, "labelterrain", N_("Set Label"), false },
{ hotkey::HOTKEY_CLEAR_LABELS, "clearlabels", N_("Clear Labels"), false },
{ hotkey::HOTKEY_SHOW_ENEMY_MOVES, "showenemymoves", N_("Show Enemy Moves"), false },
@ -658,9 +659,13 @@ void execute_command(display& disp, HOTKEY_COMMAND command, command_executor* ex
if(executor)
executor->show_statistics();
break;
case HOTKEY_LABEL_TEAM_TERRAIN:
if(executor)
executor->label_terrain(true);
break;
case HOTKEY_LABEL_TERRAIN:
if(executor)
executor->label_terrain();
executor->label_terrain(false);
break;
case HOTKEY_CLEAR_LABELS:
if(executor)

View file

@ -39,7 +39,7 @@ enum HOTKEY_COMMAND {
HOTKEY_TOGGLE_GRID, HOTKEY_STATUS_TABLE, HOTKEY_MUTE, HOTKEY_MOUSE_SCROLL,
HOTKEY_SPEAK, HOTKEY_CREATE_UNIT, HOTKEY_CHANGE_UNIT_SIDE, HOTKEY_PREFERENCES,
HOTKEY_OBJECTIVES, HOTKEY_UNIT_LIST, HOTKEY_STATISTICS, HOTKEY_QUIT_GAME,
HOTKEY_LABEL_TERRAIN, HOTKEY_CLEAR_LABELS,HOTKEY_SHOW_ENEMY_MOVES, HOTKEY_BEST_ENEMY_MOVES,
HOTKEY_LABEL_TEAM_TERRAIN, HOTKEY_LABEL_TERRAIN, HOTKEY_CLEAR_LABELS,HOTKEY_SHOW_ENEMY_MOVES, HOTKEY_BEST_ENEMY_MOVES,
HOTKEY_DELAY_SHROUD, HOTKEY_UPDATE_SHROUD, HOTKEY_CONTINUE_MOVE,
HOTKEY_SEARCH, HOTKEY_SPEAK_ALLY, HOTKEY_SPEAK_ALL, HOTKEY_HELP,
HOTKEY_CHAT_LOG, HOTKEY_LANGUAGE,
@ -175,7 +175,7 @@ public:
virtual void objectives() {}
virtual void unit_list() {}
virtual void show_statistics() {}
virtual void label_terrain() {}
virtual void label_terrain(bool /*team_only*/) {}
virtual void clear_labels() {}
virtual void show_enemy_moves(bool /*ignore_units*/) {}
virtual void toggle_shroud_updates() {}

View file

@ -22,6 +22,7 @@
#include "util.hpp"
#include "variable.hpp"
#include "wassert.hpp"
#include "game_events.hpp"
#include "serialization/string_utils.hpp"
#include <algorithm>
@ -180,13 +181,19 @@ std::string gamemap::location::write_direction(gamemap::location::DIRECTION dir)
void gamemap::location::init(const std::string &xstr, const std::string &ystr)
{
std::string xs = xstr, ys = ystr;
if (game_events::get_state_of_game())
{
xs = utils::interpolate_variables_into_string( xs, *game_events::get_state_of_game());
ys = utils::interpolate_variables_into_string( ys, *game_events::get_state_of_game());
}
//the co-ordinates in config files will be 1-based, while we
//want them as 0-based
if(xstr.empty() == false)
x = atoi(xstr.c_str()) - 1;
if(xs.empty() == false)
x = atoi(xs.c_str()) - 1;
if(ystr.empty() == false)
y = atoi(ystr.c_str()) - 1;
if(ys.empty() == false)
y = atoi(ys.c_str()) - 1;
}
gamemap::location::location(const config& cfg) : x(-1), y(-1)

View file

@ -13,141 +13,524 @@
#include "global.hpp"
#include <vector>
#include "display.hpp"
#include "font.hpp"
#include "language.hpp"
#include "map_label.hpp"
#include "wassert.hpp"
#include "replay.hpp"
#include "game_events.hpp"
namespace {
const size_t max_label_size = 64;
const size_t max_label_size = 64;
//our definition of map labels being obscured is if the tile is obscured,
//or the tile below is obscured. This is because in the case where the tile
//itself is visible, but the tile below is obscured, the bottom half of the
//tile will still be shrouded, and the label being drawn looks weird
bool is_shrouded(const display& disp, const gamemap::location& loc)
bool is_shrouded(const display& disp, const gamemap::location& loc)
{
return disp.shrouded(loc.x,loc.y) || disp.shrouded(loc.x,loc.y+1);
}
}
map_labels::map_labels(const display& disp,
const gamemap& map,
const team* team) :
disp_(disp),
team_(team),
map_(map),
changed_(true)
{
return disp.shrouded(loc.x,loc.y) || disp.shrouded(loc.x,loc.y+1);
}
}
map_labels::map_labels(const display& disp, const gamemap& map) : disp_(disp), map_(map)
{}
map_labels::map_labels(const display& disp, const config& cfg, const gamemap& map) : disp_(disp), map_(map)
map_labels::map_labels(const display& disp,
const config& cfg,
const gamemap& map,
const team* team) :
disp_(disp),
team_(team),
map_(map),
changed_(true)
{
read(cfg);
}
map_labels::~map_labels()
{
clear();
clear_all();
}
void map_labels::write(config& res) const
{
for(label_map::const_iterator i = labels_.begin(); i != labels_.end(); ++i) {
config item;
i->first.write(item);
item.values["text"] = get_label(i->first);
res.add_child("label",item);
for (team_label_map::const_iterator labs = labels_.begin(); labs != labels_.end(); ++labs)
{
for(label_map::const_iterator i = labs->second.begin(); i != labs->second.end(); ++i) {
config item;
i->second->write(item);
res.add_child("label",item);
}
}
}
void map_labels::read(const config& cfg)
{
clear();
clear_all();
const config::child_list& items = cfg.get_children("label");
for(config::child_list::const_iterator i = items.begin(); i != items.end(); ++i) {
const gamemap::location loc(**i);
const std::string& text = (**i)["text"];
set_label(loc,text);
terrain_label* label = new terrain_label(*this, **i);
add_label(loc, label);
}
recalculate_labels();
}
const std::string& map_labels::get_label(int index) const {
return font::get_floating_label_text(index);
}
int map_labels::get_max_chars() {
size_t map_labels::get_max_chars()
{
return max_label_size;
}
const std::string& map_labels::get_label(const gamemap::location& loc) const
const terrain_label* map_labels::get_label(const gamemap::location& loc)
{
const label_map::const_iterator itor = labels_.find(loc);
if(itor != labels_.end()) {
return font::get_floating_label_text(itor->second);
const label_map::const_iterator itor = labels().find(loc);
if(itor != labels().end()) {
return itor->second;
} else {
static const std::string empty_str;
return empty_str;
return 0;
}
}
void map_labels::set_label(const gamemap::location& loc, const std::string& str, const SDL_Color colour)
const map_labels::label_map& map_labels::labels()
{
std::string text = str;
if(text.size() > max_label_size) {
text.resize(max_label_size);
if (changed_)
{
label_cashe_.clear();
team_label_map::iterator i = labels_.find(team_name());
if (i != labels_.end())
{
label_cashe_.insert(i->second.begin(),i->second.end());
}
i = labels_.find(std::string());
if (i != labels_.end())
{
label_cashe_.insert(i->second.begin(),i->second.end());
}
changed_ = false;
}
return label_cashe_;
}
const label_map::iterator current_label = labels_.find(loc);
if(current_label != labels_.end()) {
font::remove_floating_label(current_label->second);
labels_.erase(current_label);
const display& map_labels::disp() const
{
return disp_;
}
const std::string& map_labels::team_name() const
{
if (team_)
{
return team_->team_name();
}
if(text == "") {
return;
}
const gamemap::location loc_nextx(loc.x+1,loc.y);
const gamemap::location loc_nexty(loc.x,loc.y+1);
const int xloc = (disp_.get_location_x(loc) + disp_.get_location_x(loc_nextx)*2)/3;
const int yloc = disp_.get_location_y(loc_nexty) - font::SIZE_NORMAL;
const int handle = font::add_floating_label(text,font::SIZE_NORMAL,colour,xloc,yloc,0,0,-1,disp_.map_area());
labels_.insert(std::pair<gamemap::location,int>(loc,handle));
if(is_shrouded(disp_,loc)) {
font::show_floating_label(handle,false);
static const std::string empty;
return empty;
}
void map_labels::set_team(const team* team)
{
if ( team_ != team )
{
team_ = team;
changed_ = true;
}
}
void map_labels::clear()
{
for(label_map::const_iterator i = labels_.begin(); i != labels_.end(); ++i) {
font::remove_floating_label(i->second);
}
const terrain_label* map_labels::set_label(const gamemap::location& loc,
const std::string& text,
replay* replay,
const std::string team_name,
const SDL_Color colour)
{
terrain_label* res = 0;
const team_label_map::const_iterator current_label_map = labels_.find(team_name);
label_map::const_iterator current_label;
if ( current_label_map != labels_.end()
&& (current_label = current_label_map->second.find(loc)) != current_label_map->second.end() )
{
// Found old checking if need to erase it
if(text.empty())
{
if (replay)
{
const_cast<terrain_label*>(current_label->second)->set_text("");
replay->add_label(current_label->second);
}
delete current_label->second;
const_cast<label_map&>(current_label_map->second).erase(loc);
changed_ = true;
const label_map::const_iterator itor = labels().find(loc);
const bool update = itor != labels().end();
if (update)
{
const_cast<terrain_label*>(itor->second)->recalculate();
}
}
else
{
const_cast<terrain_label*>(current_label->second)->update_info(text,
team_name,
colour);
if (replay)
{
replay->add_label(current_label->second);
}
res = const_cast<terrain_label*>(current_label->second);
}
}
else if(!text.empty())
{
const label_map::const_iterator itor = labels().find(loc);
const bool update = itor != labels().end();
terrain_label* label = new terrain_label(text,
team_name,
loc,
*this,
colour);
add_label(loc,label);
res = label;
if (replay)
{
replay->add_label(label);
}
if (update)
{
const_cast<terrain_label*>(itor->second)->recalculate();
}
}
return res;
}
void map_labels::add_label(const gamemap::location& loc,
const terrain_label* new_label)
{
team_label_map::const_iterator labs = labels_.find(new_label->team_name());
if(labs == labels_.end());
{
labels_.insert(std::pair<std::string,label_map>(new_label->team_name(), label_map()));
labs = labels_.find(new_label->team_name());
wassert(labs != labels_.end());
}
const_cast<label_map&>(labs->second).insert(std::pair<gamemap::location,const terrain_label*>(loc,new_label));
changed_ = true;
}
void map_labels::clear(const std::string& team_name, replay* replay)
{
team_label_map::iterator i = labels_.find(team_name);
if (i != labels_.end())
{
clear_map(i->second);
}
i = labels_.find(std::string());
if (i != labels_.end())
{
clear_map(i->second);
}
if (replay)
{
replay->clear_labels(team_name);
}
changed_ = true;
}
void map_labels::clear_map(const label_map& m)
{
for (label_map::const_iterator j = m.begin(); j != m.end(); ++j)
{
delete j->second;
}
const_cast<label_map&>(m).clear();
}
void map_labels::clear_all()
{
for(team_label_map::const_iterator i = labels_.begin(); i != labels_.end(); ++i)
{
clear_map(i->second);
}
labels_.clear();
changed_ = true;
}
void map_labels::scroll(double xmove, double ymove)
{
for(label_map::const_iterator i = labels_.begin(); i != labels_.end(); ++i) {
font::move_floating_label(i->second,xmove,ymove);
for(label_map::const_iterator i = labels().begin(); i != labels().end(); ++i) {
i->second->scroll(xmove,ymove);
}
}
void map_labels::recalculate_labels()
{
const label_map labels = labels_;
labels_.clear();
for(label_map::const_iterator i = labels.begin(); i != labels.end(); ++i) {
const std::string text = font::get_floating_label_text(i->second);
font::remove_floating_label(i->second);
set_label(i->first,text);
for(team_label_map::const_iterator i = labels_.begin(); i != labels_.end(); ++i)
{
for (label_map::const_iterator j = i->second.begin(); j != i->second.end(); ++j)
{
const_cast<terrain_label*>(j->second)->recalculate();
}
}
}
bool map_labels::visible_global_label(const gamemap::location& loc) const
{
const team_label_map::const_iterator glabels = labels_.find(team_name());
return glabels == labels_.end()
|| glabels->second.find(loc) == glabels->second.end();
}
void map_labels::recalculate_shroud()
{
for(label_map::const_iterator i = labels_.begin(); i != labels_.end(); ++i) {
font::show_floating_label(i->second,!is_shrouded(disp_,i->first));
for(label_map::const_iterator i = labels().begin(); i != labels().end(); ++i) {
i->second->calculate_shroud();
}
}
/// creating new label
terrain_label::terrain_label(const std::string& text,
const std::string& team_name,
const gamemap::location& loc,
const map_labels& parent,
const SDL_Color colour) :
handle_(0),
text_(text),
team_name_(team_name),
colour_(colour),
parent_(&parent),
loc_(loc)
{
check_text_length();
draw();
}
terrain_label::terrain_label(const map_labels& parent) :
handle_(0),
text_(),
team_name_(),
colour_(),
parent_(&parent),
loc_()
{
}
/// Load label from config
terrain_label::terrain_label(const map_labels& parent,
const config& cfg) :
handle_(0),
parent_(&parent)
{
read(cfg);
check_text_length();
}
terrain_label::~terrain_label()
{
clear();
}
void terrain_label::read(const config& cfg)
{
loc_ = gamemap::location(cfg);
SDL_Color colour = font::LABEL_COLOUR;
std::string tmp_colour = cfg["colour"];
text_ = cfg["text"];
team_name_ = cfg["team_name"];
if (game_events::get_state_of_game())
{
text_ = utils::interpolate_variables_into_string(text_,
*game_events::get_state_of_game());
team_name_ = utils::interpolate_variables_into_string(team_name_,
*game_events::get_state_of_game());
tmp_colour = utils::interpolate_variables_into_string(tmp_colour,
*game_events::get_state_of_game());
}
std::vector<std::string> tmp_c = utils::split(tmp_colour,',',
utils::REMOVE_EMPTY);
switch (tmp_c.size())
{
case 4:
colour.unused = lexical_cast_default<unsigned int>(tmp_c[3]);
case 3:
colour.b = lexical_cast_default<unsigned int>(tmp_c[2]);
colour.g = lexical_cast_default<unsigned int>(tmp_c[1]);
colour.r = lexical_cast_default<unsigned int>(tmp_c[0]);
break;
}
colour_ = colour;
}
void terrain_label::write(config& cfg) const
{
loc_.write(cfg);
cfg["text"] = text();
cfg["team_name"] = (this->team_name());
cfg["colour"] = cfg_colour();
}
const std::string& terrain_label::text() const
{
return text_;
}
const std::string& terrain_label::team_name() const
{
return team_name_;
}
void terrain_label::invalidate_handle()
{
handle_ = 0;
}
const gamemap::location& terrain_label::location() const
{
return loc_;
}
const SDL_Colour& terrain_label::colour() const
{
return colour_;
}
const std::string terrain_label::cfg_colour() const
{
std::stringstream buf;
const unsigned int red = static_cast<unsigned int>(colour_.r);
const unsigned int green = static_cast<unsigned int>(colour_.g);
const unsigned int blue = static_cast<unsigned int>(colour_.b);
const unsigned int alpha = static_cast<unsigned int>(colour_.unused);
buf << red << ","
<< green << ","
<< blue << ","
<< alpha;
return buf.str();
}
void terrain_label::set_text(const std::string& text)
{
text_ = text;
}
void terrain_label::update_info(const std::string& text,
const std::string& team_name,
const SDL_Color colour)
{
colour_ = colour;
text_ = text;
check_text_length();
team_name_ = team_name;
draw();
}
void terrain_label::scroll(const double xmove,
const double ymove) const
{
if(handle_)
{
font::move_floating_label(handle_,
xmove,
ymove);
}
}
void terrain_label::recalculate()
{
draw();
}
void terrain_label::calculate_shroud() const
{
if (handle_)
{
font::show_floating_label(handle_,
!is_shrouded(parent_->disp(),
loc_));
}
}
void terrain_label::draw()
{
clear();
if (visible())
{
const gamemap::location loc_nextx(loc_.x+1,loc_.y);
const gamemap::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;
cfg_colour();
handle_ = font::add_floating_label(text_,
font::SIZE_NORMAL,
colour_,
xloc, yloc,
0,0,
-1,
parent_->disp().map_area());
calculate_shroud();
}
}
bool terrain_label::visible() const
{
return parent_->team_name() == team_name_
|| (team_name_.empty() && parent_->visible_global_label(loc_));
}
void terrain_label::check_text_length()
{
if (text_.size() > parent_->get_max_chars())
{
text_.resize(parent_->get_max_chars());
}
}
void terrain_label::clear()
{
if (handle_)
{
font::remove_floating_label(handle_);
handle_ = 0;
}
}

View file

@ -18,39 +18,64 @@ class config;
#include "map.hpp"
#include "font.hpp"
#include <map>
#include <string>
class display;
class team;
class terrain_label;
class replay;
class game_state;
class map_labels
{
public:
map_labels(const display& disp, const gamemap& map);
map_labels(const display& disp, const config& cfg, const gamemap& map);
typedef std::map<gamemap::location,const terrain_label*> label_map;
typedef std::map<std::string,const label_map> team_label_map;
map_labels(const display& disp, const gamemap& map, const team*);
map_labels(const display& disp, const config& cfg, const gamemap& map, const team*);
~map_labels();
void write(config& res) const;
void read(const config& cfg);
static int get_max_chars();
static size_t get_max_chars();
const std::string& get_label(const gamemap::location& loc) const;
void set_label(const gamemap::location& loc, const std::string& text, const SDL_Color colour = font::NORMAL_COLOUR);
void clear();
const terrain_label* get_label(const gamemap::location& loc);
const terrain_label* set_label(const gamemap::location& loc,
const std::string& text,
replay* = 0,
const std::string team = std::string(),
const SDL_Color colour = font::NORMAL_COLOUR);
void add_label(const gamemap::location&,
const terrain_label*);
void clear(const std::string&, replay*);
void scroll(double xmove, double ymove);
void recalculate_labels();
bool visible_global_label(const gamemap::location&) const;
void recalculate_shroud();
typedef std::map<gamemap::location,int> label_map;
const label_map& labels() { return labels_; }
const std::string& get_label(int index) const;
const label_map& labels();
const display& disp() const;
const std::string& team_name() const;
void set_team(const team*);
private:
void clear_map(const label_map&);
void clear_all();
map_labels(const map_labels&);
void operator=(const map_labels&);
@ -58,7 +83,67 @@ private:
const team* team_;
const gamemap& map_;
label_map labels_;
team_label_map labels_;
label_map label_cashe_;
bool changed_;
};
/// To store label data
/// Class implements logic for rendering
class terrain_label
{
public:
terrain_label(const std::string&,
const std::string&,
const gamemap::location&,
const map_labels&,
const SDL_Color colour = font::NORMAL_COLOUR);
terrain_label(const map_labels&,
const config&);
terrain_label(const map_labels&);
~terrain_label();
void write(config& res) const;
void read(const config& cfg);
const std::string& text() const;
const std::string& team_name() const;
const gamemap::location& location() const;
const SDL_Colour& colour() const;
void set_text(const std::string&);
void update_info(const std::string&,
const std::string&,
const SDL_Color);
void scroll(double xmove, double ymove) const;
void recalculate();
void calculate_shroud() const;
void invalidate_handle();
private:
terrain_label(const terrain_label&);
const terrain_label& operator=(const terrain_label&);
void clear();
void draw();
bool visible() const;
void check_text_length();
const std::string cfg_colour() const;
int handle_;
std::string text_;
std::string team_name_;
SDL_Color colour_;
const map_labels* parent_;
gamemap::location loc_;
};
#endif

View file

@ -25,6 +25,7 @@
#include "preferences_display.hpp"
#include "replay.hpp"
#include "sound.hpp"
#include "team.hpp"
#include "unit_display.hpp"
#include "unit_types.hpp"
#include "wassert.hpp"
@ -635,6 +636,21 @@ namespace events{
return false;
}
bool menu_handler::has_team() const
{
if(is_observer()) {
return false;
}
for(size_t n = 0; n != teams_.size(); ++n) {
if(n != gui_->viewing_team() && teams_[gui_->viewing_team()].team_name() == teams_[n].team_name()) {
return true;
}
}
return false;
}
void menu_handler::recruit(const bool browse, const unsigned int team_num, const gamemap::location& last_hex)
{
@ -1303,26 +1319,63 @@ namespace events{
i->second.set_side(side);
}
void menu_handler::label_terrain(mouse_handler& mousehandler)
void menu_handler::label_terrain(mouse_handler& mousehandler, bool team_only)
{
if(map_.on_board(mousehandler.get_last_hex()) == false) {
return;
}
std::string label = gui_->labels().get_label(mousehandler.get_last_hex());
const terrain_label* old_label = gui_->labels().get_label(mousehandler.get_last_hex());
std::string label;
if (old_label)
{
label = old_label->text();
team_only = !old_label->team_name().empty();
}
std::vector<gui::check_item> options;
if (has_team() || (old_label && team_only))
{
gui::check_item team_only_chk = gui::check_item(_("Team only"),
team_only);
team_only_chk.align = gui::LEFT_ALIGN;
options.push_back(team_only_chk);
}
const int res = gui::show_dialog(*gui_,NULL,_("Place Label"),"",gui::OK_CANCEL,
NULL,NULL,_("Label:"),&label,
map_labels::get_max_chars());
map_labels::get_max_chars(), NULL, &options);
if(res == 0) {
gui_->labels().set_label(mousehandler.get_last_hex(),label);
recorder.add_label(label,mousehandler.get_last_hex());
std::string team_name;
SDL_Color colour = font::LABEL_COLOUR;
const std::string last_team_id = "9";
std::map<std::string, color_range>::iterator gp = game_config::team_rgb_range.find(last_team_id);
if ((has_team() || (old_label && team_only)) && options.front().checked)
{
team_name = gui_->labels().team_name();
}
else
{
colour = team::get_side_colour( gui_->viewing_team() + 1);
}
gui_->labels().set_label(mousehandler.get_last_hex(),label,&recorder, team_name, colour);
}
}
void menu_handler::clear_labels()
{
gui_->labels().clear();
recorder.clear_labels();
if (gui_->team_valid()
&& !is_observer())
{
gui_->labels().clear(gui_->current_team_name(),&recorder);
}
}
void menu_handler::continue_move(mouse_handler& mousehandler, const unsigned int team_num)
@ -1682,11 +1735,11 @@ namespace events{
loc.y = (loc.y + 1) % map_.y();
//Search label
const std::string label = gui_->labels().get_label(loc);
if(label.empty() == false) {
if(std::search(label.begin(), label.end(),
const terrain_label* label = gui_->labels().get_label(loc);
if(label) {
if(std::search(label->text().begin(), label->text().end(),
last_search_.begin(), last_search_.end(),
chars_equal_insensitive) != label.end()) {
chars_equal_insensitive) != label->text().end()) {
found = !gui_->shrouded(loc.x, loc.y);
}
}
@ -1785,6 +1838,7 @@ namespace events{
if(team_num == side_num) {
//if it is our turn at the moment, we have to indicate to the
//play_controller, that we are no longer in control
gui_->set_team(0);
throw end_turn_exception(side_num);
}
} else {

View file

@ -92,7 +92,7 @@ public:
void rename_unit(mouse_handler& mousehandler);
void create_unit(mouse_handler& mousehandler);
void change_unit_side(mouse_handler& mousehandler);
void label_terrain(mouse_handler& mousehandler);
void label_terrain(mouse_handler& mousehandler, bool team_only);
void clear_labels();
void continue_move(mouse_handler& mousehandler, const unsigned int team_num);
void toggle_grid();
@ -110,7 +110,7 @@ public:
void do_command(const std::string& str, const unsigned int team_num, mouse_handler& mousehandler);
void clear_undo_stack(const unsigned int team_num);
void autosave(const std::string &label, unsigned turn, const config &starting_pos) const;
bool has_team() const;
protected:
void add_chat_message(const std::string& speaker, int side, const std::string& message, display::MESSAGE_TYPE type=display::MESSAGE_PRIVATE);
void send_chat_message(const std::string& message, bool allies_only=false);

View file

@ -302,13 +302,17 @@ void playmp_controller::handle_generic_event(const std::string& name){
bool playmp_controller::can_execute_command(hotkey::HOTKEY_COMMAND command) const
{
bool res = true;
switch (command){
case hotkey::HOTKEY_SPEAK:
case hotkey::HOTKEY_SPEAK_ALLY:
case hotkey::HOTKEY_SPEAK_ALL:
case hotkey::HOTKEY_CLEAR_LABELS:
return network::nconnections() > 0;
case hotkey::HOTKEY_SPEAK_ALLY:
res = !is_observer();
case hotkey::HOTKEY_SPEAK:
case hotkey::HOTKEY_SPEAK_ALL:
res = res && network::nconnections() > 0;
break;
default:
return playsingle_controller::can_execute_command(command);
}
return res;
}

View file

@ -104,8 +104,8 @@ void playsingle_controller::change_unit_side(){
menu_handler_.change_unit_side(mouse_handler_);
}
void playsingle_controller::label_terrain(){
menu_handler_.label_terrain(mouse_handler_);
void playsingle_controller::label_terrain(bool team_only){
menu_handler_.label_terrain(mouse_handler_, team_only);
}
void playsingle_controller::continue_move(){
@ -568,6 +568,7 @@ void playsingle_controller::check_time_over(){
bool playsingle_controller::can_execute_command(hotkey::HOTKEY_COMMAND command) const
{
bool res = true;
switch (command){
case hotkey::HOTKEY_UNIT_HOLD_POSITION:
case hotkey::HOTKEY_END_UNIT_TURN:
@ -587,10 +588,13 @@ bool playsingle_controller::can_execute_command(hotkey::HOTKEY_COMMAND command)
case hotkey::HOTKEY_CHANGE_UNIT_SIDE:
return !events::commands_disabled && game_config::debug && map_.on_board(mouse_handler_.get_last_hex());
case hotkey::HOTKEY_LABEL_TEAM_TERRAIN:
res = menu_handler_.has_team();
case hotkey::HOTKEY_LABEL_TERRAIN:
return !events::commands_disabled && map_.on_board(mouse_handler_.get_last_hex())
res = res && !events::commands_disabled && map_.on_board(mouse_handler_.get_last_hex())
&& !gui_->shrouded(mouse_handler_.get_last_hex().x, mouse_handler_.get_last_hex().y)
&& !is_observer();
break;
case hotkey::HOTKEY_CONTINUE_MOVE: {
if(browse_ || events::commands_disabled)
@ -605,4 +609,5 @@ bool playsingle_controller::can_execute_command(hotkey::HOTKEY_COMMAND command)
}
default: return play_controller::can_execute_command(command);
}
return res;
}

View file

@ -46,7 +46,7 @@ public:
virtual void rename_unit();
virtual void create_unit();
virtual void change_unit_side();
virtual void label_terrain();
virtual void label_terrain(bool);
virtual void continue_move();
virtual void unit_hold_position();
virtual void end_unit_turn();

View file

@ -358,28 +358,28 @@ void replay::choose_option(int index)
add_value("choose",index);
}
void replay::add_label(const std::string& text, const gamemap::location& loc)
void replay::add_label(const terrain_label* label)
{
wassert(label);
config* const cmd = add_command(false);
(*cmd)["undo"] = "no";
config val;
loc.write(val);
val["text"] = text;
label->write(val);
cmd->add_child("label",val);
}
void replay::clear_labels()
void replay::clear_labels(const std::string& team_name)
{
config* const cmd = add_command(false);
(*cmd)["undo"] = "no";
cmd->add_child("clear_labels");
config val;
val["team_name"] = team_name;
cmd->add_child("clear_labels",val);
}
void replay::add_rename(const std::string& name, const gamemap::location& loc)
@ -729,14 +729,18 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
}
}
} else if((child = cfg->child("label")) != NULL) {
const gamemap::location loc(*child);
const std::string& text = (*child)["text"];
if (!replayer.is_skipping()){
disp.labels().set_label(loc,text);
}
terrain_label label(disp.labels(),*child);
disp.labels().set_label(label.location(),
label.text(),
0,
label.team_name(),
label.colour());
} else if((child = cfg->child("clear_labels")) != NULL) {
disp.labels().clear();
disp.labels().clear(std::string((*child)["team_name"]),0);
}
else if((child = cfg->child("rename")) != NULL) {

View file

@ -18,6 +18,7 @@
#include "map.hpp"
#include "random.hpp"
#include "unit.hpp"
#include "map_label.hpp"
class display;
class config_writer;
@ -54,8 +55,8 @@ public:
void add_attack(const gamemap::location& a, const gamemap::location& b,
int att_weapon, int def_weapon);
void choose_option(int index);
void add_label(const std::string& text, const gamemap::location& loc);
void clear_labels();
void add_label(const terrain_label*);
void clear_labels(const std::string&);
void add_rename(const std::string& name, const gamemap::location& loc);
void end_turn();
void add_event(const std::string& name);