From 3d5294003a9999728f6838c7a13eeda32c455f29 Mon Sep 17 00:00:00 2001 From: Asdow <20314541+Asdow@users.noreply.github.com> Date: Sun, 24 Dec 2023 13:48:21 +0200 Subject: [PATCH 1/5] Copy drag info to dummy soldier (#255) Fixes merc location shifted by one tile during loading a save when A* pathfinding is enabled --- Tactical/Soldier Add.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Tactical/Soldier Add.cpp b/Tactical/Soldier Add.cpp index 64a83a0c..654283be 100644 --- a/Tactical/Soldier Add.cpp +++ b/Tactical/Soldier Add.cpp @@ -93,6 +93,9 @@ INT32 FindGridNoFromSweetSpot( SOLDIERTYPE *pSoldier, INT32 sSweetGridNo, INT8 u soldier.pathing.bLevel = 0; soldier.bTeam = 1; soldier.sGridNo = sSweetGridNo; + soldier.sDragCorpseID = pSoldier->sDragCorpseID; + soldier.sDragGridNo = pSoldier->sDragGridNo; + soldier.usDragPersonID = pSoldier->usDragPersonID; sTop = ubRadius; sBottom = -ubRadius; From 62dd0914fce6dd343e01e506d2a2e2bf407246dd Mon Sep 17 00:00:00 2001 From: Asdow <20314541+Asdow@users.noreply.github.com> Date: Sun, 24 Dec 2023 17:29:01 +0200 Subject: [PATCH 2/5] Allocate one INT8 for ZStripInfo pbZChange (#256) Fixes assertion errors in DEBUG build when LOBOT is enabled. --- TileEngine/structure.cpp | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/TileEngine/structure.cpp b/TileEngine/structure.cpp index 1d8b2fc2..296d0859 100644 --- a/TileEngine/structure.cpp +++ b/TileEngine/structure.cpp @@ -2440,10 +2440,14 @@ BOOLEAN AddZStripInfoToVObject( HVOBJECT hVObject, STRUCTURE_FILE_REF * pStructu // MemAlloc returns a NULL pointer which the code would interpret as // allocation failing because of no memory. // I hope this is OK, I don't entirely understand what is done here... - // (ASDOW): Commented out the added conditional, because with an unlucky combination of sti image width and offset, eg 9x16 with x offset of -15 - // pCurr->pbZChange would be null, which then crashes the game inside the blitting functions when dereferencing a nullptr - // With Bio experiencing crashes causing him to add the check, I don't know if this is just kicking the can down the road. -// if (pCurr->ubNumberOfZChanges > 0) + // (ASDOW): Adjusted the else branch to prevent DEBUG build hitting an assertion error due to this function returning false and + // preventing crashes in blitter functions due to nullptr dereference as what happened with bio's original solution. + // Allocating one INT8 and setting it to 0 means the Z-value is not adjusted in blitters. + // So far it seems to just work, albeit we're getting a screenmessage of structure not added to the world properly, when + // the game tries to add one in AddMercStructureInfoFromAnimSurface() for said anim when we're missing the actual structureinfo. + // As the game then doesn't do anything besides returning false, it seems to not cause any issues besides the screenmessage in debug build. + // So now we should not suffer from the constant assertion errors in debug build when LOBOT is active. Though this could still use a proper solution.. + if (pCurr->ubNumberOfZChanges > 0) { pCurr->pbZChange = (INT8 *)MemAlloc(pCurr->ubNumberOfZChanges); if (pCurr->pbZChange == NULL) @@ -2485,10 +2489,28 @@ BOOLEAN AddZStripInfoToVObject( HVOBJECT hVObject, STRUCTURE_FILE_REF * pStructu pCurr->bInitialZChange = -(ubNumDecreasing); } } -// else -// { -// pCurr->pbZChange = NULL; -// } + else + { + pCurr->pbZChange = (INT8*)MemAlloc(1); + + // Abort if MemAlloc fails + if (pCurr->pbZChange == NULL) + { + // augh! + for (ubLoop2 = 0; ubLoop2 < uiLoop; ubLoop2++) + { + if (hVObject->ppZStripInfo[ubLoop2] != NULL) + { + MemFree(hVObject->ppZStripInfo[uiLoop]); + } + } + MemFree(hVObject->ppZStripInfo); + hVObject->ppZStripInfo = NULL; + return(FALSE); + } + + pCurr->pbZChange[0] = 0; + } } } } From 4d09bea13e96d7368680f2c9593cb3be2112c927 Mon Sep 17 00:00:00 2001 From: olafwqq <155308051+olafwqq@users.noreply.github.com> Date: Mon, 1 Jan 2024 21:43:31 +0100 Subject: [PATCH 3/5] Address two compiler warnings (#258) --- Tactical/Handle Items.cpp | 2 +- Tactical/Turn Based Input.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index 6eb448ad..49036979 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -8165,7 +8165,7 @@ void CorrectDragStructData( INT32 sGridNo, INT8 sLevel, UINT8 ausHitpoints, UINT if ( pStruct->ubHitPoints < pStruct->pDBStructureRef->pDBStructure->ubHitPoints || pStruct->ubDecalFlag & STRUCTURE_DECALFLAG_BLOOD ) { - gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_STRUCTURE_DAMAGED; + gpWorldLevelData[sGridNo].uiFlags |= MAPELEMENT_STRUCTURE_DAMAGED; //SetRenderFlags( RENDER_FLAG_FULL ); } diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp index a9aa6b8f..abc77380 100644 --- a/Tactical/Turn Based Input.cpp +++ b/Tactical/Turn Based Input.cpp @@ -8309,7 +8309,7 @@ void HandleTBLevelUp(void) void HandleTBBackpacks(void) { - if (UsingNewInventorySystem) + if (UsingNewInventorySystem()) { bool backpackDropped = false; SOLDIERTYPE* pTeamSoldier; From fd4b531d53c75af6fb605337563fbe50e4dcd2f1 Mon Sep 17 00:00:00 2001 From: olafwqq <155308051+olafwqq@users.noreply.github.com> Date: Tue, 2 Jan 2024 10:53:29 +0100 Subject: [PATCH 4/5] Fix GetAllForticationGridNo (#259) It was still returning gridnos as 16-bit integers. --- Tactical/DisplayCover.cpp | 6 +++--- Tactical/Handle Items.cpp | 4 ++-- Tactical/Handle Items.h | 5 +++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Tactical/DisplayCover.cpp b/Tactical/DisplayCover.cpp index 7d1a3676..f89863a9 100644 --- a/Tactical/DisplayCover.cpp +++ b/Tactical/DisplayCover.cpp @@ -1717,10 +1717,10 @@ BOOLEAN TrackerTileHasAdjTile( const INT32& ubX, const INT32& ubY, const INT32& void CalculateFortify( ) { // simply get all fortified gridnos and colour them - std::vector< std::pair > > vec = GetAllForticationGridNo( ); + auto vec = GetAllForticationGridNo(); - std::vector< std::pair > >::iterator itend = vec.end( ); - for ( std::vector< std::pair > >::iterator it = vec.begin( ); it != itend; ++it ) + auto itend = vec.end(); + for (auto it = vec.begin(); it != itend; ++it) { INT16 sX, sY; ConvertGridNoToXY( (*it).first, &sX, &sY ); diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index 49036979..7e9c6476 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -8713,9 +8713,9 @@ void AddFortificationPlanNode( INT32 sGridNo, INT8 sLevel, INT16 sFortificationS UpdateFortificationPossibleAmount(); } -std::vector< std::pair > > GetAllForticationGridNo( ) +GetAllForticationGridNoResult GetAllForticationGridNo() { - std::vector< std::pair > > gridnovector; + GetAllForticationGridNoResult gridnovector; if ( !gWorldSectorX || !gWorldSectorY ) return gridnovector; diff --git a/Tactical/Handle Items.h b/Tactical/Handle Items.h index b9b20865..cdc362b3 100644 --- a/Tactical/Handle Items.h +++ b/Tactical/Handle Items.h @@ -320,7 +320,8 @@ void AddFortificationPlanNode( INT32 sGridNo, INT8 sLevel, INT16 sFortificationS void LoadSectorFortificationPlan( INT16 sSectorX, INT16 sSectorY, INT8 sSectorZ ); void SaveSectorFortificationPlan( INT16 sSectorX, INT16 sSectorY, INT8 sSectorZ ); -std::vector< std::pair > > GetAllForticationGridNo( ); +using GetAllForticationGridNoResult = std::vector< std::pair > >; +GetAllForticationGridNoResult GetAllForticationGridNo(); INT32 GetFirstObjectInSectorPosition( UINT16 ausItem ); @@ -334,4 +335,4 @@ BOOLEAN SpendMoney( SOLDIERTYPE *pSoldier, UINT32 aAmount ); // character spen // Flugente: intel void TakePhoto( SOLDIERTYPE* pSoldier, INT32 sGridNo, INT8 bLevel ); -#endif \ No newline at end of file +#endif From 57bf3d9fa7da9c22e5ff5436afb9d3b8ce10fdd7 Mon Sep 17 00:00:00 2001 From: Asdow <20314541+Asdow@users.noreply.github.com> Date: Wed, 3 Jan 2024 00:39:44 +0200 Subject: [PATCH 5/5] Call RemovePlayerFromGroup instead of RemoveGroup (#260) There was a bug in a provided save where a merc's group had persistent flag set, even though the assignment was DRILL_MILITIA, which should never have a persistent group. When the code was calling RemoveGroup instead of RemovePlayerFromGroup at this point, it would crash the game with an assertion error in CancelEmptyPersistentGroupMovement() as the group in fact was not empty! Now we're removing the merc first and then checking if the group is empty and if so, attempt to delete it. --- Strategic/Merc Contract.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Strategic/Merc Contract.cpp b/Strategic/Merc Contract.cpp index 727ad39e..c5bbaf3d 100644 --- a/Strategic/Merc Contract.cpp +++ b/Strategic/Merc Contract.cpp @@ -995,13 +995,13 @@ BOOLEAN StrategicRemoveMerc( SOLDIERTYPE *pSoldier ) if( ( pSoldier->bAssignment != VEHICLE ) && !( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) ) //if ( pSoldier->bAssignment != VEHICLE ) { //Can only remove groups if they aren't persistant (not in a squad or vehicle) - RemoveGroup( pSoldier->ubGroupID ); + RemovePlayerFromGroup(pSoldier->ubGroupID, pSoldier); } else { // remove him from any existing merc slot he could be in RemoveMercSlot( pSoldier ); - TakeSoldierOutOfVehicle( pSoldier ); + TakeSoldierOutOfVehicle( pSoldier ); } }