00001 #include "SimpleAreaThingParser.hpp" 00002 #include "sim/spawn/SpawnAreaComponent.hpp" 00003 #include "sim/zone/ZoneAreaComponent.hpp" 00004 #include "sim/area/AreaManager.hpp" 00005 #include "sim/area/Area.hpp" 00006 #include "sim/zone/Exit.hpp" 00007 #include "sim/custom/StatComponent.hpp" 00008 #include "sim/signal/SignalComponent.hpp" 00009 #include "sim/spawn/SpawnComponent.hpp" 00010 #include "sim/spawn/SpawnComponentFactory.hpp" 00011 #include "comp/CompositeFactory.hpp" 00012 #include <cstring> 00013 00014 using namespace se_core; 00015 00016 00017 namespace se_basic { 00018 SimpleAreaThingParser 00019 ::SimpleAreaThingParser(ParseManager& parser) 00020 : Parser(parser, Parser::GAME, Parser::AREA_THINGS, 1) { 00021 } 00022 00023 00024 SimpleAreaThingParser 00025 ::~SimpleAreaThingParser() { 00026 } 00027 00028 00029 void SimpleAreaThingParser 00030 ::parse(InputStream& in) { 00031 const short MAX_AREAS = 256; 00032 Area* areas[ MAX_AREAS]; 00033 int areaCount = 0; 00034 00035 short MAX_SPAWN_POINTS = 20; 00036 int spawnPointCount = 0; 00037 ViewPoint** spawnPoints = new ViewPoint*[ MAX_SPAWN_POINTS ]; 00038 for(int i = 0; i < MAX_SPAWN_POINTS; ++i) { 00039 spawnPoints[i] = 0; 00040 } 00041 00042 static const int MAX_EXITS = 16; 00043 int exitCount = 0; 00044 Exit exits[MAX_EXITS]; 00045 00046 int code; 00047 while((code = in.readInfoCode()) != 'Q' && !in.eof()) { 00048 switch(code) { 00049 case 'D': 00050 { 00051 String tempString; 00052 in.readString(tempString); 00053 String name(in.oneDirAndBasename(), -in.basenameLen()); 00054 name.append(tempString.get()); 00055 if(SimSchema::areaManager.hasArea(name.get())) { 00056 areas[0] = SimSchema::areaManager.area(name.get()); 00057 areaCount = 1; 00058 } 00059 } 00060 break; 00061 00062 case 'N': 00063 { 00064 String tempString; 00065 in.readString(tempString); 00066 if(SimSchema::areaManager.hasArea(tempString.get())) { 00067 areas[0] = SimSchema::areaManager.area(tempString.get()); 00068 areaCount = 1; 00069 } 00070 } 00071 break; 00072 00073 case 'F': 00074 { 00075 String tempString; 00076 in.readString(tempString); 00077 areaCount = SimSchema::areaManager.areasByFactory(tempString.get(), areas, MAX_AREAS); 00078 } 00079 break; 00080 00081 case 'A': // object (thing or actor) 00082 readThing(in, areaCount, areas); 00083 break; 00084 00085 case 'C': // Cutscenes 00086 readMultiCutscene(in, areaCount, areas); 00087 break; 00088 00089 case 'E': { // entrance 00090 short id = in.readShort(); 00091 Assert(id < MAX_SPAWN_POINTS); 00092 Assert(spawnPoints[id] == 0); 00093 00094 ViewPoint* sp = new ViewPoint(); 00095 readSpawnPoint(in, *sp); 00096 00097 spawnPoints[id] = sp; 00098 if(id >= spawnPointCount) { 00099 spawnPointCount = id + 1; 00100 } 00101 } 00102 break; 00103 case 'X': 00104 { 00105 String* area = new String(); 00106 in.readString(*area); 00107 short entrance = in.readShort(); 00108 exits[ exitCount ].area_ = area; 00109 exits[ exitCount ].entrance_ = entrance; 00110 ++exitCount; 00111 } 00112 break; 00113 } 00114 } 00115 for(int i = 0; i < areaCount; ++i) { 00116 if(spawnPointCount) { 00117 //LogDetail("Set spawn points for: " << areas[i]->name() << " - " << in.name()); 00118 SpawnAreaComponent::Ptr aSpawn(*areas[i]); 00119 aSpawn->setSpawnPoints(spawnPointCount, spawnPoints); 00120 } 00121 if(exitCount) { 00122 ZoneAreaComponent::Ptr aZone(*areas[i]); 00123 aZone->setExits(exits, exitCount); 00124 } 00125 //LogDetail("Flip children for: " << areas[i]->name()); 00126 areas[i]->flipSpawns(); 00127 } 00128 //LogDetail("Parsed things for: " << area->name()); 00129 } 00130 00131 00132 void SimpleAreaThingParser 00133 ::readThing(InputStream& in, int areaCount, se_core::Area** areas, Composite** parents) { 00134 String thingName; 00135 in.readString(thingName); 00136 00137 ViewPoint vp; 00138 vp.setIdentity(); 00139 00140 bool hasAnim[4]; 00141 Anim anim[4]; 00142 for(int i = 0; i < 4; ++i) 00143 hasAnim[i] = false; 00144 00145 int isOn = -1; 00146 00147 bool isGrounded = false; 00148 bool isScaled = false; 00149 float radius = 1; 00150 00151 int code; 00152 while((code = in.readInfoCode()) != '/') { 00153 // Start reading children 00154 if(code == '[') break; 00155 00156 switch(code) { 00157 case 'G': // Grounded 00158 isGrounded = true; 00159 break; 00160 case 'S': // Scale 00161 { 00162 isScaled = true; 00163 radius = in.readFloat(); 00164 } 00165 break; 00166 case 'T': // Transform 00167 { 00168 float x = in.readFloat(); 00169 float y = in.readFloat(); 00170 float z = in.readFloat(); 00171 vp.coor_.set(CoorT::fromFloat(x), CoorT::fromFloat(y), CoorT::fromFloat(z)); 00172 } 00173 break; 00174 case 'R': // Rotation 00175 { 00176 float yaw = in.readFloat(); 00177 float pitch = in.readFloat(); 00178 float roll = in.readFloat(); 00179 //LogDetail("R " << yaw << " " << pitch << " " << roll); 00180 vp.face_.setEuler( 00181 BrayT::fromDeg(yaw) 00182 , BrayT::fromDeg(pitch) 00183 , BrayT::fromDeg(roll) 00184 ); 00185 } 00186 break; 00187 00188 case 'A': // Anim 00189 { 00190 int id = in.readShort(); 00191 int movementMode = in.readShort(); 00192 float startPos = in.readFloat(); 00193 float pos = in.readFloat(); 00194 float speed = in.readFloat(); 00195 float weight = in.readFloat(); 00196 00197 hasAnim[id] = true; 00198 anim[id].setMovementMode(movementMode); 00199 anim[id].setStartPos(pos); 00200 anim[id].resetPos(); 00201 anim[id].setStartPos(startPos); 00202 anim[id].setSpeed(speed); 00203 anim[id].setWeight(weight); 00204 } 00205 break; 00206 00207 case 'I': // Signal 00208 { 00209 isOn = in.readShort(); 00210 break; 00211 } 00212 00213 default: 00214 LogFatal("Illegal parameter to thing: " << (char)(code)); 00215 } 00216 } 00217 00218 // Array to put created things. Is relevant if the 00219 // same thing is to be put in several areas. (Useful 00220 // when all areas of the same type has this thing.) 00221 Composite** siblings = new Composite*[areaCount]; 00222 for(int i = 0; i < areaCount; ++i) { 00223 // Get parent area i (if parents array exists) 00224 Composite* parent = (parents) ? parents[i] : 0; 00225 // PosComponent of parent area 00226 PosComponent* parentPos = PosComponent::get(parent); 00227 AssertWarning(areas[i]->terrainStyle(vp.coor_) != Pos::TS_VOID, thingName.get() << " - Area: " << areas[i]->name() << " - Factory: " << areas[i]->owner()->factory()->name() << " - Coor: " << vp.coor_); 00228 // Is wanted position is at a spot where things may stand? 00229 if(areas[i]->terrainStyle(vp.coor_) == Pos::TS_VOID) 00230 continue; 00231 00232 // Spawn the thing 00233 Composite* thing = areas[i]->spawn(thingName.get(), vp, 0, parentPos); 00234 // Place the thing 00235 PosComponent* p = PosComponent::get(thing); 00236 Assert(p); 00237 if(isScaled) { 00238 // Scale relative to the default raidus of the thing 00239 float r = CoorT::toFloat(p->nextPos().radius()) * radius; 00240 p->nextPos().setRadius(r); 00241 } 00242 // Clamp to ground?? 00243 p->nextPos().setGrounded(isGrounded); 00244 // Init anims 00245 for(int j = 0; j < 4; ++j) { 00246 if(hasAnim[j]) { 00247 p->nextPos().anim(j).setAnim(anim[j]); 00248 } 00249 } 00250 // Mark as "should save" when saving to a savefile 00251 StatComponent::Ptr(*thing)->setShouldSave(true); 00252 00253 // Send signal if active 00254 if(isOn >= 0) { 00255 SignalComponent::Ptr(*thing)->send(isOn == 0); 00256 } 00257 00258 // Register sibling 00259 siblings[i] = thing; 00260 } 00261 00262 if(code == '[') { 00263 //LogDetail('['); 00264 readChildren(in, areaCount, areas, siblings); 00265 00266 // End of thing ('/') should follow 00267 code = in.readInfoCode(); 00268 00269 //LogDetail(']'); 00270 } 00271 Assert(code == '/'); 00272 delete[] siblings; 00273 //LogDetail(thing->name() << ": " << vp.toLog()); 00274 } 00275 00276 00277 void SimpleAreaThingParser 00278 ::readChildren(InputStream& in, int areaCount, Area** areas, Composite** parents) { 00279 int code; 00280 while((code = in.readInfoCode()) != ']') { 00281 //LogDetail("Code: " << (char)code); 00282 switch(code) { 00283 case 'A': // object (thing or actor) 00284 readThing(in, areaCount, areas, parents); 00285 break; 00286 } 00287 } 00288 } 00289 00290 00291 void SimpleAreaThingParser 00292 ::readSpawnPoint(InputStream& in, ViewPoint& sp) { 00293 sp.coor_.reset(); 00294 sp.face_.setIdentity(); 00295 00296 int code = 'X'; 00297 while((code = in.readInfoCode()) != '/') { 00298 switch(code) { 00299 case 'T': // Transform 00300 { 00301 float x = in.readFloat(); 00302 float y = in.readFloat(); 00303 float z = in.readFloat(); 00304 sp.coor_.set(CoorT::fromFloat(x), CoorT::fromFloat(y), CoorT::fromFloat(z)); 00305 } 00306 break; 00307 case 'R': // Transform 00308 { 00309 float yaw = in.readFloat(); 00310 float pitch = in.readFloat(); 00311 float roll = in.readFloat(); 00312 sp.face_.setEuler( 00313 BrayT::fromDeg(yaw) 00314 , BrayT::fromDeg(pitch) 00315 , BrayT::fromDeg(roll) 00316 ); 00317 } 00318 break; 00319 default: 00320 LogFatal("Illegal parameter to thing: " << (char)(code)); 00321 } 00322 } 00323 } 00324 00325 00326 void SimpleAreaThingParser 00327 ::readMultiCutscene(InputStream& in, int areaCount, Area** areas) { 00328 LogFatal("Not implemented"); 00329 /* 00330 String* name; 00331 00332 for(;;) { 00333 name = new String(); 00334 in.readString(*name); 00335 if(strcmp("/", name->get()) == 0) { 00336 delete name; 00337 break; 00338 } 00339 if(!SimSchema::sortedSimObjectList().has(got_CUTSCENE, name->get())) { 00340 LogFatal("Tried to add non-existing cutscene."); 00341 } 00342 else { 00343 Cutscene& c = *SimSchema::sortedSimObjectList().cutscene(name->get()); 00344 for(int i = 0; i < areaCount; ++i) { 00345 MultiSimObject& mgo = areas[i]->multiSimObject(Area::MGOA_CUTSCENES); 00346 mgo.add(c); 00347 } 00348 delete name; 00349 } 00350 } 00351 */ 00352 } 00353 00354 }
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:02 2007 by Doxygen version 1.3.9.1.