1 #include "Level.h"

    2 #include "GameObjectManager.h"

    3 #include "tinyxml.h"

    4 #include "GameObject.h"

    5 #include "GameObjectTemplate.h"

    6 

    7 #include "PhysicsSubSystem.h"

    8 #include "MeshSubSystem.h"

    9 #include "RenderSubSystem.h"

   10 #include "BehaviorSubSystem.h"

   11 #include "AnimationSubSystem.h"

   12 #include "SoundSubSystem.h"

   13 #include "TriggerSubSystem.h"

   14 #include "LifeSubSystem.h"

   15 

   16 #include "Event.h"

   17 #include "EventManager.h"

   18 #include "CaelumFrameListener.h"

   19 

   20 #include "MemLeakDetect.h"

   21 

   22 using namespace Ogre;

   23 

   24 Level::Level(const std::string& name,const std::string& desc,Ogre::Camera* camera,Ogre::SceneManager* sceneMgr,Ogre::Viewport* viewPort) : mSceneMgr(sceneMgr), mCamera(camera), mName(name), mDesc(desc),  mObjectCount(0), mViewport(viewPort), mFadingTimer(0), fading(false), mPlayerHitpoints(100), mKeyDirection(Ogre::Vector3::ZERO)

   25 {

   26     mFader = new Fader("Overlays/FadeInOut", "Materials/OverlayMaterial");

   27     mFader->startFadeIn(4.5);

   28 }

   29 

   30 Level::~Level()

   31 {

   32     if(hikariMgr)

   33     {

   34         acorn_count->hide();

   35         //fps->hide();

   36         lifebar->hide();

   37     }

   38 

   39     GameObjectManager::getInstance()->clearSubSystems();

   40     GameObjectManager::getInstance()->clearGameObjects();

   41     GameObjectManager::getInstance()->clearGameObjectTemplates();

   42 

   43     delete physicsSubSystem;

   44     physicsSubSystem =NULL;

   45     delete renderSubSystem;

   46     renderSubSystem =NULL;

   47     delete meshSubSystem;

   48     meshSubSystem=NULL;

   49     delete behaviorSubSystem;

   50     behaviorSubSystem=NULL;

   51     delete animationSubSystem;

   52     animationSubSystem=NULL;

   53     delete triggerSubSystem;

   54     triggerSubSystem=NULL;

   55     delete    soundSubSystem;

   56     soundSubSystem = NULL;

   57     delete lifeSubSystem;

   58     lifeSubSystem = NULL;

   59 

   60     if(mFader)

   61         delete mFader;

   62     mFader = NULL;

   63 }

   64 

   65 void Level::initialize()

   66 {

   67     Ogre::LogManager::getSingleton().logMessage("Level Init");

   68 

   69     setupHikari();

   70 

   71     // Set ambient light

   72     mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));

   73 

   74     Light* l = mSceneMgr->createLight("MainLight");

   75 

   76     //add a skybox

   77     mSceneMgr->setSkyBox(true, "TreeSkyBox", 1000);

   78 

   79     //setup the light

   80     l->setType(Light::LT_DIRECTIONAL);

   81     Vector3 dir(-0.3, -1, 0.2);

   82     dir.normalise();

   83     l->setDirection(dir);

   84     l->setDiffuseColour(1.0, 1.0, 0.8);

   85 

   86 

   87     initializeSubSystems();

   88 

   89     loadTemplates();

   90     loadInitialObjects();

   91 

   92     EventManager::getInstance()->registerListener(this,EventType::SpawnPlayer);

   93 

   94     Ogre::LogManager::getSingleton().logMessage("End Level Inits");

   95 

   96 }

   97 

   98 void Level::setupHikari()

   99 {

  100     using namespace Hikari;

  101 

  102     hikariMgr = HikariManager::GetPointer();

  103 

  104     if(!hikariMgr->getFlashControl("acorn_count"))

  105     {

  106         acorn_count = hikariMgr->createFlashOverlay("acorn_count", mViewport, 78, 54, Hikari::Position(TopRight));

  107         acorn_count->load("acorn_count.swf");

  108         acorn_count->setTransparent(true);

  109         acorn_count->setDraggable(false);

  110     }

  111     else

  112     {

  113         acorn_count = hikariMgr->getFlashControl("acorn_count");

  114         acorn_count->show();

  115     }

  116 

  117     if(!hikariMgr->getFlashControl("FPS2"))

  118     {

  119         fps = hikariMgr->createFlashOverlay("FPS2", mViewport, 130, 91, Hikari::Position(TopLeft));

  120         fps->load("fps.swf");

  121         fps->setTransparent(true);

  122         fps->setDraggable(false);

  123         fps->hide();

  124     }

  125     else

  126     {

  127         fps = hikariMgr->getFlashControl("FPS2");

  128         fps->show();

  129     }

  130 

  131     if(!hikariMgr->getFlashControl("lifebar"))

  132     {

  133         lifebar = hikariMgr->createFlashOverlay("lifebar", mViewport, 125, 32, Hikari::Position(TopLeft));

  134         lifebar->load("lifebar.swf");

  135         lifebar->setTransparent(true);

  136         lifebar->setDraggable(false);

  137     }

  138     else

  139     {

  140 

  141         lifebar = hikariMgr->getFlashControl("lifebar2");

  142         lifebar->show();

  143     }

  144 

  145 

  146     mKeyDirection = Ogre::Vector3::ZERO;

  147 }

  148 

  149 void Level::initializeSubSystems()

  150 {

  151 

  152     physicsSubSystem = new PhysicsSubSystem(mName);

  153     GameObjectManager::getInstance()->registerSubSystem(physicsSubSystem,"PhysicsComponent");

  154 

  155     meshSubSystem = new MeshSubSystem;

  156     GameObjectManager::getInstance()->registerSubSystem(meshSubSystem,"MeshComponent");

  157 

  158     renderSubSystem = new RenderSubSystem;

  159     GameObjectManager::getInstance()->registerSubSystem(renderSubSystem,"RenderComponent");

  160 

  161     triggerSubSystem = new TriggerSubSystem(physicsSubSystem);

  162     GameObjectManager::getInstance()->registerSubSystem(triggerSubSystem,"TriggerComponent");

  163 

  164     behaviorSubSystem = new BehaviorSubSystem(triggerSubSystem);

  165     GameObjectManager::getInstance()->registerSubSystem(behaviorSubSystem,"BehaviorComponent");

  166 

  167     animationSubSystem = new AnimationSubSystem;

  168     GameObjectManager::getInstance()->registerSubSystem(animationSubSystem,"AnimationComponent");

  169 

  170     soundSubSystem = new SoundSubSystem;

  171     GameObjectManager::getInstance()->registerSubSystem(soundSubSystem,"SoundComponent");

  172 

  173     lifeSubSystem = new LifeSubSystem;

  174     GameObjectManager::getInstance()->registerSubSystem(lifeSubSystem,"LifeComponent");

  175 }

  176 

  177 

  178 

  179 void Level::loadTemplates()

  180 {

  181     Ogre::String lvlstr("..\\levels\\");

  182     lvlstr+=mName;

  183     TiXmlDocument doc((lvlstr += ".xml").c_str());

  184     if (!doc.LoadFile())

  185     {

  186         Ogre::LogManager::getSingleton().logMessage("unable to load level");

  187         return;

  188     }

  189 

  190     TiXmlHandle hDoc(&doc);

  191     TiXmlElement* firstElement;

  192     TiXmlHandle hRoot(0);

  193     TiXmlNode* pNode;

  194     firstElement=hDoc.FirstChildElement().FirstChild().Element();

  195     // should always have a valid root but handle gracefully if it does not

  196     if (!firstElement) return;

  197 

  198     if(strcmp(firstElement->Value(),"Templates") == 0)

  199     {

  200         TiXmlElement* templateEle = firstElement->FirstChildElement();

  201         //for each game object template

  202         for(templateEle; templateEle; templateEle=templateEle->NextSiblingElement())

  203         {

  204             GameObjectTemplate* goTemplate = GameObjectManager::getInstance()->createGameObjectTemplate(templateEle->Value());

  205             pNode = templateEle->FirstChild();

  206             for(pNode;pNode;  pNode = pNode->NextSibling())

  207             {

  208                 const std::string familyID = pNode->Value();

  209                 TiXmlElement* compNode = pNode->FirstChildElement();

  210                 const char *name=compNode->Attribute("name");

  211                 goTemplate->addComponentTemplate(familyID,std::string(name));

  212                 //now lets add the template to the proper subsystem

  213                 GameObjectManager::getInstance()->buildComponentTemplate(familyID,pNode);

  214 

  215             }

  216         }

  217     }

  218 

  219 }

  220 

  221 void Level::loadInitialObjects()

  222 {

  223     Ogre::String lvlstr("..\\levels\\");

  224     lvlstr+=mName;

  225     TiXmlDocument doc((lvlstr += ".xml").c_str());

  226     if (!doc.LoadFile())

  227     {

  228         Ogre::LogManager::getSingleton().logMessage("unable to load level");

  229         return;

  230     }

  231 

  232     TiXmlHandle hDoc(&doc);

  233     TiXmlElement* firstElement;

  234     TiXmlHandle hRoot(0);

  235     TiXmlNode* pNode;

  236     firstElement=hDoc.FirstChildElement().FirstChild().Element();

  237     // should always have a valid root but handle gracefully if it does not

  238     if (!firstElement) return;

  239 

  240     TiXmlElement* gameObjectElement = hDoc.FirstChildElement().Child(1).Element();

  241 

  242     if(strcmp(gameObjectElement->Value(),"GameObjects") == 0)

  243     {

  244         TiXmlElement* goElement = gameObjectElement->FirstChildElement();

  245         //for a given template name

  246         for(goElement; goElement; goElement=goElement->NextSiblingElement())

  247         {

  248             std::string templateName(goElement->Value());

  249             //for each object to be made from this template

  250             TiXmlElement* dataElement = goElement->FirstChildElement();

  251             for(dataElement; dataElement; dataElement=dataElement->NextSiblingElement())

  252             {

  253 

  254                 const char *ename=dataElement->Attribute("name");

  255                 std::string goID(ename);

  256 

  257                 //make an new object with the new ID, if not specified, increment our counter

  258                 if(goID.length() == 0)

  259                 {

  260                     goID = Ogre::StringConverter::toString(mObjectCount++);

  261                 }

  262 

  263                 GameObject* go = GameObjectManager::getInstance()->createGameObject(templateName,goID);

  264                 //adjust the position and rotation with an event

  265 

  266                 PositionChange posData;

  267                 dataElement->QueryFloatAttribute("posX", &posData.posX);

  268                 dataElement->QueryFloatAttribute("posY", &posData.posY);

  269                 dataElement->QueryFloatAttribute("posZ", &posData.posZ);

  270                 dataElement->QueryFloatAttribute("rotX", &posData.rotX);

  271                 dataElement->QueryFloatAttribute("rotY", &posData.rotY);

  272                 dataElement->QueryFloatAttribute("rotZ", &posData.rotZ);

  273                 dataElement->QueryFloatAttribute("rotW", &posData.rotW);

  274 

  275                 Event* event = new Event(goID,EventType::Position,&posData);

  276                 EventManager::getInstance()->sendEvent(event);

  277 

  278             }

  279         }

  280     }

  281 

  282 }

  283 

  284 

  285 

  286 

  287 void Level::preFrameTick(const Ogre::FrameEvent &evt)

  288 {

  289 

  290     // Will fade if told so, otherwise does nothing

  291     mFader->fade(evt.timeSinceLastFrame);

  292     if(mFadingTimer>0 && fading)

  293     {

  294         mFadingTimer-= evt.timeSinceLastFrame;

  295     }

  296     else if(fading)//player died, lets fade out and reposition

  297     {

  298         fading = false;

  299         respawnPlayer();

  300     }

  301 

  302 

  303     InputManager* mInputManager = InputManager::getSingletonPtr();

  304 

  305     Ogre::Real angle =  0.0f;

  306 

  307     //mouse angle used for player orientation

  308     const Real MOUSE_SENSITIVITY = 1.0f;

  309 

  310     int mouseX =     mInputManager->getMouse()->getMouseState().X.abs;

  311     int halfWindowWidth = mInputManager->getMouse()->getMouseState().width >> 1;

  312     int halfWindowHeight =  mInputManager->getMouse()->getMouseState().height >> 1;

  313 

  314     {

  315         Real inc  = Real(halfWindowWidth - mouseX) / halfWindowWidth;

  316         inc = (inc < -1.0f) ? -1.0f : inc;

  317         inc = (inc >  1.0f) ?  1.0f : inc;

  318         angle = 3.4f * inc * MOUSE_SENSITIVITY;

  319     }

  320 

  321 

  322     if(fading)

  323     {

  324         mKeyDirection = Ogre::Vector3::ZERO;

  325     }

  326     {

  327 #ifdef _DEBUG

  328         OgreProfile("Physics");

  329 #endif

  330         physicsSubSystem->translate(mKeyDirection,angle);

  331         physicsSubSystem->update(evt.timeSinceLastFrame);

  332 

  333     }

  334     behaviorSubSystem->update(evt.timeSinceLastFrame);

  335     {

  336 #ifdef _DEBUG

  337         OgreProfile("Animation");

  338 #endif

  339         animationSubSystem->update(evt.timeSinceLastFrame);

  340     }

  341     {

  342 #ifdef _DEBUG

  343         OgreProfile("Triggers");

  344 #endif

  345         triggerSubSystem->update(evt.timeSinceLastFrame);

  346     }

  347 

  348     soundSubSystem->update(evt.timeSinceLastFrame);

  349 

  350     {

  351 #ifdef _DEBUG

  352         OgreProfile("Hikari");

  353 #endif

  354         hikariMgr->update();

  355 

  356         const RenderTarget::FrameStats& stats =Ogre::Root::getSingletonPtr()->getAutoCreatedWindow()->getStatistics();

  357         //fps->callFunction("setFPS", Hikari::Args((int)stats.lastFPS));

  358         //Ogre::LogManager::getSingleton().logMessage(Ogre::StringConverter::toString(stats.lastFPS));

  359 

  360         lifebar->callFunction("setLife",Hikari::Args((float)mPlayerHitpoints/100));

  361         acorn_count->callFunction("setAcornCount", Hikari::Args((int)GameObjectManager::getInstance()->getAcornCount()));

  362     }

  363 

  364 }

  365 

  366 void Level::postFrameTick(const Ogre::FrameEvent& evt)

  367 {

  368     GameObjectManager::getInstance()->removeQueuedObjects();

  369 }

  370 

  371 

  372 void Level::mouseMoved( const OIS::MouseEvent &evt )

  373 {

  374     //send an event to the player so it can update its camera

  375     PositionChange posData;

  376     posData.rotX =-0.15f * evt.state.X.rel;

  377     posData.rotY = -0.05f * evt.state.Y.rel;

  378     posData.rotZ -0.005f * evt.state.Z.rel;

  379     Event* event = new Event("Player",EventType::Mouse,&posData);

  380     EventManager::getInstance()->sendEvent(event);

  381 

  382 

  383 }

  384 

  385 void Level::mousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id )

  386 {

  387 }

  388 

  389 void Level::mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id )

  390 {   

  391 

  392 }

  393 void Level::keyPressed(const OIS::KeyEvent &evt)

  394 {

  395     // keep track of the player's intended direction

  396     if (evt.key == OIS::KC_W) mKeyDirection.z = -1;

  397     else if (evt.key == OIS::KC_A) mKeyDirection.x = -1;

  398     else if (evt.key == OIS::KC_S) mKeyDirection.z = 1;

  399     else if (evt.key == OIS::KC_D) mKeyDirection.x = 1;

  400     else if (evt.key == OIS::KC_SPACE) mKeyDirection.y = 1;

  401 

  402 #ifdef _DEBUG

  403     if(evt.key == OIS::KC_N)

  404     {

  405         GameObjectManager::getInstance()->clearGameObjects();   

  406     }

  407 

  408     if(evt.key == OIS::KC_M)

  409     {

  410         physicsSubSystem->loadPhysicsSystem();

  411         loadInitialObjects();

  412     }

  413 #endif

  414 

  415 }

  416 

  417 void Level::keyReleased(const OIS::KeyEvent &evt)

  418 {

  419 

  420     // keep track of the player's intended direction

  421     if (evt.key == OIS::KC_W && mKeyDirection.z == -1) mKeyDirection.z = 0;

  422     else if (evt.key == OIS::KC_A && mKeyDirection.x == -1) mKeyDirection.x = 0;

  423     else if (evt.key == OIS::KC_S && mKeyDirection.z == 1) mKeyDirection.z = 0;

  424     else if (evt.key == OIS::KC_D && mKeyDirection.x == 1) mKeyDirection.x = 0;

  425     else if (evt.key == OIS::KC_SPACE) mKeyDirection.y = 0;

  426 

  427 }

  428 

  429 void Level::handleEvent(Event *event)

  430 {

  431     switch(event->getType())

  432     {

  433     case SpawnPlayer:

  434         {

  435             if(!fading)

  436             {

  437                 mFader->startFadeOut(3.0f);

  438 

  439                 mFadingTimer = 3.0f;

  440                 fading = true;

  441                 mKeyDirection = Ogre::Vector3::ZERO;

  442             }

  443 

  444         }

  445         break;

  446     }

  447 }

  448 

  449 void Level::respawnPlayer()

  450 {

  451     mPlayerHitpoints = 100;

  452     GameObjectManager::getInstance()->clearGameObjects();

  453     GameObjectManager::getInstance()->setAcornCount(0);

  454     //level reloads

  455     //once we're done reloading we fade back in

  456     physicsSubSystem->loadPhysicsSystem();

  457     loadInitialObjects();

  458     //    PositionChange* posData = reinterpret_cast<PositionChange*>(event->getEventData());

  459     //    Event* event = new Event("Player",EventType::Position,posData);

  460     //    EventManager::getInstance()->sendEvent(event);

  461     mFader->startFadeIn(1.5f);

  462 

  463 

  464 }