示例#1
0
void CData::Load()
{
	fluids->LoadXml(PATHMANAGER::Data() + "/materials2/fluids.xml");
	LogO(String("**** Loaded Fluids: ") + toStr(fluids->fls.size()));

	objs->LoadXml();  //  collisions.xml
	LogO(String("**** Loaded Vegetation objects: ") + toStr(objs->colsMap.size()));
	
	std::string path = PATHMANAGER::GameConfigDir();
	tracks->LoadIni(path + "/tracks.ini");
	cars->LoadXml(path + "/cars.xml");

	#ifdef SR_EDITOR
		pre->LoadXml(path + "/presets.xml");
		LogO(String("**** Loaded Presets  sky: ") + toStr(pre->sky.size())+
			"  ter: " + toStr(pre->ter.size()) +
			"  road: " + toStr(pre->rd.size()) +
			"  grass: " + toStr(pre->gr.size()) +
			"  veget: " + toStr(pre->veg.size()) );
	#else
		champs->LoadXml(path + "/championships.xml", tracks);
		LogO(String("**** Loaded Championships: ") + toStr(champs->all.size()));

		chall->LoadXml(path + "/challenges.xml", tracks);
		LogO(String("**** Loaded Challenges: ") + toStr(chall->all.size()));
	#endif
}
示例#2
0
文件: Application.cpp 项目: Leph/SMA
void Application::createCamera()
{
    _camera = _scene->createCamera("camera");
    _camera->setPosition(Vector3(1000,1000,1000));
    _camera->lookAt(Vector3(0,-1000,0));
    _camera->setNearClipDistance(1);
    _camera->setFarClipDistance(100000);

    Viewport* vp = _window->addViewport(_camera);
    _camera->setAspectRatio(Real(vp->getActualWidth())/Real(vp->getActualHeight()));
    //_camera->setPolygonMode(Ogre::PM_WIREFRAME);
    vp->setBackgroundColour(ColourValue(0,0,0));
}
示例#3
0
文件: Bond.cpp 项目: Leph/SMA
void Bond::updateNode()
{
    Real distance = _end1->getPosition()
        .distance(_end2->getPosition())/2.0;
    Vector3 middle = 
        (_end1->getPosition()+_end2->getPosition())/2.0;
    _node->setPosition(middle);
    _node->setScale(Vector3(distance, 20, 20));
    _node->setOrientation(
        Vector3(1, 0, 0).getRotationTo(
            _end1->getPosition()-_end2->getPosition()
        )
    );
}
示例#4
0
  void PolyMousePicker::generateCorners()
  {
    using Ogre::Vector2;

    mCorners[0] = Vector2(-mStep, -mStep);
    mCorners[1] = Vector2(0, -mStep);
    mCorners[2] = Vector2(mStep, -mStep);
    mCorners[3] = Vector2(-mStep, 0);
    mCorners[4] = Vector2(0, 0);
    mCorners[5] = Vector2(mStep, 0);
    mCorners[6] = Vector2(-mStep, mStep);
    mCorners[7] = Vector2(0, mStep);
    mCorners[8] = Vector2(mStep, mStep);
  }
