DunGen  1.1
Dungeongenerator library for Irrlicht
Tutorial 2: Read Dungeon from File

About the XML tags

All of the DunGen XML tags have to be enclosed in a DunGen tag. The other tags:

Parameters:

Enums used in the code are specified as numbers in the XML.

Parameter Direction (used by tags CorridorRoomCave and CorridorCaveCave) uses the following correlation:

Parameter NormalWeighting (used by tag GenerateMeshCave) uses the following correlation:

Note:

The Irrlicht XML reader has some issues. So try keep the layout of the provided sample XML files and try to not use comments (they can lead to wrong parsing).

Tutorial Code

Here you find the code for reading a dungeon from a XML file.

#include <iostream>
#include <irrlicht.h>
#include <DunGen.h>
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(lib, "DunGen.lib")
#endif
int main(int argc, char* argv[])
{
// check for additional parameters: resolution, anti aliasing
irr::core::dimension2du resolution = irr::core::dimension2du(1200, 900);
if (argc>=3)
{
resolution.Width = atoi(argv[1]);
resolution.Height = atoi(argv[2]);
}
int antiAlias = 0;
if (argc>=4)
antiAlias = atoi(argv[3]);
char* filename = "dungeon_ascending.xml";
if (argc>=5)
filename = argv[4];
std::cout << "Dungeongenerator Tutorial 02 is started." << std::endl;
std::cout << "Resolution is: " << resolution.Width << " * " << resolution.Height << " , AntiAliasing: " << antiAlias << " , Filename: " << filename << std::endl;
// create Irrlicht device
irr::SIrrlichtCreationParameters irrlichtParameter;
irrlichtParameter.DriverType = irr::video::EDT_DIRECT3D9;
irrlichtParameter.WindowSize = resolution;
irrlichtParameter.Bits = 32;
irrlichtParameter.Fullscreen = false;
irrlichtParameter.Stencilbuffer = false;
irrlichtParameter.Vsync = false;
irrlichtParameter.AntiAlias = antiAlias;
irrlichtParameter.EventReceiver = 0;
irr::IrrlichtDevice* irrDevice = irr::createDeviceEx(irrlichtParameter);
if(irrDevice == 0)
{
std::cout << "Irrlicht device could not be created, program is terminated." << std::endl;
return 1;
}
irr::scene::ISceneManager* sceneManager = irrDevice->getSceneManager();
irr::video::IVideoDriver* videoDriver = irrDevice->getVideoDriver();
irrDevice->setWindowCaption(L"Dungeongenerator Tutorial 02: Read dungeon from file.");
//************************************************************************
// Start of dungeon creation
//************************************************************************
// create Dungeongenerator instance
DunGen::CDunGen *dunGen = new DunGen::CDunGen(irrDevice);
dunGen->StartUp();
dunGen->SetPrintToConsole(true);
// read Dungeon from file
dunGen->ReadDungeonFromFile(filename);
// assemble dungeon
dunGen->AddDungeon(sceneManager->getRootSceneNode(),sceneManager);
// deletes all not used objects from the Dungeongenerator to save memory
dunGen->ShutDown();
//************************************************************************
// Dungeon creation finished
//************************************************************************
// create camera
irr::scene::ICameraSceneNode* camera = sceneManager->addCameraSceneNodeFPS(0,100.0f,0.05f);
camera->setFarValue(20000.0f);
camera->setPosition(irr::core::vector3df(0,0,0));
camera->setTarget(irr::core::vector3df(99999.f, 99999.f, 99999.f));
irr::s32 lastFPS(0), actFPS(0);
irr::core::vector3d<int> lastCamPos(-1,-1,-1);
irr::core::vector3d<int> actCamPos(0,0,0);
irr::core::vector3df tmp;
// as long as the engine is active:
while(irrDevice->run() && videoDriver)
{
if (irrDevice->isWindowActive())
{
// draw everything
videoDriver->beginScene(true, true, irr::video::SColor(255,100,101,140));
sceneManager->drawAll();
videoDriver->endScene();
actFPS = videoDriver->getFPS();
tmp = camera->getAbsolutePosition();
actCamPos.X = static_cast<int>(tmp.X + 0.5f);
actCamPos.Y = static_cast<int>(tmp.Y + 0.5f);
actCamPos.Z = static_cast<int>(tmp.Z + 0.5f);
if (actFPS != lastFPS || lastCamPos != actCamPos)
{
// update FPS and camera position
// and show them as window name
lastFPS = actFPS;
lastCamPos = actCamPos;
irr::core::stringw str = L"Dungeongenerator Tutorial 02: Read dungeon from file. - FPS: ";
str += actFPS;
str += " - Position: (";
str += actCamPos.X;
str += ",";
str += actCamPos.Y;
str += ",";
str += actCamPos.Z;
str += ")";
irrDevice->setWindowCaption(str.c_str());
}
}
else
irrDevice->yield();
}
// destroy the engine
irrDevice->drop();
return 0;
}

