Freeciv-3.1
Loading...
Searching...
No Matches
chatline.cpp
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18//Qt
19#include <QApplication>
20#include <QCheckBox>
21#include <QCompleter>
22#include <QGridLayout>
23#include <QKeyEvent>
24#include <QPainter>
25#include <QScrollBar>
26#include <QStyleFactory>
27#include <QTextBlock>
28#include <QTextLayout>
29#include <QTextBrowser>
30
31// common
32#include "chat.h"
33
34// client
35#include "audio.h"
36#include "climap.h"
37#include "climisc.h" // For write_chatline_content()
38#include "connectdlg_common.h"
39#include "control.h"
40#include "game.h"
41
42// gui-qt
43#include "chatline.h"
44#include "colors.h"
45#include "fc_client.h"
46#include "gui_main.h"
47#include "qtg_cxxside.h"
48
49static bool is_plain_public_message(QString s);
50
52QStringList chat_listener::history = QStringList();
53QStringList chat_listener::word_list = QStringList();
54
55/***********************************************************************/
59{
60 QString str;
61
63 if (pconn->playing) {
64 word_list << pconn->playing->name;
65 word_list << pconn->playing->username;
66 } else {
67 word_list << pconn->username;
68 }
70
71 players_iterate(pplayer) {
72 str = pplayer->name;
73 if (!word_list.contains(str)) {
74 word_list << str;
75 }
77
79}
80
81/***********************************************************************/
85 position(HISTORY_END)
86{}
87
88/***********************************************************************/
93 const struct text_tag_list *)
94{}
95
96/***********************************************************************/
101{}
102
103/***********************************************************************/
110{
111 int index;
112 QString splayer, s;
113
114 /* FIXME
115 * Key == PICK: used for picking nation, it was put here cause those
116 * Qt slots are a bit limited ...I'm unable to pass custom player pointer
117 * or idk how to do that
118 */
119 s = message;
120 index = message.indexOf("PICK:");
121
122 if (index != -1) {
123 s = s.remove("PICK:");
124 /* now should be playername left in string */
125 players_iterate(pplayer) {
126 splayer = QString(pplayer->name);
127
128 if (!splayer.compare(s)) {
129 popup_races_dialog(pplayer);
130 }
132 return;
133 }
134
135 history << message;
137
138 /*
139 * If client send commands to take ai, set /away to disable AI
140 */
141 if (message.startsWith("/take ")) {
142 s = s.remove("/take ");
143 players_iterate(pplayer) {
144 splayer = QString(pplayer->name);
145 splayer = "\"" + splayer + "\"";
146
147 if (!splayer.compare(s)) {
148 if (is_ai(pplayer)) {
149 send_chat(message.toUtf8());
150 send_chat("/away");
151 return;
152 }
153 }
155 }
156
157 /*
158 * Option to send to allies by default
159 */
160 if (!message.isEmpty()) {
164 + " " + message).toUtf8());
165 } else {
166 send_chat(message.toUtf8());
167 }
168 }
169 // Empty messages aren't sent
170 // FIXME Inconsistent behavior: "." will send an empty message to allies
171}
172
173/***********************************************************************/
178{
179 if (!history.empty() && position == HISTORY_END) {
180 position = history.size() - 1;
181 } else if (position > 0) {
182 position--;
183 }
184 return history.empty() ? "" : history.at(position);
185}
186
187/***********************************************************************/
192{
193 if (position == HISTORY_END) {
194 return "";
195 }
196 position++;
197 if (position >= history.size()) {
199 return "";
200 } else {
201 return history.at(position);
202 }
203}
204
205/***********************************************************************/
212
213/***********************************************************************/
216chat_input::chat_input(QWidget *parent) :
217 QLineEdit(parent)
218{
219 connect(this, &QLineEdit::returnPressed, this, &chat_input::send);
222}
223
224/***********************************************************************/
228{
229 send_chat_message(text());
230 clear();
231}
232
233/***********************************************************************/
236void chat_input::chat_word_list_changed(const QStringList &cmplt_word_list)
237{
238 QCompleter *cmplt = completer();
239
240 if (cmplt != nullptr) {
241 delete cmplt;
242 }
243
244 cmplt = new QCompleter(cmplt_word_list);
245 cmplt->setCaseSensitivity(Qt::CaseInsensitive);
246 cmplt->setCompletionMode(QCompleter::InlineCompletion);
247 setCompleter(cmplt);
248}
249
250/***********************************************************************/
254{
255 if (event->type() == QEvent::KeyPress) {
256 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
257 switch (keyEvent->key()) {
258 case Qt::Key_Up:
259 setText(back_in_history());
260 return true;
261 case Qt::Key_Down:
262 setText(forward_in_history());
263 return true;
264 }
265 }
266 return QLineEdit::event(event);
267}
268
269/***********************************************************************/
272chatwdg::chatwdg(QWidget *parent)
273{
274 QGridLayout *gl;
275
276 setParent(parent);
277 cb = new QCheckBox("");
278 cb->setToolTip(_("Allies only"));
280 gl = new QGridLayout;
281 chat_line = new chat_input;
284 remove_links = new QPushButton("");
285 remove_links->setIcon(style()->standardPixmap(QStyle::SP_DialogCancelButton));
286 remove_links->setToolTip(_("Clear links"));
287 gl->setVerticalSpacing(0);
288 gl->addWidget(chat_output,0 , 0, 1 ,3);
289 gl->addWidget(chat_line,1, 0);
290 gl->addWidget(cb,1,1);
291 gl->addWidget(remove_links,1,2);
292 gl->setContentsMargins(0, 0, 6, 0);
293 setLayout(gl);
294 chat_output->setReadOnly(true);
295 chat_line->installEventFilter(this);
296 chat_output->setVisible(true);
297 chat_output->setAcceptRichText(true);
298 chat_output->setOpenLinks(false);
299 chat_output->setReadOnly(true);
300 connect(chat_output, &QTextBrowser::anchorClicked,
302 connect(chat_output, &QTextBrowser::anchorClicked,
305 this, &chatwdg::toggle_size);
306 connect(remove_links, &QAbstractButton::clicked, this, &chatwdg::rm_links);
307 connect(cb, &QCheckBox::stateChanged, this, &chatwdg::state_changed);
308 setMouseTracking(true);
309
311}
312
313/***********************************************************************/
317{
318 if (state > 0) {
320 } else {
322 }
323}
324
325/***********************************************************************/
329{
330 if (gui()->infotab->chat_maximized) {
331 gui()->infotab->restore_chat();
332 return;
333 } else {
334 gui()->infotab->maximize_chat();
335 chat_line->setFocus();
336 }
337}
338
339/***********************************************************************/
343{
344 chat_output->verticalScrollBar()->setSliderPosition(
345 chat_output->verticalScrollBar()->maximum());
346}
347
348
349/***********************************************************************/
353{
354 QFont *qf;
356 chat_output->setFont(*qf);
357}
358
359/***********************************************************************/
366
367/***********************************************************************/
370void chatwdg::anchor_clicked(const QUrl &link)
371{
372 int n;
373 QStringList sl;
374 int id;
375 enum text_link_type type;
376 struct tile *ptile = nullptr;
377
378 sl = link.toString().split(",");
379 n = sl.at(0).toInt();
380 id = sl.at(1).toInt();
381
382 type = static_cast<text_link_type>(n);
383
384 switch (type) {
385 case TLT_CITY: {
386 struct city *pcity = game_city_by_number(id);
387
388 if (pcity) {
389 ptile = client_city_tile(pcity);
390 } else {
391 output_window_append(ftc_client, _("This city isn't known!"));
392 }
393 }
394 break;
395 case TLT_TILE:
396 ptile = index_to_tile(&(wld.map), id);
397
398 if (!ptile) {
400 _("This tile doesn't exist in this game!"));
401 }
402 break;
403 case TLT_UNIT: {
404 struct unit *punit = game_unit_by_number(id);
405
406 if (punit) {
407 ptile = unit_tile(punit);
408 } else {
409 output_window_append(ftc_client, _("This unit isn't known!"));
410 }
411 }
412 break;
413 }
414 if (ptile != nullptr) {
417 }
418}
419
420/***********************************************************************/
424 const struct text_tag_list *tags)
425{
426 QColor col = chat_output->palette().color(QPalette::Text);
427 append(apply_tags(message, tags, col));
428}
429
430/***********************************************************************/
433void chatwdg::append(const QString &str)
434{
435 QTextCursor cursor;
436
437 chat_output->append(str);
438 chat_output->verticalScrollBar()->setSliderPosition(
439 chat_output->verticalScrollBar()->maximum());
440}
441
442/***********************************************************************/
445void chatwdg::paint(QPainter *painter, QPaintEvent *event)
446{
447 painter->setBrush(QColor(0, 0, 0, 35));
448 painter->drawRect(0, 0, width(), height());
449}
450
451/***********************************************************************/
454void chatwdg::paintEvent(QPaintEvent *event)
455{
456 QPainter painter;
457
458 painter.begin(this);
459 paint(&painter, event);
460 painter.end();
461}
462
463/***********************************************************************/
466bool chatwdg::eventFilter(QObject *obj, QEvent *event)
467{
468 if (obj == chat_line) {
469 if (event->type() == QEvent::KeyPress) {
470 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
471 if (keyEvent->key() == Qt::Key_Escape) {
472 gui()->infotab->restore_chat();
473 gui()->mapview_wdg->setFocus();
474 return true;
475 }
476 }
477 if (event->type() == QEvent::ShortcutOverride) {
478 event->setAccepted(true);
479 }
480 }
481
482 return QObject::eventFilter(obj, event);
483}
484
485/***********************************************************************/
489{
490 if (is_server_running()) {
491 cb->hide();
492 remove_links->hide();
493 } else {
494 cb->show();
495 remove_links->show();
496 }
497}
498
499/***********************************************************************/
504{
505 int line_count = 0;
506 int line_height;
507 int size;
508 QTextBlock qtb;
509
510 qtb = chat_output->document()->firstBlock();
511 /* Count all lines in all text blocks layouts
512 * document()->lineCount returns number of lines without wordwrap */
513
514 while (qtb.isValid()) {
515 line_count = line_count + qtb.layout()->lineCount();
516 qtb = qtb.next();
517 }
518
519 if (line_count == 0) {
520 return 0;
521 }
522
523 line_height = (chat_output->document()->size().height()
524 - 2 * chat_output->document()->documentMargin())
525 / line_count;
526
527 size = lines * line_height
528 + chat_line->size().height() + chat_output->document()->documentMargin();
529 size = qMax(0, size);
530
531 return size;
532}
533
534/***********************************************************************/
537void chatwdg::make_link(struct tile *ptile)
538{
539 struct unit *punit;
540 char buf[MAX_LEN_MSG];
541
542 punit = find_visible_unit(ptile);
543 if (tile_city(ptile)) {
544 sz_strlcpy(buf, city_link(tile_city(ptile)));
545 } else if (punit) {
547 } else {
548 sz_strlcpy(buf, tile_link(ptile));
549 }
550 chat_line->insert(QString(buf));
551 chat_line->setFocus();
552}
553
554/***********************************************************************/
557QString apply_tags(QString str, const struct text_tag_list *tags,
558 QColor bg_color)
559{
560 int start, stop, last_i;
561 QString str_col;
562 QString color;
563 QString final_string;
564 QByteArray qba;
565 QColor qc;
566 QMultiMap <int, QString> mm;
567 QByteArray str_bytes;
568
569 if (tags == nullptr) {
570 return str;
571 }
572 str_bytes = str.toUtf8();
573 qba = str_bytes.data();
574
575 text_tag_list_iterate(tags, ptag) {
576 if ((text_tag_stop_offset(ptag) == FT_OFFSET_UNSET)) {
577 stop = qba.length();
578 } else {
579 stop = text_tag_stop_offset(ptag);
580 }
581
582 if ((text_tag_start_offset(ptag) == FT_OFFSET_UNSET)) {
583 start = 0;
584 } else {
585 start = text_tag_start_offset(ptag);
586 }
587 switch (text_tag_type(ptag)) {
588 case TTT_BOLD:
589 mm.insert(stop, "</b>");
590 mm.insert(start, "<b>");
591 break;
592 case TTT_ITALIC:
593 mm.insert(stop, "</i>");
594 mm.insert(start, "<i>");
595 break;
596 case TTT_STRIKE:
597 mm.insert(stop, "</s>");
598 mm.insert(start, "<s>");
599 break;
600 case TTT_UNDERLINE:
601 mm.insert(stop, "</u>");
602 mm.insert(start, "<u>");
603 break;
604 case TTT_COLOR:
605 if (text_tag_color_foreground(ptag)) {
607 if (color == "#00008B") {
608 color = bg_color.name();
609 } else {
610 qc.setNamedColor(color);
611 qc = qc.lighter(200);
612 color = qc.name();
613 }
614 str_col = QString("<span style=color:%1>").arg(color);
615 mm.insert(stop, "</span>");
616 mm.insert(start, str_col);
617 }
618 if (text_tag_color_background(ptag)) {
620 if (QColor::isValidColor(color)) {
621 str_col = QString("<span style= background-color:%1;>").arg(color);
622 mm.insert(stop, "</span>");
623 mm.insert(start, str_col);
624 }
625 }
626 break;
627 case TTT_LINK: {
628 struct color *pcolor = nullptr;
629
630 switch (text_tag_link_type(ptag)) {
631 case TLT_CITY:
632 pcolor = get_color(tileset, COLOR_MAPVIEW_CITY_LINK);
633 break;
634 case TLT_TILE:
635 pcolor = get_color(tileset, COLOR_MAPVIEW_TILE_LINK);
636 break;
637 case TLT_UNIT:
638 pcolor = get_color(tileset, COLOR_MAPVIEW_UNIT_LINK);
639 break;
640 }
641
642 if (pcolor == nullptr) {
643 break; // Not a valid link type case.
644 }
645 color = pcolor->qcolor.name(QColor::HexRgb);
646 str_col = QString("<font color=\"%1\">").arg(color);
647 mm.insert(stop, "</a></font>");
648
649 color = QString(str_col + "<a href=%1,%2>").
650 arg(QString::number(text_tag_link_type(ptag)),
651 QString::number(text_tag_link_id(ptag)));
652 mm.insert(start, color);
653 }
654 }
656
657 // Insert html starting from last items
658 last_i = str.length();
659 QMultiMap<int, QString>::const_iterator i = mm.constEnd();
660 QMultiMap<int, QString>::const_iterator j = mm.constEnd();
661
662 while (i != mm.constBegin()) {
663 i--;
664 if (i.key() < last_i) {
665 final_string = final_string.prepend(QString(qba.mid(i.key(),
666 last_i - i.key()))
667 .toHtmlEscaped());
668 }
669 last_i = i.key();
670 j = i;
671 if (i != mm.constBegin()) {
672 j--;
673 }
674 if (j.key() == i.key() && i != j) {
675 final_string = final_string.prepend(j.value());
676 final_string = final_string.prepend(i.value());
677 i--;
678 } else {
679 final_string = final_string.prepend(i.value());
680 }
681 }
682
683 if (last_i == str.length()) {
684 return str;
685 }
686
687 return final_string;
688}
689
690/***********************************************************************/
694static bool is_plain_public_message(QString s)
695{
696 QString s1, str;
697 int i;
698
699 str = s.trimmed();
700 if (str.at(0) == SERVER_COMMAND_PREFIX
701 || str.at(0) == CHAT_ALLIES_PREFIX
702 || str.at(0) == CHAT_DIRECT_PREFIX) {
703 return false;
704 }
705
706 /* Search for private message */
707 if (!str.contains(CHAT_DIRECT_PREFIX)) {
708 return true;
709 }
710 i = str.indexOf(CHAT_DIRECT_PREFIX);
711 str = str.left(i);
712
713 /* Compare all players and connections looking for match */
715 s1 = pconn->username;
716 if (s1.length() < i) {
717 continue;
718 }
719 if (!QString::compare(s1.left(i), str, Qt::CaseInsensitive)) {
720 return false;
721 }
723 players_iterate(pplayer) {
724 s1 = pplayer->name;
725 if (s1.length() < i) {
726 continue;
727 }
728 if (!QString::compare(s1.left(i), str, Qt::CaseInsensitive)) {
729 return false;
730 }
732
733 return true;
734}
735
736/***********************************************************************/
741 const struct text_tag_list *tags,
742 int conn_id)
743{
744 QString str;
745 QString wakeup;
746 QApplication *qapp;
747
748 str = QString::fromUtf8(astring);
749 gui()->set_status_bar(str);
750
752
753 /* Format wakeup string if needed */
754 if (wakeup.contains("%1")) {
755 wakeup = wakeup.arg(client.conn.username);
756 }
757
758 qapp = current_app();
759
760 if (str.contains(client.conn.username)) {
761 qapp->alert(gui()->central_wdg);
762 }
763
764 /* Play sound if we encountered wakeup string */
765 if (str.contains(wakeup) && client_state() < C_S_RUNNING
766 && !wakeup.isEmpty()) {
767 qapp->alert(gui()->central_wdg);
768 audio_play_sound("e_player_wake", NULL);
769 }
770
773 str, tags);
774}
775
776/***********************************************************************/
781{
782 /* PORTME */
784}
785
786/***********************************************************************/
790{
791 /* PORTME */
792#if 0
793 set_output_window_text(_("Cleared output window."));
794#endif
795}
796
797/***********************************************************************/
801 QEvent(QEvent::User),
802 message(msg)
803{}
804
805/***********************************************************************/
808void qtg_version_message(const char *vertext)
809{
810 current_app()->postEvent(gui(), new version_message_event(vertext));
811}
#define str
Definition astring.c:76
#define n
Definition astring.c:77
void audio_play_sound(const char *const tag, const char *const alt_tag)
Definition audio.c:521
static QFont * get_font(enum client_font font)
Definition canvas.cpp:359
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
struct canvas int int struct sprite bool int int fog_y struct canvas struct sprite struct color * pcolor
Definition canvas_g.h:57
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
#define CHAT_DIRECT_PREFIX
Definition chat.h:31
#define CHAT_ALLIES_PREFIX
Definition chat.h:30
#define SERVER_COMMAND_PREFIX
Definition chat.h:28
void log_output_window(void)
Definition chatline.cpp:780
void clear_output_window(void)
Definition chatline.cpp:789
QString apply_tags(QString str, const struct text_tag_list *tags, QColor bg_color)
Definition chatline.cpp:557
void qtg_version_message(const char *vertext)
Definition chatline.cpp:808
void qtg_real_output_window_append(const char *astring, const struct text_tag_list *tags, int conn_id)
Definition chatline.cpp:740
static bool is_plain_public_message(QString s)
Definition chatline.cpp:694
int send_chat(const char *message)
void output_window_append(const struct ft_color color, const char *featured_text)
void write_chatline_content(const char *txt)
bool event(QEvent *event)
Definition chatline.cpp:253
virtual void chat_word_list_changed(const QStringList &cmplt_word_list)
Definition chatline.cpp:236
void send()
Definition chatline.cpp:227
chat_input(QWidget *parent=nullptr)
Definition chatline.cpp:216
QStringList current_word_list()
Definition chatline.h:74
static const int HISTORY_END
Definition chatline.h:57
QString forward_in_history()
Definition chatline.cpp:191
void send_chat_message(const QString &message)
Definition chatline.cpp:109
void reset_history_position()
Definition chatline.cpp:208
QString back_in_history()
Definition chatline.cpp:177
static QStringList history
Definition chatline.h:48
virtual void chat_word_list_changed(const QStringList &cmplt_word_list)
Definition chatline.cpp:100
static void update_word_list()
Definition chatline.cpp:58
static QStringList word_list
Definition chatline.h:53
virtual void chat_message_received(const QString &, const struct text_tag_list *)
Definition chatline.cpp:92
bool eventFilter(QObject *obj, QEvent *event)
Definition chatline.cpp:466
chat_input * chat_line
Definition chatline.h:120
chatwdg(QWidget *parent)
Definition chatline.cpp:272
void paintEvent(QPaintEvent *event)
Definition chatline.cpp:454
void update_font()
Definition chatline.cpp:352
void anchor_clicked(const QUrl &link)
Definition chatline.cpp:370
int default_size(int lines)
Definition chatline.cpp:503
text_browser_dblclck * chat_output
Definition chatline.h:139
void make_link(struct tile *ptile)
Definition chatline.cpp:537
void chat_message_received(const QString &message, const struct text_tag_list *tags)
Definition chatline.cpp:423
void scroll_to_bottom()
Definition chatline.cpp:342
void paint(QPainter *painter, QPaintEvent *event)
Definition chatline.cpp:445
void update_widgets()
Definition chatline.cpp:488
QCheckBox * cb
Definition chatline.h:141
void rm_links()
Definition chatline.cpp:362
QPushButton * remove_links
Definition chatline.h:140
void state_changed(int state)
Definition chatline.cpp:316
void append(const QString &str)
Definition chatline.cpp:433
void toggle_size()
Definition chatline.cpp:328
static fc_font * instance()
Definition fonts.cpp:41
QFont * get_font(QString name)
Definition fonts.cpp:63
static void invoke(_member_fct_ function)
Definition listener.h:175
version_message_event(const QString &msg)
Definition chatline.cpp:800
struct civclient client
enum client_states client_state(void)
@ C_S_RUNNING
Definition client_main.h:47
struct tile * client_city_tile(const struct city *pcity)
Definition climap.c:87
struct color * get_color(const struct tileset *t, enum color_std stdcolor)
bool is_server_running(void)
#define conn_list_iterate(connlist, pconn)
Definition connection.h:113
#define conn_list_iterate_end
Definition connection.h:115
struct unit * find_visible_unit(struct tile *ptile)
Definition control.c:823
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
int int id
Definition editgui_g.h:28
enum event_type event
Definition events.c:81
#define _(String)
Definition fcintl.h:67
enum text_link_type text_tag_link_type(const struct text_tag *ptag)
const char * tile_link(const struct tile *ptile)
ft_offset_t text_tag_stop_offset(const struct text_tag *ptag)
const char * text_tag_color_foreground(const struct text_tag *ptag)
const struct ft_color ftc_client
const char * city_link(const struct city *pcity)
int text_tag_link_id(const struct text_tag *ptag)
ft_offset_t text_tag_start_offset(const struct text_tag *ptag)
const char * unit_link(const struct unit *punit)
const char * text_tag_color_background(const struct text_tag *ptag)
#define text_tag_list_iterate_end
#define text_tag_list_iterate(tags, ptag)
#define FT_OFFSET_UNSET
text_link_type
@ TLT_TILE
@ TLT_UNIT
@ TLT_CITY
text_tag_type
@ TTT_LINK
@ TTT_BOLD
@ TTT_ITALIC
@ TTT_STRIKE
@ TTT_COLOR
@ TTT_UNDERLINE
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
struct unit * game_unit_by_number(int id)
Definition game.c:111
struct city * game_city_by_number(int id)
Definition game.c:102
static bool is_plain_public_message(const char *s)
Definition chatline.c:97
void popup_races_dialog(struct player *pplayer)
Definition dialogs.c:1223
GType type
Definition repodlgs.c:1312
QString apply_tags(QString str, const struct text_tag_list *tags, QColor bg_color)
Definition chatline.cpp:557
#define set_output_window_text(_pstr_)
Definition chatline.h:31
static QApplication * qapp
Definition gui_main.cpp:70
QApplication * current_app()
Definition gui_main.cpp:220
#define FC_CPP_DECLARE_LISTENER(_type_)
Definition listener.h:134
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:454
void link_mark_restore(enum text_link_type type, int id)
void center_tile_mapcanvas(const struct tile *ptile)
void link_marks_clear_all(void)
static mpgui * gui
Definition mpgui_qt.cpp:52
const char *const chatline
Definition fonts.h:31
struct client_options gui_options
Definition options.c:71
#define MAX_LEN_MSG
Definition packets.h:43
char * lines
Definition packhand.c:129
#define players_iterate_end
Definition player.h:535
#define players_iterate(_pplayer)
Definition player.h:530
#define is_ai(plr)
Definition player.h:234
size_t size
Definition specvec.h:72
Definition city.h:309
struct conn_list * est_connections
Definition game.h:97
struct conn_list * all_connections
Definition game.h:96
struct connection conn
Definition client_main.h:96
bool gui_qt_allied_chat_only
Definition options.h:388
char gui_qt_wakeup_text[512]
Definition options.h:400
Definition colors.h:20
char username[MAX_LEN_NAME]
Definition connection.h:169
Definition tile.h:49
Definition unit.h:138
struct civ_map map
#define sz_strlcpy(dest, src)
Definition support.h:167
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define unit_tile(_pu)
Definition unit.h:395