improved multiplayer chat system
This commit is contained in:
parent
14cd7419b0
commit
a9e68d52eb
7 changed files with 94 additions and 9 deletions
|
@ -124,6 +124,10 @@ language="English"
|
|||
key=b
|
||||
ctrl=yes
|
||||
[/hotkey]
|
||||
[hotkey]
|
||||
command=speak
|
||||
key=m
|
||||
[/hotkey]
|
||||
|
||||
game_title="The Battle for Wesnoth"
|
||||
version="Version"
|
||||
|
|
|
@ -106,6 +106,7 @@ void clear_surfaces(Map& surfaces)
|
|||
display::~display()
|
||||
{
|
||||
SDL_FreeSurface(minimap_);
|
||||
prune_chat_messages(true);
|
||||
}
|
||||
|
||||
Uint32 display::rgb(Uint8 red, Uint8 green, Uint8 blue)
|
||||
|
@ -557,6 +558,8 @@ void display::draw(bool update,bool force)
|
|||
draw_sidebar();
|
||||
}
|
||||
|
||||
prune_chat_messages();
|
||||
|
||||
const int max_skips = 5;
|
||||
const int time_between_draws = 20;
|
||||
const int current_time = SDL_GetTicks();
|
||||
|
@ -2580,3 +2583,42 @@ void display::remove_observer(const std::string& name)
|
|||
{
|
||||
observers_.erase(name);
|
||||
}
|
||||
|
||||
namespace {
|
||||
const int chat_message_spacing = 20;
|
||||
const int max_chat_messages = 4;
|
||||
const int chat_message_x = 10;
|
||||
const int chat_message_y = 10;
|
||||
const SDL_Color chat_message_colour = {200,200,200,200};
|
||||
}
|
||||
|
||||
void display::add_chat_message(const std::string& speaker, const std::string& msg)
|
||||
{
|
||||
std::stringstream str;
|
||||
str << "<" << speaker << "> " << msg;
|
||||
|
||||
std::cerr << "chat message '" << str.str() << "'\n";
|
||||
const SDL_Rect rect = map_area();
|
||||
const int handle = font::add_floating_label(str.str(),12,chat_message_colour,
|
||||
rect.x+chat_message_x,rect.y+chat_message_y+chat_message_spacing*chat_messages_.size(),0,0,-1,rect,font::LEFT_ALIGN);
|
||||
std::cerr << "Added label..\n";
|
||||
chat_messages_.push_back(chat_message(handle));
|
||||
|
||||
prune_chat_messages();
|
||||
std::cerr << "pruned messages...\n";
|
||||
}
|
||||
|
||||
void display::prune_chat_messages(bool remove_all)
|
||||
{
|
||||
const int message_ttl = remove_all ? 0 : 30000;
|
||||
if(chat_messages_.empty() == false && (chat_messages_.front().created_at+message_ttl < SDL_GetTicks() || chat_messages_.size() > max_chat_messages)) {
|
||||
font::remove_floating_label(chat_messages_.front().handle);
|
||||
chat_messages_.erase(chat_messages_.begin());
|
||||
|
||||
for(std::vector<chat_message>::const_iterator i = chat_messages_.begin(); i != chat_messages_.end(); ++i) {
|
||||
font::move_floating_label(i->handle,0,-chat_message_spacing);
|
||||
}
|
||||
|
||||
prune_chat_messages(remove_all);
|
||||
}
|
||||
}
|
|
@ -290,6 +290,8 @@ public:
|
|||
map_labels& labels() { return map_labels_; }
|
||||
const map_labels& labels() const { return map_labels_; }
|
||||
|
||||
void add_chat_message(const std::string& speaker, const std::string& msg);
|
||||
|
||||
private:
|
||||
display(const display&);
|
||||
void operator=(const display&);
|
||||
|
@ -417,6 +419,19 @@ private:
|
|||
|
||||
map_labels map_labels_;
|
||||
|
||||
struct chat_message
|
||||
{
|
||||
chat_message(int h) : handle(h), created_at(SDL_GetTicks())
|
||||
{}
|
||||
|
||||
int handle;
|
||||
int created_at;
|
||||
};
|
||||
|
||||
void prune_chat_messages(bool remove_all=false);
|
||||
|
||||
std::vector<chat_message> chat_messages_;
|
||||
|
||||
//for debug mode
|
||||
static std::map<gamemap::location,double> debugHighlights_;
|
||||
};
|
||||
|
|
32
src/font.cpp
32
src/font.cpp
|
@ -470,10 +470,10 @@ class floating_label
|
|||
{
|
||||
public:
|
||||
floating_label(const std::string& text, int font_size, const SDL_Color& colour,
|
||||
int xpos, int ypos, int xmove, int ymove, int lifetime, const SDL_Rect& clip_rect)
|
||||
int xpos, int ypos, int xmove, int ymove, int lifetime, const SDL_Rect& clip_rect, font::ALIGN align)
|
||||
: surf_(NULL), buf_(NULL), text_(text), font_size_(font_size), colour_(colour), xpos_(xpos), ypos_(ypos),
|
||||
xmove_(xmove), ymove_(ymove), lifetime_(lifetime), clip_rect_(clip_rect),
|
||||
alpha_change_(-255/lifetime), visible_(true)
|
||||
alpha_change_(-255/lifetime), visible_(true), align_(align)
|
||||
{}
|
||||
|
||||
void move(int xmove, int ymove);
|
||||
|
@ -488,6 +488,9 @@ public:
|
|||
void show(bool value);
|
||||
|
||||
private:
|
||||
|
||||
int xpos(size_t width) const;
|
||||
|
||||
shared_sdl_surface surf_, buf_;
|
||||
std::string text_;
|
||||
int font_size_;
|
||||
|
@ -497,6 +500,7 @@ private:
|
|||
SDL_Rect clip_rect_;
|
||||
int alpha_change_;
|
||||
bool visible_;
|
||||
font::ALIGN align_;
|
||||
};
|
||||
|
||||
typedef std::map<int,floating_label> label_map;
|
||||
|
@ -511,6 +515,18 @@ void floating_label::move(int xmove, int ymove)
|
|||
ypos_ += ymove;
|
||||
}
|
||||
|
||||
int floating_label::xpos(size_t width) const
|
||||
{
|
||||
int xpos = xpos_;
|
||||
if(align_ == font::CENTER_ALIGN) {
|
||||
xpos -= surf_->w/2;
|
||||
} else if(align_ == font::RIGHT_ALIGN) {
|
||||
xpos -= surf_->w;
|
||||
}
|
||||
|
||||
return xpos;
|
||||
}
|
||||
|
||||
void floating_label::draw(SDL_Surface* screen)
|
||||
{
|
||||
if(!visible_) {
|
||||
|
@ -542,7 +558,7 @@ void floating_label::draw(SDL_Surface* screen)
|
|||
return;
|
||||
}
|
||||
|
||||
SDL_Rect rect = {xpos_-surf_->w/2,ypos_,surf_->w,surf_->h};
|
||||
SDL_Rect rect = {xpos(surf_->w),ypos_,surf_->w,surf_->h};
|
||||
const clip_rect_setter clip_setter(screen,clip_rect_);
|
||||
SDL_BlitSurface(screen,&rect,buf_,NULL);
|
||||
SDL_BlitSurface(surf_,NULL,screen,&rect);
|
||||
|
@ -555,7 +571,7 @@ void floating_label::undraw(SDL_Surface* screen)
|
|||
return;
|
||||
}
|
||||
|
||||
SDL_Rect rect = {xpos_-surf_->w/2,ypos_,surf_->w,surf_->h};
|
||||
SDL_Rect rect = {xpos(surf_->w),ypos_,surf_->w,surf_->h};
|
||||
const clip_rect_setter clip_setter(screen,clip_rect_);
|
||||
SDL_BlitSurface(buf_,NULL,screen,&rect);
|
||||
|
||||
|
@ -580,9 +596,13 @@ void floating_label::show(bool value) { visible_ = value; }
|
|||
|
||||
namespace font {
|
||||
int add_floating_label(const std::string& text, int font_size, const SDL_Color& colour,
|
||||
int xpos, int ypos, int xmove, int ymove, int lifetime, const SDL_Rect& clip_rect)
|
||||
int xpos, int ypos, int xmove, int ymove, int lifetime, const SDL_Rect& clip_rect, ALIGN align)
|
||||
{
|
||||
labels.insert(std::pair<int,floating_label>(label_id++,floating_label(text,font_size,colour,xpos,ypos,xmove,ymove,lifetime,clip_rect)));
|
||||
if(lifetime <= 0) {
|
||||
lifetime = -1;
|
||||
}
|
||||
|
||||
labels.insert(std::pair<int,floating_label>(label_id++,floating_label(text,font_size,colour,xpos,ypos,xmove,ymove,lifetime,clip_rect,align)));
|
||||
return label_id-1;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,6 +116,8 @@ private:
|
|||
bool old_;
|
||||
};
|
||||
|
||||
enum ALIGN { LEFT_ALIGN, CENTER_ALIGN, RIGHT_ALIGN };
|
||||
|
||||
/// add a label floating on the screen above everything else.
|
||||
/// 'text': the text to display
|
||||
/// 'font_size': the size to display the text in
|
||||
|
@ -127,7 +129,7 @@ private:
|
|||
///
|
||||
/// @returns a handle to the label which can be used with other label functions
|
||||
int add_floating_label(const std::string& text, int font_size, const SDL_Color& colour,
|
||||
int xpos, int ypos, int xmove, int ymove, int lifetime, const SDL_Rect& clip_rect);
|
||||
int xpos, int ypos, int xmove, int ymove, int lifetime, const SDL_Rect& clip_rect, ALIGN alignment=CENTER_ALIGN);
|
||||
|
||||
/// moves the floating label given by 'handle' by (xmove,ymove)
|
||||
void move_floating_label(int handle, int xmove, int ymove);
|
||||
|
|
|
@ -1684,7 +1684,8 @@ void turn_info::speak()
|
|||
cfg["side"] = buf;
|
||||
|
||||
recorder.speak(cfg);
|
||||
dialogs::unit_speak(cfg,gui_,units_);
|
||||
gui_.add_chat_message(leader->second.description(),message);
|
||||
// dialogs::unit_speak(cfg,gui_,units_);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -777,7 +777,8 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
|||
advancing_units.push_back(tgt->first);
|
||||
}
|
||||
} else if((child = cfg->child("speak")) != NULL) {
|
||||
dialogs::unit_speak(*child,disp,units);
|
||||
// dialogs::unit_speak(*child,disp,units);
|
||||
disp.add_chat_message((*child)["description"],(*child)["message"]);
|
||||
} else if((child = cfg->child("label")) != NULL) {
|
||||
const gamemap::location loc(*child);
|
||||
const std::string& text = (*child)["text"];
|
||||
|
|
Loading…
Add table
Reference in a new issue