SimpleAreaThingParser.cpp

Go to the documentation of this file.
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.

SourceForge.net Logo