Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

WorldBranch.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net)
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
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  * Execute script which will add nodes.
00038  * @param datafile worldmap file
00039  * @param outEnding pointer to store ending node. It is not changed when
00040  * endingNode is set.
00041  * @param destPack pack to store node descriptions
00042  * @return root node (can be NULL)
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  * Add new node to branch.
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  * Take ending node.
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  * Store best solution author.
00112  * @param codename level codename
00113  * @param moves number of moves in solution
00114  * @param author solution author
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  * Returns true when level will solved in the past.
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  * Set node state.
00145  * @param hidden whether node is start node of hidden branch
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  * Insert node as parent child.
00163  * @throws LogicException when error occurs
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 

Generated on Wed Jun 1 09:54:32 2005 for Fish Fillets - Next Generation by  doxygen 1.4.2