From cbf284ce4ded7d9d1a90cf428a822c427cc83bd2 Mon Sep 17 00:00:00 2001 From: Flugente Date: Sun, 14 Aug 2016 18:55:09 +0000 Subject: [PATCH] Fix: tileset index 0 always present in construct/deconstruct arrays git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8289 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Tactical/Handle Items.h | 10 +++- Tactical/XML_StructureConstruct.cpp | 68 +++++++++++++-------------- Tactical/XML_StructureDeconstruct.cpp | 62 +++++++++--------------- 3 files changed, 62 insertions(+), 78 deletions(-) diff --git a/Tactical/Handle Items.h b/Tactical/Handle Items.h index a0d3662d..bb198aad 100644 --- a/Tactical/Handle Items.h +++ b/Tactical/Handle Items.h @@ -80,7 +80,10 @@ typedef struct } ITEM_POOL_LOCATOR; // Flugente: we can construct and deconstruct map structures via items. -typedef struct { +typedef struct STRUCTURE_DECONSTRUCT { + STRUCTURE_DECONSTRUCT() + : usDeconstructItem( 0 ), usItemToCreate( 0 ), usCreatedItemStatus( 0 ), szTileSetDisplayName( ), szTileSetName( ), dCreationCost( 0 ) {} + UINT16 usDeconstructItem; // the item that has to be used to deconstruct the structure UINT16 usItemToCreate; // the item that will be created when we deconstruct a structure UINT8 usCreatedItemStatus; // status of the item to create @@ -94,7 +97,10 @@ typedef struct { extern STRUCTURE_DECONSTRUCT gStructureDeconstruct[STRUCTURE_DECONSTRUCT_MAX]; -typedef struct { +typedef struct STRUCTURE_CONSTRUCT { + STRUCTURE_CONSTRUCT() + : usCreationItem( 0 ), usItemStatusLoss( 0 ), szTileSetDisplayName(), szTileSetName(), dCreationCost( 1.0 ), fFortifyAdjacentAdjustment( TRUE ) {} + UINT16 usCreationItem; // the item that will be consumed when creating the structure UINT8 usItemStatusLoss; // item will lose this number of status points char szTileSetDisplayName[20]; // name of this structure to the player (tileset names are obscure) diff --git a/Tactical/XML_StructureConstruct.cpp b/Tactical/XML_StructureConstruct.cpp index 65b58018..f9bd42c3 100644 --- a/Tactical/XML_StructureConstruct.cpp +++ b/Tactical/XML_StructureConstruct.cpp @@ -14,17 +14,14 @@ struct PARSE_STAGE curElement; CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1]; - STRUCTURE_CONSTRUCT curFood; STRUCTURE_CONSTRUCT* curArray; UINT32 maxArraySize; - + UINT32 curIndex; UINT32 currentDepth; UINT32 maxReadDepth; } typedef structureconstructParseData; -UINT16 structureconstructcnt = 0; - static void XMLCALL structureconstructStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts) { @@ -36,16 +33,12 @@ structureconstructStartElementHandle(void *userData, const XML_Char *name, const { pData->curElement = ELEMENT_LIST; - memset(pData->curArray,0,sizeof(STRUCTURE_CONSTRUCT)*pData->maxArraySize); - pData->maxReadDepth++; //we are not skipping this element } else if(strcmp(name, "STRUCTURE") == 0 && pData->curElement == ELEMENT_LIST) { pData->curElement = ELEMENT; - memset(&pData->curFood,0,sizeof(STRUCTURE_CONSTRUCT)); - pData->maxReadDepth++; //we are not skipping this element } else if(pData->curElement == ELEMENT && @@ -103,66 +96,70 @@ structureconstructEndElementHandle(void *userData, const XML_Char *name) pData->curElement = ELEMENT_LIST; // we do NOT want to read the first entry -> move stuff by 1 - if(structureconstructcnt < pData->maxArraySize) + if ( pData->curIndex < pData->maxArraySize ) { // for whatever reasons the game crashes in VS2008 Release builds when copying over the tilevector // this seems odd, as this works just fine in VS2010 and VS2013, and also works in VS205 debug builds // for now, copy over the content by hand - pData->curArray[structureconstructcnt].usCreationItem = pData->curFood.usCreationItem; - pData->curArray[structureconstructcnt].usItemStatusLoss= pData->curFood.usItemStatusLoss; - strncpy( pData->curArray[structureconstructcnt].szTileSetDisplayName, pData->curFood.szTileSetDisplayName, 20 ); - strncpy( pData->curArray[structureconstructcnt].szTileSetName, pData->curFood.szTileSetName, 20 ); - pData->curArray[structureconstructcnt].dCreationCost = pData->curFood.dCreationCost; - pData->curArray[structureconstructcnt].fFortifyAdjacentAdjustment = pData->curFood.fFortifyAdjacentAdjustment; - pData->curArray[structureconstructcnt].northtilevector = staticnorthtilevector; - pData->curArray[structureconstructcnt].southtilevector = staticsouthtilevector; - pData->curArray[structureconstructcnt].easttilevector = staticeasttilevector; - pData->curArray[structureconstructcnt].westtilevector = staticwesttilevector; + // check if the vector is empty because assigning an empty vector will crash VS2010 debug builds! + if ( !staticnorthtilevector.empty( ) ) + { + pData->curArray[pData->curIndex].northtilevector = staticnorthtilevector; + staticnorthtilevector.clear( ); + } - staticnorthtilevector.clear(); - staticsouthtilevector.clear(); - staticeasttilevector.clear(); - staticwesttilevector.clear(); + if ( !staticsouthtilevector.empty( ) ) + { + pData->curArray[pData->curIndex].southtilevector = staticsouthtilevector; + staticsouthtilevector.clear( ); + } - staticnorthtilevector.resize(1); - staticsouthtilevector.resize(1); - staticeasttilevector.resize(1); - staticwesttilevector.resize(1); + if ( !staticeasttilevector.empty( ) ) + { + pData->curArray[pData->curIndex].easttilevector = staticeasttilevector; + staticeasttilevector.clear( ); + } + + if ( !staticwesttilevector.empty( ) ) + { + pData->curArray[pData->curIndex].westtilevector = staticwesttilevector; + staticwesttilevector.clear( ); + } } - ++structureconstructcnt; + pData->curIndex++; } else if(strcmp(name, "usCreationItem") == 0) { pData->curElement = ELEMENT; - pData->curFood.usCreationItem = (UINT16) atol(pData->szCharData); + pData->curArray[pData->curIndex].usCreationItem = (UINT16)atol( pData->szCharData ); } else if(strcmp(name, "usItemStatusLoss") == 0) { pData->curElement = ELEMENT; - pData->curFood.usItemStatusLoss = (UINT8) atol(pData->szCharData); + pData->curArray[pData->curIndex].usItemStatusLoss = (UINT8)atol( pData->szCharData ); } else if(strcmp(name, "szTileSetDisplayName") == 0) { pData->curElement = ELEMENT; - strncpy( pData->curFood.szTileSetDisplayName, pData->szCharData, 20 ); + strncpy( pData->curArray[pData->curIndex].szTileSetDisplayName, pData->szCharData, 20 ); } else if ( strcmp( name, "szTileSetName" ) == 0 ) { pData->curElement = ELEMENT; - strncpy( pData->curFood.szTileSetName, pData->szCharData, 20 ); + strncpy( pData->curArray[pData->curIndex].szTileSetName, pData->szCharData, 20 ); } else if ( strcmp( name, "dCreationCost" ) == 0 ) { pData->curElement = ELEMENT; - pData->curFood.dCreationCost = (FLOAT)atof( pData->szCharData ); + pData->curArray[pData->curIndex].dCreationCost = (FLOAT)atof( pData->szCharData ); } else if ( strcmp( name, "fFortifyAdjacentAdjustment" ) == 0 ) { pData->curElement = ELEMENT; - pData->curFood.fFortifyAdjacentAdjustment = (BOOLEAN)atol( pData->szCharData ); + pData->curArray[pData->curIndex].fFortifyAdjacentAdjustment = (BOOLEAN)atol( pData->szCharData ); } else if(strcmp(name, "northfacingtile") == 0) { @@ -192,8 +189,6 @@ structureconstructEndElementHandle(void *userData, const XML_Char *name) } - - BOOLEAN ReadInStructureConstructStats(STR fileName) { HWFILE hFile; @@ -229,6 +224,7 @@ BOOLEAN ReadInStructureConstructStats(STR fileName) XML_SetCharacterDataHandler(parser, structureconstructCharacterDataHandle); memset(&pData,0,sizeof(pData)); + pData.curIndex = 0; pData.curArray = gStructureConstruct; pData.maxArraySize = STRUCTURE_CONSTRUCT_MAX; diff --git a/Tactical/XML_StructureDeconstruct.cpp b/Tactical/XML_StructureDeconstruct.cpp index 7c4c70d4..8412a06c 100644 --- a/Tactical/XML_StructureDeconstruct.cpp +++ b/Tactical/XML_StructureDeconstruct.cpp @@ -14,17 +14,14 @@ struct PARSE_STAGE curElement; CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1]; - STRUCTURE_DECONSTRUCT curFood; STRUCTURE_DECONSTRUCT * curArray; UINT32 maxArraySize; - + UINT32 curIndex; UINT32 currentDepth; UINT32 maxReadDepth; } typedef structuredeconstructParseData; -UINT16 structuredeconstructcnt = 0; - static void XMLCALL structuredeconstructStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts) { @@ -36,16 +33,12 @@ structuredeconstructStartElementHandle(void *userData, const XML_Char *name, con { pData->curElement = ELEMENT_LIST; - memset(pData->curArray,0,sizeof(STRUCTURE_DECONSTRUCT)*pData->maxArraySize); - pData->maxReadDepth++; //we are not skipping this element } else if(strcmp(name, "STRUCTURE") == 0 && pData->curElement == ELEMENT_LIST) { pData->curElement = ELEMENT; - memset(&pData->curFood,0,sizeof(STRUCTURE_DECONSTRUCT)); - pData->maxReadDepth++; //we are not skipping this element } else if(pData->curElement == ELEMENT && @@ -99,55 +92,52 @@ structuredeconstructEndElementHandle(void *userData, const XML_Char *name) { pData->curElement = ELEMENT_LIST; - if(structuredeconstructcnt < pData->maxArraySize) + if ( pData->curIndex < pData->maxArraySize ) { // for whatever reasons the game crashes in VS2008 Release builds when copying over the tilevector // this seems odd, as this works just fine in VS2010 and VS2013, and also works in VS205 debug builds // for now, copy over the content by hand - pData->curArray[structuredeconstructcnt].usDeconstructItem = pData->curFood.usDeconstructItem; - pData->curArray[structuredeconstructcnt].usItemToCreate= pData->curFood.usItemToCreate; - pData->curArray[structuredeconstructcnt].usCreatedItemStatus = pData->curFood.usCreatedItemStatus; - strncpy( pData->curArray[structuredeconstructcnt].szTileSetDisplayName, pData->curFood.szTileSetDisplayName, 20 ); - strncpy( pData->curArray[structuredeconstructcnt].szTileSetName, pData->curFood.szTileSetName, 20 ); - pData->curArray[structuredeconstructcnt].dCreationCost = pData->curFood.dCreationCost; - pData->curArray[structuredeconstructcnt].tilevector = statictilevector; - - statictilevector.clear(); + // check if the vector is empty because assigning an empty vector will crash VS2010 debug builds! + if ( !statictilevector.empty( ) ) + { + pData->curArray[pData->curIndex].tilevector = statictilevector; + statictilevector.clear( ); + } } - ++structuredeconstructcnt; + pData->curIndex++; } else if ( strcmp( name, "usDeconstructItem" ) == 0 ) { pData->curElement = ELEMENT; - pData->curFood.usDeconstructItem = (UINT16)atol( pData->szCharData ); + pData->curArray[pData->curIndex].usDeconstructItem = (UINT16)atol( pData->szCharData ); } else if(strcmp(name, "usItemToCreate") == 0) { pData->curElement = ELEMENT; - pData->curFood.usItemToCreate = (UINT16) atol(pData->szCharData); + pData->curArray[pData->curIndex].usItemToCreate = (UINT16)atol( pData->szCharData ); } else if ( strcmp( name, "usCreatedItemStatus" ) == 0 ) { pData->curElement = ELEMENT; - pData->curFood.usCreatedItemStatus = (UINT8)atol( pData->szCharData ); + pData->curArray[pData->curIndex].usCreatedItemStatus = (UINT8)atol( pData->szCharData ); } else if(strcmp(name, "szTileSetDisplayName") == 0) { pData->curElement = ELEMENT; - strncpy( pData->curFood.szTileSetDisplayName, pData->szCharData, 20 ); + strncpy( pData->curArray[pData->curIndex].szTileSetDisplayName, pData->szCharData, 20 ); } else if ( strcmp( name, "szTileSetName" ) == 0 ) { pData->curElement = ELEMENT; - strncpy( pData->curFood.szTileSetName, pData->szCharData, 20 ); + strncpy( pData->curArray[pData->curIndex].szTileSetName, pData->szCharData, 20 ); } else if ( strcmp( name, "dCreationCost" ) == 0 ) { pData->curElement = ELEMENT; - pData->curFood.dCreationCost = (FLOAT)atof( pData->szCharData ); + pData->curArray[pData->curIndex].dCreationCost = (FLOAT)atof( pData->szCharData ); } else if(strcmp(name, "allowedtile") == 0) { @@ -162,8 +152,6 @@ structuredeconstructEndElementHandle(void *userData, const XML_Char *name) } - - BOOLEAN ReadInStructureDeconstructStats(STR fileName) { HWFILE hFile; @@ -194,19 +182,17 @@ BOOLEAN ReadInStructureDeconstructStats(STR fileName) lpcBuffer[uiFSize] = 0; //add a null terminator FileClose( hFile ); - - + XML_SetElementHandler(parser, structuredeconstructStartElementHandle, structuredeconstructEndElementHandle); XML_SetCharacterDataHandler(parser, structuredeconstructCharacterDataHandle); - - + memset(&pData,0,sizeof(pData)); pData.curArray = gStructureDeconstruct; + pData.curIndex = 0; pData.maxArraySize = STRUCTURE_DECONSTRUCT_MAX; XML_SetUserData(parser, &pData); - - + if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE)) { CHAR8 errorBuf[511]; @@ -219,11 +205,9 @@ BOOLEAN ReadInStructureDeconstructStats(STR fileName) } MemFree(lpcBuffer); - - + XML_ParserFree(parser); - - + return( TRUE ); } @@ -239,10 +223,8 @@ BOOLEAN WriteStructureDeconstructStats() return( FALSE ); { - UINT32 cnt; - FilePrintf(hFile,"\r\n"); - for(cnt = 0; cnt < STRUCTURE_DECONSTRUCT_MAX; ++cnt) + for ( UINT32 cnt = 0; cnt < STRUCTURE_DECONSTRUCT_MAX; ++cnt ) { FilePrintf(hFile,"\t\r\n");