From 9d2cf84613dced47dc9a72049e42a90f4a8597cb Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Mon, 17 Nov 2025 16:16:41 +1100 Subject: [PATCH 01/11] bugfix: Builders now resume their task after having been disabled --- .../Include/GameLogic/Module/DozerAIUpdate.h | 4 ++++ .../Include/GameLogic/Module/WorkerAIUpdate.h | 3 +++ .../Object/Update/AIUpdate/DozerAIUpdate.cpp | 12 ++++++++++++ .../Object/Update/AIUpdate/WorkerAIUpdate.cpp | 12 ++++++++++++ .../Include/GameLogic/Module/DozerAIUpdate.h | 4 ++++ .../Include/GameLogic/Module/WorkerAIUpdate.h | 3 +++ .../Source/GameLogic/Object/Object.cpp | 17 +++++++++++++---- .../Object/Update/AIUpdate/DozerAIUpdate.cpp | 12 ++++++++++++ .../Object/Update/AIUpdate/WorkerAIUpdate.cpp | 12 ++++++++++++ 9 files changed, 75 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h index 63b325b5818..ae082376d09 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h @@ -140,6 +140,7 @@ class DozerAIInterface // task actions virtual void newTask( DozerTask task, Object *target ) = 0; ///< set a desire to do the requrested task virtual void cancelTask( DozerTask task ) = 0; ///< cancel this task from the queue, if it's the current task the dozer will stop working on it + virtual void resumePreviousTask(void) = 0; ///< resume the previous task if there was one // internal methods to manage behavior from within the dozer state machine virtual void internalTaskComplete( DozerTask task ) = 0; ///< set a dozer task as successfully completed @@ -239,6 +240,7 @@ class DozerAIUpdate : public AIUpdateInterface, public DozerAIInterface // task actions virtual void newTask( DozerTask task, Object *target ); ///< set a desire to do the requrested task virtual void cancelTask( DozerTask task ); ///< cancel this task from the queue, if it's the current task the dozer will stop working on it + virtual void resumePreviousTask(void); ///< resume the previous task if there was one // internal methods to manage behavior from within the dozer state machine virtual void internalTaskComplete( DozerTask task ); ///< set a dozer task as successfully completed @@ -282,6 +284,8 @@ class DozerAIUpdate : public AIUpdateInterface, public DozerAIInterface DozerPrimaryStateMachine *m_dozerMachine; ///< the custom state machine for Dozer behavior DozerTask m_currentTask; ///< current task the dozer is attending to (if any) + DozerTask m_previousTask; ///< previous task the dozer was attending to (if any) + DozerTaskInfo m_previousTaskInfo; ///< info on the previous task the dozer was attending to (if any) AudioEventRTS m_buildingSound; ///< sound is pulled from the object we are building! Bool m_isRebuild; ///< is this a rebuild of a previous building? diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h index 67f2f9e4a9c..be8f515b916 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h @@ -155,6 +155,7 @@ class WorkerAIUpdate : public AIUpdateInterface, public DozerAIInterface, public // task actions virtual void newTask( DozerTask task, Object* target ); ///< set a desire to do the requrested task virtual void cancelTask( DozerTask task ); ///< cancel this task from the queue, if it's the current task the dozer will stop working on it + virtual void resumePreviousTask(void); ///< resume the previous task if there was one // internal methods to manage behavior from within the dozer state machine virtual void internalTaskComplete( DozerTask task ); ///< set a dozer task as successfully completed @@ -218,6 +219,8 @@ class WorkerAIUpdate : public AIUpdateInterface, public DozerAIInterface, public DozerTask m_currentTask; ///< current task the dozer is attending to (if any) + DozerTask m_previousTask; ///< previous task the dozer was attending to (if any) + DozerTaskInfo m_previousTaskInfo; ///< info on the previous task the dozer was attending to (if any) // // the following info array can be used if we want to have more complicated approaches diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index f422f22de08..9bc0ca90c2d 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2040,6 +2040,15 @@ void DozerAIUpdate::cancelTask( DozerTask task ) } +//------------------------------------------------------------------------------------------------- +/** Attempt to resume the previous task */ +//------------------------------------------------------------------------------------------------- +void DozerAIUpdate::resumePreviousTask(void) +{ + if (m_previousTask != DOZER_TASK_INVALID) + newTask(m_previousTask, TheGameLogic->findObjectByID(m_previousTaskInfo.m_targetObjectID)); +} + //------------------------------------------------------------------------------------------------- /** Is there a given task waiting to be done */ //------------------------------------------------------------------------------------------------- @@ -2118,6 +2127,9 @@ void DozerAIUpdate::internalCancelTask( DozerTask task ) // call the single method that gets called for completing and canceling tasks internalTaskCompleteOrCancelled( task ); + m_previousTask = task; + m_previousTaskInfo = m_task[task]; + // remove the info for this task m_task[ task ].m_targetObjectID = INVALID_ID; m_task[ task ].m_taskOrderFrame = 0; diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index bd67b782cd2..28749b1bd53 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -695,6 +695,15 @@ void WorkerAIUpdate::cancelTask( DozerTask task ) } +//------------------------------------------------------------------------------------------------- +/** Attempt to resume the previous task */ +//------------------------------------------------------------------------------------------------- +void WorkerAIUpdate::resumePreviousTask(void) +{ + if (m_previousTask != DOZER_TASK_INVALID) + newTask(m_previousTask, TheGameLogic->findObjectByID(m_previousTaskInfo.m_targetObjectID)); +} + //------------------------------------------------------------------------------------------------- /** Is there a given task waiting to be done */ //------------------------------------------------------------------------------------------------- @@ -773,6 +782,9 @@ void WorkerAIUpdate::internalCancelTask( DozerTask task ) // call the single method that gets called for completing and canceling tasks internalTaskCompleteOrCancelled( task ); + m_previousTask = task; + m_previousTaskInfo = m_task[task]; + // remove the info for this task m_task[ task ].m_targetObjectID = INVALID_ID; m_task[ task ].m_taskOrderFrame = 0; diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h index dbf4e87eee8..98aac1ab07c 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h @@ -140,6 +140,7 @@ class DozerAIInterface // task actions virtual void newTask( DozerTask task, Object *target ) = 0; ///< set a desire to do the requested task virtual void cancelTask( DozerTask task ) = 0; ///< cancel this task from the queue, if it's the current task the dozer will stop working on it + virtual void resumePreviousTask(void) = 0; ///< resume the previous task if there was one // internal methods to manage behavior from within the dozer state machine virtual void internalTaskComplete( DozerTask task ) = 0; ///< set a dozer task as successfully completed @@ -239,6 +240,7 @@ class DozerAIUpdate : public AIUpdateInterface, public DozerAIInterface // task actions virtual void newTask( DozerTask task, Object *target ); ///< set a desire to do the requested task virtual void cancelTask( DozerTask task ); ///< cancel this task from the queue, if it's the current task the dozer will stop working on it + virtual void resumePreviousTask(void); ///< resume the previous task if there was one // internal methods to manage behavior from within the dozer state machine virtual void internalTaskComplete( DozerTask task ); ///< set a dozer task as successfully completed @@ -282,6 +284,8 @@ class DozerAIUpdate : public AIUpdateInterface, public DozerAIInterface DozerPrimaryStateMachine *m_dozerMachine; ///< the custom state machine for Dozer behavior DozerTask m_currentTask; ///< current task the dozer is attending to (if any) + DozerTask m_previousTask; ///< previous task the dozer was attending to (if any) + DozerTaskInfo m_previousTaskInfo; ///< info on the previous task the dozer was attending to (if any) AudioEventRTS m_buildingSound; ///< sound is pulled from the object we are building! Bool m_isRebuild; ///< is this a rebuild of a previous building? diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h index 793843bff40..266ef50496f 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h @@ -158,6 +158,7 @@ class WorkerAIUpdate : public AIUpdateInterface, public DozerAIInterface, public // task actions virtual void newTask( DozerTask task, Object* target ); ///< set a desire to do the requested task virtual void cancelTask( DozerTask task ); ///< cancel this task from the queue, if it's the current task the dozer will stop working on it + virtual void resumePreviousTask(void); ///< resume the previous task if there was one // internal methods to manage behavior from within the dozer state machine virtual void internalTaskComplete( DozerTask task ); ///< set a dozer task as successfully completed @@ -223,6 +224,8 @@ class WorkerAIUpdate : public AIUpdateInterface, public DozerAIInterface, public DozerTask m_currentTask; ///< current task the dozer is attending to (if any) + DozerTask m_previousTask; ///< previous task the dozer was attending to (if any) + DozerTaskInfo m_previousTaskInfo; ///< info on the previous task the dozer was attending to (if any) // // the following info array can be used if we want to have more complicated approaches diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp index e11db7d4c53..e61f346b052 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp @@ -3853,11 +3853,20 @@ void Object::onDisabledEdge(Bool becomingDisabled) (*module)->onDisabledEdge( becomingDisabled ); DozerAIInterface *dozerAI = getAI() ? getAI()->getDozerAIInterface() : nullptr; - if( becomingDisabled && dozerAI ) + if (dozerAI) { - // Have to say goodbye to the thing we might be building or repairing so someone else can do it. - if( dozerAI->getCurrentTask() != DOZER_TASK_INVALID ) - dozerAI->cancelTask( dozerAI->getCurrentTask() ); + if (becomingDisabled) + { + // Have to say goodbye to the thing we might be building or repairing so someone else can do it. + if (dozerAI->getCurrentTask() != DOZER_TASK_INVALID) + dozerAI->cancelTask(dozerAI->getCurrentTask()); + } + else + { +#if !RETAIL_COMPATIBLE_CRC + dozerAI->resumePreviousTask(); +#endif + } } Player* controller = getControllingPlayer(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 9b723e932ef..e463d634977 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2045,6 +2045,15 @@ void DozerAIUpdate::cancelTask( DozerTask task ) } +//------------------------------------------------------------------------------------------------- +/** Attempt to resume the previous task */ +//------------------------------------------------------------------------------------------------- +void DozerAIUpdate::resumePreviousTask(void) +{ + if (m_previousTask != DOZER_TASK_INVALID) + newTask(m_previousTask, TheGameLogic->findObjectByID(m_previousTaskInfo.m_targetObjectID)); +} + //------------------------------------------------------------------------------------------------- /** Is there a given task waiting to be done */ //------------------------------------------------------------------------------------------------- @@ -2123,6 +2132,9 @@ void DozerAIUpdate::internalCancelTask( DozerTask task ) // call the single method that gets called for completing and canceling tasks internalTaskCompleteOrCancelled( task ); + m_previousTask = task; + m_previousTaskInfo = m_task[task]; + // remove the info for this task m_task[ task ].m_targetObjectID = INVALID_ID; m_task[ task ].m_taskOrderFrame = 0; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 8e9a753daab..5d3154cd265 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -695,6 +695,15 @@ void WorkerAIUpdate::cancelTask( DozerTask task ) } +//------------------------------------------------------------------------------------------------- +/** Attempt to resume the previous task */ +//------------------------------------------------------------------------------------------------- +void WorkerAIUpdate::resumePreviousTask(void) +{ + if (m_previousTask != DOZER_TASK_INVALID) + newTask(m_previousTask, TheGameLogic->findObjectByID(m_previousTaskInfo.m_targetObjectID)); +} + //------------------------------------------------------------------------------------------------- /** Is there a given task waiting to be done */ //------------------------------------------------------------------------------------------------- @@ -773,6 +782,9 @@ void WorkerAIUpdate::internalCancelTask( DozerTask task ) // call the single method that gets called for completing and canceling tasks internalTaskCompleteOrCancelled( task ); + m_previousTask = task; + m_previousTaskInfo = m_task[task]; + // remove the info for this task m_task[ task ].m_targetObjectID = INVALID_ID; m_task[ task ].m_taskOrderFrame = 0; From f1ddadb543e6252f80b2bc22d9d3faa421df7cc5 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Mon, 17 Nov 2025 19:26:56 +1100 Subject: [PATCH 02/11] tweak: Add new data to the xfer logic --- .../Object/Update/AIUpdate/DozerAIUpdate.cpp | 12 +++++++++++- .../Object/Update/AIUpdate/WorkerAIUpdate.cpp | 12 +++++++++++- .../Object/Update/AIUpdate/DozerAIUpdate.cpp | 12 +++++++++++- .../Object/Update/AIUpdate/WorkerAIUpdate.cpp | 12 +++++++++++- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 9bc0ca90c2d..5af528377b5 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2453,7 +2453,11 @@ void DozerAIUpdate::crc( Xfer *xfer ) void DozerAIUpdate::xfer( Xfer *xfer ) { // version - XferVersion currentVersion = 1; +#if RETAIL_COMPATIBLE_XFER_SAVE + XferVersion currentVersion = 1; +#else + XferVersion currentVersion = 2; +#endif XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); @@ -2474,6 +2478,12 @@ void DozerAIUpdate::xfer( Xfer *xfer ) xfer->xferSnapshot(m_dozerMachine); xfer->xferUser(&m_currentTask, sizeof(m_currentTask)); + if (currentVersion >= 2) + { + xfer->xferUser(&m_previousTask, sizeof(m_previousTask)); + xfer->xferUser(&m_previousTaskInfo, sizeof(m_previousTaskInfo)); + } + Int dockPoints = DOZER_NUM_DOCK_POINTS; xfer->xferInt(&dockPoints); if (dockPoints!=DOZER_NUM_DOCK_POINTS) { diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 28749b1bd53..96606c6d953 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -1417,7 +1417,11 @@ void WorkerAIUpdate::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ void WorkerAIUpdate::xfer( Xfer *xfer ) { - XferVersion currentVersion = 1; +#if RETAIL_COMPATIBLE_XFER_SAVE + XferVersion currentVersion = 1; +#else + XferVersion currentVersion = 2; +#endif XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); @@ -1441,6 +1445,12 @@ void WorkerAIUpdate::xfer( Xfer *xfer ) xfer->xferSnapshot(m_dozerMachine); xfer->xferUser(&m_currentTask, sizeof(m_currentTask)); + if (currentVersion >= 2) + { + xfer->xferUser(&m_previousTask, sizeof(m_previousTask)); + xfer->xferUser(&m_previousTaskInfo, sizeof(m_previousTaskInfo)); + } + Int dockPoints = DOZER_NUM_DOCK_POINTS; xfer->xferInt(&dockPoints); if (dockPoints!=DOZER_NUM_DOCK_POINTS) { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index e463d634977..676fea57c85 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2465,7 +2465,11 @@ void DozerAIUpdate::crc( Xfer *xfer ) void DozerAIUpdate::xfer( Xfer *xfer ) { // version - XferVersion currentVersion = 1; +#if RETAIL_COMPATIBLE_XFER_SAVE + XferVersion currentVersion = 1; +#else + XferVersion currentVersion = 2; +#endif XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); @@ -2486,6 +2490,12 @@ void DozerAIUpdate::xfer( Xfer *xfer ) xfer->xferSnapshot(m_dozerMachine); xfer->xferUser(&m_currentTask, sizeof(m_currentTask)); + if (currentVersion >= 2) + { + xfer->xferUser(&m_previousTask, sizeof(m_previousTask)); + xfer->xferUser(&m_previousTaskInfo, sizeof(m_previousTaskInfo)); + } + Int dockPoints = DOZER_NUM_DOCK_POINTS; xfer->xferInt(&dockPoints); if (dockPoints!=DOZER_NUM_DOCK_POINTS) { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 5d3154cd265..5e34dae52ef 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -1427,7 +1427,11 @@ void WorkerAIUpdate::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ void WorkerAIUpdate::xfer( Xfer *xfer ) { - XferVersion currentVersion = 1; +#if RETAIL_COMPATIBLE_XFER_SAVE + XferVersion currentVersion = 1; +#else + XferVersion currentVersion = 2; +#endif XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); @@ -1451,6 +1455,12 @@ void WorkerAIUpdate::xfer( Xfer *xfer ) xfer->xferSnapshot(m_dozerMachine); xfer->xferUser(&m_currentTask, sizeof(m_currentTask)); + if (currentVersion >= 2) + { + xfer->xferUser(&m_previousTask, sizeof(m_previousTask)); + xfer->xferUser(&m_previousTaskInfo, sizeof(m_previousTaskInfo)); + } + Int dockPoints = DOZER_NUM_DOCK_POINTS; xfer->xferInt(&dockPoints); if (dockPoints!=DOZER_NUM_DOCK_POINTS) { From d9284a474b2c8eed49316ea1b17607533ea9ec5f Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Fri, 23 Jan 2026 03:51:50 +1100 Subject: [PATCH 03/11] docs: Add comments --- .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 3 ++- .../Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 3 ++- GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp | 1 + .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 3 ++- .../Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 3 ++- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 5af528377b5..bc234183eb9 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2448,7 +2448,8 @@ void DozerAIUpdate::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer method * Version Info: - * 1: Initial version */ + * 1: Initial version + * 2: Save the dozer's previous task */ // ------------------------------------------------------------------------------------------------ void DozerAIUpdate::xfer( Xfer *xfer ) { diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 96606c6d953..6016b2a518d 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -1413,7 +1413,8 @@ void WorkerAIUpdate::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer method * Version Info: - * 1: Initial version */ + * 1: Initial version + * 2: Save the worker's previous task */ // ------------------------------------------------------------------------------------------------ void WorkerAIUpdate::xfer( Xfer *xfer ) { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp index e61f346b052..67a5765e2d1 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp @@ -3864,6 +3864,7 @@ void Object::onDisabledEdge(Bool becomingDisabled) else { #if !RETAIL_COMPATIBLE_CRC + // TheSuperHackers @bugfix Stubbjax 17/11/2025 Resume previous task when re-enabled. dozerAI->resumePreviousTask(); #endif } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 676fea57c85..587d07ac865 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2460,7 +2460,8 @@ void DozerAIUpdate::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer method * Version Info: - * 1: Initial version */ + * 1: Initial version + * 2: Save the dozer's previous task */ // ------------------------------------------------------------------------------------------------ void DozerAIUpdate::xfer( Xfer *xfer ) { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 5e34dae52ef..bdc71c33f77 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -1423,7 +1423,8 @@ void WorkerAIUpdate::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer method * Version Info: - * 1: Initial version */ + * 1: Initial version + * 2: Save the worker's previous task */ // ------------------------------------------------------------------------------------------------ void WorkerAIUpdate::xfer( Xfer *xfer ) { From e5bfa719c8a05f8ef3bb9af0323151ebbdd2dab7 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Fri, 23 Jan 2026 03:57:39 +1100 Subject: [PATCH 04/11] tweak: Clear previous task data on resume --- .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 4 ++++ .../GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 4 ++++ .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 4 ++++ .../GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index bc234183eb9..9e693f91629 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2046,7 +2046,11 @@ void DozerAIUpdate::cancelTask( DozerTask task ) void DozerAIUpdate::resumePreviousTask(void) { if (m_previousTask != DOZER_TASK_INVALID) + { newTask(m_previousTask, TheGameLogic->findObjectByID(m_previousTaskInfo.m_targetObjectID)); + m_previousTask = DOZER_TASK_INVALID; + m_previousTaskInfo.m_targetObjectID = INVALID_ID; + } } //------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 6016b2a518d..9436cf2d226 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -701,7 +701,11 @@ void WorkerAIUpdate::cancelTask( DozerTask task ) void WorkerAIUpdate::resumePreviousTask(void) { if (m_previousTask != DOZER_TASK_INVALID) + { newTask(m_previousTask, TheGameLogic->findObjectByID(m_previousTaskInfo.m_targetObjectID)); + m_previousTask = DOZER_TASK_INVALID; + m_previousTaskInfo.m_targetObjectID = INVALID_ID; + } } //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 587d07ac865..de219f50929 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2051,7 +2051,11 @@ void DozerAIUpdate::cancelTask( DozerTask task ) void DozerAIUpdate::resumePreviousTask(void) { if (m_previousTask != DOZER_TASK_INVALID) + { newTask(m_previousTask, TheGameLogic->findObjectByID(m_previousTaskInfo.m_targetObjectID)); + m_previousTask = DOZER_TASK_INVALID; + m_previousTaskInfo.m_targetObjectID = INVALID_ID; + } } //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index bdc71c33f77..99b48ab2b99 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -701,7 +701,11 @@ void WorkerAIUpdate::cancelTask( DozerTask task ) void WorkerAIUpdate::resumePreviousTask(void) { if (m_previousTask != DOZER_TASK_INVALID) + { newTask(m_previousTask, TheGameLogic->findObjectByID(m_previousTaskInfo.m_targetObjectID)); + m_previousTask = DOZER_TASK_INVALID; + m_previousTaskInfo.m_targetObjectID = INVALID_ID; + } } //------------------------------------------------------------------------------------------------- From 2f7ba5865808073d7d0b1ca61e03b6b823f7a7d0 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Fri, 23 Jan 2026 04:12:37 +1100 Subject: [PATCH 05/11] chore: Init previous task --- .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 1 + .../Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 1 + .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 1 + .../Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 1 + 4 files changed, 4 insertions(+) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 9e693f91629..32cd36f0c0a 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -1452,6 +1452,7 @@ DozerAIUpdate::DozerAIUpdate( Thing *thing, const ModuleData* moduleData ) : } m_currentTask = DOZER_TASK_INVALID; + m_previousTask = DOZER_TASK_INVALID; m_buildSubTask = DOZER_SELECT_BUILD_DOCK_LOCATION; // irrelavant, but I want non-garbage value diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 9436cf2d226..67caed91207 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -100,6 +100,7 @@ WorkerAIUpdate::WorkerAIUpdate( Thing *thing, const ModuleData* moduleData ) : } } m_currentTask = DOZER_TASK_INVALID; + m_previousTask = DOZER_TASK_INVALID; m_buildSubTask = DOZER_SELECT_BUILD_DOCK_LOCATION; // irrelavant, but I want non-garbage value m_supplyTruckStateMachine = nullptr; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index de219f50929..18f7c4729df 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -1457,6 +1457,7 @@ DozerAIUpdate::DozerAIUpdate( Thing *thing, const ModuleData* moduleData ) : } m_currentTask = DOZER_TASK_INVALID; + m_previousTask = DOZER_TASK_INVALID; m_buildSubTask = DOZER_SELECT_BUILD_DOCK_LOCATION; // irrelevant, but I want non-garbage value diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 99b48ab2b99..8de82cf3a6d 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -100,6 +100,7 @@ WorkerAIUpdate::WorkerAIUpdate( Thing *thing, const ModuleData* moduleData ) : } } m_currentTask = DOZER_TASK_INVALID; + m_previousTask = DOZER_TASK_INVALID; m_buildSubTask = DOZER_SELECT_BUILD_DOCK_LOCATION; // irrelevant, but I want non-garbage value m_supplyTruckStateMachine = nullptr; From 75cc9eb8c855dd2283178aa6b9e9fc69a69d8f83 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Fri, 23 Jan 2026 11:57:37 +1100 Subject: [PATCH 06/11] chore: Add DozerTaskInfo constructor --- .../GameEngine/Include/GameLogic/Module/DozerAIUpdate.h | 6 ++++++ .../GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h | 6 ++++++ .../GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 3 ++- .../GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 3 ++- .../GameEngine/Include/GameLogic/Module/DozerAIUpdate.h | 6 ++++++ .../GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h | 6 ++++++ .../GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 3 ++- .../GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 3 ++- 8 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h index ae082376d09..6b59a57ede6 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h @@ -280,6 +280,12 @@ class DozerAIUpdate : public AIUpdateInterface, public DozerAIInterface { ObjectID m_targetObjectID; ///< target object ID of task UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task + + DozerTaskInfo() + { + m_targetObjectID = INVALID_ID; + m_taskOrderFrame = 0; + } } m_task[ DOZER_NUM_TASKS ]; ///< tasks we want to do indexed by DozerTask DozerPrimaryStateMachine *m_dozerMachine; ///< the custom state machine for Dozer behavior diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h index be8f515b916..9303ba42d80 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h @@ -215,6 +215,12 @@ class WorkerAIUpdate : public AIUpdateInterface, public DozerAIInterface, public { ObjectID m_targetObjectID; ///< target object ID of task UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task + + DozerTaskInfo() + { + m_targetObjectID = INVALID_ID; + m_taskOrderFrame = 0; + } } m_task[ DOZER_NUM_TASKS ]; ///< tasks we want to do indexed by DozerTask diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 32cd36f0c0a..ec26044fd38 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -1453,6 +1453,7 @@ DozerAIUpdate::DozerAIUpdate( Thing *thing, const ModuleData* moduleData ) : } m_currentTask = DOZER_TASK_INVALID; m_previousTask = DOZER_TASK_INVALID; + m_previousTaskInfo = DozerTaskInfo(); m_buildSubTask = DOZER_SELECT_BUILD_DOCK_LOCATION; // irrelavant, but I want non-garbage value @@ -2050,7 +2051,7 @@ void DozerAIUpdate::resumePreviousTask(void) { newTask(m_previousTask, TheGameLogic->findObjectByID(m_previousTaskInfo.m_targetObjectID)); m_previousTask = DOZER_TASK_INVALID; - m_previousTaskInfo.m_targetObjectID = INVALID_ID; + m_previousTaskInfo = DozerTaskInfo(); } } diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 67caed91207..01b909e1970 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -101,6 +101,7 @@ WorkerAIUpdate::WorkerAIUpdate( Thing *thing, const ModuleData* moduleData ) : } m_currentTask = DOZER_TASK_INVALID; m_previousTask = DOZER_TASK_INVALID; + m_previousTaskInfo = DozerTaskInfo(); m_buildSubTask = DOZER_SELECT_BUILD_DOCK_LOCATION; // irrelavant, but I want non-garbage value m_supplyTruckStateMachine = nullptr; @@ -705,7 +706,7 @@ void WorkerAIUpdate::resumePreviousTask(void) { newTask(m_previousTask, TheGameLogic->findObjectByID(m_previousTaskInfo.m_targetObjectID)); m_previousTask = DOZER_TASK_INVALID; - m_previousTaskInfo.m_targetObjectID = INVALID_ID; + m_previousTaskInfo = DozerTaskInfo(); } } diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h index 98aac1ab07c..accc8c32cac 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h @@ -280,6 +280,12 @@ class DozerAIUpdate : public AIUpdateInterface, public DozerAIInterface { ObjectID m_targetObjectID; ///< target object ID of task UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task + + DozerTaskInfo() + { + m_targetObjectID = INVALID_ID; + m_taskOrderFrame = 0; + } } m_task[ DOZER_NUM_TASKS ]; ///< tasks we want to do indexed by DozerTask DozerPrimaryStateMachine *m_dozerMachine; ///< the custom state machine for Dozer behavior diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h index 266ef50496f..49918a90018 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h @@ -220,6 +220,12 @@ class WorkerAIUpdate : public AIUpdateInterface, public DozerAIInterface, public { ObjectID m_targetObjectID; ///< target object ID of task UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task + + DozerTaskInfo() + { + m_targetObjectID = INVALID_ID; + m_taskOrderFrame = 0; + } } m_task[ DOZER_NUM_TASKS ]; ///< tasks we want to do indexed by DozerTask diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 18f7c4729df..2183239bc4b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -1458,6 +1458,7 @@ DozerAIUpdate::DozerAIUpdate( Thing *thing, const ModuleData* moduleData ) : } m_currentTask = DOZER_TASK_INVALID; m_previousTask = DOZER_TASK_INVALID; + m_previousTaskInfo = DozerTaskInfo(); m_buildSubTask = DOZER_SELECT_BUILD_DOCK_LOCATION; // irrelevant, but I want non-garbage value @@ -2055,7 +2056,7 @@ void DozerAIUpdate::resumePreviousTask(void) { newTask(m_previousTask, TheGameLogic->findObjectByID(m_previousTaskInfo.m_targetObjectID)); m_previousTask = DOZER_TASK_INVALID; - m_previousTaskInfo.m_targetObjectID = INVALID_ID; + m_previousTaskInfo = DozerTaskInfo(); } } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 8de82cf3a6d..3ba5cd58402 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -101,6 +101,7 @@ WorkerAIUpdate::WorkerAIUpdate( Thing *thing, const ModuleData* moduleData ) : } m_currentTask = DOZER_TASK_INVALID; m_previousTask = DOZER_TASK_INVALID; + m_previousTaskInfo = DozerTaskInfo(); m_buildSubTask = DOZER_SELECT_BUILD_DOCK_LOCATION; // irrelevant, but I want non-garbage value m_supplyTruckStateMachine = nullptr; @@ -705,7 +706,7 @@ void WorkerAIUpdate::resumePreviousTask(void) { newTask(m_previousTask, TheGameLogic->findObjectByID(m_previousTaskInfo.m_targetObjectID)); m_previousTask = DOZER_TASK_INVALID; - m_previousTaskInfo.m_targetObjectID = INVALID_ID; + m_previousTaskInfo = DozerTaskInfo(); } } From 0f6a338c50da8f1f20dbec91833085175ead9143 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Fri, 23 Jan 2026 12:00:46 +1100 Subject: [PATCH 07/11] docs: Update xfer comments --- .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 2 +- .../Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 2 +- .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 2 +- .../Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index ec26044fd38..17bb442f64a 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2455,7 +2455,7 @@ void DozerAIUpdate::crc( Xfer *xfer ) /** Xfer method * Version Info: * 1: Initial version - * 2: Save the dozer's previous task */ + * 2: TheSuperHackers @tweak Stubbjax 17/11/2025 Save the dozer's previous task */ // ------------------------------------------------------------------------------------------------ void DozerAIUpdate::xfer( Xfer *xfer ) { diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 01b909e1970..3fc04479c5f 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -1420,7 +1420,7 @@ void WorkerAIUpdate::crc( Xfer *xfer ) /** Xfer method * Version Info: * 1: Initial version - * 2: Save the worker's previous task */ + * 2: TheSuperHackers @tweak Stubbjax 17/11/2025 Save the worker's previous task */ // ------------------------------------------------------------------------------------------------ void WorkerAIUpdate::xfer( Xfer *xfer ) { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 2183239bc4b..a3d80f67587 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2467,7 +2467,7 @@ void DozerAIUpdate::crc( Xfer *xfer ) /** Xfer method * Version Info: * 1: Initial version - * 2: Save the dozer's previous task */ + * 2: TheSuperHackers @tweak Stubbjax 17/11/2025 Save the dozer's previous task */ // ------------------------------------------------------------------------------------------------ void DozerAIUpdate::xfer( Xfer *xfer ) { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 3ba5cd58402..5090014230c 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -1430,7 +1430,7 @@ void WorkerAIUpdate::crc( Xfer *xfer ) /** Xfer method * Version Info: * 1: Initial version - * 2: Save the worker's previous task */ + * 2: TheSuperHackers @tweak Stubbjax 17/11/2025 Save the worker's previous task */ // ------------------------------------------------------------------------------------------------ void WorkerAIUpdate::xfer( Xfer *xfer ) { From ea8ab195f4ca41b441b2d888736149293e130174 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Fri, 23 Jan 2026 12:02:57 +1100 Subject: [PATCH 08/11] tweak: Clear previous task data when a task is completed --- .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 3 +++ .../Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 3 +++ .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 3 +++ .../Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 3 +++ 4 files changed, 12 insertions(+) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 17bb442f64a..d5e64bfbf46 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2111,6 +2111,9 @@ void DozerAIUpdate::internalTaskComplete( DozerTask task ) m_task[ task ].m_targetObjectID = INVALID_ID; m_task[ task ].m_taskOrderFrame = 0; + m_previousTask = DOZER_TASK_INVALID; + m_previousTaskInfo = DozerTaskInfo(); + // remove dock point info for this task for( Int i = 0; i < DOZER_NUM_DOCK_POINTS; i++ ) m_dockPoint[ task ][ i ].valid = FALSE; diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 3fc04479c5f..e84b2812a8a 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -766,6 +766,9 @@ void WorkerAIUpdate::internalTaskComplete( DozerTask task ) m_task[ task ].m_targetObjectID = INVALID_ID; m_task[ task ].m_taskOrderFrame = 0; + m_previousTask = DOZER_TASK_INVALID; + m_previousTaskInfo = DozerTaskInfo(); + // remove dock point info for this task for( Int i = 0; i < DOZER_NUM_DOCK_POINTS; i++ ) m_dockPoint[ task ][ i ].valid = FALSE; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index a3d80f67587..1f6511bd1b0 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2116,6 +2116,9 @@ void DozerAIUpdate::internalTaskComplete( DozerTask task ) m_task[ task ].m_targetObjectID = INVALID_ID; m_task[ task ].m_taskOrderFrame = 0; + m_previousTask = DOZER_TASK_INVALID; + m_previousTaskInfo = DozerTaskInfo(); + // remove dock point info for this task for( Int i = 0; i < DOZER_NUM_DOCK_POINTS; i++ ) m_dockPoint[ task ][ i ].valid = FALSE; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 5090014230c..5f1e872ddcf 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -766,6 +766,9 @@ void WorkerAIUpdate::internalTaskComplete( DozerTask task ) m_task[ task ].m_targetObjectID = INVALID_ID; m_task[ task ].m_taskOrderFrame = 0; + m_previousTask = DOZER_TASK_INVALID; + m_previousTaskInfo = DozerTaskInfo(); + // remove dock point info for this task for( Int i = 0; i < DOZER_NUM_DOCK_POINTS; i++ ) m_dockPoint[ task ][ i ].valid = FALSE; From ee550e6b6ef3c7540cbf0c5b643b8b3df4846acb Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Tue, 27 Jan 2026 11:32:23 +1100 Subject: [PATCH 09/11] chore: Remove superfluous inits --- .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 1 - .../Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 1 - .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 1 - .../Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 1 - 4 files changed, 4 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index d5e64bfbf46..cfe57084737 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -1453,7 +1453,6 @@ DozerAIUpdate::DozerAIUpdate( Thing *thing, const ModuleData* moduleData ) : } m_currentTask = DOZER_TASK_INVALID; m_previousTask = DOZER_TASK_INVALID; - m_previousTaskInfo = DozerTaskInfo(); m_buildSubTask = DOZER_SELECT_BUILD_DOCK_LOCATION; // irrelavant, but I want non-garbage value diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index e84b2812a8a..72e217b3a9f 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -101,7 +101,6 @@ WorkerAIUpdate::WorkerAIUpdate( Thing *thing, const ModuleData* moduleData ) : } m_currentTask = DOZER_TASK_INVALID; m_previousTask = DOZER_TASK_INVALID; - m_previousTaskInfo = DozerTaskInfo(); m_buildSubTask = DOZER_SELECT_BUILD_DOCK_LOCATION; // irrelavant, but I want non-garbage value m_supplyTruckStateMachine = nullptr; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 1f6511bd1b0..197fb1e06ef 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -1458,7 +1458,6 @@ DozerAIUpdate::DozerAIUpdate( Thing *thing, const ModuleData* moduleData ) : } m_currentTask = DOZER_TASK_INVALID; m_previousTask = DOZER_TASK_INVALID; - m_previousTaskInfo = DozerTaskInfo(); m_buildSubTask = DOZER_SELECT_BUILD_DOCK_LOCATION; // irrelevant, but I want non-garbage value diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 5f1e872ddcf..ed4f326d7fd 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -101,7 +101,6 @@ WorkerAIUpdate::WorkerAIUpdate( Thing *thing, const ModuleData* moduleData ) : } m_currentTask = DOZER_TASK_INVALID; m_previousTask = DOZER_TASK_INVALID; - m_previousTaskInfo = DozerTaskInfo(); m_buildSubTask = DOZER_SELECT_BUILD_DOCK_LOCATION; // irrelevant, but I want non-garbage value m_supplyTruckStateMachine = nullptr; From 06d3e7576199079c978a9bfae55ff4faaebb1632 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Tue, 27 Jan 2026 11:34:35 +1100 Subject: [PATCH 10/11] refactor: Shift definition order --- .../GameEngine/Include/GameLogic/Module/DozerAIUpdate.h | 6 +++--- .../GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h | 6 +++--- .../GameEngine/Include/GameLogic/Module/DozerAIUpdate.h | 6 +++--- .../GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h index 6b59a57ede6..69ed020e4e4 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h @@ -278,14 +278,14 @@ class DozerAIUpdate : public AIUpdateInterface, public DozerAIInterface struct DozerTaskInfo { - ObjectID m_targetObjectID; ///< target object ID of task - UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task - DozerTaskInfo() { m_targetObjectID = INVALID_ID; m_taskOrderFrame = 0; } + + ObjectID m_targetObjectID; ///< target object ID of task + UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task } m_task[ DOZER_NUM_TASKS ]; ///< tasks we want to do indexed by DozerTask DozerPrimaryStateMachine *m_dozerMachine; ///< the custom state machine for Dozer behavior diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h index 9303ba42d80..d042a4c4fb2 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h @@ -213,14 +213,14 @@ class WorkerAIUpdate : public AIUpdateInterface, public DozerAIInterface, public // Dozer data struct DozerTaskInfo { - ObjectID m_targetObjectID; ///< target object ID of task - UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task - DozerTaskInfo() { m_targetObjectID = INVALID_ID; m_taskOrderFrame = 0; } + + ObjectID m_targetObjectID; ///< target object ID of task + UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task } m_task[ DOZER_NUM_TASKS ]; ///< tasks we want to do indexed by DozerTask diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h index accc8c32cac..20aff0af941 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DozerAIUpdate.h @@ -278,14 +278,14 @@ class DozerAIUpdate : public AIUpdateInterface, public DozerAIInterface struct DozerTaskInfo { - ObjectID m_targetObjectID; ///< target object ID of task - UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task - DozerTaskInfo() { m_targetObjectID = INVALID_ID; m_taskOrderFrame = 0; } + + ObjectID m_targetObjectID; ///< target object ID of task + UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task } m_task[ DOZER_NUM_TASKS ]; ///< tasks we want to do indexed by DozerTask DozerPrimaryStateMachine *m_dozerMachine; ///< the custom state machine for Dozer behavior diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h index 49918a90018..062e752a97c 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/WorkerAIUpdate.h @@ -218,14 +218,14 @@ class WorkerAIUpdate : public AIUpdateInterface, public DozerAIInterface, public // Dozer data struct DozerTaskInfo { - ObjectID m_targetObjectID; ///< target object ID of task - UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task - DozerTaskInfo() { m_targetObjectID = INVALID_ID; m_taskOrderFrame = 0; } + + ObjectID m_targetObjectID; ///< target object ID of task + UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task } m_task[ DOZER_NUM_TASKS ]; ///< tasks we want to do indexed by DozerTask From 7d574779f7f6f32297c6f7654c524e492065aa0f Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Tue, 27 Jan 2026 11:36:35 +1100 Subject: [PATCH 11/11] docs: Shift block comment end markers --- .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 3 ++- .../Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 3 ++- .../Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 3 ++- .../Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index cfe57084737..13478282f35 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2457,7 +2457,8 @@ void DozerAIUpdate::crc( Xfer *xfer ) /** Xfer method * Version Info: * 1: Initial version - * 2: TheSuperHackers @tweak Stubbjax 17/11/2025 Save the dozer's previous task */ + * 2: TheSuperHackers @tweak Stubbjax 17/11/2025 Save the dozer's previous task + */ // ------------------------------------------------------------------------------------------------ void DozerAIUpdate::xfer( Xfer *xfer ) { diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index 72e217b3a9f..5615f8d7794 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -1422,7 +1422,8 @@ void WorkerAIUpdate::crc( Xfer *xfer ) /** Xfer method * Version Info: * 1: Initial version - * 2: TheSuperHackers @tweak Stubbjax 17/11/2025 Save the worker's previous task */ + * 2: TheSuperHackers @tweak Stubbjax 17/11/2025 Save the worker's previous task + */ // ------------------------------------------------------------------------------------------------ void WorkerAIUpdate::xfer( Xfer *xfer ) { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 197fb1e06ef..fb5da2d4373 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2469,7 +2469,8 @@ void DozerAIUpdate::crc( Xfer *xfer ) /** Xfer method * Version Info: * 1: Initial version - * 2: TheSuperHackers @tweak Stubbjax 17/11/2025 Save the dozer's previous task */ + * 2: TheSuperHackers @tweak Stubbjax 17/11/2025 Save the dozer's previous task + */ // ------------------------------------------------------------------------------------------------ void DozerAIUpdate::xfer( Xfer *xfer ) { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index ed4f326d7fd..5a7af64055a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -1432,7 +1432,8 @@ void WorkerAIUpdate::crc( Xfer *xfer ) /** Xfer method * Version Info: * 1: Initial version - * 2: TheSuperHackers @tweak Stubbjax 17/11/2025 Save the worker's previous task */ + * 2: TheSuperHackers @tweak Stubbjax 17/11/2025 Save the worker's previous task + */ // ------------------------------------------------------------------------------------------------ void WorkerAIUpdate::xfer( Xfer *xfer ) {