File indexing completed on 2024-12-08 06:46:37

0001 /***************************************************************************
0002                             cmapcmdmoveplayer.cpp
0003                              -------------------
0004     begin                : Sun Mar 29 2015
0005     copyright            : (C) 2015 by Tomas Mecir
0006     email                : mecirt@gmail.com
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *                                                                         *
0011  *   This program is free software; you can redistribute it and/or modify  *
0012  *   it under the terms of the GNU General Public License as published by  *
0013  *   the Free Software Foundation; either version 2 of the License, or     *
0014  *   (at your option) any later version.                                   *
0015  *                                                                         *
0016  ***************************************************************************/
0017 
0018 #include "cmapcmdmoveplayer.h"
0019 
0020 #include "cmapelement.h"
0021 #include "cmapelementutil.h"
0022 #include "cmaplevel.h"
0023 #include "cmappath.h"
0024 #include "cmaproom.h"
0025 #include "cmapview.h"
0026 #include "cmapmanager.h"
0027 
0028 CMapCmdMovePlayer::CMapCmdMovePlayer(CMapManager *mapManager, directionTyp direction, QString specialCmd, bool create) :
0029   CMapCommand("Move Player"),
0030   m_manager(mapManager),
0031   m_create(create),
0032   m_special(specialCmd),
0033   m_direction(direction),
0034   m_newroom(nullptr),
0035   m_newpath(nullptr),
0036   m_createdlevel(nullptr)
0037 {
0038 }
0039 
0040 CMapCmdMovePlayer::~CMapCmdMovePlayer()
0041 {
0042 }
0043 
0044 void CMapCmdMovePlayer::redo()
0045 {
0046   m_createdlevel = nullptr;
0047   m_newpath = nullptr;
0048   m_newroom = nullptr;
0049 
0050   m_origroom = m_manager->getCurrentRoom();
0051   if (!m_origroom) return;
0052   CMapRoom *tgroom = m_origroom->getPathTarget(m_direction, m_special);
0053 
0054   if ((!tgroom) && (m_direction != SPECIAL))
0055   {
0056     // try a special exit with the directional name
0057     tgroom = m_origroom->getPathTarget(SPECIAL, m_manager->directionToText(m_direction, ""));
0058     // short direction too
0059     if (!tgroom) tgroom = m_origroom->getPathTarget(SPECIAL, m_manager->directionToText(m_direction, "", true));
0060   }
0061 
0062   if (tgroom) {
0063     m_manager->setCurrentRoom(tgroom);
0064     return;
0065   }
0066 
0067   // Nothing suitable -- if we can't create, we are done
0068   if (!m_create) return;
0069 
0070   CMapRoom *srcRoom = m_origroom;
0071   CMapPath *oppositePath = nullptr;
0072 
0073   CMapLevel *destLevel = m_origroom->getLevel();
0074 
0075   int x = 0, y = 0;
0076   // Check to see if there is a path in the opposite direction that we should be using
0077   foreach (CMapPath *path2, *srcRoom->getConnectingPathList())
0078   {
0079     if (path2->getDestDir() == m_direction)
0080     {
0081       tgroom = path2->getSrcRoom();
0082       destLevel = tgroom->getLevel();
0083       x = tgroom->getX();
0084       y = tgroom->getY();
0085       oppositePath = path2;
0086       break;
0087     }
0088   }
0089 
0090   if (!tgroom) {
0091     QSize grid = m_manager->getMapData()->gridSize;
0092     // Nothing found, so let's see if there is already a room where we are going
0093     QPoint inc;
0094     m_manager->directionToCord(m_direction,QSize(grid.width()*2, grid.height()*2),&inc);
0095     x = srcRoom->getX() + inc.x();
0096     y = srcRoom->getY() + inc.y();
0097 
0098     if ((m_direction == UP) || (m_direction == DOWN))
0099     {
0100       int pos = (m_direction == UP) ? destLevel->getZone()->levelCount() : 0;
0101       destLevel = (m_direction == UP) ? destLevel->getNextLevel() : destLevel->getPrevLevel();
0102       if (!destLevel) {
0103         destLevel = new CMapLevel (m_manager, pos);
0104         m_createdlevel = destLevel;
0105       }
0106     }
0107 
0108     // Check to see if the map needs to be moved
0109     // and calulate the offset to move if it needs moving.
0110     if (x < grid.width()*3 || y < grid.height()*2)
0111     {
0112       int movex, movey;
0113 
0114       if (x < grid.width()*3)
0115       {
0116         movex = grid.width()*3 - x;
0117         x+=movex;
0118       }
0119       else
0120         movex = 0;
0121 
0122       if (y < grid.height()*3)
0123       {
0124         movey = grid.height() * 3- y;
0125         y+=movey;
0126       }
0127       else
0128         movey = 0;
0129 
0130       m_manager->moveMap (QPoint(movex,movey),m_origroom->getZone());
0131     }
0132 
0133     // Check to see if the room already exists
0134     tgroom = dynamic_cast<CMapRoom *>(destLevel->findElementAt(QPoint (x,y), ROOM));
0135 
0136     // if it doesn't, we need to create one
0137     if (!tgroom) {
0138       tgroom = CMapElementUtil::createRoom(m_manager, QPoint (x,y),destLevel);
0139       if (!tgroom) return;
0140       m_newroom = tgroom;
0141     }
0142   }
0143 
0144   directionTyp destDir = m_manager->getOpsiteDirection(m_direction);
0145   // Create the new path to the room
0146   // TODO: move path creation to utils!
0147   bool undo = m_manager->getUndoActive();
0148   m_manager->setUndoActive(false);
0149 
0150   CMapPath *newPath = m_manager->createPath(srcRoom, m_direction, tgroom, destDir, false);
0151   m_newpath = newPath;
0152 
0153   // Make the path two way if the default path type is two way
0154   if (m_manager->getMapData()->defaultPathTwoWay && (!oppositePath))
0155     newPath->makeTwoWay();
0156 
0157   m_manager->setCurrentRoom(tgroom);
0158   m_manager->setUndoActive(undo);
0159 }
0160 
0161 void CMapCmdMovePlayer::undo()
0162 {
0163   // move player back to the original location
0164   if (m_origroom) m_manager->setCurrentRoom(m_origroom);
0165   // delete the created room/exit if needed
0166   if (m_create) {
0167     delete m_newpath;
0168     delete m_newroom;
0169     delete m_createdlevel;
0170     m_newroom = nullptr;
0171     m_newpath = nullptr;
0172     m_createdlevel = nullptr;
0173   }
0174 }
0175