13 #include <QtConcurrent/QtConcurrent>
26 #include "AssetsManager.h"
69 Q_ASSERT(messageManager != NULL);
70 Q_ASSERT(scriptManager != NULL);
96 archetype *arch = find_archetype(item->arch->name);
100 if (item->face && item->face != arch->clone.face)
103 information->
addFace(item->face->name);
105 if (item->animation && item->animation != arch->clone.animation)
113 if (item->type == EXIT || item->type == TELEPORTER || item->type == PLAYER_CHANGER) {
117 if (!item->slaying) {
123 if (strcmp(item->slaying,
"/!"))
124 strcpy(ep, EXIT_PATH(item));
130 start = strstr(item->msg,
"\nfinal_map ");
131 if (!
start && strncmp(item->msg,
"final_map", strlen(
"final_map")) == 0)
135 const char *end = strchr(
start+1,
'\n');
137 start += strlen(
"final_map")+2;
146 char exit_path[500], tmppath[MAX_BUF];
147 path_combine_and_normalize(env->map->path, ep, exit_path, 500);
148 create_pathname(exit_path, tmppath, MAX_BUF);
149 if (!QFileInfo(tmppath).exists()) {
150 printf(
" map %s doesn't exist in map %s, at %d, %d.\n", ep, env->map->path, env->x, env->y);
152 QString exit = exit_path;
162 link = get_map_info(exit_path);
163 add_map(link, &info->exits_from);
164 add_map(info, &link->exits_to);
166 if (do_regions_link) {
167 mapstruct *link = ready_map_name(exit_path, 0);
169 if (link && link != m) {
172 add_region_link(m, link, item->arch->clone.name);
173 link->reset_time = 1;
174 link->in_memory = MAP_IN_MEMORY;
184 if (QUERY_FLAG(item, FLAG_MONSTER))
187 FOR_INV_PREPARE(item, inv)
208 char tmppath[MAX_BUF];
209 create_pathname(path.toLatin1(), tmppath, MAX_BUF);
210 QFileInfo info(tmppath);
218 if (!information->
mapTime().isNull() && information->
mapTime() >= info.lastModified())
220 foreach(QString exit, information->
exitsTo())
234 mapstruct *m = mapfile_load(path.toLatin1(), MAP_STYLE | MAP_NO_DIFFICULTY);
238 if (m->region != NULL)
246 if (m->background_music)
250 if (m->shopitems != NULL)
252 for (
int i = 0; i < m->shopitems[0].index; i++)
254 information->
shopItems().insert(QString(m->shopitems[i].name == NULL ?
"*" : m->shopitems[i].name), m->shopitems[i].strength);
257 if (m->shoprace != NULL)
261 information->
setResetGroup(m->reset_group ? m->reset_group : QString());
265 for (
int x = 0; x < 4; x++)
266 if (m->tile_path[x] != NULL) {
267 path_combine_and_normalize(m->path, m->tile_path[x], exit_path,
sizeof(exit_path));
268 create_pathname(exit_path, tmppath, MAX_BUF);
269 if (!QFileInfo(tmppath).exists()) {
270 printf(
" map %s doesn't exist in map %s, for tile %d.\n", exit_path, m->path, x);
273 QString exit = exit_path;
283 for (
int x = MAP_WIDTH(m)-1; x >= 0; x--)
285 for (
int y = MAP_HEIGHT(m)-1; y >= 0; y--)
287 FOR_MAP_PREPARE(m, x, y, item)
294 QString region(
"undefined");
295 if (m->region == NULL)
296 qDebug() <<
"map without region" << m->name << m->path;
298 region = m->region->name;
302 m->in_memory = MAP_IN_MEMORY;
306 QMutexLocker lock(&
myLock);
323 if (first_map_ext_path[0] != 0)
325 getManager()->archetypes()->each([
this] (archetype *arch)
327 if (arch->clone.type == PLAYER)
329 char path[MAX_BUF], name[MAX_BUF];
330 snprintf(name, sizeof(name),
"%s/%s", first_map_ext_path, arch->name);
331 create_pathname(name, path, sizeof(path));
332 if (QFileInfo(path).exists()) {
333 myToProcess.append(name);
340 recurseStyleDirectory(
"styles");
342 while (myCurrentMap < myToProcess.size())
344 process(myToProcess[myCurrentMap]);
352 for (
auto map : myInformation) {
359 qDebug() <<
"experience repartition:";
360 foreach(QString region, myExperience.keys())
362 qDebug() << region << myExperience[region];
365 qDebug() << myToProcess.size() <<
"maps processed";
376 QMutexLocker lock(&
myLock);
382 QMutexLocker lock(&
myLock);
388 QMutexLocker lock(&
myLock);
394 QMutexLocker lock(&
myLock);
400 QMutexLocker lock(&
myLock);
410 file.open(QFile::ReadOnly);
412 QXmlStreamReader reader(&file);
413 bool hasMaps =
false;
416 while (!reader.atEnd())
420 if (reader.isStartElement() && reader.name() ==
"maps")
422 int version = reader.attributes().value(
"version").toString().toInt();
432 if (reader.isStartElement() && reader.name() ==
"map")
437 if (reader.isStartElement() && reader.name() ==
"path")
439 QString path = reader.readElementText();
445 if (reader.isStartElement() && reader.name() ==
"name")
447 map->
setName(reader.readElementText());
450 if (reader.isStartElement() && reader.name() ==
"lastModified")
452 QString date = reader.readElementText();
453 map->
setMapTime(QDateTime::fromString(date, Qt::ISODateWithMs));
456 if (reader.isStartElement() && reader.name() ==
"difficulty")
460 if (reader.isStartElement() && reader.name() ==
"computedDifficulty")
464 if (reader.isStartElement() && reader.name() ==
"experience")
468 if (reader.isStartElement() && reader.name() ==
"region")
470 map->
setRegion(reader.readElementText());
472 if (reader.isStartElement() && reader.name() ==
"arch")
474 QString arch = reader.readElementText();
479 if (reader.isStartElement() && reader.name() ==
"face")
481 QString face = reader.readElementText();
486 if (reader.isStartElement() && reader.name() ==
"animation")
488 QString anim = reader.readElementText();
493 if (reader.isStartElement() && reader.name() ==
"exitTo")
495 QString path = reader.readElementText();
499 if (reader.isStartElement() && reader.name() ==
"accessedFrom")
501 QString path = reader.readElementText();
505 if (reader.isStartElement() && reader.name() ==
"messageFile")
507 QString file = reader.readElementText();
511 message->
maps().append(map);
514 if (reader.isStartElement() && reader.name() ==
"quest")
516 QString code = reader.readElementText();
521 if (reader.isStartElement() && reader.name() ==
"shopItem")
523 QString item = reader.attributes().value(
"name").toString();
524 int strength = reader.readElementText().toInt();
527 if (reader.isStartElement() && reader.name() ==
"shopGreed")
529 double greed = reader.readElementText().toDouble();
532 if (reader.isStartElement() && reader.name() ==
"shopRace")
536 if (reader.isStartElement() && reader.name() ==
"shopMin")
538 quint64 min = reader.readElementText().toULongLong();
541 if (reader.isStartElement() && reader.name() ==
"shopMax")
543 quint64 max = reader.readElementText().toULongLong();
546 if (reader.isStartElement() && reader.name() ==
"script")
548 int x = reader.attributes().value(
"x").toString().toInt();
549 int y = reader.attributes().value(
"x").toString().toInt();
550 QString item = reader.attributes().value(
"itemName").toString();
551 QString plugin = reader.attributes().value(
"pluginName").toString();
552 QString
event = reader.attributes().value(
"eventName").toString();
553 QString script = reader.readElementText();
556 if (reader.isStartElement() && reader.name() ==
"random_map")
558 int x = reader.attributes().value(
"x").toString().toInt();
559 int y = reader.attributes().value(
"y").toString().toInt();
560 QString params = reader.attributes().value(
"params").toString();
563 if (reader.isStartElement() && reader.name() ==
"background_music")
568 if (reader.isStartElement() && reader.name() ==
"reset_group")
574 if (reader.isEndElement() && reader.name() ==
"map")
588 file.open(QFile::WriteOnly | QFile::Truncate);
590 QXmlStreamWriter writer(&file);
592 writer.setAutoFormatting(
true);
593 writer.writeStartDocument();
595 writer.writeStartElement(
"maps");
596 writer.writeAttribute(
"version",
"1");
601 writer.writeStartElement(
"map");
602 writer.writeTextElement(
"path", map->
path());
603 writer.writeTextElement(
"name", map->
name());
604 writer.writeTextElement(
"lastModified", map->
mapTime().toString(Qt::ISODateWithMs));
605 writer.writeTextElement(
"difficulty", QString::number(map->
difficulty()));
606 writer.writeTextElement(
"computedDifficulty", QString::number(map->
computedDifficulty()));
607 writer.writeTextElement(
"experience", QString::number(map->
experience()));
608 writer.writeTextElement(
"region", map->
region());
611 writer.writeTextElement(
"arch", arch);
613 foreach(QString face, map->
faces())
615 writer.writeTextElement(
"face", face);
619 writer.writeTextElement(
"animation", anim);
621 foreach(QString path, map->
exitsTo())
623 writer.writeTextElement(
"exitTo", path);
627 writer.writeTextElement(
"accessedFrom", path);
629 foreach(QString file, map->
messages())
631 writer.writeTextElement(
"messageFile", file);
633 foreach(QString code, map->
quests())
635 writer.writeTextElement(
"quest", code);
637 foreach(QString item, map->
shopItems().keys())
639 writer.writeStartElement(
"shopItem");
640 writer.writeAttribute(
"name", item);
641 writer.writeCharacters(QString::number(map->
shopItems()[item]));
642 writer.writeEndElement();
646 writer.writeTextElement(
"shopGreed", QString::number(map->
shopGreed()));
650 writer.writeTextElement(
"shopRace", map->
shopRace());
654 writer.writeTextElement(
"shopMin", QString::number(map->
shopMin()));
658 writer.writeTextElement(
"shopMax", QString::number(map->
shopMax()));
666 if (hook->
map() == map)
668 writer.writeStartElement(
"script");
669 writer.writeAttribute(
"x", QString::number(hook->
x()));
670 writer.writeAttribute(
"y", QString::number(hook->
y()));
671 writer.writeAttribute(
"itemName", hook->
itemName());
672 writer.writeAttribute(
"pluginName", hook->
pluginName());
673 writer.writeAttribute(
"eventName", hook->
eventName());
674 writer.writeCharacters(script->
path());
675 writer.writeEndElement();
682 writer.writeStartElement(
"random_map");
683 writer.writeAttribute(
"x", QString::number(random->
x()));
684 writer.writeAttribute(
"y", QString::number(random->
y()));
685 StringBuffer* sb = write_map_parameters_to_string(random->
parameters());
686 char* params = stringbuffer_finish(sb);
687 writer.writeAttribute(
"params", params);
689 writer.writeEndElement();
698 writer.writeTextElement(
"reset_group", map->
resetGroup());
701 writer.writeEndElement();
704 writer.writeEndElement();
706 writer.writeEndDocument();
721 QMutexLocker lock(&
myLock);
728 QMutexLocker lock(&
myLock);
729 if (!
myFaceUse.values(name).contains(map))
735 QMutexLocker lock(&
myLock);
741 QMutexLocker lock(&
myLock);
749 const QString slaying =
"/python/dialog/npc_dialog.py";
750 const QString python =
"Python";
752 if (item->type != EVENT_CONNECTOR)
755 if (item->subtype > 0 && item->subtype < NR_EVENTS)
760 if (python != item->title)
763 if (item->subtype == EVENT_SAY && slaying == item->slaying)
766 QString path = item->name;
767 if (!path.startsWith(
'/'))
773 if (!message->
maps().contains(map))
774 message->
maps().append(map);
777 qDebug() <<
"missing message file" << path <<
"in" << map->
path();
780 if (QString(item->slaying).startsWith(
"/python/quests/"))
783 QStringList split = QString(item->name).split(
' ', QString::SkipEmptyParts);
784 if (split.length() > 1)
795 QList<CREMapInformation*> list;
799 if (map->
region() == region)
810 QFile::remove(settings.
mapCacheDirectory() + QDir::separator() +
"maps_cache.xml");
815 QList<RandomMap*> maps;
826 create_pathname(from.toLatin1(), full,
sizeof(full));
829 QFileInfoList items = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot, QDir::DirsFirst);
830 foreach(QFileInfo info, items)
832 QString relative(from + QDir::separator() + info.baseName());