00001 /* 00002 SagaEngine library 00003 Copyright (c) 2002-2006 Skalden Studio AS 00004 00005 This software is provided 'as-is', without any express or implied 00006 warranty. In no event will the authors be held liable for any 00007 damages arising from the use of this software. 00008 00009 Permission is granted to distribute the library under the terms of the 00010 Q Public License version 1.0. Be sure to read and understand the license 00011 before using the library. It should be included here, or you may read it 00012 at http://www.trolltech.com/products/qt/licenses/licensing/qpl 00013 00014 The original version of this library can be located at: 00015 http://www.sagaengine.com/ 00016 00017 Rune Myrland 00018 rune@skalden.com 00019 */ 00020 00021 00022 #include "CutsceneParser.hpp" 00023 #include "io/stream/InputStream.hpp" 00024 #include "sim/sim.hpp" 00025 #include "sim/schema/SimSchema.hpp" 00026 #include "sim/script/Cutscene.hpp" 00027 #include "sim/script/TimelineScript.hpp" 00028 #include "sim/script/QuestGoal.hpp" 00029 #include "comp/schema/CompSchema.hpp" 00030 #include "comp/list/ObjectRepository.hpp" 00031 #include "comp/list/ObjectList.hpp" 00032 #include "sim/area/Area.hpp" 00033 #include "sim/area/AreaManager.hpp" 00034 #include "util/type/String.hpp" 00035 #include "util/error/Log.hpp" 00036 #include <cstring> 00037 #include <cstdio> 00038 00039 00040 namespace se_core { 00041 00042 00043 CutsceneParser 00044 ::CutsceneParser(ParseManager& parser) 00045 : Parser(parser, Parser::ENGINE, Parser::CUTSCENE, 1) { 00046 } 00047 00048 00049 void CutsceneParser 00050 ::parse(InputStream& in) { 00051 String* name; 00052 Cutscene* cutscene = 0; 00053 00054 int code = ' '; 00055 while((code = in.readInfoCode()) != 'Q') { 00056 //printf("Code: %c\n", code); 00057 switch(code) { 00058 case 'N': // Cutscene name 00059 name = new String(); 00060 in.readString(*name); 00061 cutscene = new Cutscene(name); 00062 break; 00063 00064 case 'O': // Actors owning (triggering) this cutscene 00065 readMultiOwner(in, cutscene); 00066 break; 00067 00068 case 'M': // Actors that are members this cutscene 00069 readMultiMember(in, cutscene); 00070 break; 00071 00072 case 'X': // Areas owning this cutscene 00073 readMultiArea(in, cutscene); 00074 break; 00075 00076 case 'S': // Script 00077 readScript(in, cutscene->name(), 40); 00078 break; 00079 00080 case 'Z': // Zero mode script 00081 readScript(in, cutscene->name(), 1); 00082 break; 00083 00084 case 'A': // AFTER: QuestGoals that must be accomplished first 00085 readMultiQuest(in, cutscene->beforeTheseGoals()); 00086 break; 00087 00088 case 'B': // BEFORE: QuestGoals that must be accomplished after 00089 readMultiQuest(in, cutscene->afterTheseGoals()); 00090 break; 00091 00092 case 'R': // REWARD: QuestGoal that is rewarded 00093 name = new String(); 00094 in.readString(*name); 00095 if(!QuestGoal::lookup(name->get())) { 00096 cutscene->setQuestGoal(new QuestGoal(name)); 00097 } 00098 else { 00099 cutscene->setQuestGoal(QuestGoal::lookup(name->get())); 00100 delete name; 00101 } 00102 break; 00103 00104 default: 00105 LogFatal("Unsupported token"); 00106 break; 00107 } 00108 } 00109 } 00110 00111 00112 void CutsceneParser 00113 ::readScript(InputStream& in, const char* cutsceneName, short trackerPosCount) { 00114 String* name; 00115 String* attribute; 00116 name = new String(); 00117 in.readString(*name); 00118 char* fullname = new char[ strlen(cutsceneName) + strlen(name->get()) + 2 ]; 00119 sprintf(fullname, "%s.%s", cutsceneName, name->get()); 00120 //name->set(fullname); 00121 TimelineScript* script = new TimelineScript(fullname, trackerPosCount); 00122 int trackerPos = 0; 00123 int parameter = 0; 00124 name = new String(); 00125 00126 int code = 'X'; 00127 while((code = in.readInfoCode()) != '/') { 00128 switch(code) { 00129 case 'C': // Command with no parameter 00130 trackerPos = in.readShort(); 00131 in.readString(*name); 00132 script->addAction(trackerPos, name->get()); 00133 break; 00134 00135 case 'P': // Command with parameter 00136 trackerPos = in.readShort(); 00137 in.readString(*name); 00138 parameter = in.readShort(); 00139 script->addAction(trackerPos, name->get(), parameter); 00140 break; 00141 00142 case 'A': // Command with attribute 00143 trackerPos = in.readShort(); 00144 in.readString(*name); 00145 attribute = new String(); 00146 in.readString(*attribute); 00147 script->addAction(trackerPos, name->get(), attribute); 00148 break; 00149 00150 case 'B': // Command with attribute and parameter 00151 trackerPos = in.readShort(); 00152 in.readString(*name); 00153 attribute = new String(); 00154 in.readString(*attribute); 00155 parameter = in.readShort(); 00156 script->addAction(trackerPos, name->get(), attribute, parameter); 00157 break; 00158 } 00159 } 00160 delete name; 00161 } 00162 00163 00164 void CutsceneParser 00165 ::readMultiQuest(InputStream& in, ObjectList& mgo) { 00166 String* name; 00167 int count = 0; 00168 for(;;) { 00169 name = new String(); 00170 in.readString(*name); 00171 if(strcmp("/", name->get()) == 0) { 00172 delete name; 00173 break; 00174 } 00175 if(!CompSchema::objectRepository().has(QuestGoal::hash(got_QUEST_GOAL, name->get()))) { 00176 QuestGoal* g = new QuestGoal(name); 00177 mgo.add(*g); 00178 } 00179 else { 00180 mgo.add(*QuestGoal::lookup(name->get())); 00181 delete name; 00182 } 00183 ++count; 00184 AssertFatal(count > 10, "More than 10 quest goals, loop hangs?"); 00185 } 00186 } 00187 00188 00189 void CutsceneParser 00190 ::readMultiOwner(InputStream& in, Cutscene* cutscene) { 00191 String* name; 00192 for(;;) { 00193 name = new String(); 00194 in.readString(*name); 00195 if(strcmp("/", name->get()) == 0) { 00196 delete name; 00197 break; 00198 } 00199 //TODO: 00200 LogFatal("TODO"); 00201 //SimSchema::thingManager().addCutscene(name->get(), cutscene); 00202 delete name; 00203 } 00204 } 00205 00206 void CutsceneParser 00207 ::readMultiMember(InputStream& in, Cutscene* cutscene) { 00208 String* name; 00209 for(;;) { 00210 name = new String(); 00211 in.readString(*name); 00212 if(strcmp("/", name->get()) == 0) { 00213 delete name; 00214 break; 00215 } 00216 //TODO: 00217 LogFatal("TODO"); 00218 //SimSchema::thingManager().addCutsceneMembership(name->get(), cutscene); 00219 delete name; 00220 } 00221 } 00222 00223 void CutsceneParser 00224 ::readMultiArea(InputStream& in, Cutscene* cutscene) { 00225 String* name; 00226 for(;;) { 00227 name = new String(); 00228 in.readString(*name); 00229 if(strcmp("/", name->get()) == 0) { 00230 delete name; 00231 break; 00232 } 00233 //TODO: 00234 //SimSchema::areaManager.area(name->get())->multiSimObject(Area::MGOA_CUTSCENES).add(*cutscene); 00235 LogFatal("TODO"); 00236 delete name; 00237 } 00238 } 00239 00240 }
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:10 2007 by Doxygen version 1.3.9.1.