00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "WorldBranch.h"
00010
00011 #include "def-script.h"
00012 #include "Log.h"
00013 #include "Path.h"
00014 #include "LevelNode.h"
00015 #include "LevelStatus.h"
00016 #include "ScriptState.h"
00017 #include "ResDialogPack.h"
00018 #include "LevelDesc.h"
00019 #include "LogicException.h"
00020
00021 #include "worldmap-script.h"
00022
00023
00024 WorldBranch::WorldBranch(LevelNode *root)
00025 {
00026 m_root = root;
00027 m_ending = NULL;
00028 m_outPack = NULL;
00029
00030 m_script->registerFunc("worldmap_addDesc", script_worldmap_addDesc);
00031 m_script->registerFunc("branch_addNode", script_branch_addNode);
00032 m_script->registerFunc("branch_setEnding", script_branch_setEnding);
00033 m_script->registerFunc("node_bestSolution", script_node_bestSolution);
00034 }
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 LevelNode *
00045 WorldBranch::parseMap(const Path &datafile, LevelNode **outEnding,
00046 ResDialogPack *destPack)
00047 {
00048 m_outPack = destPack;
00049 scriptInclude(datafile);
00050 m_outPack = NULL;
00051
00052 if (m_ending) {
00053 if (outEnding) {
00054 *outEnding = m_ending;
00055 }
00056 else {
00057 throw LogicException(ExInfo("cannot export ending node")
00058 .addInfo("ending", m_ending->getCodename()));
00059 }
00060 }
00061
00062 if (m_root && m_root->getState() < LevelNode::STATE_OPEN) {
00063 m_root->setState(LevelNode::STATE_OPEN);
00064 }
00065 return m_root;
00066 }
00067
00068 void
00069 WorldBranch::addDesc(const std::string &codename, LevelDesc *desc)
00070 {
00071 if (m_outPack) {
00072 m_outPack->addRes(codename, desc);
00073 }
00074 else {
00075 throw LogicException(ExInfo("cannot export level description")
00076 .addInfo("codename", codename));
00077 }
00078 }
00079
00080
00081
00082
00083 void
00084 WorldBranch::addNode(const std::string &parent, LevelNode *new_node,
00085 bool hidden)
00086 {
00087 prepareNode(new_node, hidden);
00088 insertNode(parent, new_node);
00089 }
00090
00091
00092
00093
00094 void
00095 WorldBranch::setEnding(LevelNode *new_node)
00096 {
00097 if (m_ending) {
00098 delete m_ending;
00099 }
00100 m_ending = new_node;
00101 if (wasSolved(m_ending->getCodename())) {
00102 m_ending->setState(LevelNode::STATE_SOLVED);
00103 }
00104 else {
00105 m_ending->setState(LevelNode::STATE_OPEN);
00106 }
00107 m_ending->setDepth(-1);
00108 }
00109
00110
00111
00112
00113
00114
00115
00116 void
00117 WorldBranch::bestSolution(const std::string &codename, int moves,
00118 const std::string &author)
00119 {
00120 LevelNode *node = m_root->findNamed(codename);
00121 if (node) {
00122 node->bestSolution(moves, author);
00123 }
00124 else {
00125 throw LogicException(ExInfo("there is no such node")
00126 .addInfo("codename", codename)
00127 .addInfo("moves", moves)
00128 .addInfo("author", author));
00129 }
00130 }
00131
00132
00133
00134
00135 bool
00136 WorldBranch::wasSolved(const std::string &codename)
00137 {
00138 Path solved =
00139 Path::dataReadPath(LevelStatus::getSolutionFilename(codename));
00140 return solved.exists();
00141 }
00142
00143
00144
00145
00146
00147 void
00148 WorldBranch::prepareNode(LevelNode *node, bool hidden)
00149 {
00150 if (wasSolved(node->getCodename())) {
00151 node->setState(LevelNode::STATE_SOLVED);
00152 }
00153 else if (hidden) {
00154 node->setState(LevelNode::STATE_HIDDEN);
00155 }
00156 else {
00157 node->setState(LevelNode::STATE_FAR);
00158 }
00159 }
00160
00161
00162
00163
00164
00165 void
00166 WorldBranch::insertNode(const std::string &parent, LevelNode *new_node)
00167 {
00168 try {
00169 if (parent == "" && m_root) {
00170 throw LogicException(ExInfo("there is a one root node already")
00171 .addInfo("root", m_root->getCodename())
00172 .addInfo("new_node", new_node->getCodename()));
00173 }
00174
00175 if (m_root) {
00176 LevelNode *parentNode = m_root->findNamed(parent);
00177 if (parentNode) {
00178 parentNode->addChild(new_node);
00179 }
00180 else {
00181 throw LogicException(ExInfo("there is no such parent node")
00182 .addInfo("parent", parent)
00183 .addInfo("new_node", new_node->getCodename()));
00184 }
00185 }
00186 else {
00187 if (parent != "") {
00188 LOG_WARNING(ExInfo("root node should have empty parent")
00189 .addInfo("parent", parent)
00190 .addInfo("new_node", new_node->getCodename()));
00191 }
00192 m_root = new_node;
00193 }
00194 }
00195 catch (...) {
00196 delete new_node;
00197 throw;
00198 }
00199 }
00200