Crossfire Server, Trunk
CREResourcesWindow.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 <Qt>
14 #include <QtWidgets>
15 #include <QScriptValue>
16 #include <stdexcept>
17 
18 #include "CREResourcesWindow.h"
19 #include "CREPixmap.h"
20 
21 #include "CREFilterDialog.h"
22 #include "CREFilterDefinition.h"
23 
24 #include "CRESettings.h"
25 
26 #include "CREReportDialog.h"
27 #include "CREReportDisplay.h"
28 #include "CREReportDefinition.h"
29 
37 #include "recipes/RecipePanel.h"
38 #include "CREMapPanel.h"
39 #include "regions/RegionPanel.h"
40 #include "CREQuestPanel.h"
41 #include "CREMessagePanel.h"
44 #include "faces/FacesetsPanel.h"
46 
48 
50 #include "MessageFile.h"
52 
53 #include "CREScriptEngine.h"
54 
55 #include "random_maps/RandomMap.h"
57 
58 #include "global.h"
59 #include "recipe.h"
60 #include "assets.h"
61 #include "AssetsManager.h"
62 
63 #include "MessageManager.h"
64 #include "ResourcesManager.h"
65 #include "assets/AssetModel.h"
66 #include "faces/FacePanel.h"
67 #include "sounds/SoundFilesPanel.h"
68 #include "sounds/SoundFilePanel.h"
69 #include "sounds/GameSoundsPanel.h"
70 #include "sounds/GameSoundPanel.h"
71 #include "QuickFilterDialog.h"
72 
73 CREResourcesWindow::CREResourcesWindow(CREMapInformationManager* store, MessageManager* messages, ResourcesManager* resources, ScriptFileManager* scripts, AssetModel *model, const QModelIndex &root, QWidget* parent) : QWidget(parent)
74 {
75  QApplication::setOverrideCursor(Qt::WaitCursor);
76  setWindowTitle(model->data(root, Qt::DisplayRole).toString());
77 
78  Q_ASSERT(store);
79  myStore = store;
80  Q_ASSERT(messages);
82  Q_ASSERT(resources);
83  myResources = resources;
84  Q_ASSERT(scripts);
86  myModel = new ScriptFilterAssetModel(model, &myEngine, this);
87  myTreeRoot = root;
88 
89  setAttribute(Qt::WA_DeleteOnClose);
90 
91  QVBoxLayout* layout = new QVBoxLayout(this);
92 
93  myFiltersMenu = new QMenu(this);
94  QHBoxLayout* buttons = new QHBoxLayout();
95  myFilterButton = new QPushButton(tr("Filter..."), this);
96  myFilterButton->setMenu(myFiltersMenu);
97  buttons->addWidget(myFilterButton);
98 
99  myReportsMenu = new QMenu(this);
100  QPushButton* report = new QPushButton(tr("Report"), this);
101  report->setMenu(myReportsMenu);
102  buttons->addWidget(report);
103 
104  layout->addLayout(buttons);
105 
106  auto splitter = new QSplitter(this);
107  layout->addWidget(splitter);
108 
109  myTree = new QTreeView(this);
110  myTree->setModel(myModel);
111  myTree->setRootIndex(myModel->mapFromSource(root));
112  splitter->addWidget(myTree);
113  myTree->setIconSize(QSize(32, 32));
114  myTree->collapseAll();
115  myTree->expand(myModel->mapFromSource(root));
116  myTree->setSelectionMode(QAbstractItemView::SingleSelection);
117  myTree->setDragEnabled(true);
118  myTree->setDropIndicatorShown(true);
119  myTree->setDragDropMode(QAbstractItemView::DragDrop);
120  myTree->setContextMenuPolicy(Qt::CustomContextMenu);
121  connect(myTree, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(treeCustomMenu(const QPoint&)));
122  connect(myTree->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(currentRowChanged(const QModelIndex&, const QModelIndex&)));
123  connect(myModel, &QAbstractItemModel::rowsInserted, [this](const QModelIndex &parent, int /*first*/, int /*last*/) {
124  myTree->expand(parent);
125  });
126 
127  QWidget* w = new QWidget(splitter);
128  myStackedPanels = new QStackedLayout(w);
129  splitter->addWidget(w);
130 
131  /* dummy panel to display for empty items */
132  AssetWrapperPanel* dummy = new AssetWrapperPanel(this);
133  dummy->addLabel(tr("No details available."), nullptr);
134  addPanel("empty", dummy);
135  myStackedPanels->setCurrentWidget(dummy);
136  myCurrentPanel = dummy;
137 
138  connect(&myFiltersMapper, SIGNAL(mapped(QObject*)), this, SLOT(onFilterChange(QObject*)));
139  updateFilters();
140  connect(&myReportsMapper, SIGNAL(mapped(QObject*)), this, SLOT(onReportChange(QObject*)));
141  updateReports();
142 
143  addPanel("Archetype", new ArchetypePanel(model, this));
144  addPanel("Face", new CREFacePanel(this, model, myResources, myStore));
145  addPanel("Animation", new AnimationPanel(this, model));
146  addPanel("Artifact", new ArtifactPanel(this, myResources));
147  addPanel("ArtifactList", new ArtifactListPanel(this));
148  addPanel("Recipe", new RecipePanel(this));
149  addPanel("Treasure", new TreasurePanel(this));
150  addPanel("TreasureList", new CRETreasurePanel(model, this));
151  addPanel("Faceset", new FacesetsPanel(this, myResources->licenseManager()));
152  addPanel("Quest", new CREQuestPanel(model, this));
153  addPanel("QuestStep", new QuestStepPanel(myMessages, this));
154  addPanel("GeneralMessage", new CREGeneralMessagePanel(this));
155  addPanel("Region", new RegionPanel(this));
156  addPanel("Map", new CREMapPanel(myScripts, this));
157  addPanel("Script", new CREScriptPanel(model, this));
158  addPanel("Message", new CREMessagePanel(myMessages, this));
159  addPanel("RandomMap", new CRERandomMapPanel(this));
160  addPanel("AttackMessage", new AttackMessagePanel(this));
161  addPanel("SoundFiles", new SoundFilesPanel(this));
162  addPanel("SoundFile", new SoundFilePanel(this, model));
163  addPanel("GameSounds", new GameSoundsPanel(this));
164  addPanel("GameSound", new GameSoundPanel(this));
165 
166  splitter->setSizes({5000, 5000});
167 
168  QApplication::restoreOverrideCursor();
169 }
170 
172 {
173  qDeleteAll(myPanels);
174 }
175 
176 void CREResourcesWindow::currentRowChanged(const QModelIndex &current, const QModelIndex &)
177 {
178  if (!current.isValid()) {
179  myCurrentPanel = nullptr;
180  return;
181  }
182 
183  auto rc = myModel->mapToSource(current);
184  AssetWrapper *item = reinterpret_cast<AssetWrapper *>(rc.internalPointer());
185  if (!item) {
186  return;
187  }
188 
189  auto newPanel = myPanels[item->displayPanelName()];
190  if (!newPanel) {
191 // printf("no panel for %s\n", qPrintable(item->getPanelName()));
192  return;
193  }
194 
195  newPanel->setAsset(item);
196 
197  if (myCurrentPanel != newPanel) {
198  myStackedPanels->setCurrentWidget(newPanel);
199  myCurrentPanel = newPanel;
200  }
201 }
202 
204 {
205  panel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
206  myPanels[name] = panel;
207  myStackedPanels->addWidget(panel);
208 }
209 
211 {
212  CREFilterDialog dlg;
213  if (dlg.exec() != QDialog::Accepted)
214  return;
215 
216  /* sending this signal will ultimately call our own updateFilters() */
217  emit filtersModified();
218 }
219 
221 {
222  CREReportDialog dlg;
223  if (dlg.exec() != QDialog::Accepted)
224  return;
225 
226  /* sending this signal will ultimately call our own updateReports() */
227  emit reportsModified();
228 }
229 
231 {
233  settings.loadFilters(myFilters);
234 
235  myFiltersMenu->clear();
236 
237  QAction* clear = new QAction(tr("(none)"), this);
238  connect(clear, SIGNAL(triggered()), this, SLOT(clearFilter()));
239  myFiltersMenu->addAction(clear);
240 
241  if (myFilters.filters().size() > 0)
242  {
243 
245  {
246  QAction* a = new QAction(filter->name(), this);
247  myFiltersMenu->addAction(a);
248  myFiltersMapper.setMapping(a, filter);
249  connect(a, SIGNAL(triggered()), &myFiltersMapper, SLOT(map()));
250  }
251  }
252  myFiltersMenu->addSeparator();
253 
254  QAction* quick = new QAction(tr("Quick filter..."), this);
255  connect(quick, SIGNAL(triggered()), this, SLOT(onQuickFilter()));
256  myFiltersMenu->addAction(quick);
257  QAction* dialog = new QAction(tr("Filters definition..."), this);
258  connect(dialog, SIGNAL(triggered()), this, SLOT(onFilter()));
259  myFiltersMenu->addAction(dialog);
260 
261  clearFilter();
262 }
263 
264 void CREResourcesWindow::onFilterChange(QObject* object) {
265  CREFilterDefinition* filter = qobject_cast<CREFilterDefinition*>(object);
266  if (filter == NULL)
267  return;
268  setFilter(filter->filter(), filter->name());
269 }
270 
272  QuickFilterDialog dlg(this, myModel->filter());
273  if (dlg.exec() != QDialog::Accepted) {
274  return;
275  }
276  setFilter(dlg.filter(), dlg.filter());
277 }
278 
280  setFilter(QString(), QString());
281 }
282 
283 void CREResourcesWindow::setFilter(const QString &filter, const QString &name) {
285  myFilterButton->setText(filter.isEmpty() ? tr("Filter...") : tr("Filter: %1").arg(name));
286  auto root = myModel->mapFromSource(myTreeRoot);
287  if (!myTreeRoot.isValid() || root.isValid()) {
288  if (myTree->model() == nullptr) {
289  myTree->setModel(myModel);
290  connect(myTree->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(currentRowChanged(const QModelIndex&, const QModelIndex&)));
291  }
292  myTree->setRootIndex(root);
293  } else {
294  myTree->setModel(nullptr);
295  }
296 }
297 
299 {
301  settings.loadReports(myReports);
302 
303  myReportsMenu->clear();
304 
305  if (myReports.reports().size() > 0)
306  {
308  {
309  QAction* a = new QAction(report->name(), this);
310  myReportsMenu->addAction(a);
311  myReportsMapper.setMapping(a, report);
312  connect(a, SIGNAL(triggered()), &myReportsMapper, SLOT(map()));
313  }
314 
315  myReportsMenu->addSeparator();
316  }
317 
318  QAction* dialog = new QAction(tr("Reports definition..."), this);
319  connect(dialog, SIGNAL(triggered()), this, SLOT(onReport()));
320  myReportsMenu->addAction(dialog);
321 }
322 
324 {
325  CREReportDefinition* report = qobject_cast<CREReportDefinition*>(object);
326  if (report == NULL)
327  return;
328 
329  int count = myModel->rowCount(myTree->rootIndex());
330 
331  QProgressDialog progress(tr("Generating report..."), tr("Abort report"), 0, count - 1, this);
332  progress.setWindowTitle(tr("Report: '%1'").arg(report->name()));
333  progress.setWindowModality(Qt::WindowModal);
334 
335  QStringList headers = report->header().split("\n");
336  QStringList fields = report->itemDisplay().split("\n");
337  QString sort = report->itemSort();
338 
339  QString text("<table><thead><tr>");
340 
341  foreach(QString header, headers)
342  {
343  text += "<th>" + header + "</th>";
344  }
345  text += "</tr></thead><tbody>";
346 
347  CREScriptEngine engine;
348  std::vector<QScriptValue> items;
349  for (int i = 0; i < count; i++) {
350  auto idx = myModel->index(i, 0, myTree->rootIndex());
351  if (!idx.isValid()) {
352  continue;
353  }
354  idx = myModel->mapToSource(idx);
355  auto w = static_cast<AssetWrapper *>(idx.internalPointer());
356  items.push_back(engine.newQObject(w));
357  }
358 
359  if (!sort.isEmpty())
360  {
361  try
362  {
363  progress.setLabelText(tr("Sorting items..."));
364 
365  engine.pushContext();
366 
367  sort = "(function(left, right) { return " + sort + "; })";
368  QScriptValue sortFun = engine.evaluate(sort);
369  if (!sortFun.isValid() || engine.hasUncaughtException())
370  throw std::runtime_error("A script error happened while compiling the sort criteria:\n" + engine.uncaughtException().toString().toStdString());
371 
372  std::sort(items.begin(), items.end(), [&sortFun, &engine](QScriptValue left, QScriptValue right) {
373  QScriptValueList args;
374  args.push_back(left);
375  args.push_back(right);
376  auto ret = sortFun.call(QScriptValue(), args);
377  if (!ret.isValid() || engine.hasUncaughtException())
378  {
379  throw std::runtime_error("A script error happened while sorting items:\n" + engine.uncaughtException().toString().toStdString());
380  return false;
381  }
382  return ret.isValid() ? ret.toBoolean() : true;
383  });
384  printf("complete");
385  engine.popContext();
386  }
387  catch (std::runtime_error& ex)
388  {
389  QMessageBox::critical(this, "Script error", ex.what(), QMessageBox::Ok);
390  return;
391  }
392  }
393 
394  progress.setLabelText(tr("Generating items text..."));
395  foreach(QScriptValue item, items)
396  {
397  if (progress.wasCanceled())
398  return;
399 
400  text += "<tr>";
401 
402  engine.pushContext();
403  engine.globalObject().setProperty("item", item);
404 
405  foreach(QString field, fields)
406  {
407  text += "<td>";
408  QString data = engine.evaluate(field).toString();
409  if (engine.hasUncaughtException())
410  {
411  QMessageBox::critical(this, "Script error", "A script error happened while display items:\n" + engine.uncaughtException().toString(), QMessageBox::Ok);
412  return;
413  }
414  text += data;
415  text += "</td>\n";
416  }
417  engine.popContext();
418  text += "</tr>\n";
419 
420  progress.setValue(progress.value() + 1);
421  }
422  text += "</tbody>";
423 
424  QStringList footers = report->footer().split("\n");
425  text += "<tfoot>";
426 
427  foreach(QString footer, footers)
428  {
429  text += "<th>" + footer + "</th>";
430  }
431  text += "</tfoot>";
432 
433  text += "</table>";
434  qDebug() << "report finished";
435 
436  CREReportDisplay display(text, tr("Report: '%1'").arg(report->name()));
437  display.exec();
438  progress.hide();
439 }
440 
441 void CREResourcesWindow::treeCustomMenu(const QPoint & pos)
442 {
443  QMenu menu;
444 
445  QModelIndex index = myModel->mapToSource(myTree->indexAt(pos));
446  if (index.isValid() && index.internalPointer()) {
447  AssetWrapper *item = reinterpret_cast<AssetWrapper *>(index.internalPointer());
448  if (item) {
449  item->fillMenu(&menu);
450  }
451  }
452 
453  if (menu.actions().size() == 0)
454  return;
455  menu.exec(myTree->mapToGlobal(pos) + QPoint(5, 5));
456 }
457 
459 {
460  auto name = QInputDialog::getText(this, "Create new quest", "New quest code").toStdString();
461  if (name.empty()) {
462  return;
463  }
464  if (getManager()->quests()->find(name)) {
465  QMessageBox::critical(this, "Quest already exists", tr("Quest %1 already exists!").arg(name.data()));
466  return;
467  }
468 
469  auto quest = quest_create(name.data());
470  quest->face = getManager()->faces()->get("quest_generic.111");
472 }
473 
475 {
476 #if 0
477  MessageFile* file = new MessageFile("<new file>");
478  file->setModified();
479  myMessages->messages().append(file);
480 #endif
481 }
CREResourcesWindow::onFilter
void onFilter()
Definition: CREResourcesWindow.cpp:210
SoundFilePanel
Definition: SoundFilePanel.h:22
MessageFile.h
ResourcesManager::licenseManager
LicenseManager * licenseManager()
Definition: ResourcesManager.h:152
global.h
AssetWrapperPanel::addLabel
QLabel * addLabel(const QString &label, const char *property, bool wrapText=false)
Definition: AssetWrapperPanel.cpp:68
settings
struct Settings settings
Definition: init.cpp:139
CREResourcesWindow::onFilterChange
void onFilterChange(QObject *object)
Definition: CREResourcesWindow.cpp:264
ScriptFilterAssetModel
Definition: AssetModel.h:78
CREFilterDialog.h
layout
Definition: main.cpp:84
CREResourcesWindow::reportsModified
void reportsModified()
AnimationPanel
Definition: AnimationPanel.h:29
ArtifactListPanel.h
MessageManager::messages
QList< MessageFile * > & messages()
Definition: MessageManager.cpp:51
python_init.scripts
scripts
Definition: python_init.py:11
ScriptFilterAssetModel::setFilter
void setFilter(const QString &filter)
Definition: AssetModel.cpp:256
CREResourcesWindow::myFiltersMapper
QSignalMapper myFiltersMapper
Definition: CREResourcesWindow.h:62
CREResourcesWindow::updateFilters
void updateFilters()
Definition: CREResourcesWindow.cpp:230
AssetsCollection::get
T * get(const Key &name)
Definition: AssetsCollection.h:89
FacePanel.h
CREReportDefinition
Definition: CREReportDefinition.h:19
CREQuestPanel.h
CREScriptPanel
Definition: ScriptFilePanel.h:23
filter
Definition: filter.py:1
CRESettings.h
CREResourcesWindow::onReport
void onReport()
Definition: CREResourcesWindow.cpp:220
ArtifactListPanel
Definition: ArtifactListPanel.h:23
recipe.h
CREResourcesWindow::myMessages
MessageManager * myMessages
Definition: CREResourcesWindow.h:57
fields
non standard information is not specified or uptime fields
Definition: arch-handbook.txt:204
RandomMap.h
AssetWrapperPanel
Definition: AssetWrapperPanel.h:29
CREResourcesWindow::myFilters
CREFilterDefinitionManager myFilters
Definition: CREResourcesWindow.h:63
CREResourcesWindow::addPanel
void addPanel(QString name, AssetWrapperPanel *panel)
Definition: CREResourcesWindow.cpp:203
root
static char root[500]
Definition: mapper.cpp:304
TreasureListPanel.h
mad_mage_user.file
file
Definition: mad_mage_user.py:15
CREMessagePanel.h
TreasurePanel
Definition: TreasurePanel.h:26
AssetModel.h
CREReportDefinitionManager::reports
QList< CREReportDefinition * > & reports()
Definition: CREReportDefinitionManager.cpp:42
CREResourcesWindow::treeCustomMenu
void treeCustomMenu(const QPoint &pos)
Definition: CREResourcesWindow.cpp:441
CREMapInformationManager
Definition: CREMapInformationManager.h:27
ScriptFileManager.h
CREResourcesWindow::myReportsMenu
QMenu * myReportsMenu
Definition: CREResourcesWindow.h:64
CREScriptEngine
Definition: CREScriptEngine.h:18
quest_create
quest_definition * quest_create(const char *name)
Definition: Quests.cpp:63
ScriptFileManager
Definition: ScriptFileManager.h:26
QuestStepPanel
Definition: CREQuestPanel.h:30
AssetsManager.h
getManager
AssetsManager * getManager()
Definition: assets.cpp:305
AssetWrapperPanel.h
AssetWrapper
Definition: AssetWrapper.h:25
CREResourcesWindow::myTree
QTreeView * myTree
Definition: CREResourcesWindow.h:51
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
CREGeneralMessagePanel
Definition: GeneralMessagePanel.h:21
quest
Definition: quest.py:1
CREResourcesWindow::CREResourcesWindow
CREResourcesWindow(CREMapInformationManager *store, MessageManager *messages, ResourcesManager *resources, ScriptFileManager *scripts, AssetModel *model, const QModelIndex &root, QWidget *parent)
Definition: CREResourcesWindow.cpp:73
AssetsManager::quests
Quests * quests()
Definition: AssetsManager.h:71
ArtifactPanel.h
disinfect.map
map
Definition: disinfect.py:4
CREFilterDialog
Definition: CREFilterDialog.h:24
CREResourcesWindow::myFiltersMenu
QMenu * myFiltersMenu
Definition: CREResourcesWindow.h:61
GameSoundsPanel.h
SoundFilePanel.h
ArtifactPanel
Definition: ArtifactPanel.h:29
ArchetypePanel
Definition: ArchetypePanel.h:27
CREResourcesWindow::myStackedPanels
QStackedLayout * myStackedPanels
Definition: CREResourcesWindow.h:55
CREResourcesWindow::myEngine
CREScriptEngine myEngine
Definition: CREResourcesWindow.h:67
CREResourcesWindow::myCurrentPanel
AssetWrapperPanel * myCurrentPanel
Definition: CREResourcesWindow.h:53
ResourcesManager
Definition: ResourcesManager.h:80
RecipePanel.h
navar-midane_time.data
data
Definition: navar-midane_time.py:11
CREFacePanel
Definition: FacePanel.h:30
GameSoundPanel.h
CREMapPanel.h
FacesetsPanel.h
CREResourcesWindow::onReportChange
void onReportChange(QObject *object)
Definition: CREResourcesWindow.cpp:323
disinfect.count
int count
Definition: disinfect.py:7
CREResourcesWindow::myTreeRoot
QModelIndex myTreeRoot
Definition: CREResourcesWindow.h:52
RecipePanel
Definition: RecipePanel.h:27
CREReportDefinition.h
ArchetypePanel.h
CREResourcesWindow::myReportsMapper
QSignalMapper myReportsMapper
Definition: CREResourcesWindow.h:65
TreasurePanel.h
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
ScriptFilePanel.h
CRESettings
Definition: CRESettings.h:21
CREResourcesWindow::addQuest
void addQuest(bool)
Definition: CREResourcesWindow.cpp:458
AssetModel::data
virtual QVariant data(const QModelIndex &index, int role) const override
Definition: AssetModel.cpp:70
CREFilterDefinition
Definition: CREFilterDefinition.h:19
CREResourcesWindow::setFilter
void setFilter(const QString &filter, const QString &name)
Definition: CREResourcesWindow.cpp:283
CREReportDialog.h
CREResourcesWindow::clearFilter
void clearFilter()
Definition: CREResourcesWindow.cpp:279
CREResourcesWindow::myResources
ResourcesManager * myResources
Definition: CREResourcesWindow.h:58
navar-midane_apply.messages
list messages
Definition: navar-midane_apply.py:8
QuickFilterDialog.h
CREResourcesWindow::myReports
CREReportDefinitionManager myReports
Definition: CREResourcesWindow.h:66
CREResourcesWindow::myPanels
QHash< QString, QPointer< AssetWrapperPanel > > myPanels
Definition: CREResourcesWindow.h:54
ResourcesManager.h
AnimationPanel.h
CREPixmap.h
report
Definition: report.py:1
AssetsCollection::define
T * define(const Key &name, T *asset)
Definition: AssetsCollection.h:120
CREResourcesWindow::addMessage
void addMessage(bool)
Definition: CREResourcesWindow.cpp:474
CREMapInformationManager.h
ScriptFilterAssetModel::filter
const QString & filter() const
Definition: AssetModel.h:83
item
Definition: item.py:1
CREResourcesWindow.h
CREResourcesWindow::myFilterButton
QPushButton * myFilterButton
Definition: CREResourcesWindow.h:60
RegionPanel
Definition: RegionPanel.h:22
GameSoundPanel
Definition: GameSoundPanel.h:19
CREReportDialog
Definition: CREReportDialog.h:24
AssetsManager::faces
Faces * faces()
Definition: AssetsManager.h:39
CREMapPanel
Definition: CREMapPanel.h:26
RegionPanel.h
CREResourcesWindow::updateReports
void updateReports()
Definition: CREResourcesWindow.cpp:298
CREResourcesWindow::~CREResourcesWindow
virtual ~CREResourcesWindow()
Definition: CREResourcesWindow.cpp:171
CREScriptEngine.h
MessageFile
Definition: MessageFile.h:68
CRETreasurePanel
Definition: TreasureListPanel.h:28
CREFilterDefinitionManager::filters
QList< CREFilterDefinition * > & filters()
Definition: CREFilterDefinitionManager.cpp:41
assets.h
SoundFilesPanel.h
npc_dialog.index
int index
Definition: npc_dialog.py:102
QuickFilterDialog::filter
QString filter() const
Definition: QuickFilterDialog.cpp:33
CRERandomMapPanel
Definition: RandomMapPanel.h:25
GameSoundsPanel
Definition: GameSoundsPanel.h:19
CREResourcesWindow::myScripts
ScriptFileManager * myScripts
Definition: CREResourcesWindow.h:59
CREResourcesWindow::myStore
CREMapInformationManager * myStore
Definition: CREResourcesWindow.h:56
CREFilterDefinition.h
ArtifactWrapper.h
CREMessagePanel
Definition: CREMessagePanel.h:31
CREReportDisplay.h
a
Magical Runes Runes are magical inscriptions on the dungeon which cast a spell or detonate when something steps on them Flying objects don t detonate runes Beware ! Runes are invisible most of the time They are only visible occasionally ! There are several runes which are there are some special runes which may only be called with the invoke and people may apply it to read it Maybe useful for mazes ! This rune will not nor is it ordinarily invisible Partial Visibility of they ll be visible only part of the time They have a(your level/2) chance of being visible in any given round
MessageManager
Definition: MessageManager.h:25
AssetModel
Definition: AssetModel.h:29
CREResourcesWindow::onQuickFilter
void onQuickFilter()
Definition: CREResourcesWindow.cpp:271
CREResourcesWindow::myModel
ScriptFilterAssetModel * myModel
Definition: CREResourcesWindow.h:50
RandomMapPanel.h
FacesetsPanel
Definition: FacesetsPanel.h:28
connect
Definition: connect.py:1
hall_of_fame.header
list header
Definition: hall_of_fame.py:38
AttackMessagePanel
Definition: AttackMessagePanel.h:26
AttackMessagePanel.h
replace.current
current
Definition: replace.py:64
quests
static struct_quest ** quests
Definition: mapper.cpp:894
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
CREResourcesWindow::currentRowChanged
void currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
Definition: CREResourcesWindow.cpp:176
SoundFilesPanel
Definition: SoundFilesPanel.h:18
CREQuestPanel
Definition: CREQuestPanel.h:40
CREResourcesWindow::filtersModified
void filtersModified()
QuickFilterDialog
Definition: QuickFilterDialog.h:23
CREReportDisplay
Definition: CREReportDisplay.h:19
GeneralMessagePanel.h
MessageManager.h