The following XML code basically creates the same dungeon as in tutorial 1:

<?xml version="1.0"?>
<DunGen>
<Materials BackfaceCulling = "0" AntiAliasing = "1" />
<Cave Shader = "MultiColor" Red = "1.0" Green = "1.0" Blue = "1.0" />
<Corridor Texture = "data/corridor_texture.jpg" />
</Materials>
<RandomGenerator Seed = "0" A = "1103515245" C = "12345" M = "32768" />
<WarpOptions Warping = "1" Smoothing = "1" WarpRandomSeed = "0" WarpStrength = "0.45" />
<DrawVoxelCave StartString = "YYFYF" StartRadius = "14" Derivation = "8">
<Basic VoxelBorder = "3" MinDrawRadius = "3" />
<Radius RadiusFactor = "1" RadiusDecrement = "0" />
<Angle Yaw = "250" Pitch = "1" Roll = "0" />
<Rule Symbol = "F" Substitution = "F-YX-X---" />
<Rule Symbol = "X" Substitution = "F$F++F-X" />
<Rule Symbol = "Y" Substitution = "oYX--XX++" />
</DrawVoxelCave>
<Erode Likelihood = "0.5" />
<PlaceRoom Filename = "data/roompattern_sphere_aa.irr">
<Position X = "379" Y = "239" Z = "497" />
<Rotation X = "0" Y = "180" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
</PlaceRoom>
<PlaceRoom Filename = "data/roompattern_sphere.irr">
<Position X = "14" Y = "260" Z = "121" />
<Rotation X = "0" Y = "0" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
</PlaceRoom>
<PlaceRoom Filename = "data/roompattern_square4_aa.irr">
<Position X = "539" Y = "281" Z = "378" />
<Rotation X = "0" Y = "180" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
</PlaceRoom>
<PlaceRoom Filename = "data/roompattern_square4_aa.irr">
<Position X = "312" Y = "272" Z = "-80" />
<Rotation X = "0" Y = "270" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
</PlaceRoom>
<PlaceRoom Filename = "data/roompattern_square4_aa.irr">
<Position X = "72" Y = "202" Z = "557" />
<Rotation X = "0" Y = "80" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
</PlaceRoom>
<PlaceRoom Filename = "data/roompattern_square2_aa.irr">
<Position X = "404" Y = "259" Z = "651" />
<Rotation X = "0" Y = "90" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
</PlaceRoom>
<PlaceRoom Filename = "data/roompattern_square2_aa.irr">
<Position X = "145" Y = "260" Z = "0" />
<Rotation X = "0" Y = "200" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
</PlaceRoom>
<PlaceRoom Filename = "data/roompattern_square2_aa.irr">
<Position X = "700" Y = "200" Z = "250" />
<Rotation X = "0" Y = "305" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
</PlaceRoom>
<PlaceRoom Filename = "data/roompattern_square1_aa.irr">
<Position X = "440" Y = "277" Z = "803" />
<Rotation X = "0" Y = "90" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
</PlaceRoom>
<PlaceRoom Filename = "data/roompattern_square1_aa.irr">
<Position X = "287" Y = "270" Z = "-245" />
<Rotation X = "0" Y = "270" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
</PlaceRoom>
<PlaceRoom Filename = "data/roompattern_square1_aa.irr">
<Position X = "-129" Y = "211" Z = "584" />
<Rotation X = "0" Y = "20" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
</PlaceRoom>
<PlaceRoom Filename = "data/roompattern_square1_aa.irr">
<Position X = "-100" Y = "300" Z = "-70" />
<Rotation X = "0" Y = "300" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
</PlaceRoom>
<CorridorSettings Sampling = "0.6" TextureSampling = "0.125">
<Point PosX="-4" PosY="-4" TexX="1.4" />
<Point PosX="-4" PosY="0" TexX="0.9" />
<Point PosX="-3" PosY="2" TexX="0.6" />
<Point PosX="-2" PosY="3" TexX="0.3" />
<Point PosX="0" PosY="4" TexX="0.0" />
<Point PosX="4" PosY="0" TexX="0.9" />
<Point PosX="4" PosY="-4" TexX="1.4" />
<Point PosX="0" PosY="-4" TexX="2.0" />
</CorridorSettings>
<CorridorDetailobjects>
<Detailobject Name = "Torch1" Model = "data/detailobject.3ds" AntiAliasing = "1" Lighting = "0">
<Position X = "-4.0" Y = "-0.5" />
<Rotation X = "0" Y = "90" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
<Distance Sampling = "0.6" NumFactor = "4" NumMin = "3" NumMax = "3" />
<FirstAndLast NumMinFirst ="0" NumMaxFirst = "0" ObjectAt1 = "0" />
</Detailobject>
<Detailobject Name = "Torch2" Model = "data/detailobject.3ds" AntiAliasing = "1" Lighting = "0">
<Position X = "4.0" Y = "-0.5" />
<Rotation X = "0" Y = "270" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
<Distance Sampling = "0.6" NumFactor = "4" NumMin = "3" NumMax = "3" />
<FirstAndLast NumMinFirst ="0" NumMaxFirst = "0" ObjectAt1 = "0" />
</Detailobject>
</CorridorDetailobjects>
<CorridorRoomRoom>
<Room Index = "0" DockingSite = "2" Distance = "4" Strength = "200" />
<Room Index = "2" DockingSite = "1" Distance = "4" Strength = "200" />
</CorridorRoomRoom>
<CorridorRoomRoom>
<Room Index = "0" DockingSite = "1" Distance = "4" Strength = "100" />
<Room Index = "5" DockingSite = "0" Distance = "4" Strength = "100" />
</CorridorRoomRoom>
<CorridorRoomRoom>
<Room Index = "5" DockingSite = "1" Distance = "4" Strength = "100" />
<Room Index = "8" DockingSite = "0" Distance = "4" Strength = "100" />
</CorridorRoomRoom>
<CorridorRoomRoom>
<Room Index = "2" DockingSite = "2" Distance = "4" Strength = "150" />
<Room Index = "7" DockingSite = "0" Distance = "4" Strength = "250" />
</CorridorRoomRoom>
<CorridorRoomRoom>
<Room Index = "2" DockingSite = "3" Distance = "4" Strength = "150" />
<Room Index = "7" DockingSite = "1" Distance = "4" Strength = "250" />
</CorridorRoomRoom>
<CorridorRoomRoom>
<Room Index = "1" DockingSite = "1" Distance = "4" Strength = "200" />
<Room Index = "6" DockingSite = "0" Distance = "4" Strength = "200" />
</CorridorRoomRoom>
<CorridorRoomRoom>
<Room Index = "1" DockingSite = "2" Distance = "4" Strength = "200" />
<Room Index = "11" DockingSite = "0" Distance = "4" Strength = "200" />
</CorridorRoomRoom>
<CorridorRoomRoom>
<Room Index = "6" DockingSite = "1" Distance = "4" Strength = "200" />
<Room Index = "3" DockingSite = "3" Distance = "4" Strength = "200" />
</CorridorRoomRoom>
<CorridorRoomRoom>
<Room Index = "3" DockingSite = "2" Distance = "4" Strength = "100" />
<Room Index = "9" DockingSite = "0" Distance = "4" Strength = "100" />
</CorridorRoomRoom>
<CorridorRoomRoom>
<Room Index = "4" DockingSite = "1" Distance = "4" Strength = "100" />
<Room Index = "10" DockingSite = "0" Distance = "4" Strength = "100" />
</CorridorRoomRoom>
<CorridorRoomRoom>
<Room Index = "4" DockingSite = "2" Distance = "4" Strength = "400" />
<Room Index = "4" DockingSite = "3" Distance = "4" Strength = "400" />
</CorridorRoomRoom>
<CorridorRoomCave>
<Room Index = "4" DockingSite = "0" Distance = "4" Strength = "100" />
<Cave Direction = "3" Distance = "4" Strength = "100" >
<MinVox X = "46" Y = "172" Z = "470" />
<MaxVox X = "54" Y = "180" Z = "470" />
</Cave>
</CorridorRoomCave>
<CorridorRoomCave>
<Room Index = "0" DockingSite = "0" Distance = "4" Strength = "200" />
<Cave Direction = "3" Distance = "4" Strength = "200" >
<MinVox X = "136" Y = "189" Z = "450" />
<MaxVox X = "144" Y = "197" Z = "450" />
</Cave>
</CorridorRoomCave>
<CorridorRoomCave>
<Room Index = "0" DockingSite = "3" Distance = "4" Strength = "100" />
<Cave Direction = "3" Distance = "4" Strength = "100" >
<MinVox X = "389" Y = "231" Z = "450" />
<MaxVox X = "397" Y = "239" Z = "450" />
</Cave>
</CorridorRoomCave>
<CorridorRoomCave>
<Room Index = "2" DockingSite = "0" Distance = "4" Strength = "400" />
<Cave Direction = "3" Distance = "4" Strength = "200" >
<MinVox X = "478" Y = "257" Z = "260" />
<MaxVox X = "486" Y = "265" Z = "260" />
</Cave>
</CorridorRoomCave>
<CorridorRoomCave>
<Room Index = "3" DockingSite = "1" Distance = "4" Strength = "400" />
<Cave Direction = "2" Distance = "4" Strength = "400" >
<MinVox X = "460" Y = "264" Z = "80" />
<MaxVox X = "468" Y = "272" Z = "80" />
</Cave>
</CorridorRoomCave>
<CorridorRoomCave>
<Room Index = "3" DockingSite = "0" Distance = "4" Strength = "50" />
<Cave Direction = "2" Distance = "4" Strength = "50" >
<MinVox X = "340" Y = "287" Z = "40" />
<MaxVox X = "348" Y = "295" Z = "40" />
</Cave>
</CorridorRoomCave>
<CorridorRoomCave>
<Room Index = "1" DockingSite = "0" Distance = "4" Strength = "400" />
<Cave Direction = "0" Distance = "4" Strength = "300" >
<MinVox X = "50" Y = "318" Z = "262" />
<MaxVox X = "50" Y = "326" Z = "270" />
</Cave>
</CorridorRoomCave>
<CorridorRoomCave>
<Room Index = "1" DockingSite = "3" Distance = "4" Strength = "100" />
<Cave Direction = "2" Distance = "4" Strength = "100" >
<MinVox X = "80" Y = "181" Z = "240" />
<MaxVox X = "88" Y = "189" Z = "240" />
</Cave>
</CorridorRoomCave>
<CorridorSettings Sampling = "0.6" TextureSampling = "0.125">
<Point PosX="-4" PosY="-4" TexX="0.0" />
<Point PosX="-4" PosY="4" TexX="1.0" />
<Point PosX="4" PosY="4" TexX="2.0" />
<Point PosX="4" PosY="-4" TexX="1.0" />
</CorridorSettings>
<CorridorDetailobjects>
<Detailobject Name = "Torch1" Model = "data/detailobject.3ds" AntiAliasing = "1" Lighting = "0">
<Position X = "-4.0" Y = "0.0" />
<Rotation X = "0" Y = "90" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
<Distance Sampling = "0.6" NumFactor = "4" NumMin = "3" NumMax = "3" />
<FirstAndLast NumMinFirst ="0" NumMaxFirst = "0" ObjectAt1 = "0" />
</Detailobject>
<Detailobject Name = "Torch2" Model = "data/detailobject.3ds" AntiAliasing = "1" Lighting = "0">
<Position X = "4.0" Y = "0.0" />
<Rotation X = "0" Y = "270" Z = "0" />
<Scaling X = "1" Y = "1" Z = "1" />
<Distance Sampling = "0.6" NumFactor = "4" NumMin = "3" NumMax = "3" />
<FirstAndLast NumMinFirst ="0" NumMaxFirst = "0" ObjectAt1 = "0" />
</Detailobject>
</CorridorDetailobjects>
<CorridorCaveCave>
<Cave Direction = "1" Distance = "4" Strength = "200" >
<MinVox X = "300" Y = "306" Z = "205" />
<MaxVox X = "302" Y = "314" Z = "213" />
</Cave>
<Cave Direction = "0" Distance = "4" Strength = "200" >
<MinVox X = "350" Y = "244" Z = "259" />
<MaxVox X = "352" Y = "252" Z = "267" />
</Cave>
</CorridorCaveCave>
<Filter />
<GenerateMeshCave NormalWeighting = "0" />
</DunGen>