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

0001 /***************************************************************************
0002  *  Copyright (C) 2020 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 "updater/vmapitem/characteritemupdater.h"
0021 
0022 #include "controller/item_controllers/characteritemcontroller.h"
0023 #include "network/networkmessagereader.h"
0024 #include "worker/convertionhelper.h"
0025 #include "worker/messagehelper.h"
0026 
0027 namespace properties
0028 {
0029 constexpr auto side{"side"};
0030 constexpr auto stateColor{"stateColor"};
0031 constexpr auto number{"number"};
0032 constexpr auto playableCharacter{"playableCharacter"};
0033 constexpr auto thumnailRect{"thumnailRect"};
0034 constexpr auto visionShape{"visionShape"};
0035 constexpr auto font{"font"};
0036 
0037 constexpr auto vision_radius{"radius"};
0038 constexpr auto vision_angle{"angle"};
0039 constexpr auto vision_rotation{"rotation"};
0040 constexpr auto vision_position{"position"};
0041 // constexpr auto vision_shape{"shape"};
0042 constexpr auto vision_path{"path"};
0043 constexpr auto vision_removed{"removed"};
0044 
0045 } // namespace properties
0046 
0047 CharacterItemUpdater::CharacterItemUpdater(QObject* parent) : VMapItemControllerUpdater(parent) {}
0048 
0049 void CharacterItemUpdater::addItemController(vmap::VisualItemController* ctrl, bool sendOff)
0050 {
0051     if(nullptr == ctrl)
0052         return;
0053 
0054     auto itemCtrl= dynamic_cast<vmap::CharacterItemController*>(ctrl);
0055 
0056     if(nullptr == itemCtrl)
0057         return;
0058 
0059     VMapItemControllerUpdater::addItemController(ctrl);
0060 
0061     connect(itemCtrl, &vmap::CharacterItemController::sideEdited, this,
0062             [this, itemCtrl]() { sendOffVMapChanges<qreal>(itemCtrl, properties::side); });
0063     connect(itemCtrl, &vmap::CharacterItemController::stateColorChanged, this,
0064             [this, itemCtrl]() { sendOffVMapChanges<QColor>(itemCtrl, properties::stateColor); });
0065     connect(itemCtrl, &vmap::CharacterItemController::numberChanged, this,
0066             [this, itemCtrl]() { sendOffVMapChanges<QColor>(itemCtrl, properties::number); });
0067     connect(itemCtrl, &vmap::CharacterItemController::playableCharacterChanged, this,
0068             [this, itemCtrl]() { sendOffVMapChanges<bool>(itemCtrl, properties::playableCharacter); });
0069     connect(itemCtrl, &vmap::CharacterItemController::visionShapeChanged, this,
0070             [this, itemCtrl]() { sendOffVMapChanges<CharacterVision::SHAPE>(itemCtrl, properties::visionShape); });
0071     connect(itemCtrl, &vmap::CharacterItemController::fontChanged, this,
0072             [this, itemCtrl]() { sendOffVMapChanges<QFont>(itemCtrl, properties::font); });
0073     connect(itemCtrl, &vmap::CharacterItemController::rectEditFinished, this,
0074             [this, itemCtrl]() { sendOffVMapChanges<QRectF>(itemCtrl, properties::thumnailRect); });
0075 
0076     { // vision
0077         auto vision= itemCtrl->vision();
0078 
0079         connect(vision, &CharacterVision::radiusEdited, this,
0080                 [this, itemCtrl]() { sendOffVisionChanges<qreal>(itemCtrl, properties::vision_radius); });
0081         connect(vision, &CharacterVision::angleEdited, this,
0082                 [this, itemCtrl]() { sendOffVisionChanges<qreal>(itemCtrl, properties::vision_angle); });
0083         connect(vision, &CharacterVision::rotationEdited, this,
0084                 [this, itemCtrl]() { sendOffVisionChanges<qreal>(itemCtrl, properties::vision_rotation); });
0085         connect(vision, &CharacterVision::positionEdited, this,
0086                 [this, itemCtrl]() { sendOffVisionChanges<QPointF>(itemCtrl, properties::vision_position); });
0087         connect(vision, &CharacterVision::pathEdited, this,
0088                 [this, itemCtrl]() { sendOffVisionChanges<QPainterPath>(itemCtrl, properties::vision_path); });
0089         connect(vision, &CharacterVision::removedChanged, this,
0090                 [this, itemCtrl]() { sendOffVisionChanges<bool>(itemCtrl, properties::vision_removed); });
0091     }
0092 
0093     connect(itemCtrl, &vmap::CharacterItemController::rectEditFinished, this,
0094             [this, itemCtrl]() { sendOffVMapChanges<QRectF>(itemCtrl, properties::thumnailRect); });
0095 
0096     if(!ctrl->remote() && sendOff)
0097         MessageHelper::sendOffCharacter(itemCtrl, ctrl->mapUuid());
0098 }
0099 
0100 bool CharacterItemUpdater::updateItemProperty(NetworkMessageReader* msg, vmap::VisualItemController* ctrl)
0101 {
0102 
0103     if(nullptr == msg || nullptr == ctrl)
0104         return false;
0105 
0106     qDebug() << "update Character Item property" << msg->action();
0107     if(msg->action() == NetMsg::CharacterVisionChanged)
0108     {
0109         return updateVisionProperty(msg, ctrl);
0110     }
0111 
0112     // TODO implement save/restore
0113     auto datapos= msg->pos();
0114 
0115     if(VMapItemControllerUpdater::updateItemProperty(msg, ctrl))
0116         return true;
0117 
0118     msg->resetToPos(datapos);
0119 
0120     updatingCtrl= ctrl;
0121 
0122     auto property= msg->string16();
0123 
0124     qDebug() << "property" << property;
0125 
0126     QVariant var;
0127 
0128     if(property == properties::side)
0129     {
0130         var= QVariant::fromValue(msg->real());
0131     }
0132     else if(property == properties::stateColor)
0133     {
0134         var= QVariant::fromValue(QColor(msg->rgb()));
0135     }
0136     else if(property == properties::number)
0137     {
0138         var= QVariant::fromValue(msg->uint64());
0139     }
0140     else if(property == properties::playableCharacter)
0141     {
0142         var= QVariant::fromValue(msg->uint8());
0143     }
0144     else if(property == properties::thumnailRect)
0145     {
0146         auto x= msg->real();
0147         auto y= msg->real();
0148         auto w= msg->real();
0149         auto h= msg->real();
0150         var= QVariant::fromValue(QRectF(x, y, w, h));
0151     }
0152     else if(property == properties::visionShape)
0153     {
0154         var= QVariant::fromValue(static_cast<CharacterVision::SHAPE>(msg->uint8()));
0155     }
0156     else if(property == properties::font)
0157     {
0158         auto str= msg->string8();
0159         var= QVariant::fromValue(QFont(str));
0160     }
0161     else
0162     {
0163         return false;
0164     }
0165 
0166     m_updatingFromNetwork= true;
0167     auto feedback= ctrl->setProperty(property.toLocal8Bit().data(), var);
0168     m_updatingFromNetwork= false;
0169     updatingCtrl= nullptr;
0170 
0171     return feedback;
0172 }
0173 
0174 bool CharacterItemUpdater::updateVisionProperty(NetworkMessageReader* msg, vmap::VisualItemController* ctrl)
0175 {
0176     if(nullptr == msg || nullptr == ctrl)
0177         return false;
0178 
0179     auto itemCtrl= dynamic_cast<vmap::CharacterItemController*>(ctrl);
0180 
0181     if(nullptr == itemCtrl)
0182         return false;
0183 
0184     auto vision= itemCtrl->vision();
0185 
0186     if(nullptr == vision)
0187         return false;
0188 
0189     auto property= msg->string16();
0190 
0191     QVariant var;
0192 
0193     if(property == properties::vision_radius)
0194     {
0195         var= QVariant::fromValue(msg->real());
0196     }
0197     else if(property == properties::vision_angle)
0198     {
0199         var= QVariant::fromValue(msg->real());
0200     }
0201     else if(property == properties::vision_rotation)
0202     {
0203         var= QVariant::fromValue(msg->real());
0204     }
0205     else if(property == properties::vision_position)
0206     {
0207         auto x= msg->real();
0208         auto y= msg->real();
0209         var= QVariant::fromValue(QPointF{x, y});
0210     }
0211     else if(property == properties::vision_removed)
0212     {
0213         var= QVariant::fromValue(static_cast<bool>(msg->uint8()));
0214     }
0215     else if(property == properties::vision_path)
0216     {
0217         auto data= msg->byteArray32();
0218         {
0219             QDataStream read(&data, QIODevice::ReadOnly);
0220             QPainterPath path;
0221             read >> path;
0222             var= QVariant::fromValue(path);
0223         }
0224     }
0225     else
0226     {
0227         return false;
0228     }
0229 
0230     m_updatingFromNetwork= true;
0231     auto feedback= vision->setProperty(property.toLocal8Bit().data(), var);
0232     m_updatingFromNetwork= false;
0233     updatingCtrl= nullptr;
0234 
0235     return feedback;
0236 }