File indexing completed on 2024-04-28 05:38:12

0001 /***************************************************************************
0002  *   Copyright (C) 2015 by Renaud Guezennec                                *
0003  *   https://rolisteam.org/contact                   *
0004  *                                                                         *
0005  *   rolisteam 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 
0021 #include "sightitem.h"
0022 
0023 #include <QDebug>
0024 #include <QGraphicsObject>
0025 #include <QGraphicsScene>
0026 #include <QGraphicsView>
0027 #include <QMenu>
0028 #include <QPainter>
0029 #include <QStyleOptionGraphicsItem>
0030 #include <QTransform>
0031 #include <math.h>
0032 
0033 #include "controller/item_controllers/sightcontroller.h"
0034 #include "controller/view_controller/vectorialmapcontroller.h"
0035 #include "model/playermodel.h"
0036 
0037 #include "data/character.h"
0038 
0039 #define PI 3.14159265
0040 
0041 /////////////////////////////////
0042 /// Code SightItem
0043 /////////////////////////////////
0044 
0045 SightItem::SightItem(vmap::SightController* ctrl) : VisualItem(ctrl), m_sightCtrl(ctrl)
0046 {
0047     setZValue(std::numeric_limits<qreal>::max());
0048     auto updateFunc= [this]() { update(); };
0049     connect(m_sightCtrl, &vmap::SightController::visibleChanged, this,
0050             [this]() { setVisible(m_sightCtrl->visible()); });
0051     connect(m_sightCtrl, &vmap::SightController::colorChanged, this, updateFunc);
0052     connect(m_sightCtrl, &vmap::SightController::fowPathChanged, this, updateFunc);
0053     connect(m_sightCtrl, &vmap::SightController::rectChanged, this, updateFunc);
0054     connect(m_sightCtrl, &vmap::SightController::characterSightChanged, this, updateFunc);
0055     connect(m_sightCtrl, &vmap::SightController::requiredUpdate, this, updateFunc);
0056     connect(m_sightCtrl, &vmap::SightController::characterCountChanged, this, updateFunc);
0057 
0058     setFlag(QGraphicsItem::ItemUsesExtendedStyleOption);
0059     setAcceptedMouseButtons(Qt::NoButton);
0060     if(m_ctrl)
0061         m_ctrl->setLayer(Core::Layer::FOG);
0062     setFlags(QGraphicsItem::ItemSendsGeometryChanges);
0063 
0064     connect(this, &QGraphicsObject::parentChanged, this,
0065             [this]()
0066             {
0067                 connect(scene(), &QGraphicsScene::sceneRectChanged, m_sightCtrl, &vmap::SightController::setRect);
0068                 m_sightCtrl->setRect(scene()->sceneRect());
0069             });
0070 }
0071 
0072 SightItem::~SightItem() {}
0073 void SightItem::updateItemFlags()
0074 {
0075     VisualItem::updateItemFlags();
0076     setAcceptedMouseButtons(Qt::NoButton);
0077     setFlag(QGraphicsItem::ItemIsMovable, false);
0078 }
0079 
0080 QRectF SightItem::boundingRect() const
0081 {
0082     if(m_sightCtrl)
0083         return m_sightCtrl->rect();
0084     else
0085         return {};
0086 }
0087 void SightItem::setNewEnd(const QPointF& nend)
0088 {
0089     Q_UNUSED(nend)
0090     return;
0091 }
0092 
0093 void SightItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
0094 {
0095     Q_UNUSED(option)
0096     Q_UNUSED(widget)
0097     painter->save();
0098     painter->setPen(Qt::NoPen);
0099     m_sightCtrl->localIsGM() ? painter->setBrush(QColor(0, 0, 0, 125)) : painter->setBrush(QColor(0, 0, 0));
0100 
0101     QPainterPath path= m_sightCtrl->fowPath();
0102 
0103     if(m_sightCtrl->characterSight())
0104     {
0105         auto visions= m_sightCtrl->visionData();
0106         for(auto& vision : visions)
0107         {
0108             if(vision->removed())
0109                 continue;
0110 
0111             QPainterPath subArea;
0112             subArea.setFillRule(Qt::WindingFill);
0113             auto itemRadius= vision->radius();
0114             qreal rot= vision->rotation();
0115             QTransform trans;
0116             QPointF center= vision->position(); // + QPointF(itemRadius, itemRadius);
0117             trans.translate(center.x(), center.y());
0118             trans.rotate(rot);
0119 
0120             auto side = vision->side()/2;
0121             QPainterPath token;
0122             token.addRect(QRectF{0,0,side*2,side*2});
0123             path= path.subtracted(
0124                 trans.map(token.translated(-side,-side))); // always see the user
0125             switch(vision->shape())
0126             {
0127             case CharacterVision::DISK:
0128                 subArea.addEllipse(QPointF(0, 0), vision->radius() + itemRadius, vision->radius() + itemRadius);
0129                 break;
0130             case CharacterVision::ANGLE:
0131             {
0132                 QRectF rectArc;
0133                 rectArc.setCoords(-vision->radius(), -vision->radius(), vision->radius(), vision->radius());
0134                 subArea.arcTo(rectArc, -vision->angle() / 2, vision->angle());
0135             }
0136             break;
0137             }
0138             path.moveTo(vision->position());
0139             path= path.subtracted(trans.map(subArea));
0140         }
0141     }
0142 
0143     painter->drawPath(path);
0144     painter->restore();
0145 }
0146 
0147 void SightItem::moveVision(qreal id, QPointF& pos)
0148 {
0149     Q_UNUSED(id)
0150     Q_UNUSED(pos)
0151     /*if(m_visionMap.contains(id))
0152     {
0153         m_visionMap.value(id)->setRadius(pos.x());
0154     }*/
0155 }