mudlet/src/CustomLineSession.cpp
Vadim Peretokin b6738dd8c2
infrastructure: Apply clang-format to all CPP files (#8804)
#### 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.
2026-01-19 18:10:44 +01:00

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;
}