Crossfire Server, Trunk
CREPlayerRepliesPanel.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 2022 the Crossfire Development Team
5  *
6  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
7  * welcome to redistribute it under certain conditions. For details, please
8  * see COPYING and LICENSE.
9  *
10  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
11  */
12 
13 #include <QtWidgets>
14 #include "CREPlayerRepliesPanel.h"
15 #include "global.h"
16 #include "dialog.h"
17 #include "sproto.h"
18 
22 class CREMessageTypeDelegate : public QStyledItemDelegate
23 {
24 public:
25  CREMessageTypeDelegate(QObject* parent) : QStyledItemDelegate(parent)
26  {
27  }
28 
29  virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex&) const override
30  {
31  QComboBox* box = new QComboBox(parent);
32  box->addItem(get_reply_text_own(rt_say), QString::number(static_cast<int>(rt_say)));
33  box->addItem(get_reply_text_own(rt_reply), QString::number(static_cast<int>(rt_reply)));
34  box->addItem(get_reply_text_own(rt_question), QString::number(static_cast<int>(rt_question)));
35  return box;
36  }
37 
38  virtual void setEditorData(QWidget* editor, const QModelIndex& index) const override
39  {
40  QComboBox* box = qobject_cast<QComboBox*>(editor);
41  if (!box)
42  return;
43 
44  box->setCurrentIndex(box->findData(index.data(Qt::UserRole).toString()));
45  }
46 
47  virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override
48  {
49  QComboBox* box = qobject_cast<QComboBox*>(editor);
50  if (!box)
51  return;
52  model->setData(index, box->currentData(Qt::UserRole).toString(), Qt::UserRole);
53  }
54 
55  virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex&) const override
56  {
57  editor->setGeometry(option.rect);
58  QComboBox* box = qobject_cast<QComboBox*>(editor);
59  if (!box)
60  return;
61  box->showPopup();
62  }
63 };
64 
65 CREPlayerRepliesPanel::CREPlayerRepliesPanel(QWidget* parent) : QDialog(parent)
66 {
67  setWindowTitle(tr("Player suggested replies"));
68 
69  myReplies = new QTableWidget(this);
70  myReplies->setColumnCount(3);
71  myReplies->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
72  myReplies->setItemDelegateForColumn(2, new CREMessageTypeDelegate(this));
73 
74  QPushButton* addReply = new QPushButton(tr("add reply"), this);
75  connect(addReply, SIGNAL(clicked(bool)), this, SLOT(onAddCondition(bool)));
76 
77  QPushButton* deleteReply = new QPushButton(tr("delete reply"), this);
78  connect(deleteReply, SIGNAL(clicked(bool)), this, SLOT(onDeleteCondition(bool)));
79 
80  QPushButton* reset = new QPushButton(tr("reset changes"), this);
81  connect(reset, SIGNAL(clicked(bool)), this, SLOT(onReset(bool)));
82 
83  QHBoxLayout* buttons = new QHBoxLayout();
84  buttons->addWidget(addReply);
85  buttons->addWidget(deleteReply);
86  buttons->addWidget(reset);
87 
88  QVBoxLayout* l = new QVBoxLayout(this);
89  l->addWidget(myReplies);
90  l->addLayout(buttons);
91  setLayout(l);
92 }
93 
95 {
96 }
97 
98 const char* convertType(const QString& type)
99 {
100  int i = type.toInt();
101  if (i < 0 || i > rt_question)
102  i = 0;
103  return get_reply_text_own(static_cast<reply_type>(i));
104 }
105 
106 QTableWidgetItem* createItem(const QString& text, const QString& edit)
107 {
108  QTableWidgetItem* wi = new QTableWidgetItem(text);
109  wi->setData(Qt::UserRole, edit);
110  wi->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
111  return wi;
112 }
113 
114 void CREPlayerRepliesPanel::addItem(const QStringList& item)
115 {
116  int row = myReplies->rowCount();
117  myReplies->setRowCount(row + 1);
118  myReplies->setItem(row, 0, createItem(item[0], item[0]));
119  myReplies->setItem(row, 1, createItem(item[1], item[1]));
120  myReplies->setItem(row, 2, createItem(convertType(item.size() > 2 ? item[2] : "0"), item.size() > 2 ? item[2] : "0"));
121 }
122 
123 void CREPlayerRepliesPanel::setData(const QList<QStringList>& data)
124 {
125  myReplies->clearContents();
126  myReplies->setRowCount(0);
127  myReplies->setHorizontalHeaderLabels(QStringList() << "What the player should say" << "What the player will be displayed as saying" << "Message type");
128  for (QStringList item : data)
129  {
130  addItem(item);
131  }
132  myOriginal = data;
133 }
134 
135 QList<QStringList> CREPlayerRepliesPanel::data() const
136 {
137  QList<QStringList> value;
138  for (int r = 0; r < myReplies->rowCount(); r++)
139  {
140  QStringList i;
141  i << myReplies->item(r, 0)->data(Qt::DisplayRole).toString();
142  i << myReplies->item(r, 1)->data(Qt::DisplayRole).toString();
143  i << myReplies->item(r, 2)->data(Qt::UserRole).toString();
144  value.append(i);
145  }
146  return value;
147 }
148 
150 {
151  QStringList item;
152  item << "*" << "?" << "0";
153  addItem(item);
154  myReplies->setCurrentItem(myReplies->item(myReplies->rowCount() - 1, 0));
155 }
156 
158 {
159  if (myReplies->currentRow() == -1)
160  return;
161 
162  myReplies->removeRow(myReplies->currentRow());
163 }
164 
166 {
167  if (QMessageBox::question(this, "Confirm reset", "Reset the replies to the initial values of the message?") != QMessageBox::StandardButton::Yes)
168  return;
170 }
CREPlayerRepliesPanel::~CREPlayerRepliesPanel
virtual ~CREPlayerRepliesPanel()
Definition: CREPlayerRepliesPanel.cpp:94
global.h
CREPlayerRepliesPanel::addItem
void addItem(const QStringList &item)
Definition: CREPlayerRepliesPanel.cpp:114
banquet.l
l
Definition: banquet.py:164
CREMessageTypeDelegate::CREMessageTypeDelegate
CREMessageTypeDelegate(QObject *parent)
Definition: CREPlayerRepliesPanel.cpp:25
CREPlayerRepliesPanel::onDeleteCondition
void onDeleteCondition(bool)
Definition: CREPlayerRepliesPanel.cpp:157
CREMessageTypeDelegate::updateEditorGeometry
virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const override
Definition: CREPlayerRepliesPanel.cpp:55
CREPlayerRepliesPanel::onAddCondition
void onAddCondition(bool)
Definition: CREPlayerRepliesPanel.cpp:149
CREMessageTypeDelegate::createEditor
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const override
Definition: CREPlayerRepliesPanel.cpp:29
CREMessageTypeDelegate::setEditorData
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const override
Definition: CREPlayerRepliesPanel.cpp:38
CREPlayerRepliesPanel::setData
void setData(const QList< QStringList > &data)
Definition: CREPlayerRepliesPanel.cpp:123
CREPlayerRepliesPanel::myReplies
QTableWidget * myReplies
Definition: CREPlayerRepliesPanel.h:42
convertType
const char * convertType(const QString &type)
Definition: CREPlayerRepliesPanel.cpp:98
navar-midane_time.data
data
Definition: navar-midane_time.py:11
rt_say
@ rt_say
Definition: dialog.h:8
CFweardisguise.option
option
Definition: CFweardisguise.py:16
say.box
box
Definition: say.py:152
sproto.h
rt_reply
@ rt_reply
Definition: dialog.h:9
buttons
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your and press< Return > You can also use say if you feel like typing a little extra Other NPCs may not speak to but display intelligence with their movement Some monsters can be and may attack the nearest of your enemies Others can be in that they follow you around and help you in your quest to kill enemies and find treasure SPECIAL ITEMS There are many special items which can be found in of these the most important may be the signs all a player must do is apply the handle In the case of buttons
Definition: survival-guide.txt:57
CREPlayerRepliesPanel.h
createItem
QTableWidgetItem * createItem(const QString &text, const QString &edit)
Definition: CREPlayerRepliesPanel.cpp:106
CREPlayerRepliesPanel::myOriginal
QList< QStringList > myOriginal
Definition: CREPlayerRepliesPanel.h:43
reply_type
reply_type
Definition: dialog.h:7
dialog.h
get_reply_text_own
const char * get_reply_text_own(reply_type rt)
Definition: monster.cpp:2320
CREMessageTypeDelegate
Definition: CREPlayerRepliesPanel.cpp:22
item
Definition: item.py:1
rt_question
@ rt_question
Definition: dialog.h:10
CREPlayerRepliesPanel::onReset
void onReset(bool)
Definition: CREPlayerRepliesPanel.cpp:165
autojail.value
value
Definition: autojail.py:6
CREMessageTypeDelegate::setModelData
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
Definition: CREPlayerRepliesPanel.cpp:47
npc_dialog.index
int index
Definition: npc_dialog.py:102
addReply
static PyObject * addReply(PyObject *self, PyObject *args)
Definition: cfpython.cpp:671
reset
Python Guilds Quick outline Add a guild(mapmakers) this is still a problem *after dropping the token to gain access to the stove a woodfloor now appears which is Toolshed Token(found in Guild_HQ) *Note also have multiple gates in place to protect players and items from the mana explosion drop x for Jewelers room *Jewelers room works just need to determine what x is drop x for Thaumaturgy room *Thaumaturgy room works just need to determine what x is drop gold dropping the Firestar named fearless allows access to but I suspect that the drop location of the chest is not as intended because the player is in the way once you enter the chest the exit back to the basement is things such as the message et al reside on teleporters which then transport items to the map as they are when the map is reset(which is normal)
say.item
dictionary item
Definition: say.py:149
connect
Definition: connect.py:1
text
Crossfire Protocol most of the time after the actual code was already omit certain important and possibly make life miserable any new developer or curious player should be able to find most of the relevant information here If inconsistencies are found or this documentation proves to be consider the latest server side protocol code in the public source code repository as the authoritative reference Introduction If you were ever curious enough to telnet or netcat to a Crossfire chances are you were sorely disappointed While the protocol may seem to use plain text at it actually uses a mix of ASCII and binary data This handbook attempts to document various aspects of the Crossfire protocol As consult the README file to find out how to get in touch with helpful people via mailing and more History the communications plan was set to be a text based system It was up to the server and client to parse these messages and determine what to do These messages were assumed to be line per message At a reasonably early stage of Eric Anderson wrote a then the data itself you could send many data and after the other end could decode these commands This works fairly but I think the creation of numerous sub packets has some performance hit the eutl was not especially well so writing a client for a different platform became more Eric left to work on other products shortly after writing his which didn t really leave anyone with a full understanding of the socket code I have decided to remove the eutl dependency At least one advantage is that having this network related code directly in the client and server makes error handling a bit easier cleaner Packet Format the outside packet method the byte size for the size information is not included here Eutl originally used bytes for the size to bytes seems it makes a least some sense The actual data is something of the nature of the commands listed below It is a text followed by possible other data The remaining data can be binary it is up to the client and server to decode what it sent The commands as described below is just the data portion of the packet If writing a new remember that you must take into account the size of the packet There is no termination of other than knowing how long it should be For most everything that is sent is text This is more or less how things worked under except it packed the ints into bytes in a known order In some we handle ints as in they are sent as binary information How any command handles it is detailed below in the command description The S and C represent the direction of the we use MSB as well as any ints or shorts that get sent inside the packets All packets are defined to have at least one word of text
Definition: protocol.txt:84
ring_occidental_mages.r
r
Definition: ring_occidental_mages.py:6
is_valid_types_gen.type
list type
Definition: is_valid_types_gen.py:25
CREPlayerRepliesPanel::CREPlayerRepliesPanel
CREPlayerRepliesPanel(QWidget *parent)
Definition: CREPlayerRepliesPanel.cpp:65
CREPlayerRepliesPanel::data
QList< QStringList > data() const
Definition: CREPlayerRepliesPanel.cpp:135