Skip to content

Commit b399119

Browse files
authored
feat(view): Add ability to rotate the camera in 45 degree increments using the mouse (#1848)
The view can be rotated in 45 degree increments by holding the CTRL modifier key while pressing the middle mouse button and moving the cursor
1 parent 2677c39 commit b399119

File tree

4 files changed

+24
-4
lines changed

4 files changed

+24
-4
lines changed

Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class LookAtTranslator : public GameMessageTranslator
7171
ICoord2D m_anchor;
7272
ICoord2D m_originalAnchor;
7373
ICoord2D m_currentPos;
74+
Real m_anchorAngle;
7475
Bool m_isScrolling; // set to true if we are in the act of RMB scrolling
7576
Bool m_isRotating; // set to true if we are in the act of MMB rotating
7677
Bool m_isPitching; // set to true if we are in the act of ALT pitch rotation

Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
291291

292292
m_isRotating = true;
293293
m_anchor = msg->getArgument( 0 )->pixel;
294+
m_anchorAngle = TheTacticalView->getAngle();
294295
m_originalAnchor = msg->getArgument( 0 )->pixel;
295296
m_currentPos = msg->getArgument( 0 )->pixel;
296297
m_timestamp = TheGameClient->getFrame();
@@ -360,10 +361,18 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
360361
if (m_isRotating)
361362
{
362363
const Real FACTOR = 0.01f;
364+
const Real angle = FACTOR * (m_currentPos.x - m_originalAnchor.x);
365+
Real targetAngle = m_anchorAngle + angle;
363366

364-
Real angle = FACTOR * (m_currentPos.x - m_anchor.x);
367+
// TheSuperHackers @tweak Stubbjax 13/11/2025 Snap angle to nearest 45 degrees
368+
// while using force attack mode for convenience.
369+
if (TheInGameUI->isInForceAttackMode())
370+
{
371+
const Real snapRadians = DEG_TO_RADF(45);
372+
targetAngle = WWMath::Round(targetAngle / snapRadians) * snapRadians;
373+
}
365374

366-
TheTacticalView->setAngle( TheTacticalView->getAngle() + angle );
375+
TheTacticalView->setAngle(targetAngle);
367376
m_anchor = msg->getArgument( 0 )->pixel;
368377
}
369378

GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class LookAtTranslator : public GameMessageTranslator
7171
ICoord2D m_anchor;
7272
ICoord2D m_originalAnchor;
7373
ICoord2D m_currentPos;
74+
Real m_anchorAngle;
7475
Bool m_isScrolling; // set to true if we are in the act of RMB scrolling
7576
Bool m_isRotating; // set to true if we are in the act of MMB rotating
7677
Bool m_isPitching; // set to true if we are in the act of ALT pitch rotation

GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
290290

291291
m_isRotating = true;
292292
m_anchor = msg->getArgument( 0 )->pixel;
293+
m_anchorAngle = TheTacticalView->getAngle();
293294
m_originalAnchor = msg->getArgument( 0 )->pixel;
294295
m_currentPos = msg->getArgument( 0 )->pixel;
295296
m_timestamp = TheGameClient->getFrame();
@@ -359,10 +360,18 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
359360
if (m_isRotating)
360361
{
361362
const Real FACTOR = 0.01f;
363+
const Real angle = FACTOR * (m_currentPos.x - m_originalAnchor.x);
364+
Real targetAngle = m_anchorAngle + angle;
362365

363-
Real angle = FACTOR * (m_currentPos.x - m_anchor.x);
366+
// TheSuperHackers @tweak Stubbjax 13/11/2025 Snap angle to nearest 45 degrees
367+
// while using force attack mode for convenience.
368+
if (TheInGameUI->isInForceAttackMode())
369+
{
370+
const Real snapRadians = DEG_TO_RADF(45);
371+
targetAngle = WWMath::Round(targetAngle / snapRadians) * snapRadians;
372+
}
364373

365-
TheTacticalView->setAngle( TheTacticalView->getAngle() + angle );
374+
TheTacticalView->setAngle(targetAngle);
366375
m_anchor = msg->getArgument( 0 )->pixel;
367376
}
368377

0 commit comments

Comments
 (0)