File indexing completed on 2024-05-19 05:40:37

0001 /***************************************************************************
0002  *  Copyright (C) 2019 by Renaud Guezennec                               *
0003  *   http://www.rolisteam.org/contact                                      *
0004  *                                                                         *
0005  *   This software is free software; you can redistribute it and/or modify *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 #include "controller/view_controller/vectorialmapcontroller.h"
0021 
0022 #include <set>
0023 
0024 #include "diceparser_qobject/diceroller.h"
0025 
0026 #include "undoCmd/addfogofwarchangecommand.h"
0027 #include "undoCmd/addvmapitem.h"
0028 #include "undoCmd/anchorvmapitemcommand.h"
0029 #include "undoCmd/changecoloritem.h"
0030 #include "undoCmd/changesizevmapitem.h"
0031 #include "undoCmd/deletevmapitem.h"
0032 #include "undoCmd/dupplicatevmapitem.h"
0033 #include "undoCmd/hideotherlayercommand.h"
0034 #include "undoCmd/rollinitcommand.h"
0035 #include "undoCmd/showtransparentitemcommand.h"
0036 
0037 #include "controller/item_controllers/characteritemcontroller.h"
0038 #include "controller/item_controllers/vmapitemfactory.h"
0039 
0040 #include "worker/iohelper.h"
0041 
0042 VectorialMapController::VectorialMapController(const QString& id, QObject* parent)
0043     : MediaControllerBase(id, Core::ContentType::VECTORIALMAP, parent)
0044     , m_vmapModel(new vmap::VmapItemModel)
0045     , m_gridController(new vmap::GridController(this))
0046 {
0047     m_sightController.reset(new vmap::SightController(this));
0048 
0049     connect(m_vmapModel.get(), &vmap::VmapItemModel::itemControllerAdded, this,
0050             &VectorialMapController::visualItemControllerCreated);
0051 
0052     connect(m_vmapModel.get(), &vmap::VmapItemModel::itemControllersRemoved, this,
0053             &VectorialMapController::visualItemControllersRemoved);
0054 
0055     connect(m_vmapModel.get(), &vmap::VmapItemModel::npcAdded, this, [this]() { setNpcNumber(npcNumber() + 1); });
0056     connect(m_vmapModel.get(), &vmap::VmapItemModel::rowsInserted, this, [this] { setModified(); });
0057     connect(m_vmapModel.get(), &vmap::VmapItemModel::rowsRemoved, this, [this] { setModified(); });
0058     connect(m_vmapModel.get(), &vmap::VmapItemModel::dataChanged, this, [this] { setModified(); });
0059     connect(this, &VectorialMapController::modifiedChanged, this,
0060             [this](bool b)
0061             {
0062                 if(!b)
0063                     m_vmapModel->setModifiedToAllItem();
0064             });
0065 }
0066 
0067 VectorialMapController::~VectorialMapController()= default;
0068 
0069 vmap::GridController* VectorialMapController::gridController() const
0070 {
0071     return m_gridController.get();
0072 }
0073 
0074 vmap::SightController* VectorialMapController::sightController() const
0075 {
0076     return m_sightController.get();
0077 }
0078 
0079 vmap::VisualItemController* VectorialMapController::itemController(const QString& id) const
0080 {
0081     auto res= m_vmapModel->item(id);
0082     if(!res)
0083     {
0084         if(id == m_sightController->uuid())
0085             res= sightController();
0086     }
0087     return res;
0088 }
0089 
0090 QString VectorialMapController::addItemController(const std::map<QString, QVariant>& params, bool isRemote)
0091 {
0092     auto tool= m_tool;
0093     auto it= params.find(Core::vmapkeys::KEY_TOOL);
0094     if(it != params.end())
0095         tool= static_cast<Core::SelectableTool>(it->second.toInt());
0096 
0097     auto item= vmap::VmapItemFactory::createVMapItem(this, tool, params);
0098 
0099     if(!item)
0100         return {};
0101 
0102     item->setRemote(isRemote);
0103     m_vmapModel->appendItemController(item);
0104     return item->uuid();
0105 }
0106 
0107 void VectorialMapController::addRemoteItem(vmap::VisualItemController* ctrl)
0108 {
0109     m_vmapModel->appendItemController(ctrl);
0110 }
0111 Core::PermissionMode VectorialMapController::permission() const
0112 {
0113     return m_permission;
0114 }
0115 
0116 int VectorialMapController::gridSize() const
0117 {
0118     return m_gridSize;
0119 }
0120 
0121 bool VectorialMapController::gridVisibility() const
0122 {
0123     return m_gridVisibility;
0124 }
0125 
0126 qreal VectorialMapController::gridScale() const
0127 {
0128     return m_gridScale;
0129 }
0130 
0131 bool VectorialMapController::gridAbove() const
0132 {
0133     return m_gridAbove;
0134 }
0135 
0136 bool VectorialMapController::collision() const
0137 {
0138     return m_collision;
0139 }
0140 
0141 Core::ScaleUnit VectorialMapController::scaleUnit() const
0142 {
0143     return m_scaleUnit;
0144 }
0145 
0146 Core::GridPattern VectorialMapController::gridPattern() const
0147 {
0148     return m_gridPattern;
0149 }
0150 
0151 Core::VisibilityMode VectorialMapController::visibility() const
0152 {
0153     return m_visibilityMode;
0154 }
0155 
0156 QColor VectorialMapController::backgroundColor() const
0157 {
0158     return m_backgroundColor;
0159 }
0160 
0161 QColor VectorialMapController::toolColor() const
0162 {
0163     return m_toolColor;
0164 }
0165 
0166 QColor VectorialMapController::gridColor() const
0167 {
0168     return m_gridColor;
0169 }
0170 
0171 quint16 VectorialMapController::penSize() const
0172 {
0173     return m_penSize;
0174 }
0175 
0176 QString VectorialMapController::npcName() const
0177 {
0178     return m_npcName;
0179 }
0180 
0181 int VectorialMapController::npcNumber() const
0182 {
0183     return m_npcNumber;
0184 }
0185 
0186 qreal VectorialMapController::zoomLevel() const
0187 {
0188     return m_zoomLevel;
0189 }
0190 
0191 Core::Layer VectorialMapController::layer() const
0192 {
0193     return m_layer;
0194 }
0195 
0196 Core::SelectableTool VectorialMapController::tool() const
0197 {
0198     return m_tool;
0199 }
0200 
0201 Core::EditionMode VectorialMapController::editionMode() const
0202 {
0203     return m_editionMode;
0204 }
0205 
0206 qreal VectorialMapController::opacity() const
0207 {
0208     return m_opacity;
0209 }
0210 
0211 bool VectorialMapController::npcNameVisible() const
0212 {
0213     return m_npcNameVisible;
0214 }
0215 
0216 bool VectorialMapController::pcNameVisible() const
0217 {
0218     return m_pcNameVisible;
0219 }
0220 
0221 bool VectorialMapController::npcNumberVisible() const
0222 {
0223     return m_npcNumberVisible;
0224 }
0225 
0226 bool VectorialMapController::healthBarVisible() const
0227 {
0228     return m_healthBarVisible;
0229 }
0230 
0231 bool VectorialMapController::initScoreVisible() const
0232 {
0233     return m_initScoreVisible;
0234 }
0235 
0236 bool VectorialMapController::characterVision() const
0237 {
0238     return m_characterVision;
0239 }
0240 
0241 bool VectorialMapController::stateLabelVisible() const
0242 {
0243     return m_stateLabelVisible;
0244 }
0245 
0246 QRectF VectorialMapController::visualRect() const
0247 {
0248     return m_visualRect;
0249 }
0250 
0251 void VectorialMapController::setVisualRect(QRectF visualRect)
0252 {
0253     if(m_visualRect == visualRect)
0254         return;
0255 
0256     m_visualRect= visualRect;
0257     emit visualRectChanged(m_visualRect);
0258 }
0259 
0260 QString VectorialMapController::layerToText(Core::Layer id)
0261 {
0262     static QStringList layerNames(
0263         {QObject::tr("Ground"), QObject::tr("Object"), QObject::tr("Character"), QObject::tr("GameMaster")});
0264 
0265     auto idx= qBound(0, static_cast<int>(id), layerNames.size() - 1);
0266     return layerNames.at(idx);
0267 }
0268 
0269 vmap::VmapItemModel* VectorialMapController::model() const
0270 {
0271     return m_vmapModel.get();
0272 }
0273 
0274 void VectorialMapController::addVision(CharacterVision* vision)
0275 {
0276     m_sightController->addCharacterVision(vision);
0277 }
0278 
0279 void VectorialMapController::setPermission(Core::PermissionMode mode)
0280 {
0281     if(m_permission == mode)
0282         return;
0283     m_permission= mode;
0284     emit permissionChanged(m_permission);
0285 }
0286 
0287 void VectorialMapController::setGridVisibility(bool visible)
0288 {
0289     if(visible == m_gridVisibility)
0290         return;
0291     m_gridVisibility= visible;
0292     emit gridVisibilityChanged(m_gridVisibility);
0293 }
0294 
0295 void VectorialMapController::setGridAbove(bool above)
0296 {
0297     if(m_gridAbove == above)
0298         return;
0299     m_gridAbove= above;
0300     emit gridAboveChanged(m_gridAbove);
0301 }
0302 
0303 void VectorialMapController::setGridSize(int gridSize)
0304 {
0305     if(m_gridSize == gridSize)
0306         return;
0307     m_gridSize= gridSize;
0308     emit gridSizeChanged(m_gridSize);
0309 }
0310 
0311 void VectorialMapController::setGridPattern(Core::GridPattern pattern)
0312 {
0313     if(pattern == m_gridPattern)
0314         return;
0315     m_gridPattern= pattern;
0316     emit gridPatternChanged(m_gridPattern);
0317 }
0318 
0319 void VectorialMapController::setVisibility(Core::VisibilityMode mode)
0320 {
0321     if(mode == m_visibilityMode)
0322         return;
0323     m_visibilityMode= mode;
0324     emit visibilityChanged(m_visibilityMode);
0325 }
0326 
0327 void VectorialMapController::setBackgroundColor(QColor color)
0328 {
0329     if(color == m_backgroundColor)
0330         return;
0331     m_backgroundColor= color;
0332     emit backgroundColorChanged(m_backgroundColor);
0333 }
0334 
0335 void VectorialMapController::setToolColor(QColor color)
0336 {
0337     if(color == m_toolColor)
0338         return;
0339     m_toolColor= color;
0340     emit toolColorChanged(color);
0341 }
0342 
0343 void VectorialMapController::setPenSize(quint16 size)
0344 {
0345     if(size == m_penSize)
0346         return;
0347     m_penSize= size;
0348     emit penSizeChanged(m_penSize);
0349 }
0350 
0351 void VectorialMapController::setNpcName(const QString& name)
0352 {
0353     if(name == m_npcName)
0354         return;
0355     m_npcName= name;
0356     emit npcNameChanged(m_npcName);
0357 }
0358 
0359 void VectorialMapController::setNpcNumber(int number)
0360 {
0361     if(number == m_npcNumber)
0362         return;
0363     m_npcNumber= number;
0364     emit npcNumberChanged(m_npcNumber);
0365 }
0366 
0367 void VectorialMapController::setGridScale(qreal scale)
0368 {
0369     if(qFuzzyCompare(m_gridScale, scale))
0370         return;
0371     m_gridScale= scale;
0372     emit gridScaleChanged(m_gridScale);
0373 }
0374 
0375 void VectorialMapController::setScaleUnit(Core::ScaleUnit unit)
0376 {
0377     if(m_scaleUnit == unit)
0378         return;
0379     m_scaleUnit= unit;
0380     emit scaleUnitChanged(m_scaleUnit);
0381 }
0382 
0383 void VectorialMapController::setZoomLevel(qreal lvl)
0384 {
0385     lvl= qBound(0.2, lvl, 4.0);
0386     if(qFuzzyCompare(lvl, m_zoomLevel))
0387         return;
0388 
0389     m_zoomLevel= lvl;
0390     emit zoomLevelChanged();
0391 }
0392 
0393 void VectorialMapController::zoomIn(qreal step)
0394 {
0395     setZoomLevel(m_zoomLevel + step);
0396 }
0397 
0398 void VectorialMapController::zoomOut(qreal step)
0399 {
0400     setZoomLevel(m_zoomLevel - step);
0401 }
0402 
0403 void VectorialMapController::setCollision(bool col)
0404 {
0405     if(m_collision == col)
0406         return;
0407     m_collision= col;
0408     emit collisionChanged(m_collision);
0409 }
0410 
0411 void VectorialMapController::setLayer(Core::Layer layer)
0412 {
0413     if(layer == m_layer)
0414         return;
0415     m_layer= layer;
0416     emit layerChanged(m_layer);
0417 }
0418 
0419 void VectorialMapController::setTool(Core::SelectableTool tool)
0420 {
0421     if(tool == m_tool)
0422         return;
0423     m_tool= tool;
0424     emit toolChanged(m_tool);
0425 }
0426 
0427 void VectorialMapController::setEditionMode(Core::EditionMode mode)
0428 {
0429     if(mode == m_editionMode)
0430         return;
0431     m_editionMode= mode;
0432     emit editionModeChanged(m_editionMode);
0433 }
0434 
0435 void VectorialMapController::setOpacity(qreal opacity)
0436 {
0437     if(qFuzzyCompare(m_opacity, opacity))
0438         return;
0439     m_opacity= opacity;
0440     emit opacityChanged(m_opacity);
0441 }
0442 
0443 void VectorialMapController::setNpcNameVisible(bool visible)
0444 {
0445     if(visible == m_npcNameVisible)
0446         return;
0447     m_npcNameVisible= visible;
0448     emit npcNameVisibleChanged(m_npcNameVisible);
0449 }
0450 
0451 void VectorialMapController::setPcNameVisible(bool visible)
0452 {
0453     if(visible == m_pcNameVisible)
0454         return;
0455     m_pcNameVisible= visible;
0456     emit pcNameVisibleChanged(m_pcNameVisible);
0457 }
0458 
0459 void VectorialMapController::setHealthBarVisible(bool visible)
0460 {
0461     if(visible == m_healthBarVisible)
0462         return;
0463     m_healthBarVisible= visible;
0464     emit healthBarVisibleChanged(m_healthBarVisible);
0465 }
0466 
0467 void VectorialMapController::setInitScoreVisible(bool visible)
0468 {
0469     if(m_initScoreVisible == visible)
0470         return;
0471     m_initScoreVisible= visible;
0472     emit initScoreVisibleChanged(m_initScoreVisible);
0473 }
0474 
0475 void VectorialMapController::setNpcNumberVisible(bool visible)
0476 {
0477     if(visible == m_npcNumberVisible)
0478         return;
0479     m_npcNumberVisible= visible;
0480     emit npcNumberVisibleChanged(m_npcNumberVisible);
0481 }
0482 
0483 void VectorialMapController::setGridColor(QColor color)
0484 {
0485     if(color == m_gridColor)
0486         return;
0487     m_gridColor= color;
0488     emit gridColorChanged(m_gridColor);
0489 }
0490 
0491 void VectorialMapController::setCharacterVision(bool b)
0492 {
0493     if(b == m_characterVision)
0494         return;
0495     m_characterVision= b;
0496     emit characterVisionChanged(m_characterVision);
0497 }
0498 
0499 void VectorialMapController::setStateLabelVisible(bool b)
0500 {
0501     if(b == m_stateLabelVisible)
0502         return;
0503     m_stateLabelVisible= b;
0504     emit stateLabelVisibleChanged(m_stateLabelVisible);
0505 }
0506 
0507 void VectorialMapController::insertItemAt(const std::map<QString, QVariant>& params)
0508 {
0509     auto tool= m_tool;
0510 
0511     if(params.end() != params.find(Core::vmapkeys::KEY_TOOL))
0512         tool= params.at(Core::vmapkeys::KEY_TOOL).value<Core::SelectableTool>();
0513 
0514     setIdle(false);
0515     emit performCommand(new AddVmapItemCommand(m_vmapModel.get(), tool, this, params));
0516 }
0517 
0518 void VectorialMapController::aboutToRemove(const QList<vmap::VisualItemController*>& list)
0519 {
0520     emit performCommand(new DeleteVmapItemCommand(this, list));
0521 }
0522 
0523 void VectorialMapController::askForColorChange(vmap::VisualItemController* itemCtrl)
0524 {
0525     emit performCommand(new ChangeColorItemCmd(itemCtrl, toolColor()));
0526 }
0527 
0528 void VectorialMapController::changeFogOfWar(const QPolygonF& poly, vmap::VisualItemController* itemCtrl, bool mask)
0529 {
0530     emit popCommand(); // remove controller of shape
0531     emit performCommand(new AddFogOfWarChangeCommand(m_sightController.get(), poly, mask));
0532 }
0533 
0534 void VectorialMapController::addHighLighter(const QPointF& point)
0535 {
0536     auto color= localGM() ? m_toolColor : m_localColor;
0537     emit sendOffHighLightAt(point, m_penSize, color);
0538     emit highLightAt(point, m_penSize, color);
0539 }
0540 
0541 void VectorialMapController::showHightLighter(const QPointF& p, const qreal& penSize, const QColor& color)
0542 {
0543     emit highLightAt(p, penSize, color);
0544 }
0545 
0546 bool VectorialMapController::idle() const
0547 {
0548     return m_idle;
0549 }
0550 
0551 qreal VectorialMapController::zIndex() const
0552 {
0553     return m_zIndex;
0554 }
0555 
0556 void VectorialMapController::setIdle(bool b)
0557 {
0558     if(b == m_idle)
0559         return;
0560     m_idle= b;
0561     emit idleChanged(m_idle);
0562 }
0563 
0564 void VectorialMapController::setZindex(qreal index)
0565 {
0566     if(qFuzzyCompare(index, m_zIndex))
0567         return;
0568     m_zIndex= index;
0569     emit zIndexChanged(m_zIndex);
0570 }
0571 
0572 void VectorialMapController::setRemote(bool remote)
0573 {
0574     MediaControllerBase::setRemote(remote);
0575     m_sightController->setRemote(remote);
0576     // m_gridController->setRemote(remote);
0577 }
0578 
0579 void VectorialMapController::normalizeSize(const QList<vmap::VisualItemController*>& list, Method method,
0580                                            const QPointF& mousePos)
0581 {
0582     if(list.isEmpty())
0583         return;
0584 
0585     emit performCommand(new ChangeSizeVmapItemCommand(list, method, mousePos));
0586 }
0587 
0588 bool VectorialMapController::pasteData(const QMimeData& mimeData)
0589 {
0590     if(!mimeData.hasImage())
0591         return false;
0592 
0593     auto pix= qvariant_cast<QPixmap>(mimeData.imageData());
0594     if(pix.isNull())
0595         return false;
0596 
0597     auto databytes= IOHelper::pixmapToData(pix);
0598 
0599     insertItemAt({{"tool", Core::SelectableTool::IMAGE}, {"data", databytes}});
0600     return true;
0601 }
0602 
0603 void VectorialMapController::showTransparentItems()
0604 {
0605     auto const& items= m_vmapModel->items();
0606     QList<vmap::VisualItemController*> list;
0607     std::transform(std::begin(items), std::end(items), std::back_inserter(list),
0608                    [](vmap::VisualItemController* item)
0609                    { return qFuzzyCompare(item->opacity(), 0.0) ? item : nullptr; });
0610     list.removeAll(nullptr);
0611     emit performCommand(new ShowTransparentItemCommand(list));
0612 }
0613 
0614 void VectorialMapController::hideOtherLayers(bool b)
0615 {
0616     emit performCommand(new HideOtherLayerCommand(m_layer, m_vmapModel.get(), b));
0617 }
0618 
0619 QList<QPointer<vmap::CharacterItemController>> sublist(Core::CharacterScope scope,
0620                                                        const std::vector<vmap::VisualItemController*>& data)
0621 {
0622     QList<QPointer<vmap::CharacterItemController>> list;
0623     for(auto const& ctrl : data)
0624     {
0625         if(ctrl->itemType() != vmap::VisualItemController::CHARACTER)
0626             continue;
0627         auto characterCtrl= dynamic_cast<vmap::CharacterItemController*>(ctrl);
0628         if(!characterCtrl)
0629             continue;
0630         bool res= false;
0631         switch(scope)
0632         {
0633         case Core::CharacterScope::AllNPC:
0634             res= !characterCtrl->playableCharacter();
0635             break;
0636         case Core::CharacterScope::AllCharacter:
0637             res= true;
0638             break;
0639         case Core::CharacterScope::SelectionOnly:
0640             res= characterCtrl->selected();
0641             break;
0642         }
0643 
0644         if(res)
0645         {
0646             list << characterCtrl;
0647         }
0648     }
0649     return list;
0650 }
0651 void VectorialMapController::rollInit(Core::CharacterScope scope)
0652 {
0653     auto items= m_vmapModel->items();
0654     auto list= sublist(scope, items);
0655     emit performCommand(new RollInitCommand(list, m_diceParser));
0656 }
0657 
0658 void VectorialMapController::rollInit(QList<QPointer<vmap::CharacterItemController>> list)
0659 {
0660     emit performCommand(new RollInitCommand(list, m_diceParser));
0661 }
0662 
0663 void VectorialMapController::setDiceParser(DiceRoller* parser)
0664 {
0665     m_diceParser= parser;
0666 }
0667 
0668 void VectorialMapController::cleanUpInit(Core::CharacterScope scope)
0669 {
0670     auto items= m_vmapModel->items();
0671     auto list= sublist(scope, items);
0672     addCommand(new CleanUpRollCommand(list));
0673 }
0674 void VectorialMapController::cleanUpInit(QList<QPointer<vmap::CharacterItemController>> list)
0675 {
0676     addCommand(new CleanUpRollCommand(list));
0677 }
0678 
0679 void VectorialMapController::runDiceCommand(QList<QPointer<vmap::CharacterItemController>> list, QString cmd)
0680 {
0681     addCommand(new CleanUpRollCommand(list));
0682 }
0683 
0684 void VectorialMapController::changeZValue(const QList<vmap::VisualItemController*>& list, StackOrder order)
0685 {
0686     qDebug() << list.size() << "list size" << order;
0687     // emit performCommand(new ChangeStackOrderVMapCommand(this, list, order));
0688 }
0689 
0690 void VectorialMapController::setParent(vmap::VisualItemController* child, vmap::VisualItemController* newParent)
0691 {
0692     if(!child)
0693         return;
0694     addCommand(new AnchorVMapItemCommand(child, newParent));
0695 }
0696 
0697 void VectorialMapController::removeItemController(const QSet<QString>& ids, bool fromNetwork)
0698 {
0699     m_vmapModel->removeItemController(ids, fromNetwork);
0700 }
0701 void VectorialMapController::addCommand(QUndoCommand* cmd)
0702 {
0703     emit performCommand(cmd);
0704 }
0705 void VectorialMapController::dupplicateItem(const QList<vmap::VisualItemController*>& vitem)
0706 {
0707     addCommand(new DupplicateVMapItem(vitem, this));
0708 }