Crossfire Server, Trunk
CREMessageItemModel.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 
15 #include "CREMessageItemModel.h"
16 
17 CREMessageItemModel::CREMessageItemModel(QObject* parent) : QAbstractItemModel(parent), myMessage(nullptr)
18 {
19 }
20 
22 {
23 }
24 
26 {
27  beginResetModel();
29  endResetModel();
30 }
31 
33 {
34  auto blue(myBlue), red(myRed);
35  myBlue.clear();
36  myRed.clear();
37 
38  int row = index.row();
39  if (row < 0 || row >= myMessage->rules().size())
40  return;
41 
42  MessageRule* rule = myMessage->rules()[row];
43 
44  foreach(QStringList pre, rule->preconditions())
45  {
46  if (pre.size() < 3)
47  continue;
48 
49  if (pre[0] != "token" && pre[0] != "npctoken")
50  continue;
51 
52  QStringList acceptable = pre;
53  acceptable.removeFirst();
54  acceptable.removeFirst();
55 
56  for (int c = 0; c < myMessage->rules().size(); c++)
57  {
59 
60  if (check == rule)
61  continue;
62 
63  bool match = false;
64  foreach(QStringList post, check->postconditions())
65  {
66  if (post.size() < 3)
67  continue;
68  if ((post[0] != "settoken" && post[0] != "setnpctoken") || post[1] != pre[1] || !acceptable.contains(post[2]))
69  continue;
70  match = true;
71  break;
72  }
73 
74  if (match)
75  myRed.insert(c);
76  }
77  }
78 
79  foreach(QStringList post, rule->postconditions())
80  {
81  if (post.size() < 3)
82  continue;
83 
84  if (post[0] != "settoken" && post[0] != "setnpctoken")
85  continue;
86 
87  for (int c = 0; c < myMessage->rules().size(); c++)
88  {
90 
91  if (check == rule)
92  continue;
93 
94  bool match = false;
95  foreach(QStringList pre, check->preconditions())
96  {
97  if (pre.size() < 3)
98  continue;
99  if ((pre[0] != "token" && pre[0] != "npctoken") || pre[1] != post[1])
100  continue;
101 
102  QStringList acceptable = pre;
103  acceptable.removeFirst();
104  acceptable.removeFirst();
105  if (!acceptable.contains(post[2]))
106  continue;
107 
108  match = true;
109  break;
110  }
111 
112  if (match)
113  myBlue.insert(c);
114  }
115  }
116 
117  for (int b : myBlue)
118  {
119  emit dataChanged(createIndex(b, 0), createIndex(b, 6));
120  blue.remove(b);
121  red.remove(b);
122  }
123  for (int r : myRed)
124  {
125  emit dataChanged(createIndex(r, 0), createIndex(r, 6));
126  blue.remove(r);
127  red.remove(r);
128  }
129 
130  for (int old : red + blue)
131  {
132  emit dataChanged(createIndex(old, 0), createIndex(old, 6));
133  }
134 }
135 
136 int CREMessageItemModel::columnCount(const QModelIndex& parent) const
137 {
138  if (parent.isValid())
139  return 0;
140  return 6;
141 }
142 
143 QModelIndex CREMessageItemModel::index(int row, int column, const QModelIndex& parent) const
144 {
145  if (parent.isValid())
146  return QModelIndex();
147  return createIndex(row, column);
148 }
149 
150 QModelIndex CREMessageItemModel::parent(const QModelIndex&) const
151 {
152  return QModelIndex();
153 }
154 
155 int CREMessageItemModel::rowCount(const QModelIndex& index) const
156 {
157  if (!myMessage || index.isValid())
158  return 0;
159 
160  return myMessage->rules().size();
161 }
162 
163 static QString toDisplay(const QList<QStringList>& list)
164 {
165  QStringList data;
166  foreach(QStringList item, list)
167  data.append(item.join(" "));
168  return data.join("\n");
169 }
170 
171 QVariant CREMessageItemModel::data(const QModelIndex& index, int role) const
172 {
173  if (myMessage == NULL || !index.isValid())
174  return QVariant();
175 
176  if (role == Qt::BackgroundColorRole)
177  {
178  if (myBlue.contains(index.row()))
179  return QVariant::fromValue(QBrush(Qt::blue));
180  if (myRed.contains(index.row()))
181  return QVariant::fromValue(QBrush(Qt::red));
182  return QVariant();
183  }
184 
185  if (role != Qt::DisplayRole && role != Qt::EditRole)
186  return QVariant();
187 
188  Q_ASSERT(index.row() < myMessage->rules().size());
189  const MessageRule* rule = myMessage->rules()[index.row()];
190 
191  switch(index.column())
192  {
193  case 0:
194  return role == Qt::DisplayRole ? QVariant::fromValue(rule->match().join("\n")) : QVariant::fromValue(rule->match());
195  case 1:
196  return role == Qt::DisplayRole ? QVariant::fromValue(toDisplay(rule->preconditions())) : QVariant::fromValue(rule->preconditions());
197  case 2:
198  return role == Qt::DisplayRole ? QVariant::fromValue(toDisplay(rule->replies())) : QVariant::fromValue(rule->replies());
199  case 3:
200  return role == Qt::DisplayRole ? QVariant::fromValue(rule->messages().join("\n")) : QVariant::fromValue(rule->messages());
201  case 4:
202  return role == Qt::DisplayRole ? QVariant::fromValue(toDisplay(rule->postconditions())) : QVariant::fromValue(rule->postconditions());
203  case 5:
204  return role == Qt::DisplayRole ? QVariant::fromValue(rule->include().join("\n")) : QVariant::fromValue(rule->include());
205  }
206 
207  return QVariant();;
208 }
209 
210 QVariant CREMessageItemModel::headerData(int section, Qt::Orientation orientation, int role) const
211 {
212  if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
213  return QVariant();
214 
215  switch(section)
216  {
217  case 0:
218  return tr("match");
219  case 1:
220  return tr("pre-conditions");
221  case 2:
222  return tr("player suggested replies");
223  case 3:
224  return tr("NPC messages");
225  case 4:
226  return tr("post-conditions");
227  case 5:
228  return tr("includes");
229  }
230 
231  return QVariant();
232 }
233 
234 Qt::ItemFlags CREMessageItemModel::flags(const QModelIndex& index) const
235 {
236  if (!index.isValid())
237  return 0;
238  return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
239 }
240 
241 bool CREMessageItemModel::setData(const QModelIndex& index, const QVariant& value, int role)
242 {
243  if (!index.isValid() || myMessage == nullptr || myMessage->rules().size() <= index.row())
244  return false;
245  if (role != Qt::EditRole)
246  return false;
247 
248  MessageRule* rule = myMessage->rules()[index.row()];
249 
250  switch (index.column())
251  {
252  case 0:
253  rule->setMatch(value.value<QStringList>());
254  break;
255  case 1:
256  rule->setPreconditions(value.value<QList<QStringList>>());
257  break;
258  case 2:
259  rule->setReplies(value.value<QList<QStringList>>());
260  break;
261  case 3:
262  rule->setMessages(value.value<QStringList>());
263  break;
264  case 4:
265  rule->setPostconditions(value.value<QList<QStringList>>());
266  break;
267  case 5:
268  rule->setInclude(value.value<QStringList>());
269  break;
270  default:
271  return false;
272  }
273 
274  myMessage->setModified(true);
275  emit dataChanged(index, index);
276 
277  return true;
278 }
279 
280 bool CREMessageItemModel::insertRows(int row, int count, const QModelIndex& parent)
281 {
282  if (parent.isValid())
283  return false;
284 
285  beginInsertRows(parent, row, row + count - 1);
286  while (count > 0)
287  {
288  myMessage->rules().insert(row, new MessageRule());
289  count--;
290  }
291  endInsertRows();
292  myMessage->setModified(true);
293 
294  return true;
295 }
296 
297 bool CREMessageItemModel::removeRows(int row, int count, const QModelIndex& parent)
298 {
299  if (parent.isValid())
300  return false;
301  if (row < 0 || row >= myMessage->rules().size())
302  return false;
303 
304  beginRemoveRows(parent, row, row + count);
305  while (count > 0 && row < myMessage->rules().size())
306  {
307  myMessage->rules().removeAt(row);
308  count--;
309  }
310  endRemoveRows();
311  myMessage->setModified(true);
312 
313  return true;
314 }
315 
316 void CREMessageItemModel::moveUpDown(int row, bool up)
317 {
318  if (!myMessage)
319  return;
320 
321  const int shift = up ? -1 : 1;
322  if (row < 0 || row >= myMessage->rules().size() || (row + shift) < 0 || (row + shift) >= myMessage->rules().size())
323  return;
324 
325  MessageRule* moved = myMessage->rules()[row];
326  myMessage->rules()[row] = myMessage->rules()[row + shift];
327  myMessage->rules()[row + shift] = moved;
328 
329  emit dataChanged(createIndex(up ? row - 1 : row, 0), createIndex(up ? row : row + 1, 6));
330  myMessage->setModified(true);
331 }
332 
334 {
335  if (!myMessage || row < 0 || row >= myMessage->rules().count())
336  return;
337 
338  beginInsertRows(QModelIndex(), row + 1, row + 1);
339  myMessage->rules().insert(row + 1, new MessageRule(*myMessage->rules()[row]));
340  endInsertRows();
341  myMessage->setModified(true);
342 }
CREMessageItemModel::CREMessageItemModel
CREMessageItemModel(QObject *parent)
Definition: CREMessageItemModel.cpp:17
MessageFile::setModified
void setModified(bool modified=true)
Definition: MessageFile.cpp:394
MessageFile::rules
QList< MessageRule * > & rules()
Definition: MessageFile.cpp:266
CREMessageItemModel::~CREMessageItemModel
virtual ~CREMessageItemModel()
Definition: CREMessageItemModel.cpp:21
c
static event_registration c
Definition: citylife.cpp:425
CREMessageItemModel::headerData
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override
Definition: CREMessageItemModel.cpp:210
guildoracle.list
list
Definition: guildoracle.py:87
CREMessageItemModel::myMessage
MessageFile * myMessage
Definition: CREMessageItemModel.h:52
CREMessageItemModel::setSelectedRule
void setSelectedRule(const QModelIndex &index)
Definition: CREMessageItemModel.cpp:32
CREMessageItemModel::moveUpDown
void moveUpDown(int row, bool up)
Definition: CREMessageItemModel.cpp:316
CREMessageItemModel::columnCount
virtual int columnCount(const QModelIndex &parent) const override
Definition: CREMessageItemModel.cpp:136
CREMessageItemModel::myRed
QSet< int > myRed
Definition: CREMessageItemModel.h:53
CREMessageItemModel::flags
virtual Qt::ItemFlags flags(const QModelIndex &index) const override
Definition: CREMessageItemModel.cpp:234
CREMessageItemModel::setMessage
void setMessage(MessageFile *message)
Definition: CREMessageItemModel.cpp:25
Ice.b
b
Definition: Ice.py:48
message
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 message
Definition: survival-guide.txt:34
navar-midane_time.data
data
Definition: navar-midane_time.py:11
disinfect.count
int count
Definition: disinfect.py:7
push.match
bool match
Definition: push.py:61
bigchest.check
check
Definition: bigchest.py:10
CREMessageItemModel::removeRows
virtual bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Definition: CREMessageItemModel.cpp:297
item
Definition: item.py:1
autojail.value
value
Definition: autojail.py:6
CREMessageItemModel::parent
virtual QModelIndex parent(const QModelIndex &index) const override
Definition: CREMessageItemModel.cpp:150
MessageFile
Definition: MessageFile.h:68
CREMessageItemModel::insertRows
virtual bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Definition: CREMessageItemModel.cpp:280
npc_dialog.index
int index
Definition: npc_dialog.py:102
toDisplay
static QString toDisplay(const QList< QStringList > &list)
Definition: CREMessageItemModel.cpp:163
CREMessageItemModel::setData
virtual bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Definition: CREMessageItemModel.cpp:241
CREMessageItemModel::myBlue
QSet< int > myBlue
Definition: CREMessageItemModel.h:53
CREMessageItemModel::duplicateRow
void duplicateRow(int row)
Definition: CREMessageItemModel.cpp:333
MessageRule
Definition: MessageFile.h:25
CREMessageItemModel::data
virtual QVariant data(const QModelIndex &index, int role) const override
Definition: CREMessageItemModel.cpp:171
npc_dialog.rule
rule
Definition: npc_dialog.py:108
CREMessageItemModel::rowCount
virtual int rowCount(const QModelIndex &parent) const override
Definition: CREMessageItemModel.cpp:155
ring_occidental_mages.r
r
Definition: ring_occidental_mages.py:6
CREMessageItemModel.h
CREMessageItemModel::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const override
Definition: CREMessageItemModel.cpp:143