File indexing completed on 2024-02-18 04:03:26

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 bool MapParser::characters(const QStringView &ch)
0063 {
0064     m_buffer = ch.toString();
0065     return true;
0066 }
0067 
0068 bool MapParser::startElement(const QStringView &namespaceURI, const QStringView &localName, const QStringView &qName, const QXmlStreamAttributes &atts)
0069 {
0070     Q_UNUSED(namespaceURI)
0071     Q_UNUSED(localName)
0072     if (qName == QLatin1String("Arena")) {
0073         int nbRows = 0;
0074         int nbColumns = 0;
0075         if (atts.hasAttribute(QLatin1String("rowCount"))) {
0076             nbRows = atts.value(QLatin1String("rowCount")).toInt();
0077         }
0078         if (atts.hasAttribute(QLatin1String("colCount"))) {
0079             nbColumns = atts.value(QLatin1String("colCount")).toInt();
0080         }
0081         // Create the Arena matrix
0082         m_arena->init(nbRows, nbColumns);
0083     }
0084 
0085     return true;
0086 }
0087 
0088 bool MapParser::endElement(const QStringView &namespaceURI, const QStringView &localName, const QStringView &qName)
0089 {
0090     Q_UNUSED(namespaceURI)
0091     Q_UNUSED(localName)
0092 
0093     if (qName.toString() == QLatin1String("Row")) {
0094         for (int i=0; i<m_buffer.length();++i)
0095         {
0096             switch(m_buffer.at(i).toLatin1())
0097             {
0098                 case ' ':
0099                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::HOLE);
0100                     break;
0101                 case '=':
0102                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::WALL);
0103                     break;
0104                 case '_':
0105                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::GROUND);
0106                     break;
0107                 case '+':
0108                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::BLOCK);
0109                     break;
0110                 case 'x':
0111                     // create a random block
0112                     if(granatier::RNG::fromRange(0, 100) > 25)
0113                     {
0114                         m_arena->setCellType(m_counterRows,i,Granatier::Cell::BLOCK);
0115                     }
0116                     else
0117                     {
0118                         m_arena->setCellType(m_counterRows,i,Granatier::Cell::GROUND);
0119                     }
0120                     break;
0121                 case 'o':
0122                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::BOMBMORTAR);
0123                     break;
0124                 case '-':
0125                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::ICE);
0126                     break;
0127                 case 'u':
0128                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::ARROWUP);
0129                     break;
0130                 case 'r':
0131                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::ARROWRIGHT);
0132                     break;
0133                 case 'd':
0134                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::ARROWDOWN);
0135                     break;
0136                 case 'l':
0137                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::ARROWLEFT);
0138                     break;
0139                 case 'p':
0140                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::GROUND);
0141                     m_arena->addPlayerPosition(QPointF(i+0.5, m_counterRows+0.5));
0142                     break;
0143                 default:
0144                     m_arena->setCellType(m_counterRows,i,Granatier::Cell::GROUND);
0145             }
0146         }
0147         m_counterRows ++;
0148     }
0149     return true;
0150 }