add schema new loader model using xml separated work and load data validation using schema map data in xml new core model... proecting
402 lines
12 KiB
C++
402 lines
12 KiB
C++
#include "loader.h"
|
|
|
|
Loader::Loader(QObject *parent) :
|
|
QObject(parent)
|
|
{
|
|
doc = new QDomDocument("data");
|
|
//create();
|
|
load();
|
|
}
|
|
|
|
|
|
void Loader::load()
|
|
{
|
|
validate();
|
|
file = new QFile("data.xml");
|
|
if (!file->open(QIODevice::ReadOnly))
|
|
qFatal("No file data.xml found!");
|
|
if (!doc->setContent(file))
|
|
{
|
|
file->close();
|
|
qFatal("Error parsing data.xml");
|
|
}
|
|
readAliens();
|
|
readMaps();
|
|
readLevels();
|
|
//readMorphs();
|
|
//readSplashes();
|
|
//readTowers();
|
|
//readLevTowers();
|
|
//readTriggers();
|
|
readWaves();
|
|
readWaveParts();
|
|
readLevWaves();
|
|
|
|
file->close();
|
|
}
|
|
|
|
|
|
void Loader::create()
|
|
{
|
|
QFile cfile("data.xml");
|
|
if (!cfile.open(QIODevice::WriteOnly))
|
|
return;
|
|
cfile.resize(0);
|
|
// if (!doc.setContent(&file)) {
|
|
// file.close();
|
|
// return;
|
|
// }
|
|
QDomElement elem;
|
|
QDomElement root = doc->createElement("ADdata");
|
|
doc->appendChild(root);
|
|
QDomElement child = doc->createElement("aliens");
|
|
root.appendChild(child);
|
|
elem = doc->createElement("alien");
|
|
child.appendChild(elem);
|
|
elem.setAttribute("name","my alien");
|
|
elem.setAttribute("speed",0.012);
|
|
elem.setAttribute("health",100);
|
|
elem.setAttribute("prise",0);
|
|
elem.setAttribute("id",10);
|
|
elem.setAttribute("imageType",1);
|
|
elem = doc->createElement("alien");
|
|
child.appendChild(elem);
|
|
elem.setAttribute("name","MONSTR");
|
|
elem.setAttribute("speed",0.0099);
|
|
elem.setAttribute("health",200);
|
|
elem.setAttribute("prise",1);
|
|
elem.setAttribute("id",12);
|
|
elem.setAttribute("imageType",1);
|
|
child = doc->createElement("towers");
|
|
root.appendChild(child);
|
|
elem = doc->createElement("tower");
|
|
child.appendChild(elem);
|
|
elem.setAttribute("name","my tower");
|
|
elem.setAttribute("imageType",1);
|
|
elem.setAttribute("reload",20);
|
|
elem.setAttribute("buildTime",100);
|
|
elem.setAttribute("price",10);
|
|
elem.setAttribute("radius",1.2);
|
|
elem.setAttribute("splashType",0);
|
|
elem.setAttribute("id",0);
|
|
elem = doc->createElement("tower");
|
|
child.appendChild(elem);
|
|
elem.setAttribute("name","Wall");
|
|
elem.setAttribute("imageType",1);
|
|
elem.setAttribute("buildTime",300);
|
|
elem.setAttribute("reload",0);
|
|
elem.setAttribute("price",9);
|
|
elem.setAttribute("radius",0);
|
|
elem.setAttribute("splashType",0);
|
|
elem.setAttribute("id",1);
|
|
child = doc->createElement("maps");
|
|
root.appendChild(child);
|
|
elem = doc->createElement("map");
|
|
child.appendChild(elem);
|
|
elem.setAttribute("name","Map 16x16");
|
|
elem.setAttribute("maxPlayers","2");
|
|
elem.setAttribute("id",1);
|
|
elem.setAttribute("imageType",1);
|
|
elem.setAttribute("data",CreateMapExample());
|
|
child = doc->createElement("splashes");
|
|
root.appendChild(child);
|
|
elem = doc->createElement("splash");
|
|
child.appendChild(elem);
|
|
elem.setAttribute("name","shot");
|
|
elem.setAttribute("imageType",1);
|
|
elem.setAttribute("damage",2.5);
|
|
elem.setAttribute("speed",100);
|
|
elem.setAttribute("autoControl","true");
|
|
elem.setAttribute("radius",1.2);
|
|
elem.setAttribute("id",0);
|
|
|
|
cfile.write(doc->toByteArray());
|
|
cfile.close();
|
|
}
|
|
|
|
|
|
QString Loader::CreateMapExample()
|
|
{
|
|
QVector < QVector < int > > Cells;
|
|
Cells.resize(16);
|
|
for (int i=0; i<Cells.size(); i++)
|
|
{
|
|
Cells[i].resize(16);
|
|
Cells[i][0]=Map::Wall;
|
|
Cells[i][Cells[i].size()-1]=Map::Wall;
|
|
}
|
|
for (int i=0; i<Cells.size(); i++)
|
|
{
|
|
for (int j=0; j<Cells[i].size(); j++)
|
|
{
|
|
Cells[0][j]=Map::Wall;
|
|
Cells[Cells.size()-1][j]=Map::Wall;
|
|
}
|
|
}
|
|
for (int i=1; i<Cells.size()/2; i++)
|
|
for (int j=1; j<Cells[i].size()-1; j++)
|
|
Cells[i][j]=Map::Player;
|
|
for (int i=Cells.size()/2; i<Cells.size()-1; i++)
|
|
for (int j=1; j<Cells[i].size()-1; j++)
|
|
Cells[i][j]=Map::Player+1;
|
|
for (int i=2; i<Cells.size()-2; i++)
|
|
Cells[i][Cells[i].size()/2] = Map::Wall;
|
|
Cells[Cells.size()/2][0]=Map::Start;
|
|
Cells[Cells.size()/2-1][0]=Map::Start;
|
|
Cells[Cells.size()/2][Cells[Cells.size()/2].size()-1]=Map::Finish;
|
|
Cells[Cells.size()/2-1][Cells[Cells.size()/2].size()-1]=Map::Finish;
|
|
QByteArray ba;
|
|
QDataStream tmps(&ba,QIODevice::ReadWrite);
|
|
tmps << Cells;
|
|
ba = qCompress(ba);
|
|
ba = ba.toBase64();
|
|
QString str(ba);
|
|
return str;
|
|
}
|
|
|
|
|
|
void Loader::readAliens()
|
|
{
|
|
QDomNodeList alelems = doc->elementsByTagName("alien");
|
|
for (int i=0; i<alelems.size(); i++)
|
|
{
|
|
tbAlien al;
|
|
QDomNamedNodeMap nm = alelems.at(i).attributes();
|
|
al.id = nm.namedItem("id").nodeValue().toInt();
|
|
if (aliens.contains(al.id)) qCritical("Same alien ID dedected, replacing...");
|
|
al.name = nm.namedItem("name").nodeValue();
|
|
al.speed = nm.namedItem("speed").nodeValue().toFloat();
|
|
al.health = nm.namedItem("health").nodeValue().toFloat();
|
|
al.prise = nm.namedItem("prise").nodeValue().toInt();
|
|
al.armor = nm.namedItem("armor").nodeValue().toFloat();
|
|
al.imgType = nm.namedItem("imageType").nodeValue().toInt();
|
|
al.regeneration = nm.namedItem("regeneration").nodeValue().toFloat();
|
|
aliens.insert(al.id,al);
|
|
qDebug() << tr("Alien %1 id=%2 health=%3 speed=%4 prise=%5 imgType=%6 armor=%7 regeneration=%8").arg(al.name).arg(al.id).arg(al.health).arg(al.speed).arg(al.prise).arg(al.imgType).arg(al.armor).arg(al.regeneration);
|
|
}
|
|
qDebug("================");
|
|
qDebug() << tr("Found %1 aliens").arg(aliens.size());
|
|
qDebug("================");
|
|
}
|
|
|
|
|
|
void Loader::readWaves()
|
|
{
|
|
QDomNodeList welems = doc->elementsByTagName("wave");
|
|
for (int i=0; i<welems.size(); i++)
|
|
{
|
|
tbWave w;
|
|
QDomNamedNodeMap nm = welems.at(i).attributes();
|
|
w.id = nm.namedItem("id").nodeValue().toInt();
|
|
if (waves.contains(w.id)) qCritical("Same wave ID dedected, replacing...");
|
|
w.prise = nm.namedItem("prise").nodeValue().toInt();
|
|
w.timeout = nm.namedItem("timeout").nodeValue().toInt();
|
|
waves.insert(w.id,w);
|
|
qDebug() << tr("Wave %1 prise=%2 timeout=%3").arg(w.id).arg(w.prise).arg(w.timeout);
|
|
}
|
|
qDebug("================");
|
|
qDebug() << tr("Found %1 waves").arg(waves.size());
|
|
qDebug("================");
|
|
}
|
|
|
|
|
|
void Loader::readWaveParts()
|
|
{
|
|
QDomNodeList wpelems = doc->elementsByTagName("wavePart");
|
|
for (int i=0; i<wpelems.size(); i++)
|
|
{
|
|
bool OK = true;
|
|
tbWavePart wp;
|
|
QDomNamedNodeMap nm = wpelems.at(i).attributes();
|
|
wp.waveId = nm.namedItem("wave").nodeValue().toInt();
|
|
if (!waves.contains(wp.waveId))
|
|
{
|
|
qCritical("invalid wave Id");
|
|
OK = false;
|
|
}
|
|
wp.alienId = nm.namedItem("alien").nodeValue().toInt();
|
|
if (!aliens.contains(wp.alienId))
|
|
{
|
|
qCritical("invalid alien Id");
|
|
OK = false;
|
|
}
|
|
wp.count = nm.namedItem("count").nodeValue().toInt();
|
|
if (OK)
|
|
{
|
|
waveParts.insert(wp.waveId,wp);
|
|
qDebug() << tr("Wave=%1 alien=%2 count=%3").arg(wp.waveId).arg(wp.alienId).arg(wp.count);
|
|
}
|
|
}
|
|
qDebug("================");
|
|
qDebug() << tr("Found %1 waveParts").arg(waveParts.size());
|
|
qDebug("================");
|
|
}
|
|
|
|
|
|
void Loader::readLevWaves()
|
|
{
|
|
QDomNodeList lwelems = doc->elementsByTagName("waveOnLevel");
|
|
for (int i=0; i<lwelems.size(); i++)
|
|
{
|
|
bool OK = true;
|
|
tbWaveOnLevel lw;
|
|
QDomNamedNodeMap nm = lwelems.at(i).attributes();
|
|
lw.levelId= nm.namedItem("level").nodeValue().toInt();
|
|
if (!levels.contains(lw.levelId))
|
|
{
|
|
qCritical("invalid level Id");
|
|
OK = false;
|
|
}
|
|
lw.waveId = nm.namedItem("wave").nodeValue().toInt();
|
|
if (!waves.contains(lw.waveId))
|
|
{
|
|
qCritical("invalid wave Id");
|
|
OK = false;
|
|
}
|
|
if (OK)
|
|
{
|
|
levWaves.insert(lw.levelId,lw);
|
|
qDebug() << tr("level=%1 wave=%2").arg(lw.levelId).arg(lw.waveId);
|
|
}
|
|
}
|
|
qDebug("================");
|
|
qDebug() << tr("Found %1 Waves On Level").arg(levWaves.size());
|
|
qDebug("================");
|
|
}
|
|
|
|
|
|
void Loader::readLevels()
|
|
{
|
|
QDomNodeList lelems = doc->elementsByTagName("level");
|
|
for (int i=0; i<lelems.size(); i++)
|
|
{
|
|
bool OK = true;
|
|
tbLevel l;
|
|
QDomNamedNodeMap nm = lelems.at(i).attributes();
|
|
l.id = nm.namedItem("id").nodeValue().toInt();
|
|
l.name = nm.namedItem("name").nodeValue();
|
|
if (levels.contains(l.id)) qCritical("Same wave ID dedected, replacing...");
|
|
l.mapId = nm.namedItem("map").nodeValue().toInt();
|
|
if (!maps.contains(l.mapId))
|
|
{
|
|
qCritical("invalid map Id");
|
|
OK = false;
|
|
}
|
|
if (OK)
|
|
{
|
|
levels.insert(l.id,l);
|
|
qDebug() << tr("Level %1 id=%2 map=%3 ").arg(l.name).arg(l.id).arg(l.mapId);
|
|
}
|
|
}
|
|
qDebug("================");
|
|
qDebug() << tr("Found %1 levels").arg(levels.size());
|
|
qDebug("================");
|
|
}
|
|
|
|
|
|
void Loader::readSplashes()
|
|
{
|
|
QString str;
|
|
QDomNodeList selems = doc->elementsByTagName("splash");
|
|
for (int i=0; i<selems.size(); i++)
|
|
{
|
|
tbSplash s;
|
|
// s.id = selems.at(i).attributes().namedItem("id").nodeValue().toInt();
|
|
// if (splashes.contains(s.id)) qCritical("Same splash ID dedected, replacing...");
|
|
// s.name = selems.at(i).attributes().namedItem("name").nodeValue();
|
|
// s.speed = selems.at(i).attributes().namedItem("speed").nodeValue().toFloat();
|
|
// s.radius = selems.at(i).attributes().namedItem("radius").nodeValue().toFloat();
|
|
// s.damage = selems.at(i).attributes().namedItem("damage").nodeValue().toFloat();
|
|
// s.timer = selems.at(i).attributes().namedItem("timer").nodeValue().toInt();
|
|
// s.lifetime = selems.at(i).attributes().namedItem("lifetime").nodeValue().toInt();
|
|
// s.imgType = selems.at(i).attributes().namedItem("imageType").nodeValue().toInt();
|
|
// str = selems.at(i).attributes().namedItem("autoControl").nodeValue();
|
|
// s.autoControl = (str == "true");
|
|
// str = selems.at(i).attributes().namedItem("triggerDeath").nodeValue();
|
|
// s.isDeadAfterTrigger = (str == "true");
|
|
// str = selems.at(i).attributes().namedItem("trigger").nodeValue();
|
|
// s.trigger = tbSplash::noTrigger;
|
|
// if (str == "onDestination")
|
|
// s.trigger = tbSplash::onDestination;
|
|
// if (str == "onTimer")
|
|
// s.trigger = tbSplash::onTimer;
|
|
// if (str == "onAlienInRadius")
|
|
// s.trigger = tbSplash::onAlienInRadius;
|
|
// splashes.insert(s.id,s);
|
|
// qDebug() << tr("Splash %1 id=%2 damage=%3 speed=%4 radius=%5 imgType=%6 ").arg(s.name).arg(s.id).arg(s.damage).arg(s.speed).arg(s.radius).arg(s.imgType) << tr("lifetime=%1 timer=%2 trigger=%3 autoControl=%4 triggerDeath=%5").arg(s.lifetime).arg(s.timer).arg(s.trigger).arg(s.autoControl).arg(s.isDeadAfterTrigger);
|
|
}
|
|
qDebug("================");
|
|
qDebug() << tr("Found %1 splashes").arg(splashes.size());
|
|
qDebug("================");
|
|
}
|
|
|
|
|
|
void Loader::readTowers()
|
|
{
|
|
QDomNodeList twelems = doc->elementsByTagName("tower");
|
|
for (int i=0; i<twelems.size(); i++)
|
|
{
|
|
tbTower tw;
|
|
tw.id = twelems.at(i).attributes().namedItem("id").nodeValue().toInt();
|
|
if (towers.contains(tw.id)) qCritical("Same tower ID dedected, replacing...");
|
|
tw.name = twelems.at(i).attributes().namedItem("name").nodeValue();
|
|
towers.insert(tw.id,tw);
|
|
qDebug() << tr("Tower %1 id=%2").arg(tw.name).arg(tw.id);
|
|
}
|
|
qDebug("================");
|
|
qDebug() << tr("Found %1 towers").arg(towers.size());
|
|
qDebug("================");
|
|
}
|
|
|
|
|
|
void Loader::readMaps()
|
|
{
|
|
QDomNodeList melems = doc->elementsByTagName("map");
|
|
for (int i=0; i<melems.size(); i++)
|
|
{
|
|
tbMap m;
|
|
QDomNamedNodeMap mn = melems.at(i).attributes();
|
|
m.id = mn.namedItem("id").nodeValue().toInt();
|
|
if (maps.contains(m.id)) qCritical("Same map ID dedected, replacing...");
|
|
m.name = mn.namedItem("name").nodeValue();
|
|
m.imgType = mn.namedItem("imageType").nodeValue().toInt();
|
|
m.maxPlayers = mn.namedItem("maxPlayers").nodeValue().toInt();
|
|
QByteArray ba = QByteArray::fromBase64(mn.namedItem("data").nodeValue().toUtf8());
|
|
ba = qUncompress(ba);
|
|
QDataStream s(ba);
|
|
s >> m.cells;
|
|
maps.insert(m.id,m);
|
|
qDebug() << tr("Map %1 id=%2 imgType=%3 maxPlayers=%5").arg(m.name).arg(m.id).arg(m.imgType).arg(m.maxPlayers);
|
|
for (int k=0; k<m.cells.size(); k++) qDebug()<<m.cells.at(k);
|
|
}
|
|
qDebug("================");
|
|
qDebug() << tr("Found %1 maps").arg(maps.size());
|
|
qDebug("================");
|
|
}
|
|
|
|
|
|
void Loader::validate()
|
|
{
|
|
QFile sfile("schema.xml");
|
|
if (!sfile.open(QIODevice::ReadOnly))
|
|
qFatal("No file schema.xml found!");
|
|
QXmlSchema schema;
|
|
if (!schema.load(&sfile))
|
|
qFatal("Error parsing schema.xml");
|
|
if (!schema.isValid())
|
|
qFatal("Invalid XMLSchema in schema.xml");
|
|
QXmlSchemaValidator sval(schema);
|
|
QFile dfile("data.xml");
|
|
if (!dfile.open(QIODevice::ReadOnly))
|
|
qFatal("No file data.xml found!");
|
|
if (!sval.validate(&dfile))
|
|
qFatal("Validation failure!");
|
|
else
|
|
{
|
|
sfile.close();
|
|
dfile.close();
|
|
qDebug("Validation SUCSESS!!!");
|
|
qDebug("================");
|
|
}
|
|
}
|