Crossfire Server, Trunk
CREMapInformationManager.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 <QtConcurrent/QtConcurrent>
14 
16 #include "CRESettings.h"
17 #include "MessageManager.h"
18 #include "MessageFile.h"
20 #include "scripts/ScriptFile.h"
21 #include "random_maps/RandomMap.h"
22 #include "CREUtils.h"
23 
24 #include "global.h"
25 #include "assets.h"
26 #include "AssetsManager.h"
27 
28 const char* eventNames[NR_EVENTS] = {
29  "EVENT_NONE",
30  "EVENT_APPLY",
31  "EVENT_ATTACKED",
32  "EVENT_DEATH",
33  "EVENT_DROP",
34  "EVENT_PICKUP",
35  "EVENT_SAY",
36  "EVENT_STOP",
37  "EVENT_TIME",
38  "EVENT_THROW",
39  "EVENT_TRIGGER",
40  "EVENT_CLOSE",
41  "EVENT_TIMER",
42  "EVENT_DESTROY",
43  "EVENT_BORN",
44  "EVENT_CLOCK",
45  "EVENT_CRASH",
46  "EVENT_PLAYER_DEATH",
47  "EVENT_GKILL",
48  "EVENT_LOGIN",
49  "EVENT_LOGOUT",
50  "EVENT_MAPENTER",
51  "EVENT_MAPLEAVE",
52  "EVENT_MAPRESET",
53  "EVENT_REMOVE",
54  "EVENT_SHOUT",
55  "EVENT_TELL",
56  "EVENT_MUZZLE",
57  "EVENT_KICK",
58  "EVENT_MAPUNLOAD",
59  "EVENT_MAPLOAD",
60  "EVENT_USER",
61  "EVENT_SELLING",
62  "EVENT_ATTACKS",
63  "EVENT_BOUGHT",
64  "EVENT_MAPREADY",
65 };
66 
67 CREMapInformationManager::CREMapInformationManager(QObject* parent, MessageManager* messageManager, ScriptFileManager* scriptManager) : QObject(parent)
68 {
69  Q_ASSERT(messageManager != NULL);
70  Q_ASSERT(scriptManager != NULL);
71  myMessageManager = messageManager;
72  myScriptManager = scriptManager;
73  connect(this, SIGNAL(addHook(const QString &, HookInformation *)), scriptManager, SLOT(addHook(const QString &, HookInformation *)));
74 }
75 
77 {
78  qDeleteAll(myInformation);
79 }
80 
82 {
83  return myWorker.isFinished();
84 }
85 
87 {
88  if (myWorker.isRunning())
89  return;
90 
91  myWorker = QtConcurrent::run(this, &CREMapInformationManager::browseMaps);
92 }
93 
94 void CREMapInformationManager::checkItem(const object* item, CREMapInformation* information, const object* env)
95 {
96  archetype *arch = find_archetype(item->arch->name);
97  if (arch != NULL) {
98  addArchetypeUse(arch->name, information);
99  information->addArchetype(arch->name);
100  if (item->face && item->face != arch->clone.face)
101  {
102  addFaceUse(item->face->name, information);
103  information->addFace(item->face->name);
104  }
105  if (item->animation && item->animation != arch->clone.animation)
106  {
107  addAnimationUse(item->animation->name, information);
108  information->addAnimation(item->animation->name);
109  }
110  }
111  checkEvent(item, information, env);
112 
113  if (item->type == EXIT || item->type == TELEPORTER || item->type == PLAYER_CHANGER) {
114  char ep[500];
115  const char *start;
116 
117  if (!item->slaying) {
118  ep[0] = '\0';
119  /*if (warn_no_path)
120  printf(" exit without any path at %d, %d on %s\n", item->x, item->y, info->path);*/
121  } else {
122  memset(ep, 0, 500);
123  if (strcmp(item->slaying, "/!"))
124  strcpy(ep, EXIT_PATH(item));
125  else {
126  if (!item->msg) {
127  //printf(" random map without message in %s at %d, %d\n", info->path, item->x, item->y);
128  } else {
129  /* Some maps have a 'exit_on_final_map' flag, ignore it. */
130  start = strstr(item->msg, "\nfinal_map ");
131  if (!start && strncmp(item->msg, "final_map", strlen("final_map")) == 0)
132  /* Message start is final_map, nice */
133  start = item->msg;
134  if (start) {
135  const char *end = strchr(start+1, '\n');
136 
137  start += strlen("final_map")+2;
138  strncpy(ep, start, end-start);
139  }
140 
141  information->addRandomMap(new RandomMap(information, env->x, env->y, item->msg));
142  }
143  }
144 
145  if (strlen(ep)) {
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);
151  } else {
152  QString exit = exit_path;
153  if (!myToProcess.contains(exit))
154  myToProcess.append(exit);
155 
157  Q_ASSERT(other);
158  other->addAccessedFrom(exit);
159  information->addExitTo(exit_path);
160 
161 #if 0
162  link = get_map_info(exit_path);
163  add_map(link, &info->exits_from);
164  add_map(info, &link->exits_to);
165 
166  if (do_regions_link) {
167  mapstruct *link = ready_map_name(exit_path, 0);
168 
169  if (link && link != m) {
170  /* no need to link a map with itself. Also, if the exit points to the same map, we don't
171  * want to reset it. */
172  add_region_link(m, link, item->arch->clone.name);
173  link->reset_time = 1;
174  link->in_memory = MAP_IN_MEMORY;
175  delete_map(link);
176  }
177  }
178 #endif
179  }
180  }
181  }
182  }
183 
185  information->setExperience(information->experience() + item->stats.exp);
186 
188  {
189  checkItem(inv, information, env);
190  } FOR_INV_FINISH();
191 }
192 
193 void CREMapInformationManager::process(const QString& path2)
194 {
195  /*
196  don't ask why, but the variable gets apparently destroyed on the myToProcess.append() when it reallocated values...
197  so keep a copy to avoid messes
198  */
199  QString path(path2);
200 
201  if (myCancelled)
202  return;
203 
204  emit browsingMap(path);
205 // qDebug() << "processing" << path;
207 
208  char tmppath[MAX_BUF];
209  create_pathname(path.toLatin1(), tmppath, MAX_BUF);
210  QFileInfo info(tmppath);
211 
212  if (!info.exists())
213  {
214 // qDebug() << "non existant map" << tmppath;
215  return;
216  }
217 
218  if (!information->mapTime().isNull() && information->mapTime() >= info.lastModified())
219  {
220  foreach(QString exit, information->exitsTo())
221  {
222  if (!myToProcess.contains(exit))
223  myToProcess.append(exit);
224  }
225 // qDebug() << "skipping " << tmppath;
226  return;
227  }
228 
229  /* remove scripts to avoid duplications */
230  myScriptManager->removeMap(information);
231 
232  auto locker = CREUtils::lockCrossfireData();
233 
235 // qDebug() << "processing" << path << information->mapTime() << info.lastModified();
236  information->setName(m->name);
237  information->setMapTime(info.lastModified());
238  if (m->region != NULL)
239  information->setRegion(m->region->name);
240  else
241  information->setRegion("wilderness");
242  information->setDifficulty(m->difficulty);
243  m->difficulty = 0;
245  m->difficulty = information->difficulty();
246  if (m->background_music)
247  information->setBackgroundMusic(m->background_music);
248 
249  information->setShopGreed(m->shopgreed);
250  if (m->shopitems != NULL)
251  {
252  for (int i = 0; i < m->shopitems[0].index; i++)
253  {
254  information->shopItems().insert(QString(m->shopitems[i].name == NULL ? "*" : m->shopitems[i].name), m->shopitems[i].strength);
255  }
256  }
257  if (m->shoprace != NULL)
258  information->setShopRace(m->shoprace);
259  information->setShopMin(m->shopmin);
260  information->setShopMax(m->shopmax);
261  information->setResetGroup(m->reset_group ? m->reset_group : QString());
262 
263  char exit_path[500];
264 
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);
271  }
272 
273  QString exit = exit_path;
274  if (!myToProcess.contains(exit))
275  myToProcess.append(exit);
276 
278  Q_ASSERT(other);
279  other->addAccessedFrom(path);
280  information->addExitTo(exit_path);
281  }
282 
283  for (int x = MAP_WIDTH(m)-1; x >= 0; x--)
284  {
285  for (int y = MAP_HEIGHT(m)-1; y >= 0; y--)
286  {
287  FOR_MAP_PREPARE(m, x, y, item)
288  {
289  checkItem(item, information, item);
290  } FOR_MAP_FINISH();
291  }
292  }
293 
294  QString region("undefined");
295  if (m->region == NULL)
296  qDebug() << "map without region" << m->name << m->path;
297  else
298  region = m->region->name;
299  myExperience[m->region ? m->region->name : "(undefined)"] += information->experience();
300 
301  m->reset_time = 1;
302  m->in_memory = MAP_IN_MEMORY;
303  delete_map(m);
304  locker.reset();
305 
306  QMutexLocker lock(&myLock);
307  myExperience[region] += information->experience();
308 }
309 
311 {
312  qDeleteAll(myInformation);
313  myArchetypeUse.clear();
314 
315  loadCache();
316 
317  myCancelled = false;
318  myCurrentMap = 0;
319  myToProcess.clear();
320  myToProcess.append(QString(first_map_path));
321 
322  /* try to find race-specific start maps */
323  if (first_map_ext_path[0] != 0)
324  {
325  getManager()->archetypes()->each([this] (archetype *arch)
326  {
327  if (arch->clone.type == PLAYER)
328  {
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);
334  }
335  }
336  });
337  }
338 
339  /* Add style maps */
340  recurseStyleDirectory("styles");
341 
342  while (myCurrentMap < myToProcess.size())
343  {
344  process(myToProcess[myCurrentMap]);
345  myCurrentMap++;
346  if (myCancelled)
347  break;
348  }
349 
350  storeCache();
351 
352  for (auto map : myInformation) {
353  emit mapAdded(map);
354  }
355 
356  emit finished();
357 
359  qDebug() << "experience repartition:";
360  foreach(QString region, myExperience.keys())
361  {
362  qDebug() << region << myExperience[region];
363  }
364 
365  qDebug() << myToProcess.size() << "maps processed";
366 }
367 
369 {
370  myCancelled = true;
371  myWorker.waitForFinished();
372 }
373 
374 QList<CREMapInformation*> CREMapInformationManager::allMaps()
375 {
376  QMutexLocker lock(&myLock);
377  return myInformation.values();
378 }
379 
381 {
382  QMutexLocker lock(&myLock);
383  return myArchetypeUse.values(arch->name);
384 }
385 
386 QList<CREMapInformation*> CREMapInformationManager::getFaceUse(const Face* face)
387 {
388  QMutexLocker lock(&myLock);
389  return myFaceUse.values(face->name);
390 }
391 
392 QList<CREMapInformation*> CREMapInformationManager::getAnimationUse(const Animations* animation)
393 {
394  QMutexLocker lock(&myLock);
395  return myAnimationUse.values(animation->name);
396 }
397 
399 {
400  QMutexLocker lock(&myLock);
401  return myQuestUse.values(quest->quest_code);
402 }
403 
405 {
406  Q_ASSERT(myInformation.isEmpty());
407 
409  QFile file(settings.mapCacheDirectory() + QDir::separator() + "maps_cache.xml");
410  file.open(QFile::ReadOnly);
411 
412  QXmlStreamReader reader(&file);
413  bool hasMaps = false;
414  CREMapInformation* map = NULL;
415 
416  while (!reader.atEnd())
417  {
418  reader.readNext();
419 
420  if (reader.isStartElement() && reader.name() == "maps")
421  {
422  int version = reader.attributes().value("version").toString().toInt();
423  if (version < 1)
424  return;
425  hasMaps = true;
426  continue;
427  }
428 
429  if (!hasMaps)
430  continue;
431 
432  if (reader.isStartElement() && reader.name() == "map")
433  {
434  map = new CREMapInformation();
435  continue;
436  }
437  if (reader.isStartElement() && reader.name() == "path")
438  {
439  QString path = reader.readElementText();
440  map->setPath(path);
441  Q_ASSERT(!myInformation.contains(path));
443  continue;
444  }
445  if (reader.isStartElement() && reader.name() == "name")
446  {
447  map->setName(reader.readElementText());
448  continue;
449  }
450  if (reader.isStartElement() && reader.name() == "lastModified")
451  {
452  QString date = reader.readElementText();
453  map->setMapTime(QDateTime::fromString(date, Qt::ISODateWithMs));
454  continue;
455  }
456  if (reader.isStartElement() && reader.name() == "difficulty")
457  {
458  map->setDifficulty(reader.readElementText().toInt());
459  }
460  if (reader.isStartElement() && reader.name() == "computedDifficulty")
461  {
462  map->setComputedDifficulty(reader.readElementText().toInt());
463  }
464  if (reader.isStartElement() && reader.name() == "experience")
465  {
466  map->setExperience(reader.readElementText().toLongLong());
467  }
468  if (reader.isStartElement() && reader.name() == "region")
469  {
470  map->setRegion(reader.readElementText());
471  }
472  if (reader.isStartElement() && reader.name() == "arch")
473  {
474  QString arch = reader.readElementText();
475  map->addArchetype(arch);
477  continue;
478  }
479  if (reader.isStartElement() && reader.name() == "face")
480  {
481  QString face = reader.readElementText();
482  map->addFace(face);
483  addFaceUse(face, map);
484  continue;
485  }
486  if (reader.isStartElement() && reader.name() == "animation")
487  {
488  QString anim = reader.readElementText();
489  map->addAnimation(anim);
491  continue;
492  }
493  if (reader.isStartElement() && reader.name() == "exitTo")
494  {
495  QString path = reader.readElementText();
496  map->addExitTo(path);
497  continue;
498  }
499  if (reader.isStartElement() && reader.name() == "accessedFrom")
500  {
501  QString path = reader.readElementText();
502  map->addAccessedFrom(path);
503  continue;
504  }
505  if (reader.isStartElement() && reader.name() == "messageFile")
506  {
507  QString file = reader.readElementText();
508  map->addMessage(file);
510  if (message != NULL)
511  message->maps().append(map);
512  continue;
513  }
514  if (reader.isStartElement() && reader.name() == "quest")
515  {
516  QString code = reader.readElementText();
517  map->addQuest(code);
518  addQuestUse(code, map);
519  continue;
520  }
521  if (reader.isStartElement() && reader.name() == "shopItem")
522  {
523  QString item = reader.attributes().value("name").toString();
524  int strength = reader.readElementText().toInt();
525  map->shopItems()[item] = strength;
526  }
527  if (reader.isStartElement() && reader.name() == "shopGreed")
528  {
529  double greed = reader.readElementText().toDouble();
530  map->setShopGreed(greed);
531  }
532  if (reader.isStartElement() && reader.name() == "shopRace")
533  {
534  map->setShopRace(reader.readElementText());
535  }
536  if (reader.isStartElement() && reader.name() == "shopMin")
537  {
538  quint64 min = reader.readElementText().toULongLong();
539  map->setShopMin(min);
540  }
541  if (reader.isStartElement() && reader.name() == "shopMax")
542  {
543  quint64 max = reader.readElementText().toULongLong();
544  map->setShopMax(max);
545  }
546  if (reader.isStartElement() && reader.name() == "script")
547  {
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();
554  emit addHook(script, new HookInformation(map, x, y, item, plugin, event));
555  }
556  if (reader.isStartElement() && reader.name() == "random_map")
557  {
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();
561  map->addRandomMap(new RandomMap(map, x, y, params.toLatin1().constData()));
562  }
563  if (reader.isStartElement() && reader.name() == "background_music")
564  {
565  map->setBackgroundMusic(reader.readElementText());
566  continue;
567  }
568  if (reader.isStartElement() && reader.name() == "reset_group")
569  {
570  map->setResetGroup(reader.readElementText());
571  continue;
572  }
573 
574  if (reader.isEndElement() && reader.name() == "map")
575  {
576  map = NULL;
577  continue;
578  }
579  }
580 
581 // qDebug() << "loaded maps from cache:" << myInformation.size();
582 }
583 
585 {
587  QFile file(settings.mapCacheDirectory() + QDir::separator() + "maps_cache.xml");
588  file.open(QFile::WriteOnly | QFile::Truncate);
589 
590  QXmlStreamWriter writer(&file);
591 
592  writer.setAutoFormatting(true);
593  writer.writeStartDocument();
594 
595  writer.writeStartElement("maps");
596  writer.writeAttribute("version", "1");
597 
598  QList<CREMapInformation*> maps = myInformation.values();
599  foreach(CREMapInformation* map, maps)
600  {
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());
609  foreach(QString arch, map->archetypes())
610  {
611  writer.writeTextElement("arch", arch);
612  }
613  foreach(QString face, map->faces())
614  {
615  writer.writeTextElement("face", face);
616  }
617  foreach(QString anim, map->animations())
618  {
619  writer.writeTextElement("animation", anim);
620  }
621  foreach(QString path, map->exitsTo())
622  {
623  writer.writeTextElement("exitTo", path);
624  }
625  foreach(QString path, map->accessedFrom())
626  {
627  writer.writeTextElement("accessedFrom", path);
628  }
629  foreach(QString file, map->messages())
630  {
631  writer.writeTextElement("messageFile", file);
632  }
633  foreach(QString code, map->quests())
634  {
635  writer.writeTextElement("quest", code);
636  }
637  foreach(QString item, map->shopItems().keys())
638  {
639  writer.writeStartElement("shopItem");
640  writer.writeAttribute("name", item);
641  writer.writeCharacters(QString::number(map->shopItems()[item]));
642  writer.writeEndElement();
643  }
644  if (map->shopGreed() != 0)
645  {
646  writer.writeTextElement("shopGreed", QString::number(map->shopGreed()));
647  }
648  if (!map->shopRace().isEmpty())
649  {
650  writer.writeTextElement("shopRace", map->shopRace());
651  }
652  if (map->shopMin() != 0)
653  {
654  writer.writeTextElement("shopMin", QString::number(map->shopMin()));
655  }
656  if (map->shopMax() != 0)
657  {
658  writer.writeTextElement("shopMax", QString::number(map->shopMax()));
659  }
660 
661  QList<ScriptFile*> scripts = myScriptManager->scriptsForMap(map);
662  foreach(ScriptFile* script, scripts)
663  {
664  foreach(const HookInformation* hook, script->hooks())
665  {
666  if (hook->map() == map)
667  {
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();
676  }
677  }
678  }
679 
680  foreach(RandomMap* random, map->randomMaps())
681  {
682  writer.writeStartElement("random_map");
683  writer.writeAttribute("x", QString::number(random->x()));
684  writer.writeAttribute("y", QString::number(random->y()));
686  char* params = stringbuffer_finish(sb);
687  writer.writeAttribute("params", params);
688  free(params);
689  writer.writeEndElement();
690  }
691 
692  if (!map->backgroundMusic().isEmpty())
693  {
694  writer.writeTextElement("background_music", map->backgroundMusic());
695  }
696  if (!map->resetGroup().isEmpty())
697  {
698  writer.writeTextElement("reset_group", map->resetGroup());
699  }
700 
701  writer.writeEndElement();
702  }
703 
704  writer.writeEndElement();
705 
706  writer.writeEndDocument();
707 }
708 
710 {
711  if (!myInformation.contains(path))
712  {
713  CREMapInformation* information = new CREMapInformation(path);
714  myInformation[path] = information;
715  }
716  return myInformation[path];
717 }
718 
720 {
721  QMutexLocker lock(&myLock);
722  if (!myArchetypeUse.values(name).contains(map))
723  myArchetypeUse.insert(name, map);
724 }
725 
727 {
728  QMutexLocker lock(&myLock);
729  if (!myFaceUse.values(name).contains(map))
730  myFaceUse.insert(name, map);
731 }
732 
734 {
735  QMutexLocker lock(&myLock);
736  if (!myAnimationUse.values(name).contains(map))
737  myAnimationUse.insert(name, map);
738 }
739 
741  QMutexLocker lock(&myLock);
742  if (!myQuestUse.values(name).contains(map))
743  myQuestUse.insert(name, map);
744 }
745 
746 
748 {
749  const QString slaying = "/python/dialog/npc_dialog.py";
750  const QString python = "Python";
751 
752  if (item->type != EVENT_CONNECTOR)
753  return;
754 
755  if (item->subtype > 0 && item->subtype < NR_EVENTS)
756  {
757  emit addHook(item->slaying, new HookInformation(map, env->x, env->y, env->name, item->title, eventNames[item->subtype]));
758  }
759 
760  if (python != item->title)
761  return;
762 
763  if (item->subtype == EVENT_SAY && slaying == item->slaying)
764  {
765  //qDebug() << "message event in" << map->path() << item->name;
766  QString path = item->name;
767  if (!path.startsWith('/'))
768  path = '/' + path;
769 
771  if (message != NULL)
772  {
773  if (!message->maps().contains(map))
774  message->maps().append(map);
775  map->addMessage(path);
776  } else
777  qDebug() << "missing message file" << path << "in" << map->path();
778  }
779 
780  if (QString(item->slaying).startsWith("/python/quests/"))
781  {
782  //qDebug() << "quest-related Python stuff";
783  QStringList split = QString(item->name).split(' ', QString::SkipEmptyParts);
784  if (split.length() > 1)
785  {
786  //qDebug() << "definitely quest" << split[0];
787  map->addQuest(split[0]);
788  addQuestUse(split[0], map);
789  }
790  }
791 }
792 
793 QList<CREMapInformation*> CREMapInformationManager::getMapsForRegion(const QString& region)
794 {
795  QList<CREMapInformation*> list;
796 
797  foreach(CREMapInformation* map, myInformation.values())
798  {
799  if (map->region() == region)
800  list.append(map);
801  }
802 
803  return list;
804 }
805 
807 {
809  Q_ASSERT(myWorker.isFinished());
810  QFile::remove(settings.mapCacheDirectory() + QDir::separator() + "maps_cache.xml");
811 }
812 
814 {
815  QList<RandomMap*> maps;
816  foreach(CREMapInformation* map, myInformation.values())
817  {
818  maps.append(map->randomMaps());
819  }
820  return maps;
821 }
822 
824 {
825  char full[MAX_BUF];
826  create_pathname(from.toLatin1(), full, sizeof(full));
827 
828  QDir dir(full);
829  QFileInfoList items = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot, QDir::DirsFirst);
830  foreach(QFileInfo info, items)
831  {
832  QString relative(from + QDir::separator() + info.baseName());
833  if (info.isDir())
834  {
835  recurseStyleDirectory(relative);
836  }
837  else
838  {
839  myToProcess.append(relative);
840  }
841  }
842 }
Face::name
sstring name
Definition: face.h:19
ScriptFileManager
Definition: ScriptFileManager.h:26
Face
Definition: face.h:14
HookInformation::x
int x() const
Definition: ScriptFile.cpp:86
RandomMap
Definition: RandomMap.h:24
add_map
static void add_map(struct_map_info *info, struct_map_list *list)
Definition: mapper.cpp:1167
PLAYER
@ PLAYER
Definition: object.h:112
CREMapInformation::setShopGreed
void setShopGreed(double greed)
Definition: CREMapInformation.cpp:233
global.h
CREMapInformationManager::~CREMapInformationManager
virtual ~CREMapInformationManager()
Definition: CREMapInformationManager.cpp:76
RandomMap::parameters
const RMParms * parameters() const
Definition: RandomMap.cpp:39
settings
struct Settings settings
Definition: init.cpp:139
FOR_MAP_FINISH
#define FOR_MAP_FINISH()
Definition: define.h:730
CREMapInformationManager::myCurrentMap
int myCurrentMap
Definition: CREMapInformationManager.h:63
CREMapInformationManager::randomMaps
QList< RandomMap * > randomMaps()
Definition: CREMapInformationManager.cpp:813
CREMapInformationManager::checkItem
void checkItem(const object *item, CREMapInformation *information, const object *env)
Definition: CREMapInformationManager.cpp:94
CREMapInformationManager::browsingMap
void browsingMap(const QString &path)
MAP_NO_DIFFICULTY
#define MAP_NO_DIFFICULTY
Definition: map.h:93
CREMapInformation::setComputedDifficulty
void setComputedDifficulty(int computed)
Definition: CREMapInformation.cpp:172
maps
static std::unordered_map< std::string, mapzone * > maps
Definition: citylife.cpp:92
EVENT_CONNECTOR
@ EVENT_CONNECTOR
Definition: object.h:232
NR_EVENTS
#define NR_EVENTS
Definition: events.h:59
python_init.scripts
scripts
Definition: python_init.py:11
diamondslots.x
x
Definition: diamondslots.py:15
ScriptFileManager.h
ready_map_name
mapstruct * ready_map_name(const char *name, int flags)
Definition: map.cpp:1762
CREMapInformation::difficulty
int difficulty
Definition: CREMapInformation.h:33
first_map_path
char first_map_path[MAX_BUF]
Definition: init.cpp:120
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
MessageManager.h
archininventory.arch
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
Definition: archininventory.py:16
AssetsManager.h
send.date
date
Definition: send.py:29
MessageManager::findMessage
MessageFile * findMessage(const QString &path)
Definition: MessageManager.cpp:61
first_map_ext_path
char first_map_ext_path[MAX_BUF]
Definition: init.cpp:121
CREMapInformationManager::start
void start()
Definition: CREMapInformationManager.cpp:86
CREMapInformation::exitsTo
QStringList exitsTo() const
Definition: CREMapInformation.cpp:135
get_map_info
static struct_map_info * get_map_info(const char *path)
Definition: mapper.cpp:1260
CREMapInformationManager::addHook
void addHook(const QString &file, HookInformation *hook)
EXIT_PATH
#define EXIT_PATH(xyz)
Definition: define.h:439
CREMapInformationManager::clearCache
void clearCache()
Definition: CREMapInformationManager.cpp:806
CREUtils.h
CREMapInformation::shopItems
QHash< QString, int > & shopItems()
Definition: CREMapInformation.cpp:218
guildoracle.list
list
Definition: guildoracle.py:87
CREMapInformationManager::myWorker
QFuture< void > myWorker
Definition: CREMapInformationManager.h:64
HookInformation::map
const CREMapInformation * map() const
Definition: ScriptFile.cpp:81
commongive.inv
inv
Definition: commongive.py:29
mad_mage_user.file
file
Definition: mad_mage_user.py:15
CREMapInformationManager::getAnimationUse
QList< CREMapInformation * > getAnimationUse(const Animations *anim)
Definition: CREMapInformationManager.cpp:392
RandomMap::x
int x() const
Definition: RandomMap.cpp:29
CREMapInformationManager::allMaps
QList< CREMapInformation * > allMaps()
Definition: CREMapInformationManager.cpp:374
CREMapInformation::setDifficulty
void setDifficulty(int difficulty)
Definition: CREMapInformation.cpp:162
CREMapInformationManager::getArchetypeUse
QList< CREMapInformation * > getArchetypeUse(const archetype *arch)
Definition: CREMapInformationManager.cpp:380
CREMapInformation::addAnimation
void addAnimation(const QString &anim)
Definition: CREMapInformation.cpp:120
CREMapInformationManager::myCancelled
bool myCancelled
Definition: CREMapInformationManager.h:65
CREMapInformationManager::process
void process(const QString &path)
Definition: CREMapInformationManager.cpp:193
EVENT_SAY
#define EVENT_SAY
Definition: events.h:29
RandomMap.h
CREMapInformationManager::addArchetypeUse
void addArchetypeUse(const QString &name, CREMapInformation *map)
Definition: CREMapInformationManager.cpp:719
HookInformation::itemName
QString itemName() const
Definition: ScriptFile.cpp:96
MessageFile
Definition: MessageFile.h:68
CREMapInformationManager::myExperience
QHash< QString, qint64 > myExperience
Definition: CREMapInformationManager.h:67
CREMapInformationManager::addAnimationUse
void addAnimationUse(const QString &name, CREMapInformation *map)
Definition: CREMapInformationManager.cpp:733
getManager
AssetsManager * getManager()
Definition: assets.cpp:305
MAP_STYLE
#define MAP_STYLE
Definition: map.h:94
CREMapInformationManager::recurseStyleDirectory
void recurseStyleDirectory(const QString &from)
Definition: CREMapInformationManager.cpp:823
HookInformation::y
int y() const
Definition: ScriptFile.cpp:91
m
static event_registration m
Definition: citylife.cpp:425
quest
Definition: quest.py:1
CREMapInformation
Definition: CREMapInformation.h:27
CREMapInformation::setRegion
void setRegion(const QString &region)
Definition: CREMapInformation.cpp:191
MAP_IN_MEMORY
#define MAP_IN_MEMORY
Definition: map.h:126
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.cpp:76
CREMapInformation::mapTime
const QDateTime & mapTime() const
Definition: CREMapInformation.cpp:125
CREMapInformationManager::CREMapInformationManager
CREMapInformationManager(QObject *parent, MessageManager *messageManager, ScriptFileManager *scriptManager)
Definition: CREMapInformationManager.cpp:67
disinfect.map
map
Definition: disinfect.py:4
CREMapInformation::setShopMin
void setShopMin(quint64 min)
Definition: CREMapInformation.cpp:253
ScriptFile::path
const QString & path() const
Definition: ScriptFile.cpp:47
RandomMap::y
int y() const
Definition: RandomMap.cpp:34
ScriptFile.h
ScriptFileManager::scriptsForMap
QList< ScriptFile * > scriptsForMap(CREMapInformation *map)
Definition: ScriptFileManager.cpp:26
path_combine_and_normalize
char * path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size)
Definition: path.cpp:172
CREMapInformation::setShopRace
void setShopRace(const QString &race)
Definition: CREMapInformation.cpp:243
CRESettings.h
HookInformation::pluginName
QString pluginName() const
Definition: ScriptFile.cpp:101
python_init.path
path
Definition: python_init.py:8
ScriptFileManager::removeMap
void removeMap(CREMapInformation *map)
Definition: ScriptFileManager.cpp:50
CREMapInformationManager::myAnimationUse
QMultiHash< QString, CREMapInformation * > myAnimationUse
Definition: CREMapInformationManager.h:60
CREUtils::lockCrossfireData
static std::unique_ptr< QMutexLocker > lockCrossfireData()
Definition: CREUtils.cpp:59
CREMapInformation::addFace
void addFace(const QString &face)
Definition: CREMapInformation.cpp:110
python
Definition: python.py:1
FOR_INV_FINISH
#define FOR_INV_FINISH()
Definition: define.h:677
CREMapInformation::experience
qint64 experience
Definition: CREMapInformation.h:35
say.max
dictionary max
Definition: say.py:148
MessageManager
Definition: MessageManager.h:25
archetype
Definition: object.h:481
doors_galore.process
def process()
Definition: doors_galore.py:72
AssetsCollection::each
void each(std::function< void(T *)> op)
Definition: AssetsCollection.h:158
animate.anim
string anim
Definition: animate.py:20
delete_map
void delete_map(mapstruct *m)
Definition: map.cpp:1699
CREMapInformationManager::myScriptManager
ScriptFileManager * myScriptManager
Definition: CREMapInformationManager.h:56
CREMapInformationManager::myArchetypeUse
QMultiHash< QString, CREMapInformation * > myArchetypeUse
Definition: CREMapInformationManager.h:58
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
MAP_WIDTH
#define MAP_WIDTH(m)
Definition: map.h:73
CREMapInformationManager::browseFinished
bool browseFinished() const
Definition: CREMapInformationManager.cpp:81
AssetsManager::archetypes
Archetypes * archetypes()
Definition: AssetsManager.h:44
env
static std::shared_ptr< inja::Environment > env
Definition: mapper.cpp:2168
MAX_BUF
#define MAX_BUF
Definition: define.h:35
CREMapInformationManager.h
CREMapInformationManager::getMapsForRegion
QList< CREMapInformation * > getMapsForRegion(const QString &region)
Definition: CREMapInformationManager.cpp:793
StringBuffer
Definition: stringbuffer.cpp:25
ScriptFile
Definition: ScriptFile.h:48
FOR_MAP_PREPARE
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:723
EXIT
@ EXIT
Definition: object.h:186
CREMapInformation::addExitTo
void addExitTo(const QString &path)
Definition: CREMapInformation.cpp:140
region
Definition: map.h:272
diamondslots.message
string message
Definition: diamondslots.py:57
MessageFile.h
CREMapInformationManager::myLock
QMutex myLock
Definition: CREMapInformationManager.h:66
CREMapInformationManager::myFaceUse
QMultiHash< QString, CREMapInformation * > myFaceUse
Definition: CREMapInformationManager.h:59
add_region_link
static void add_region_link(mapstruct *source, mapstruct *dest)
Definition: mapper.cpp:1356
CREMapInformation::setBackgroundMusic
void setBackgroundMusic(const QString &music)
Definition: CREMapInformation.cpp:79
CREMapInformationManager::getOrCreateMapInformation
CREMapInformation * getOrCreateMapInformation(const QString &path)
Definition: CREMapInformationManager.cpp:709
CREMapInformation::addRandomMap
void addRandomMap(RandomMap *map)
Definition: CREMapInformation.cpp:273
CREMapInformation::setMapTime
void setMapTime(const QDateTime &date)
Definition: CREMapInformation.cpp:130
CREMapInformationManager::myToProcess
QStringList myToProcess
Definition: CREMapInformationManager.h:62
CREMapInformationManager::addQuestUse
void addQuestUse(const QString &name, CREMapInformation *map)
Definition: CREMapInformationManager.cpp:740
CREMapInformationManager::browseMaps
void browseMaps()
Definition: CREMapInformationManager.cpp:310
item
Definition: item.py:1
CREMapInformation::setShopMax
void setShopMax(quint64 max)
Definition: CREMapInformation.cpp:263
CREMapInformationManager::addFaceUse
void addFaceUse(const QString &name, CREMapInformation *map)
Definition: CREMapInformationManager.cpp:726
PLAYER_CHANGER
@ PLAYER_CHANGER
Definition: object.h:167
mapstruct
Definition: map.h:313
create_pathname
char * create_pathname(const char *name, char *buf, size_t size)
Definition: map.cpp:104
Animations
Definition: face.h:25
CRESettings
Definition: CRESettings.h:21
quest_definition
Definition: quest.h:37
find_archetype
archetype * find_archetype(const char *name)
Definition: assets.cpp:266
CREMapInformationManager::checkEvent
void checkEvent(const object *item, CREMapInformation *map, const object *env)
Definition: CREMapInformationManager.cpp:747
CREMapInformation::setResetGroup
void setResetGroup(const QString &resetGroup)
Definition: CREMapInformation.cpp:89
mapstruct::in_memory
uint32_t in_memory
Definition: map.h:333
roll-o-matic.params
params
Definition: roll-o-matic.py:193
diamondslots.y
y
Definition: diamondslots.py:16
assets.h
CREMapInformation::setName
void setName(const QString &name)
Definition: CREMapInformation.cpp:69
CREMapInformationManager::cancel
void cancel()
Definition: CREMapInformationManager.cpp:368
MAP_HEIGHT
#define MAP_HEIGHT(m)
Definition: map.h:75
CREMapInformationManager::loadCache
void loadCache()
Definition: CREMapInformationManager.cpp:404
do_regions_link
static bool do_regions_link
Definition: mapper.cpp:381
CREMapInformation::addArchetype
void addArchetype(const QString &archetype)
Definition: CREMapInformation.cpp:99
CREMapInformationManager::myInformation
QHash< QString, CREMapInformation * > myInformation
Definition: CREMapInformationManager.h:57
animate.event
event
DIALOGCHECK MINARGS 1 MAXARGS 2
Definition: animate.py:17
CREMapInformationManager::getMapsForQuest
QList< CREMapInformation * > getMapsForQuest(const quest_definition *quest)
Definition: CREMapInformationManager.cpp:398
CREMapInformationManager::myMessageManager
MessageManager * myMessageManager
Definition: CREMapInformationManager.h:55
CREMapInformationManager::getFaceUse
QList< CREMapInformation * > getFaceUse(const Face *face)
Definition: CREMapInformationManager.cpp:386
CREMapInformationManager::myQuestUse
QMultiHash< QString, CREMapInformation * > myQuestUse
Definition: CREMapInformationManager.h:61
calculate_difficulty
int calculate_difficulty(mapstruct *m)
Definition: map.cpp:1888
CREMapInformation::addAccessedFrom
void addAccessedFrom(const QString &path)
Definition: CREMapInformation.cpp:151
ScriptFile::hooks
QList< HookInformation * > hooks() const
Definition: ScriptFile.cpp:42
split
static std::vector< std::string > split(const std::string &field, const std::string &by)
Definition: mapper.cpp:2606
mapstruct::reset_time
uint32_t reset_time
Definition: map.h:320
say.item
dictionary item
Definition: say.py:149
connect
Definition: connect.py:1
CREMapInformation::setExperience
void setExperience(qint64 experience)
Definition: CREMapInformation.cpp:182
HookInformation
Definition: ScriptFile.h:25
mapfile_load
mapstruct * mapfile_load(const char *map, int flags)
Definition: map.cpp:1217
TELEPORTER
@ TELEPORTER
Definition: object.h:146
eventNames
const char * eventNames[NR_EVENTS]
Definition: CREMapInformationManager.cpp:28
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:670
write_map_parameters_to_string
StringBuffer * write_map_parameters_to_string(const RMParms *RP)
Definition: random_map.cpp:749
CREMapInformationManager::storeCache
void storeCache()
Definition: CREMapInformationManager.cpp:584
Animations::name
sstring name
Definition: face.h:26
give.name
name
Definition: give.py:27
HookInformation::eventName
QString eventName() const
Definition: ScriptFile.cpp:106