Crossfire Server, Trunk
MessageManager.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 "MessageManager.h"
14 #include "MessageFile.h"
15 #include "QuestConditionScript.h"
16 #include "quests/QuestWrapper.h"
17 
18 #include "global.h"
19 
20 #include <QDir>
21 #include <QDebug>
22 
24  setProperty(tipProperty, tr("Display all NPC dialogs."));
25 }
26 
28 {
29  qDeleteAll(myMessages);
30  qDeleteAll(myPreConditions);
31  qDeleteAll(myPostConditions);
32 }
33 
35 {
36  loadDirectory("");
37 
38  /* get pre and post conditions */
41 }
42 
44 {
45  foreach(MessageFile* file, myMessages)
46  {
47  file->save();
48  }
49 }
50 
51 QList<MessageFile*>& MessageManager::messages()
52 {
53  return myMessages;
54 }
55 
56 const QList<MessageFile*>& MessageManager::messages() const
57 {
58  return myMessages;
59 }
60 
62 {
63  foreach(MessageFile* file, myMessages)
64  {
65  if (file->path() == path)
66  return file;
67  }
68 
69  return NULL;
70 }
71 
72 void MessageManager::loadDirectory(const QString& directory)
73 {
74  //qDebug() << "load" << directory;
75  QDir dir(QString("%1/%2/%3").arg(settings.datadir, settings.mapdir, directory));
76 
77  // first messages
78  QStringList messages = dir.entryList(QStringList("*.msg"), QDir::Files);
79  //qDebug() << "found" << messages;
80  foreach(QString message, messages)
81  {
82  QString path = directory + QDir::separator() + message;
83  MessageFile* file = new MessageFile(this, path);
84  if (file->parseFile())
85  {
86  myMessages.append(file);
87  }
88  else
89  {
90  qDebug() << "dialog parse error" << path;
91  delete file;
92  }
93  }
94 
95  // recurse
96  QStringList subdirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
97  foreach(QString sub, subdirs)
98  loadDirectory(directory + QDir::separator() + sub);
99 }
100 
101 QList<QuestConditionScript*> MessageManager::preConditions() const
102 {
103  return myPreConditions;
104 }
105 
106 QList<QuestConditionScript*> MessageManager::postConditions() const
107 {
108  return myPostConditions;
109 }
110 
111 QString MessageManager::loadScriptComment(const QString& path) const
112 {
113  QFile file(path);
114  if (!file.open(QIODevice::ReadOnly))
115  return "";
116 
117  QTextStream stream(&file);
118  QStringList lines = stream.readAll().split("\n");
119 
120  QString comment, line;
121 
122  /* by convention, the first 2 lines are encoding and script name */
123  for(int i = 2; i < lines.size(); i++)
124  {
125  line = lines[i];
126  if (!line.startsWith("# "))
127  break;
128  comment += line.mid(2) + "\n";
129  }
130 
131  return comment.trimmed();
132 }
133 
134 void MessageManager::findPrePost(const QString directory, QList<QuestConditionScript*>& list)
135 {
136  QDir dir(QString("%1/%2/python/dialog/%3").arg(settings.datadir, settings.mapdir, directory));
137  QFileInfoList files = dir.entryInfoList(QStringList("*.py"));
138  foreach(QFileInfo file, files)
139  {
140  list.append(new QuestConditionScript(file.baseName(), loadScriptComment(file.absoluteFilePath())));
141  }
142 }
143 
144 AssetWrapper::PossibleUse MessageManager::uses(const AssetWrapper *asset, std::string &) const {
145  auto quest = dynamic_cast<const QuestWrapper *>(asset);
146  if (quest) {
147  return ChildrenMayUse;
148  }
149  return DoesntUse;
150 }
MessageFile.h
QuestWrapper.h
global.h
line
Install Bug reporting Credits so make sure you have version or later There are files involved in the automatic convert convertall and filelist py GuildList has the list of guilds for the server GuildLocations is what is used by the install script for setting up the maps It has columns in the first is the name of the no spaces The second is the region of the the third is the destination folder for the the fourth is the exit the fifth and sixth are the x and y coords within the exit the seventh eighth and ninth are the exit location for the storage hall If field seven is then it uses the same exit map as for the guild hall itself filelist py has a list of which files to process for each guild hall convert py takes all the files in filelist py and customises them to the specific guild then outputs them into a in the same order that they are listed in GuildLocations convertall py reads the lines from GuildLocations and runs line by line
Definition: README.txt:12
settings
struct Settings settings
Definition: init.cpp:139
Files
Install Bug reporting Credits but rather whatever guild name you are using *With the current map and server there are three they and GreenGoblin *Whatever name you give the folder should but it will still use GUILD_TEMPLATE *You can change what guild it uses by editing the map files Modify Map Files
Definition: README.txt:17
AssetWrapper::tipProperty
static const char * tipProperty
Definition: AssetWrapper.h:34
MessageManager::messages
QList< MessageFile * > & messages()
Definition: MessageManager.cpp:51
guildoracle.list
list
Definition: guildoracle.py:87
MessageManager::findPrePost
void findPrePost(const QString directory, QList< QuestConditionScript * > &list)
Definition: MessageManager.cpp:134
QuestConditionScript.h
mad_mage_user.file
file
Definition: mad_mage_user.py:15
MessageManager::saveMessages
void saveMessages()
Definition: MessageManager.cpp:43
QuestWrapper
Definition: QuestWrapper.h:66
AssetWrapper
Definition: AssetWrapper.h:25
QuestConditionScript
Definition: QuestConditionScript.h:21
quest
Definition: quest.py:1
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
MessageManager::findMessage
MessageFile * findMessage(const QString &path)
Definition: MessageManager.cpp:61
MessageManager::uses
virtual PossibleUse uses(const AssetWrapper *asset, std::string &) const override
Definition: MessageManager.cpp:144
AssetWrapper::ChildrenMayUse
@ ChildrenMayUse
Definition: AssetWrapper.h:32
MessageManager::myMessages
QList< MessageFile * > myMessages
Definition: MessageManager.h:73
MessageManager::myPreConditions
QList< QuestConditionScript * > myPreConditions
Definition: MessageManager.h:74
AssetWrapper::PossibleUse
PossibleUse
Definition: AssetWrapper.h:32
path
pluglist shows those as well as a short text describing each the list will simply appear empty The keyword for the Python plugin is Python plugout< keyword > Unloads a given identified by its _keyword_ So if you want to unload the Python you need to do plugout Python plugin< libname > Loads a given whose _filename_ is libname So in the case of you d have to do a plugin cfpython so Note that all filenames are relative to the default plugin path(SHARE/plugins). Console messages. ----------------- When Crossfire starts
MessageManager::MessageManager
MessageManager(AssetWrapper *parent)
Definition: MessageManager.cpp:23
MessageManager::preConditions
QList< QuestConditionScript * > preConditions() const
Definition: MessageManager.cpp:101
MessageManager::myPostConditions
QList< QuestConditionScript * > myPostConditions
Definition: MessageManager.h:75
MessageManager::loadDirectory
void loadDirectory(const QString &directory)
Definition: MessageManager.cpp:72
MessageManager::~MessageManager
virtual ~MessageManager()
Definition: MessageManager.cpp:27
MessageFile
Definition: MessageFile.h:68
MessageManager::loadMessages
void loadMessages()
Definition: MessageManager.cpp:34
Settings::mapdir
const char * mapdir
Definition: global.h:251
MessageManager::loadScriptComment
QString loadScriptComment(const QString &path) const
Definition: MessageManager.cpp:111
Settings::datadir
const char * datadir
Definition: global.h:248
MessageManager::postConditions
QList< QuestConditionScript * > postConditions() const
Definition: MessageManager.cpp:106
AssetWrapper::DoesntUse
@ DoesntUse
Definition: AssetWrapper.h:32
MessageManager.h