Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,12 @@
#include "GameClient/GameWindow.h"
#include "GameClient/GameWindowManager.h"
#include "GameClient/InGameUI.h"
#include "GameClient/Keyboard.h"
#include "GameClient/AnimateWindowManager.h"

// TheSuperHackers @feature How many units a shift click queues or cancels at once.
static const Int SHIFT_CLICK_BATCH_SIZE = 5;

#include "GameLogic/GameLogic.h"
#include "GameLogic/Object.h"
#include "GameLogic/Module/ProductionUpdate.h"
Expand Down Expand Up @@ -440,14 +444,28 @@ CBCommandStatus ControlBar::processCommandUI( GameWindow *control,

}

// get a new production id to assign to this
ProductionID productionID = pu->requestUniqueUnitID();
// TheSuperHackers @feature Shift queues a batch instead of a single unit.
Int unitsToQueue = 1;
if( TheKeyboard && TheKeyboard->isShift() )
unitsToQueue = SHIFT_CLICK_BATCH_SIZE;

for( Int queued = 0; queued < unitsToQueue; ++queued )
{
// Re-check every time round. canMakeUnit covers money, queue space, parking and
// per player unit caps, and each unit we just queued moves those. Stop quietly
// once we can no longer build -- the first unit already reported any problem.
if( queued > 0 && TheBuildAssistant->canMakeUnit( factory, whatToBuild ) != CANMAKE_OK )
break;

// get a new production id to assign to this
ProductionID productionID = pu->requestUniqueUnitID();

// create a message to build this thing
// create a message to build this thing

GameMessage *msg = TheMessageStream->appendMessage( GameMessage::MSG_QUEUE_UNIT_CREATE );
msg->appendIntegerArgument( whatToBuild->getTemplateID() );
msg->appendIntegerArgument( productionID );
GameMessage *msg = TheMessageStream->appendMessage( GameMessage::MSG_QUEUE_UNIT_CREATE );
msg->appendIntegerArgument( whatToBuild->getTemplateID() );
msg->appendIntegerArgument( productionID );
}

break;

Expand Down Expand Up @@ -492,6 +510,29 @@ CBCommandStatus ControlBar::processCommandUI( GameWindow *control,
GameMessage *msg = TheMessageStream->appendMessage( GameMessage::MSG_CANCEL_UNIT_CREATE );
msg->appendIntegerArgument( productionIDToCancel );

// TheSuperHackers @feature Shift cancels a batch: the clicked entry plus the newest
// queued units. The queue is displayed oldest to newest, so the extra cancels walk
// from the tail towards the clicked slot - taking the most recently queued entries
// first and leaving whatever is closest to completion alone for as long as
// possible. Deliberately not filtered by template: the point of the batch is to
// clear what was just queued, whatever it was. Only unit entries are taken, so an
// upgrade sitting in the queue is never swept up.
if( TheKeyboard && TheKeyboard->isShift() )
{
Int cancelled = 1;
for( Int j = MAX_BUILD_QUEUE_BUTTONS - 1; j > i && cancelled < SHIFT_CLICK_BATCH_SIZE; --j )
{
if( m_queueData[ j ].control == nullptr )
continue;
if( m_queueData[ j ].type != PRODUCTION_UNIT )
continue;
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
Comment on lines +526 to +528

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Cancellation conflates unit templates

When later queue slots contain different unit templates, this loop treats every PRODUCTION_UNIT as a copy of the clicked unit and cancels it by production ID, causing Shift-click to remove and refund up to four unrelated queued units.

Prompt To Fix With AI
This is a comment left during a code review.
Path: Core/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarCommandProcessing.cpp
Line: 523-525

Comment:
**Cancellation conflates unit templates**

When later queue slots contain different unit templates, this loop treats every `PRODUCTION_UNIT` as a copy of the clicked unit and cancels it by production ID, causing Shift-click to remove and refund up to four unrelated queued units.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deliberate, and now stated in the code (b2b70ca): the batch is positional, not per template - its point is to clear what was just queued, whatever it was, the same way five individual clicks on the tail would. The PRODUCTION_UNIT check exists to keep an upgrade entry from being swept up, not to filter templates. The suggested template comparison is intentionally not taken.


msg = TheMessageStream->appendMessage( GameMessage::MSG_CANCEL_UNIT_CREATE );
msg->appendIntegerArgument( m_queueData[ j ].productionID );
++cancelled;
}
}

break;

}
Expand Down