mirror of
https://github.com/Mudlet/Mudlet
synced 2026-08-13 18:26:27 -04:00
#### Brief overview of PR changes/additions Ran clang-format on all 134 CPP files in src/ using the project's .clang-format config #### Motivation for adding to Mudlet Ensures consistent code formatting across the codebase. #### Other info (issues closed, discussion etc) None **Test case:** Build the project and verify it compiles successfully.
321 lines
9 KiB
C++
321 lines
9 KiB
C++
/***************************************************************************
|
|
* Copyright (C) 2025 by Piotr Wilczynski - delwing@gmail.com *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
|
|
#include "CustomLineSession.h"
|
|
|
|
#include "T2DMap.h"
|
|
#include "TMap.h"
|
|
#include "TRoom.h"
|
|
#include "TRoomDB.h"
|
|
|
|
#include <cmath>
|
|
|
|
CustomLineSession::CustomLineSession(T2DMap& mapWidget)
|
|
: mMapWidget(mapWidget)
|
|
{
|
|
}
|
|
|
|
bool CustomLineSession::isSnapToGridEnabled() const
|
|
{
|
|
return mSnapToGridEnabled;
|
|
}
|
|
|
|
void CustomLineSession::setSnapToGridEnabled(bool enabled)
|
|
{
|
|
if (mSnapToGridEnabled == enabled) {
|
|
return;
|
|
}
|
|
|
|
if (enabled) {
|
|
restoreOriginalLineIfNeeded();
|
|
const auto key = currentLineKey();
|
|
if (!key) {
|
|
mSnapToGridEnabled = enabled;
|
|
return;
|
|
}
|
|
|
|
TRoom* room = nullptr;
|
|
QList<QPointF>* points = resolveLinePoints(*key, room);
|
|
if (!points || !room) {
|
|
mSnapToGridEnabled = enabled;
|
|
return;
|
|
}
|
|
|
|
rememberOriginalLine(*key, *points);
|
|
snapLineToGrid(*key, *points, *room);
|
|
} else {
|
|
restoreOriginalLineIfNeeded();
|
|
mSnapToGridEnabled = enabled;
|
|
if (mMapWidget.mpMap) {
|
|
mMapWidget.repaint();
|
|
}
|
|
mOriginalLine.reset();
|
|
return;
|
|
}
|
|
|
|
mSnapToGridEnabled = enabled;
|
|
}
|
|
|
|
QPointF CustomLineSession::snapPointToGrid(const QPointF& point) const
|
|
{
|
|
constexpr qreal snapIncrement = 0.5;
|
|
const qreal snappedX = std::round(point.x() / snapIncrement) * snapIncrement;
|
|
const qreal snappedY = std::round(point.y() / snapIncrement) * snapIncrement;
|
|
return QPointF(snappedX, snappedY);
|
|
}
|
|
|
|
bool CustomLineSession::canMoveSelectedCustomLineLastPointToTargetRoom() const
|
|
{
|
|
if (!mMapWidget.mpMap || !mMapWidget.mpMap->mpRoomDB) {
|
|
return false;
|
|
}
|
|
|
|
if (mMapWidget.mCustomLineSelectedRoom <= 0 || mMapWidget.mCustomLineSelectedExit.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
TRoom* room = mMapWidget.mpMap->mpRoomDB->getRoom(mMapWidget.mCustomLineSelectedRoom);
|
|
if (!room) {
|
|
return false;
|
|
}
|
|
|
|
return canMoveCustomLineLastPointToTargetRoom(*room, mMapWidget.mCustomLineSelectedExit);
|
|
}
|
|
|
|
bool CustomLineSession::canMoveCustomLineLastPointToTargetRoom(const TRoom& room, const QString& exitKey) const
|
|
{
|
|
if (!mMapWidget.mpMap || !mMapWidget.mpMap->mpRoomDB) {
|
|
return false;
|
|
}
|
|
|
|
const auto itLine = room.customLines.constFind(exitKey);
|
|
if (itLine == room.customLines.constEnd()) {
|
|
return false;
|
|
}
|
|
|
|
const QList<QPointF>& points = itLine.value();
|
|
if (points.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
const auto targetRoomId = resolveCustomLineTargetRoomId(room, exitKey);
|
|
if (!targetRoomId || *targetRoomId <= 0) {
|
|
return false;
|
|
}
|
|
|
|
return mMapWidget.mpMap->mpRoomDB->getRoom(*targetRoomId) != nullptr;
|
|
}
|
|
|
|
void CustomLineSession::moveCustomLineLastPointToTargetRoom()
|
|
{
|
|
if (!mMapWidget.mpMap || !mMapWidget.mpMap->mpRoomDB) {
|
|
return;
|
|
}
|
|
|
|
const auto key = currentLineKey();
|
|
if (!key) {
|
|
return;
|
|
}
|
|
|
|
TRoom* room = nullptr;
|
|
QList<QPointF>* points = resolveLinePoints(*key, room);
|
|
if (!points || !room || points->isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
const auto targetRoomId = resolveCustomLineTargetRoomId(*room, key->exitKey);
|
|
if (!targetRoomId || *targetRoomId <= 0) {
|
|
return;
|
|
}
|
|
|
|
TRoom* targetRoom = mMapWidget.mpMap->mpRoomDB->getRoom(*targetRoomId);
|
|
if (!targetRoom) {
|
|
return;
|
|
}
|
|
|
|
QPointF newPoint(targetRoom->x(), targetRoom->y());
|
|
if (mSnapToGridEnabled) {
|
|
newPoint = snapPointToGrid(newPoint);
|
|
}
|
|
|
|
QPointF& lastPoint = points->last();
|
|
if (qFuzzyIsNull(lastPoint.x() - newPoint.x()) && qFuzzyIsNull(lastPoint.y() - newPoint.y())) {
|
|
return;
|
|
}
|
|
|
|
lastPoint = newPoint;
|
|
room->calcRoomDimensions();
|
|
mMapWidget.repaint();
|
|
if (mMapWidget.mpMap) {
|
|
mMapWidget.mpMap->setUnsaved(__func__);
|
|
}
|
|
}
|
|
|
|
void CustomLineSession::clearOriginalPoints()
|
|
{
|
|
mOriginalLine.reset();
|
|
}
|
|
|
|
std::optional<CustomLineSession::LineKey> CustomLineSession::currentLineKey() const
|
|
{
|
|
if (mMapWidget.mCustomLineSelectedRoom > 0 && !mMapWidget.mCustomLineSelectedExit.isEmpty()) {
|
|
return LineKey{mMapWidget.mCustomLineSelectedRoom, mMapWidget.mCustomLineSelectedExit};
|
|
}
|
|
|
|
if (mMapWidget.mCustomLinesRoomFrom > 0 && !mMapWidget.mCustomLinesRoomExit.isEmpty()) {
|
|
return LineKey{mMapWidget.mCustomLinesRoomFrom, mMapWidget.mCustomLinesRoomExit};
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
|
|
QList<QPointF>* CustomLineSession::resolveLinePoints(const LineKey& key, TRoom*& room) const
|
|
{
|
|
if (!key.isValid() || !mMapWidget.mpMap || !mMapWidget.mpMap->mpRoomDB) {
|
|
return nullptr;
|
|
}
|
|
|
|
room = mMapWidget.mpMap->mpRoomDB->getRoom(key.roomId);
|
|
if (!room) {
|
|
return nullptr;
|
|
}
|
|
|
|
auto itLine = room->customLines.find(key.exitKey);
|
|
if (itLine == room->customLines.end()) {
|
|
return nullptr;
|
|
}
|
|
|
|
return &itLine.value();
|
|
}
|
|
|
|
void CustomLineSession::rememberOriginalLine(const LineKey& key, const QList<QPointF>& points)
|
|
{
|
|
if (!key.isValid()) {
|
|
mOriginalLine.reset();
|
|
return;
|
|
}
|
|
|
|
mOriginalLine = OriginalLine{key, points};
|
|
}
|
|
|
|
void CustomLineSession::snapLineToGrid(LineKey key, QList<QPointF>& points, TRoom& room)
|
|
{
|
|
if (!key.isValid()) {
|
|
return;
|
|
}
|
|
|
|
bool changed = false;
|
|
for (QPointF& point : points) {
|
|
const QPointF snapped = snapPointToGrid(point);
|
|
if (!qFuzzyIsNull(point.x() - snapped.x()) || !qFuzzyIsNull(point.y() - snapped.y())) {
|
|
point = snapped;
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
if (changed) {
|
|
room.calcRoomDimensions();
|
|
mMapWidget.repaint();
|
|
if (mMapWidget.mpMap) {
|
|
mMapWidget.mpMap->setUnsaved(__func__);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CustomLineSession::restoreOriginalLineIfNeeded()
|
|
{
|
|
if (!mOriginalLine) {
|
|
return;
|
|
}
|
|
|
|
const auto key = currentLineKey();
|
|
if (!key || !(mOriginalLine->key == *key)) {
|
|
mOriginalLine.reset();
|
|
return;
|
|
}
|
|
|
|
TRoom* room = nullptr;
|
|
QList<QPointF>* points = resolveLinePoints(mOriginalLine->key, room);
|
|
if (!points || !room) {
|
|
mOriginalLine.reset();
|
|
return;
|
|
}
|
|
|
|
if (*points == mOriginalLine->points) {
|
|
mOriginalLine.reset();
|
|
return;
|
|
}
|
|
|
|
*points = mOriginalLine->points;
|
|
room->calcRoomDimensions();
|
|
mMapWidget.repaint();
|
|
if (mMapWidget.mpMap) {
|
|
mMapWidget.mpMap->setUnsaved(__func__);
|
|
}
|
|
|
|
mOriginalLine.reset();
|
|
}
|
|
|
|
std::optional<int> CustomLineSession::resolveCustomLineTargetRoomId(const TRoom& room, const QString& exitKey) const
|
|
{
|
|
if (exitKey == QLatin1String("nw")) {
|
|
return room.getNorthwest();
|
|
}
|
|
if (exitKey == QLatin1String("n")) {
|
|
return room.getNorth();
|
|
}
|
|
if (exitKey == QLatin1String("ne")) {
|
|
return room.getNortheast();
|
|
}
|
|
if (exitKey == QLatin1String("up")) {
|
|
return room.getUp();
|
|
}
|
|
if (exitKey == QLatin1String("w")) {
|
|
return room.getWest();
|
|
}
|
|
if (exitKey == QLatin1String("e")) {
|
|
return room.getEast();
|
|
}
|
|
if (exitKey == QLatin1String("down")) {
|
|
return room.getDown();
|
|
}
|
|
if (exitKey == QLatin1String("sw")) {
|
|
return room.getSouthwest();
|
|
}
|
|
if (exitKey == QLatin1String("s")) {
|
|
return room.getSouth();
|
|
}
|
|
if (exitKey == QLatin1String("se")) {
|
|
return room.getSoutheast();
|
|
}
|
|
if (exitKey == QLatin1String("in")) {
|
|
return room.getIn();
|
|
}
|
|
if (exitKey == QLatin1String("out")) {
|
|
return room.getOut();
|
|
}
|
|
|
|
const auto& specialExits = room.getSpecialExits();
|
|
const auto itSpecial = specialExits.constFind(exitKey);
|
|
if (itSpecial != specialExits.constEnd()) {
|
|
return itSpecial.value();
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|