示例#5
0
Atom_Unbound_Virt::Atom_Unbound_Virt(const Vector3& position) : 
    Atom::Atom(100, position)
{
    //Création de l'apparence graphique de l'atome
    initNode(
        Geometry::sphere(3),
        ColourValue(0.5, 1.0, 1.0, 1.0)
    );
}
示例#6
0
文件: Atom_Apply.cpp 项目: Leph/SMA
Atom_Apply::Atom_Apply(const Vector3& position) : 
    Atom::Atom(200, position)
{
    //Création de l'apparence graphique de l'atome
    initNode(
        Geometry::sphere(10), 
        ColourValue(1.0, 0.0, 0.0, 1.0)
    );
}
示例#7
0
文件: Atom_Term.cpp 项目: Leph/SMA
Atom_Term::Atom_Term(const Vector3& position, int value) : 
    Atom::Atom(75, position),
    _value(value)
{
    assert(value >=0 && value <= 1);
    Real color = 0.2+8.0*value/10.0;

    //Création de l'apparence graphique de l'atome
    initNode(
        Geometry::sphere(10),
        ColourValue(color, color, color, 1.0)
    );
}
示例#8
0
void CData::Load(std::map <std::string, int>* surf_map, bool check)
{
	//  common
	fluids->LoadXml(PATHMANAGER::Data() + "/materials2/fluids.xml", /**/surf_map);
	LogO(String("**** Loaded Fluids: ") + toStr(fluids->fls.size()));

	objs->LoadXml();  //  collisions.xml
	LogO(String("**** Loaded Vegetation objects: ") + toStr(objs->colsMap.size()));
	
	std::string snd = PATHMANAGER::Sounds();
	reverbs->LoadXml(snd + "/reverbs.xml");
	LogO(String("**** Loaded Reverbs sets: ") + toStr(reverbs->revs.size()));

	//  cars and tracks
	std::string path = PATHMANAGER::GameConfigDir();
	tracks->LoadIni(path + "/tracks.ini", check);
	cars->LoadXml(path + "/cars.xml");
	
	#ifdef SR_EDITOR  // ed
		pre->LoadXml(path + "/presets.xml");
		LogO(String("**** Loaded Presets  sky: ") + toStr(pre->sky.size())+
			"  ter: " + toStr(pre->ter.size()) +
			"  road: " + toStr(pre->rd.size()) +
			"  grass: " + toStr(pre->gr.size()) +
			"  veget: " + toStr(pre->veg.size()) );
	#else	// game
		colors->LoadIni(path + "/colors.ini");
		LogO(String("**** Loaded Car Colors: ") + toStr(colors->v.size()));

		champs->LoadXml(path + "/championships.xml", tracks, check);
		LogO(String("**** Loaded Championships: ") + toStr(champs->all.size()));

		chall->LoadXml(path + "/challenges.xml", tracks, check);
		LogO(String("**** Loaded Challenges: ") + toStr(chall->all.size()));
	#endif
}
示例#9
0
void InGameState::initState(){
	
	//Load in unit hp bar
	UnitHPBar::container=luabind::object_cast<int>(luabind::globals(state)["HPBARCONTAINERTEXTUREID"]);


	
	BotRecycler* recycler=game->getGSM()->getSpriteManager()->getBotRecycler();
	string err="";

	game->getGUI()->getCursor(GS_GAME_IN_PROGRESS)->setActiveCursorID(0);
	//Load in Warrior Unit
	Warrior *w = new Warrior();
	w->setSpriteType(luabind::call_function<AnimatedSpriteType*>(state,"getWarriorSpriteType"));
	w->setCurrentState((wstring)L"IDLE_STATE_NORTH");
	this->loadUnit<Warrior>("Warrior",state,w->getSpriteType());
	recycler->registerBotType(L"WARRIOR",w);
	recycler->initRecyclableBots(L"WARRIOR",600);
	
	//Load in Archer Unit
	Archer *arch = new Archer();
	arch->setSpriteType(game->getGSM()->getSpriteManager()->getSpriteType("ArcherSprite"));
	arch->setCurrentState((wstring)L"IDLE_STATE_NORTH");
	this->loadUnit<Archer>("Archer",state,arch->getSpriteType());
	recycler->registerBotType(L"Archer",arch);
	recycler->initRecyclableBots(L"Archer",300);

	//Load in Wizard Unit
	WizardUnit *wiz = new WizardUnit();
	wiz->setSpriteType(game->getGSM()->getSpriteManager()->getSpriteType("WizardSprite"));
	wiz->setCurrentState((wstring)L"IDLE_STATE_NORTH");
	this->loadUnit<WizardUnit>("Wizard",state,wiz->getSpriteType());
	recycler->registerBotType(L"Wizard",wiz);
	recycler->initRecyclableBots(L"Wizard",300);

	//Load in Knight Unit
	Knight *knight = new Knight();
	knight->setSpriteType(game->getGSM()->getSpriteManager()->getSpriteType("KnightSprite"));
	knight->setCurrentState((wstring)L"IDLE_STATE_NORTH");
	this->loadUnit<Knight>("Knight",state,knight->getSpriteType());
	recycler->registerBotType(L"Knight",knight);
	recycler->initRecyclableBots(L"Knight",300);

	//LOAD IN THE OGRE UNIT
	Ogre *o = new Ogre();
	o->setSpriteType(luabind::call_function<AnimatedSpriteType*>(state,"getOgreSpriteType"));
	o->setCurrentState((wstring)L"IDLE_STATE_NORTH");
	this->loadUnit<Ogre>("Ogre",state,o->getSpriteType());
	recycler->registerBotType(L"OGRE",o);
	recycler->initRecyclableBots(L"OGRE",30);

	
	Barracks* tmp= new Barracks();
	tmp->setSpriteType(game->getGSM()->getSpriteManager()->getSpriteType("BarracksSprite"));
	this->loadBuilding<Barracks>("Barracks",state,tmp->getSpriteType());
	recycler->registerBotType(L"Barracks",tmp);
	recycler->initRecyclableBots(L"Barracks",10);

	Altar* altar= new Altar();
	altar->setSpriteType(game->getGSM()->getSpriteManager()->getSpriteType("AltarSprite"));
	this->loadBuilding<Altar>("Altar",state,altar->getSpriteType());
	recycler->registerBotType(L"Altar",altar);
	recycler->initRecyclableBots(L"Altar",10);

	
	Farm* farm= new Farm();
	farm->setSpriteType(game->getGSM()->getSpriteManager()->getSpriteType("FarmSprite"));
	this->loadBuilding<Farm>("Farm",state,farm->getSpriteType());
	recycler->registerBotType(L"Farm",farm);
	recycler->initRecyclableBots(L"Farm",10);

	
	ScoutTower* scouttower= new ScoutTower();
	scouttower->setSpriteType(game->getGSM()->getSpriteManager()->getSpriteType("ScoutTowerSprite"));
	this->loadBuilding<ScoutTower>("ScoutTower",state,scouttower->getSpriteType());
	recycler->registerBotType(L"ScoutTower",scouttower);
	recycler->initRecyclableBots(L"ScoutTower",10);



	Tower::loadSelf(state);	
	err="";
	if(luaL_dostring(state,"createUnits()")==1) 
		err="Couldn't run Lua program: "+(string)lua_tostring(state, -1);
	cout<<err;
	Tower::hpScaleX=Tower::hpScaleY=(float)mainPlayer->tower->getSpriteType()->getTextureWidth() /128;
	Tower::hpOffX=0;
	Tower::hpOffY=32*Tower::hpScaleY;
	


	Player::unitTypes.clear();
	for(luabind::iterator i(luabind::globals(state)["UnitEntriesDatabase"]),end;i!=end;++i){
		UnitEntry newType;
		int x=1;
		newType.BotRecyclerID=convertwstrX(luabind::object_cast<string>(i->operator[](x++)));
		newType.imageID=ResourceBankgetResource(luabind::object_cast<string>(i->operator[](x++)));
		newType.incomeIncrease.push_back(luabind::object_cast<int>(i->operator[](x++)));
		newType.buildTime=luabind::object_cast<int>(i->operator[](x++));
		newType.popCost=luabind::object_cast<int>(i->operator[](x++));
		newType.goldCost=luabind::object_cast<int>(i->operator[](x++));
		newType.title=convertwstrX(luabind::object_cast<string>(i->operator[](x++)));
		newType.tooltip=convertwstrX(luabind::object_cast<string>(i->operator[](x++)));
		newType.titleFont=convertwstrX(luabind::object_cast<string>(i->operator[](x++)));
		newType.tooltipFont=convertwstrX(luabind::object_cast<string>(i->operator[](x++)));
		newType.width=luabind::object_cast<int>(i->operator[](x++));
		for(int k=0;k<4;k++)newType.titleColor[k]=luabind::object_cast<int>(i->operator[](x++));
		for(int k=0;k<4;k++)newType.tooltipColor[k]=luabind::object_cast<int>(i->operator[](x++));
		newType.numToBuild=0;
		newType.currentPercent=0;
		Player::unitTypes.push_back(newType);
	}





	//SETUP SPELL DB
	spellDB = new SpellDB();
	spellDB->loadDB(game, state);

	mainPlayer->wizard = new Wizard();
	
	//Setup Spells 
	Fireball::displayId=luabind::object_cast<int>(luabind::globals(state)["FIREBALLPROJECTILEID"]);
	FlameWall::displayIds.clear();
	for(luabind::iterator i(luabind::globals(state)["FLAMEWALLIDS"]),end;i!=end;++i)
		FlameWall::displayIds.push_back(luabind::object_cast<int>(*i));
	GravityWell::displayIds.clear();
	for(luabind::iterator i(luabind::globals(state)["GRAVITYWELLIDS"]),end;i!=end;++i)
		GravityWell::displayIds.push_back(luabind::object_cast<int>(*i));
	GravityBomb::displayIds.clear();
	for(luabind::iterator i(luabind::globals(state)["GRAVITYBOMBIDS"]),end;i!=end;++i)
		GravityBomb::displayIds.push_back(luabind::object_cast<int>(*i));
	Meteor::displayId=luabind::object_cast<int>(luabind::globals(state)["METEORID"]);
	Meteor::shadowId=luabind::object_cast<int>(luabind::globals(state)["METEORSHADOWID"]);
	MeteorShower::displayId=luabind::object_cast<int>(luabind::globals(state)["METEORID"]);
	MeteorShower::shadowId=luabind::object_cast<int>(luabind::globals(state)["METEORSHADOWID"]);
	KineticBooster::displayId=luabind::object_cast<int>(luabind::globals(state)["KINETICBOOSTERID"]);
	SpellDB::BUTTON_SOCKET=luabind::object_cast<int>(luabind::globals(state)["SPELLBUTTONSOCKETID"]);	

	Spell::SpellArrowID=game->getResManager()->getImageIDLua("$$SpellArrow",false);
	Spell::SpellCircleID=game->getResManager()->getImageIDLua("$$SpellCircle",false);
	Spell::SpellLineID=game->getResManager()->getImageIDLua("$$SpellLine",false);
	Spell::SpellAOEID=game->getResManager()->getImageIDLua("$$SpellAOE",false);

	//SETUP BUTTONS
	toolbar.initializeToolbar(game);
	displayUnits.initializeToolbar(this);
	//setupButtons(spellDB);
	this->setupMiscDisplayIDs();

	SpellSelectionGUI *ssg = new SpellSelectionGUI();
	ssg->setupScreen(game, state, spellDB);
	overlayWorkers[SPELL_SELECTION_GUI] = ssg;

	StatsScreen *ss = new StatsScreen();
	ss->onStart(game); //currently initializes the screen and its vars
	overlayWorkers[STATS_SCREEN] = ss;

	count=0;
	spells.empty();
	 TutorialSysGUI* tsGUI = new TutorialSysGUI();
	 tsGUI->setupSys(this,game,state);
	 overlayWorkers[TUTSYSSCREENOVERLAYNUM]=tsGUI;
	 tsGUI->currentTutorial="StartGame";
	 this->tutSys=tsGUI;


	popicon=ResourceBankgetResource((string)"PopIcon");
	goldicon=ResourceBankgetResource((string)"GoldIcon");
	gridMapCount=0;
	fontStr=L"Times New Roman";


	
	players[1]->enemy=players[0];
	players[0]->enemy=players[1];
//if(!mainPlayer->wizard->startGameTutorial){
//
//			game->getGSM()->overlayGameState=TUTSYSSCREENOVERLAYNUM;
//			tutSys->currentTutorial="StartGame";
//			mainPlayer->wizard->startGameTutorial=true;
//		}
	//Cheats
	
	//mainPlayer->gold=10000;
	//mainPlayer->pop=1000;
	
	//players[1]->gold=10000;
	//players[1]->pop=1000;
}
示例#10
0
文件: Application.cpp 项目: Leph/SMA
void Application::initSimulation()
{
    //Initialisation le générateur aléatoire
    //(debug)
    int seed = (int)Math::RangeRandom(20, 10000000);
    std::cout << "===>" << (int)seed << std::endl;
    //int seed = 6486951;//7264745 8983653;
    //int seed = 7264745;
    //int seed = 8983653;
    //int seed = 9765800;
    srand(seed);

    _scene->setAmbientLight(ColourValue(0.1, 0.1, 0.1));
    Ogre::Light *light1 = _scene->createLight();
    light1->setDiffuseColour(1.0, 1.0, 1.0);
    light1->setSpecularColour(1.0, 1.0, 1.0);
    light1->setPosition(-100, 200, 100);

    Entity* ent = _scene->createEntity("ogrehead.mesh");
    SceneNode* node = _scene->getRootSceneNode()->createChildSceneNode();
    node->attachObject(ent);

    for (int i=0;i<2000;i++) {
        Vector3 position = Vector3(
            Math::RangeRandom(-1500, 1500),
            Math::RangeRandom(-1500, 1500),
            Math::RangeRandom(-1500, 1500));
        Atom* a;
        Real r = Math::RangeRandom(0,100);
        if (r>=90) a = new Atom_Lambda(position);
        else if (r>=80) a = new Atom_Lambda_Virt(position);
        else if (r>=70) a = new Atom_Apply(position);
        else if (r>=60) a = new Atom_Apply_Virt(position);
        else if (r>=50) a = new Atom_Association(position);
        else if (r>=40) a = new Atom_Association_Virt(position);
        else if (r>=35) a = new Atom_Bound(position);
        else if (r>=30) a = new Atom_Bound_Virt(position);
        else if (r>=25) a = new Atom_Unbound(position);
        else if (r>=20) a = new Atom_Unbound_Virt(position);
        else if (r>=10) a = new Atom_Term(
            position, 
            (int)Math::RangeRandom(0.0, 2.0)
        );
        else if (r>=0) a = new Atom_Term_Virt(
            position, 
            (int)Math::RangeRandom(0.0, 2.0)
        );
        if (!_positionResolver->checkCollisionAtoms(
            a->getPosition(), a->getRadius())) 
        {
            _atoms->add(a);
            _scene->_updateSceneGraph(0);
        } else {
            delete a;
        }
    }
    
    /*
    _atoms->createBond(
        _atoms->get(0),
        _atoms->get(1),
        150
    );
    _atoms->createBond(
        _atoms->get(1),
        _atoms->get(2),
        150
    );
    _atoms->createBond(
        _atoms->get(2),
        _atoms->get(3),
        150
    );
    _atoms->createBond(
        _atoms->get(3),
        _atoms->get(0),
        150
    );
    _atoms->get(0)->transfertBonds(_atoms->get(1));
    _atoms->get(1)->transfertBonds(_atoms->get(2));

    Graph* g = 0;
    for (size_t i=0;i<_atoms->getSize();i++) {
        if (_atoms->get(i)->isType<Atom_Lambda>()) {
            g = new Graph();
            g->build(_atoms->get(i));
            break;
        }
    }
    TransformLambda t = TransformLambda(*g);
    std::cout << t.isValid() << std::endl;
    if (t.isValid()) {
        while(t.doTransformStep());
    }
    */
}
示例#11
0
//  Load
//--------------------------------------------------------------------------------------------------------------------------------------
//  Load Ini
//--------------------------------------------------------------------------------------------------------------------------------------
bool TracksXml::LoadIni(string file, bool check)
{
    //  clear
    trks.clear();
    trkmap.clear();
    times.clear();
    cntAll = 0;

    int i=1;  // 0 = not found
    char s[256], name[32],scenery[24],author[32];
    float time=0.f;
    TrackInfo t;

    set<string> scns;  //stats
    map<string, int> scn_trks;

    ifstream fs(file.c_str());
    if (fs.fail())  return false;

    while (fs.good())
    {
        fs.getline(s,254);

        //  starting with digit
        if (strlen(s) > 0 && s[0] >= '0' && s[0] <= '9')
        {
            //114,Fin1-Lakes  v=2.0 06/04/13 07/04/13 :Finland  |o0 w1 ~1 J2 L0 P0 /1 s1 l2 !2 *4  T=107.8  a:CH
            sscanf(s,
                   "%d,%s v%f %d/%d/%d %d/%d/%d :%s |o%d c%d w%d ~%d J%d L%d P%d /%d s%d l%d !%d *%d  T=%f a:%s"
                   ,&t.n, name, &t.crtver
                   ,&t.created.day, &t.created.month, &t.created.year
                   ,&t.modified.day, &t.modified.month, &t.modified.year
                   ,scenery
                   ,&t.objects, &t.obstacles
                   ,&t.fluids, &t.bumps, &t.jumps, &t.loops, &t.pipes
                   ,&t.banked, &t.frenzy, &t.longn, &t.diff, &t.rating
                   ,&time, author);

            t.name = name;
            t.scenery = scenery;
            t.author = author;
            t.ver = std::ceil(t.crtver*10.f);

            if (check)
            {   scns.insert(scenery);
                ++scn_trks[scenery];
            }
            //  sigma rating
            t.sum = t.objects+ t.obstacles+  t.fluids+ t.bumps+
                    t.jumps+ t.loops+ t.pipes+  t.banked+ t.frenzy+  t.longn/3;

            string shrt;  //-  name short  (without prefix)
            size_t p = t.name.find("-");
            if (p != string::npos /*&& !(name[0]=='T' && name[1]=='e')*/)
                shrt = t.name.substr(p+1);  // short name
            else
                shrt = t.name;
            t.nshrt = shrt;

            //  get number from name, id for scenery
            t.nn = 0;
            size_t p2 = t.name.find('-'), p1;
            if (p2 != string::npos)
            {
                p1 = t.name.find_first_of("1234567890");
                if (p1 != string::npos && p2-p1 > 0)
                {
                    string ss = t.name.substr(p1, p2-p1);
                    t.nn = atoi(ss.c_str());
                    t.nn += uchar(t.name[0])<<16;  // meh
                    t.nn += uchar(t.name[1])<<8;
                    //LogO(t.name+"  "+ss+"  "+toStr(t.nn));
                }
            }

            t.testC = t.name.length() > 5 ? t.name.substr(0,5)=="TestC" : false;
            if (t.testC)  t.test = false;
            else
                t.test  = t.name.length() > 4 ? t.name.substr(0,4)=="Test"  : false;
            t.vdrift = author == "VDrift";
            if (!t.testC && !t.test)
                ++cntAll;

            trks.push_back(t);
            trkmap[name] = i++;
            times[name] = time;
        }
    }

    ///  *  checks and  Log sceneries with stats  *
    //--------------------------------------------------------------
    if (check)
    {
        LogO("))) Checking: tracks.ini");
        i=1;
        int c,n, nn = trks.size()-1;

        stringstream ss;
        ss << fixed;
        ss << "))) Sceneries stats:\n""Num - Name - tracks count - last track in it (num trks back)""\n";

        for (set<string>::iterator it = scns.begin(); it != scns.end(); ++it,++i)
        {
            //  find last trk in this scn
            n = nn;
            bool srch = true;
            while (srch && n >= 0)
            {
                if (trks[n].scenery == *it)
                    srch = false;
                else  --n;
            }
            int d = nn-n;
            c = scn_trks[*it];
            ss << right << setw(2) << i << "  " << setw(13) << left << *it << "  "
               << setw(3) << c << (c==1 ? "!!" : c==2 ? "! " : "  ") << " "
               << setw(4) << d << (d>35?"!":"") << (d>50?"!":"") << (d>90?"!":"") << endl;
        }
        LogO(ss.str());

        LogO("))) Checking for all tracks ghosts");
        nn = trks.size();
        for (i=0; i < nn; ++i)
        {
            const TrackInfo& ti = trks[i];
            const string& s = ti.name;
            for (int r=0; r < 2; ++r)
            {
                string sRev = r==1 ? "_r" : "";
                string file = PATHMANAGER::TrkGhosts()+"/"+ s + sRev + ".gho";
                if (!ti.test && !ti.testC)
                    if (!PATHMANAGER::FileExists(file))
                    {   if (r==1)	LogO("!Rev Missing trk gho for: " + s);
                        else		LogO("! Missing trk gho for: " + s);
                    } else
                    {   //  check time  can take few sec
                        TrackGhost gho;
                        gho.LoadFile(file, false);
                        float tgh = gho.GetTimeLength();
                        float ti = times[s]*1.02f, td = tgh - ti;
                        if (fabs(td) > 20.f)
                        {   ss.str("");
                            ss << "time diff big: " << setw(19) << s+sRev;
                            ss << " time "+StrTime(tgh)+" trk "+StrTime(ti)+" d "+fToStr(td,0,3);
                            LogO(ss.str());
                        }
                    }
            }
        }
        LogO("");

        //  not in tracks.ini
        strlist li;
        PATHMANAGER::DirList(PATHMANAGER::Tracks(), li);
        for (strlist::iterator i = li.begin(); i != li.end(); ++i)
        {
            string s = *i;
            if (trkmap[s]==0)
                LogO("!! Track not in ini: " + s);
        }
        LogO("");
    }

    return true;
}
示例#12
0
    std::vector<std::string> BookTextParser::split(std::string utf8Text, const int width, const int height)
    {
        using Ogre::UTFString;
        std::vector<std::string> result;

        MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor
        utf8Text = Interpreter::fixDefinesBook(utf8Text, interpreterContext);

        boost::algorithm::replace_all(utf8Text, "\n", "");
        boost::algorithm::replace_all(utf8Text, "\r", "");
        boost::algorithm::replace_all(utf8Text, "<BR>", "\n");
        boost::algorithm::replace_all(utf8Text, "<P>", "\n\n");

        UTFString text(utf8Text);
        const int spacing = 48;

        const UTFString::unicode_char LEFT_ANGLE = unicodeCharFromChar('<');
        const UTFString::unicode_char NEWLINE = unicodeCharFromChar('\n');
        const UTFString::unicode_char SPACE = unicodeCharFromChar(' ');

        while (!text.empty())
        {
            // read in characters until we have exceeded the size, or run out of text
            int currentWidth = 0;
            int currentHeight = 0;

            size_t currentWordStart = 0;
            size_t index = 0;
            
            {
                std::string texToTrim = text.asUTF8();
                boost::algorithm::trim( texToTrim );
                text = UTFString(texToTrim);
            }
            
            
            while (currentHeight <= height - spacing && index < text.size())
            {
                const UTFString::unicode_char ch = text.getChar(index);
                if (ch == LEFT_ANGLE)
                {
                    const size_t tagStart = index + 1;
                    const size_t tagEnd = text.find('>', tagStart);
                    if (tagEnd == UTFString::npos)
                        throw std::runtime_error("BookTextParser Error: Tag is not terminated");
                    const std::string tag = text.substr(tagStart, tagEnd - tagStart).asUTF8();

                    if (boost::algorithm::starts_with(tag, "IMG"))
                    {
                        const int h = mHeight;
                        parseImage(tag, false);
                        currentHeight += (mHeight - h);
                        currentWidth = 0;
                    }
                    else if (boost::algorithm::starts_with(tag, "FONT"))
                    {
                        parseFont(tag);
                        if (currentWidth != 0) {
                            currentHeight += currentFontHeight();
                            currentWidth = 0;
                        }
                        currentWidth = 0;
                    }
                    else if (boost::algorithm::starts_with(tag, "DIV"))
                    {
                        parseDiv(tag);
                        if (currentWidth != 0) {
                            currentHeight += currentFontHeight();
                            currentWidth = 0;
                        }
                    }
                    index = tagEnd;
                }
                else if (ch == NEWLINE)
                {
                    currentHeight += currentFontHeight();
                    currentWidth = 0;
                    currentWordStart = index;
                }
                else if (ch == SPACE)
                {
                    currentWidth += 3; // keep this in sync with the font's SpaceWidth property
                    currentWordStart = index;
                }
                else
                {
                    currentWidth += widthForCharGlyph(ch);
                }

                if (currentWidth > width)
                {
                    currentHeight += currentFontHeight();
                    currentWidth = 0;
                    // add size of the current word
                    UTFString word = text.substr(currentWordStart, index - currentWordStart);
                    for (UTFString::const_iterator it = word.begin(), end = word.end(); it != end; ++it)
                        currentWidth += widthForCharGlyph(it.getCharacter());
                }
                index += UTFString::_utf16_char_length(ch);
            }
            const size_t pageEnd = (currentHeight > height - spacing && currentWordStart != 0)
                    ? currentWordStart : index;

            result.push_back(text.substr(0, pageEnd).asUTF8());
            text.erase(0, pageEnd);
        }
        
        std::vector<std::string> nonEmptyPages;
        boost::copy(result | boost::adaptors::filtered(is_not_empty), std::back_inserter(nonEmptyPages));
        return nonEmptyPages;
    }