File indexing completed on 2023-12-03 07:52:33

0001 /*
0002     SPDX-FileCopyrightText: 2008 Mathias Kraus <k.hias@gmx.de>
0003     SPDX-FileCopyrightText: 2007-2008 Nathalie Liesse <nathalie.liesse@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "mapparser.h"
0009 #include "arena.h"
0010 #include "granatier_random.h"
0011 
0012 #include <cstdlib>
0013 #include <QPointF>
0014 
0015 MapParser::MapParser(Arena* p_arena)
0016 {
0017     m_arena = p_arena;
0018     m_counterRows = 0;
0019 }
0020 
0021 MapParser::~MapParser()
0022 = default;
0023 
0024 bool MapParser::parse(QIODevice *input)
0025 {
0026     QXmlStreamReader reader(input);
0027 
0028     while (!reader.atEnd()) {
0029         reader.readNext();
0030         if (reader.hasError())
0031             return false;
0032 
0033         switch (reader.tokenType()) {
0034         case QXmlStreamReader::StartElement:
0035             if (!startElement(reader.namespaceUri(), reader.name(),
0036                               reader.qualifiedName(), reader.attributes())) {
0037                 return false;
0038             }
0039             break;
0040         case QXmlStreamReader::EndElement:
0041             if (!endElement(reader.namespaceUri(), reader.name(),
0042                             reader.qualifiedName())) {
0043                 return false;
0044             }
0045             break;
0046         case QXmlStreamReader::Characters:
0047             if (!reader.isWhitespace() && !reader.text().toString().trimmed().isEmpty()) {
0048                 if (!characters(reader.text()))
0049                     return false;
0050             }
0051             break;
0052         default:
0053             break;
0054         }
0055     }
0056 
0057     if (!reader.isEndDocument())
0058         return false;
0059 
0060     return true;
0061 }
0062 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0063 bool MapParser::characters(const QStringRef &ch)
0064 #else
0065 bool MapParser::characters(const QStringView &ch)
0066 #endif
0067 {
0068     m_buffer = ch.toString();
0069     return true;
0070 }
0071 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0072 bool MapParser::startElement(const QStringRef &namespaceURI, const QStringRef &localName, const QStringRef &qName, const QXmlStreamAttributes &atts)
0073 #else
0074 bool MapParser::startElement(const QStringView &namespaceURI, const QStringView &localName, const QStringView &qName, const QXmlStreamAttributes &atts)
0075 #endif
0076 {
0077     Q_UNUSED(namespaceURI)
0078     Q_UNUSED(localName)
0079     if (qName == QLatin1String("Arena")) {
0080         int nbRows = 0;
0081         int nbColumns = 0;
0082         if (atts.hasAttribute(QLatin1String("rowCount"))) {
0083             nbRows = atts.value(QLatin1String("rowCount")).toInt();
0084         }
0085         if (atts.hasAttribute(QLatin1String("colCount"))) {
0086             nbColumns = atts.value(QLatin1String("colCount")).toInt();
0087         }
0088         // Create the Arena matrix
0089         m_arena->init(nbRows, nbColumns);
0090     }
0091 
0092     return true;
0093 }
0094 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0095 bool MapParser::endElement(const QStringRef &namespaceURI, const QStringRef &localName, const QStringRef &qName)
0096 #else
0097 bool MapParser::endElement(const QStringView &namespaceURI, const QStringView &localName, const QStringView &qName)
0098 #endif
0099 {
0100     Q_UNUSED(namespaceURI)
0101     Q_UNUSED(localName)
0102 
0103     if (qName.toString() == QLatin1String("Row")) {
0104         for (int i=0; i<m_buffer.length();++i)
0105         {
0106             switch(m_buffer.at(i).toLatin1())
0107             {
0108                 case ' ':
0109                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::HOLE);
0110                     break;
0111                 case '=':
0112                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::WALL);
0113                     break;
0114                 case '_':
0115                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::GROUND);
0116                     break;
0117                 case '+':
0118                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::BLOCK);
0119                     break;
0120                 case 'x':
0121                     // create a random block
0122                     if(granatier::RNG::fromRange(0, 100) > 25)
0123                     {
0124                         m_arena->setCellType(m_counterRows,i,Granatier::Cell::BLOCK);
0125                     }
0126                     else
0127                     {
0128                         m_arena->setCellType(m_counterRows,i,Granatier::Cell::GROUND);
0129                     }
0130                     break;
0131                 case 'o':
0132                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::BOMBMORTAR);
0133                     break;
0134                 case '-':
0135                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::ICE);
0136                     break;
0137                 case 'u':
0138                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::ARROWUP);
0139                     break;
0140                 case 'r':
0141                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::ARROWRIGHT);
0142                     break;
0143                 case 'd':
0144                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::ARROWDOWN);
0145                     break;
0146                 case 'l':
0147                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::ARROWLEFT);
0148                     break;
0149                 case 'p':
0150                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::GROUND);
0151                     m_arena->addPlayerPosition(QPointF(i+0.5, m_counterRows+0.5));
0152                     break;
0153                 default:
0154                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::GROUND);
0155             }
0156         }
0157         m_counterRows ++;
0158     }
0159     return true;
0160 }