00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "LevelStatus.h"
00010
00011 #include "def-script.h"
00012 #include "Path.h"
00013 #include "ScriptState.h"
00014 #include "ScriptException.h"
00015 #include "DemoMode.h"
00016
00017 extern "C" {
00018 #include "lua.h"
00019 }
00020 #include <stdio.h>
00021
00022
00023 inline LevelStatus *
00024 getStatus(lua_State *L)
00025 {
00026 return dynamic_cast<LevelStatus*>(script_getLeader(L));
00027 }
00028
00029
00030
00031
00032
00033
00034 static int
00035 script_status_readMoves(lua_State *L) throw()
00036 {
00037 BEGIN_NOEXCEPTION;
00038 const char *saved_moves = luaL_checkstring(L, 1);
00039 getStatus(L)->readMoves(saved_moves);
00040 END_NOEXCEPTION;
00041 return 0;
00042 }
00043
00044
00045 LevelStatus::LevelStatus()
00046 {
00047 m_bestMoves = -1;
00048 m_complete = false;
00049 m_wasRunning = false;
00050 m_script->registerFunc("status_readMoves", script_status_readMoves);
00051 }
00052
00053 void
00054 LevelStatus::readMoves(const std::string &savedMoves)
00055 {
00056 m_savedMoves = savedMoves;
00057 }
00058
00059 void
00060 LevelStatus::prepareRun(const std::string &codename, const std::string &poster,
00061 int bestMoves, const std::string &bestAuthor)
00062 {
00063 m_complete = false;
00064 m_wasRunning = false;
00065 m_codename = codename;
00066 m_poster = poster;
00067 m_bestMoves = bestMoves;
00068 m_bestAuthor = bestAuthor;
00069 }
00070
00071 std::string
00072 LevelStatus::getSolutionFilename(const std::string &codename)
00073 {
00074 return "solved/" + codename + ".lua";
00075 }
00076
00077 std::string
00078 LevelStatus::getSolutionFilename() const
00079 {
00080 return getSolutionFilename(m_codename);
00081 }
00082
00083
00084
00085
00086
00087 std::string
00088 LevelStatus::readSolvedMoves()
00089 {
00090 m_savedMoves = "";
00091
00092 Path oldSolution = Path::dataReadPath(getSolutionFilename());
00093 if (oldSolution.exists()) {
00094 try {
00095 scriptDo("saved_moves=nil");
00096 scriptInclude(oldSolution);
00097 scriptDo("status_readMoves(saved_moves)");
00098 }
00099 catch (ScriptException &e) {
00100 LOG_WARNING(e.info());
00101 }
00102 }
00103
00104 return m_savedMoves;
00105 }
00106
00107
00108
00109
00110
00111 void
00112 LevelStatus::writeSolvedMoves(const std::string &moves)
00113 {
00114 std::string prevMoves = readSolvedMoves();
00115
00116 if (prevMoves.empty() || moves.size() < prevMoves.size()) {
00117 Path file = Path::dataWritePath(getSolutionFilename());
00118 FILE *saveFile = fopen(file.getNative().c_str(), "w");
00119 if (saveFile) {
00120 fputs("\nsaved_moves = '", saveFile);
00121 fputs(moves.c_str(), saveFile);
00122 fputs("'\n", saveFile);
00123 fclose(saveFile);
00124 }
00125 else {
00126 LOG_WARNING(ExInfo("cannot save solution")
00127 .addInfo("file", file.getNative())
00128 .addInfo("moves", moves));
00129 }
00130 }
00131 }
00132
00133
00134
00135
00136 GameState *
00137 LevelStatus::createPoster() const
00138 {
00139 DemoMode *result = NULL;
00140 if (!m_poster.empty()) {
00141 result = new DemoMode(Path::dataReadPath(m_poster));
00142 }
00143 return result;
00144 }
00145
00146
00147
00148
00149
00150 int
00151 LevelStatus::compareToBest()
00152 {
00153 int moves = readSolvedMoves().size();
00154 int result = 1;
00155 if (m_bestMoves > 0) {
00156 if (m_bestMoves < moves) {
00157 result = -1;
00158 }
00159 else if (m_bestMoves == moves) {
00160 result = 0;
00161 }
00162 }
00163 return result;
00164 }
00165