MapFormatJson.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * MapFormatJson.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "MapFormatJson.h"
  12. #include "CMap.h"
  13. #include "../CModHandler.h"
  14. #include "../VCMI_Lib.h"
  15. static const std::string conditionNames[] = {
  16. "haveArtifact", "haveCreatures", "haveResources", "haveBuilding",
  17. "control", "destroy", "transport",
  18. "daysPassed", "isHuman", "daysWithoutTown", "standardWin"
  19. };
  20. static const std::string typeNames[] = { "victory", "defeat" };
  21. CMapLoaderJson::CMapLoaderJson(JsonNode stream):
  22. input(stream)
  23. {
  24. }
  25. std::unique_ptr<CMap> CMapLoaderJson::loadMap()
  26. {
  27. map = new CMap();
  28. mapHeader.reset(map);
  29. readMap();
  30. mapHeader.reset();
  31. return std::unique_ptr<CMap>(map);
  32. }
  33. std::unique_ptr<CMapHeader> CMapLoaderJson::loadMapHeader()
  34. {
  35. mapHeader.reset(new CMapHeader);
  36. readHeader();
  37. return std::move(mapHeader);
  38. }
  39. /*
  40. //This code can be used to write map header to console or file in its Json representation
  41. JsonNode out;
  42. JsonNode data;
  43. data["victoryString"].String() = mapHeader->victoryMessage;
  44. data["defeatString"].String() = mapHeader->defeatMessage;
  45. data["victoryIconIndex"].Float() = mapHeader->victoryIconIndex;
  46. data["defeatIconIndex"].Float() = mapHeader->defeatIconIndex;
  47. for (const TriggeredEvent & entry : mapHeader->triggeredEvents)
  48. {
  49. JsonNode event;
  50. event["message"].String() = entry.onFulfill;
  51. event["effect"]["messageToSend"].String() = entry.effect.toOtherMessage;
  52. event["effect"]["type"].String() = typeNames[entry.effect.type];
  53. event["condition"] = entry.trigger.toJson(eventToJson);
  54. data["triggeredEvents"][entry.identifier] = event;
  55. }
  56. out[mapHeader->name] = data;
  57. logGlobal->errorStream() << out;
  58. JsonNode eventToJson(const EventCondition & cond)
  59. {
  60. JsonNode ret;
  61. ret.Vector().resize(2);
  62. ret.Vector()[0].String() = conditionNames[size_t(cond.condition)];
  63. JsonNode & data = ret.Vector()[1];
  64. data["type"].Float() = cond.objectType;
  65. data["value"].Float() = cond.value;
  66. data["position"].Vector().resize(3);
  67. data["position"].Vector()[0].Float() = cond.position.x;
  68. data["position"].Vector()[1].Float() = cond.position.y;
  69. data["position"].Vector()[2].Float() = cond.position.z;
  70. return ret;
  71. }
  72. */
  73. void CMapLoaderJson::patchMapHeader(std::unique_ptr<CMapHeader> & header)
  74. {
  75. header.swap(mapHeader);
  76. if (!input.isNull())
  77. readPatchData();
  78. header.swap(mapHeader);
  79. }
  80. void CMapLoaderJson::readMap()
  81. {
  82. readHeader();
  83. assert(0); // Not implemented, vcmi does not have its own map format right now
  84. }
  85. void CMapLoaderJson::readHeader()
  86. {
  87. //TODO: read such data like map name & size
  88. readPatchData();
  89. readPlayerInfo();
  90. assert(0); // Not implemented
  91. }
  92. void CMapLoaderJson::readPatchData()
  93. {
  94. mapHeader->victoryMessage = input["victoryString"].String();
  95. mapHeader->victoryIconIndex = input["victoryIconIndex"].Float();
  96. mapHeader->defeatMessage = input["defeatString"].String();
  97. mapHeader->defeatIconIndex = input["defeatIconIndex"].Float();
  98. readTriggeredEvents();
  99. }
  100. void CMapLoaderJson::readTriggeredEvents()
  101. {
  102. mapHeader->triggeredEvents.clear();
  103. for (auto & entry : input["triggeredEvents"].Struct())
  104. {
  105. TriggeredEvent event;
  106. event.identifier = entry.first;
  107. readTriggeredEvent(event, entry.second);
  108. mapHeader->triggeredEvents.push_back(event);
  109. }
  110. }
  111. static EventCondition JsonToCondition(const JsonNode & node)
  112. {
  113. EventCondition event;
  114. event.condition = EventCondition::EWinLoseType(vstd::find_pos(conditionNames, node.Vector()[0].String()));
  115. if (node.Vector().size() > 1)
  116. {
  117. const JsonNode & data = node.Vector()[1];
  118. if (data["type"].getType() == JsonNode::DATA_STRING)
  119. event.objectType = VLC->modh->identifiers.getIdentifier(data["type"]).get();
  120. if (data["type"].getType() == JsonNode::DATA_FLOAT)
  121. event.objectType = data["type"].Float();
  122. if (!data["value"].isNull())
  123. event.value = data["value"].Float();
  124. if (!data["position"].isNull())
  125. {
  126. event.position.x = data["position"].Vector()[0].Float();
  127. event.position.y = data["position"].Vector()[1].Float();
  128. event.position.z = data["position"].Vector()[2].Float();
  129. }
  130. }
  131. return event;
  132. }
  133. void CMapLoaderJson::readTriggeredEvent(TriggeredEvent & event, const JsonNode & source)
  134. {
  135. event.onFulfill = source["message"].String();
  136. event.description = source["description"].String();
  137. event.effect.type = vstd::find_pos(typeNames, source["effect"]["type"].String());
  138. event.effect.toOtherMessage = source["effect"]["messageToSend"].String();
  139. event.trigger = EventExpression(source["condition"], JsonToCondition); // logical expression
  140. }
  141. void CMapLoaderJson::readPlayerInfo()
  142. {
  143. assert(0); // Not implemented
  144. }