diff --git a/Init.cpp b/Init.cpp index a6998e4c..5db819a9 100644 --- a/Init.cpp +++ b/Init.cpp @@ -388,6 +388,10 @@ BOOLEAN LoadExternalGameplayData(STR directoryName) strcat(fileName, CLOTHESFILENAME); SGP_THROW_IFFALSE(ReadInClothesStats(fileName),CLOTHESFILENAME); + strcpy(fileName, directoryName); + strcat(fileName, RANDOMITEMFILENAME); + SGP_THROW_IFFALSE(ReadInRandomItemStats(fileName),RANDOMITEMFILENAME); + strcpy(fileName, directoryName); strcat(fileName, ARMOURSFILENAME); SGP_THROW_IFFALSE(ReadInArmourStats(fileName),ARMOURSFILENAME); diff --git a/Strategic/XML_SectorNames.cpp b/Strategic/XML_SectorNames.cpp index 738832e1..9b300cf9 100644 --- a/Strategic/XML_SectorNames.cpp +++ b/Strategic/XML_SectorNames.cpp @@ -325,7 +325,7 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name) else if(strcmp(name, "usCurfewValue") == 0) { pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usCurfewValue = (UINT16) atoi(pData->szCharData); + pData->usCurfewValue = (UINT8) atoi(pData->szCharData); } pData->maxReadDepth--; diff --git a/Tactical/Inventory Choosing.cpp b/Tactical/Inventory Choosing.cpp index 87c7e429..cd051ba3 100644 --- a/Tactical/Inventory Choosing.cpp +++ b/Tactical/Inventory Choosing.cpp @@ -1037,6 +1037,11 @@ void ChooseWeaponForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bWeaponC // the weapon class here ranges from 1 to 11, so subtract 1 to get a gun level usGunIndex = SelectStandardArmyGun( (UINT8) (bWeaponClass - 1)); + // Flugente: random items + UINT16 newitemfromrandom = 0; + if ( GetItemFromRandomItem(usGunIndex, &newitemfromrandom) ) + usGunIndex = newitemfromrandom; + //WarmSteel - Removed the attachment check here. why check twice anyway? //Now, we have chosen all of the correct items. Now, we will assign them into the slots. //Because we are dealing with enemies, automatically give them full ammo in their weapon. @@ -3437,6 +3442,11 @@ UINT16 PickARandomItem(UINT8 typeIndex, UINT8 maxCoolness, BOOLEAN getMatchingCo } usItem = gArmyItemChoices[ typeIndex ].bItemNo[ uiChoice ]; + // Flugente: random items + UINT16 newitemfromrandom = 0; + if ( GetItemFromRandomItem(usItem, &newitemfromrandom) ) + usItem = newitemfromrandom; + pickItem = FALSE; if (usItem >= 0 && Item[usItem].ubCoolness <= maxCoolness && ItemIsLegal(usItem)) diff --git a/Tactical/Item Types.cpp b/Tactical/Item Types.cpp index 6ddc5047..b9661109 100644 --- a/Tactical/Item Types.cpp +++ b/Tactical/Item Types.cpp @@ -5,6 +5,7 @@ #include "GameSettings.h" #include "screenids.h" #include "Action Items.h" // added by Flugente for the ACTION_ITEM_BLOW_UP value +#include "Random.h" // added by Flugente int BODYPOSFINAL = GUNSLINGPOCKPOS;//RESET in initInventory @@ -1326,6 +1327,11 @@ OBJECTTYPE& OBJECTTYPE::operator=(const OLD_OBJECTTYPE_101& src) this->usItem = NONE; } + // Flugente: random items + UINT16 newitemfromrandom = 0; + if ( GetItemFromRandomItem(src.usItem, &newitemfromrandom) ) + this->usItem = newitemfromrandom; + //and now the big change, the union //copy the old data, making sure not to write over, since the old size is actually 9 bytes if (ubNumberOfObjects == 1) { @@ -1341,7 +1347,8 @@ OBJECTTYPE& OBJECTTYPE::operator=(const OLD_OBJECTTYPE_101& src) (*this)[0]->data.gun.bGunAmmoStatus = 0; (*this)[0]->data.gun.ubGunState = 0; //Lastly, convert values from the old format to the new based on the type of object - switch(Item[src.usItem].usItemClass) + + switch(Item[this->usItem].usItemClass) { case IC_MONEY: (*this)[0]->data.money.uiMoneyAmount = src.ugYucky.uiMoneyAmount; diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index 632bd4a6..aa9c82b2 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -1138,8 +1138,25 @@ typedef struct // Flugente: clothes type that 'links' to an entry in Clothes.xml UINT32 clothestype; + // Flugente: a link to RandomItemsClass.xml. Out of such an item, a random object is created, depending on the entries in the xml + UINT16 randomitem; + INT8 randomitemcoolnessmodificator; // alters the allowed maximum coolness a random item can have + } INVTYPE; + +// Flugente: move this to a better position +typedef struct RANDOM_ITEM_CHOICE_TYPE +{ + UINT16 uiIndex; + //CHAR16 szName[80]; // name of this choice (not used ingame, only for readability) + UINT16 randomitem[10]; // room to link to other random item choices + UINT16 item[10]; // room for up to 10 items + +} RANDOM_ITEM_CHOICE_TYPE; + +extern RANDOM_ITEM_CHOICE_TYPE gRandomItemClass[200]; + // CHRISL: Added new structures to handle LBE gear and the two new XML files that will be needed to deal // with the IC pockets and the new inventory system. //DBrot: Increased the LBE combo to 32bit to allow for multiple combos (using a bitwise system) diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index da6bd4eb..37633c69 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -7649,6 +7649,12 @@ BOOLEAN CreateItem( UINT16 usItem, INT16 bStatus, OBJECTTYPE * pObj ) DebugBreakpoint(); return( FALSE ); } + + // Flugente: random items + UINT16 newitemfromrandom = 0; + if ( GetItemFromRandomItem(usItem, &newitemfromrandom) ) + usItem = newitemfromrandom; + if (Item[ usItem ].usItemClass == IC_GUN) { fRet = CreateGun( usItem, bStatus, pObj ); @@ -14705,3 +14711,167 @@ BOOLEAN GetFirstClothesItemWithSpecificData( UINT16* pusItem, PaletteRepID aPalV return( FALSE ); } + +#define RANDOM_ITEM_MAX_NUMBER 200 +#define RANDOM_TABOO_MAX 50 +#define RANDOM_XML_LENGTH 10 + +UINT16 randomitemarray[RANDOM_ITEM_MAX_NUMBER]; +UINT16 randomitemtabooarray[RANDOM_TABOO_MAX]; // We remember which random items we added, to prevent loops +UINT16 randomitemclasstabooarray[RANDOM_TABOO_MAX]; // We also remember the random item classes + +UINT16 itemcnt = 0; +UINT16 rdtaboocnt = 0; +UINT16 rdclasstaboocnt = 0; + +INT8 rditemmaxcoolness = 0; + +BOOL AddToRandomListFromRandomItemClass( UINT16 usRandomItemClass ); +BOOL AddToRandomListFromRandomItem( UINT16 usRandomItem ); +BOOL AddToRandomListFromItem( UINT16 usItem ); +BOOL RandomItemClassIsTaboo( UINT16 usRandomItemClass ); +BOOL RandomItemIsTaboo( UINT16 usRandomItem ); + +BOOLEAN GetItemFromRandomItem( UINT16 usRandomItem, UINT16* pusNewItem ) +{ + *pusNewItem = 0; + + // is this a random item? + if ( Item[usRandomItem].randomitem > 0 ) + { + // we build a list of all the items in the random item class this item references to + // We also have to check for other random item classes + // as it is also possible to reference to other random items, we also have to check for them + + // clear the random item arrays and reset the counters + for ( int i = 0; i < RANDOM_ITEM_MAX_NUMBER; ++i) + randomitemarray[i] = 0; + + for ( int i = 0; i < RANDOM_TABOO_MAX; ++i) + { + randomitemtabooarray[i] = 0; + randomitemclasstabooarray[i] = 0; + } + + itemcnt = 0; + rdtaboocnt = 0; + rdclasstaboocnt = 0; + + // determine maximum allowed coolness + // TODO: adjust this depending on a random item coolness modificator + rditemmaxcoolness = HighestPlayerProgressPercentage() / 10 + 1 + Item[usRandomItem].randomitemcoolnessmodificator; // the random item itself can modify coolness + + // build the list of items to choose from. We will search down the random item class an can even branch into mulitple other random item classes. + // We only stop if maximum number of items or random item classes is reached + AddToRandomListFromRandomItem(usRandomItem); + + if ( itemcnt ) + { + // select a random item from our list + UINT16 random = Random(itemcnt); + + *pusNewItem = randomitemarray[random]; + + return TRUE; + } + } + + return FALSE; +} + +BOOL AddToRandomListFromRandomItemClass( UINT16 usRandomItemClass ) +{ + if ( usRandomItemClass && !RandomItemClassIsTaboo(usRandomItemClass) ) + { + // end if we reached the maximum number of taboos + if ( rdclasstaboocnt >= RANDOM_TABOO_MAX ) + return FALSE; + + // add items + for ( int i = 0; i < RANDOM_XML_LENGTH; ++i) + { + // if this returns false, we're either at the maximum number of items or taboos - both reasons to end + if ( !AddToRandomListFromItem(gRandomItemClass[usRandomItemClass].item[i]) ) + return FALSE; + } + + // add random item classes + for ( int i = 0; i < RANDOM_XML_LENGTH; ++i) + { + // if this returns false, we're either at the maximum number of items or taboos - both reasons to end + if ( !AddToRandomListFromRandomItemClass(gRandomItemClass[usRandomItemClass].randomitem[i]) ) + return FALSE; + } + } + + return TRUE; +} + +// add from a random item to the list +BOOL AddToRandomListFromRandomItem( UINT16 usRandomItem ) +{ + if ( Item[usRandomItem].randomitem > 0 && !RandomItemIsTaboo( usRandomItem ) ) + { + // end if we reached the maximum number of taboos + if ( rdtaboocnt >= RANDOM_TABOO_MAX ) + return FALSE; + + return AddToRandomListFromRandomItemClass(Item[usRandomItem].randomitem); + } + + return TRUE; +} + +// add an item to the list +BOOL AddToRandomListFromItem( UINT16 usItem ) +{ + if ( usItem ) + { + // is it another random item? + if ( Item[usItem].randomitem > 0 ) + { + // continue adding items from this new random item + return AddToRandomListFromRandomItem(usItem); + } + else + { + // only allow those items that are viable at the current progress + if ( Item[usItem].ubCoolness <= rditemmaxcoolness ) + randomitemarray[itemcnt++] = usItem; + + // if maximum is reached, return false, thereby signalling an end + return ( itemcnt < RANDOM_ITEM_MAX_NUMBER ); + } + } + + return TRUE; +} + +// check wether this class is already on the taboo list (forbidden to add from there again, because this can lead to loops). If not, add this to the taboo list +BOOL RandomItemClassIsTaboo( UINT16 usRandomItemClass ) +{ + for ( int i = 0; i < rdclasstaboocnt; ++i) + { + if ( randomitemclasstabooarray[i] == usRandomItemClass ) + return TRUE; + } + + // add to taboo list + randomitemclasstabooarray[rdclasstaboocnt++] = usRandomItemClass; + + return FALSE; +} + +BOOL RandomItemIsTaboo( UINT16 usRandomItem ) +{ + for ( int i = 0; i < rdtaboocnt; ++i) + { + if ( randomitemtabooarray[i] == usRandomItem ) + return TRUE; + } + + // add to taboo list + randomitemtabooarray[rdtaboocnt++] = usRandomItem; + + return FALSE; +} diff --git a/Tactical/Items.h b/Tactical/Items.h index 4d1bdfe5..00f6898a 100644 --- a/Tactical/Items.h +++ b/Tactical/Items.h @@ -501,6 +501,9 @@ INT8 GetNumberAltFireAimLevels( SOLDIERTYPE * pSoldier, INT32 iGridNo ); // Flugente: retrieve a specific clothes item, if such a thing exists BOOLEAN GetFirstClothesItemWithSpecificData( UINT16* pusItem, PaletteRepID aPalVest, PaletteRepID aPalPants ); +// Flugente: function to determine what item a random item spawns +BOOLEAN GetItemFromRandomItem( UINT16 usRandomItem, UINT16* pusNewItem ); + #endif diff --git a/Tactical/Tactical_VS2010.vcxproj b/Tactical/Tactical_VS2010.vcxproj index dfebc40c..6088303b 100644 --- a/Tactical/Tactical_VS2010.vcxproj +++ b/Tactical/Tactical_VS2010.vcxproj @@ -224,6 +224,7 @@ + diff --git a/Tactical/Tactical_VS2010.vcxproj.filters b/Tactical/Tactical_VS2010.vcxproj.filters index f11bfebb..050a06be 100644 --- a/Tactical/Tactical_VS2010.vcxproj.filters +++ b/Tactical/Tactical_VS2010.vcxproj.filters @@ -632,5 +632,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp index 8c9710ea..4ffe163d 100644 --- a/Tactical/Turn Based Input.cpp +++ b/Tactical/Turn Based Input.cpp @@ -4446,10 +4446,10 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) } else if ( fAlt ) { - /*// Flugente: spawn items while debugging + // Flugente: spawn items while debugging if ( gusSelectedSoldier != NOBODY ) { - static UINT16 usitem = 269; + static UINT16 usitem = 1623; static INT16 status = 100; static FLOAT temperature = 0.0; @@ -4465,7 +4465,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) if ( !AutoPlaceObject( MercPtrs[ gusSelectedSoldier ], &newobj, FALSE ) ) AddItemToPool( MercPtrs[ gusSelectedSoldier ]->sGridNo, &newobj, 1, 0, 0, -1 ); - }*/ + } } else { diff --git a/Tactical/XML.h b/Tactical/XML.h index b21e5208..9a85fcf6 100644 --- a/Tactical/XML.h +++ b/Tactical/XML.h @@ -68,6 +68,7 @@ typedef PARSE_STAGE; #define DRUGSFILENAME "Drugs.xml" #define FOODFILENAME "Food.xml" #define CLOTHESFILENAME "Clothes.xml" +#define RANDOMITEMFILENAME "RandomItem.xml" #define AMMOFILENAME "AmmoStrings.xml" #define AMMOTYPESFILENAME "AmmoTypes.xml" #define INCOMPATIBLEATTACHMENTSFILENAME "IncompatibleAttachments.xml" @@ -299,7 +300,7 @@ extern BOOLEAN WriteMercStartingGearStats(); extern BOOLEAN ReadInExplosiveStats(STR fileName); extern BOOLEAN WriteExplosiveStats(); -// Flugente: externalisation of drugs +// Flugente: drugs extern BOOLEAN ReadInDrugsStats(STR fileName); extern BOOLEAN WriteDrugsStats(); @@ -311,6 +312,10 @@ extern BOOLEAN WriteFoodStats(); extern BOOLEAN ReadInClothesStats(STR fileName); extern BOOLEAN WriteClothesStats(); +// Flugente: random items +extern BOOLEAN ReadInRandomItemStats(STR fileName); +extern BOOLEAN WriteRandomItemStats(); + extern BOOLEAN ReadInAmmoStats(STR fileName); extern BOOLEAN WriteAmmoStats(); diff --git a/Tactical/XML_RandomItem.cpp b/Tactical/XML_RandomItem.cpp new file mode 100644 index 00000000..c414e08f --- /dev/null +++ b/Tactical/XML_RandomItem.cpp @@ -0,0 +1,330 @@ +#ifdef PRECOMPILEDHEADERS + #include "Tactical All.h" +#else + #include "sgp.h" + #include "overhead.h" + #include "Debug Control.h" + #include "expat.h" + #include "XML.h" + #include "Item Types.h" +#endif + +RANDOM_ITEM_CHOICE_TYPE gRandomItemClass[200]; + +struct +{ + PARSE_STAGE curElement; + + CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1]; + RANDOM_ITEM_CHOICE_TYPE curRandomItemClass; + RANDOM_ITEM_CHOICE_TYPE * curArray; + UINT32 maxArraySize; + + UINT32 currentDepth; + UINT32 maxReadDepth; +} +typedef randomitemParseData; + +static void XMLCALL +randomitemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts) +{ + randomitemParseData * pData = (randomitemParseData *)userData; + + if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element? + { + if(strcmp(name, "RANDOMITEMLIST") == 0 && pData->curElement == ELEMENT_NONE) + { + pData->curElement = ELEMENT_LIST; + + memset(pData->curArray,0,sizeof(RANDOM_ITEM_CHOICE_TYPE)*pData->maxArraySize); + + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "RANDOMITEM") == 0 && pData->curElement == ELEMENT_LIST) + { + pData->curElement = ELEMENT; + + memset(&pData->curRandomItemClass,0,sizeof(RANDOM_ITEM_CHOICE_TYPE)); + + pData->maxReadDepth++; //we are not skipping this element + } + else if(pData->curElement == ELEMENT && + (strcmp(name, "uiIndex") == 0 || + strcmp(name, "szName") == 0 || + strcmp(name, "randomitem1") == 0 || + strcmp(name, "randomitem2") == 0 || + strcmp(name, "randomitem3") == 0 || + strcmp(name, "randomitem4") == 0 || + strcmp(name, "randomitem5") == 0 || + strcmp(name, "randomitem6") == 0 || + strcmp(name, "randomitem7") == 0 || + strcmp(name, "randomitem8") == 0 || + strcmp(name, "randomitem9") == 0 || + strcmp(name, "randomitem10") == 0 || + strcmp(name, "item1") == 0 || + strcmp(name, "item2") == 0 || + strcmp(name, "item3") == 0 || + strcmp(name, "item4") == 0 || + strcmp(name, "item5") == 0 || + strcmp(name, "item6") == 0 || + strcmp(name, "item7") == 0 || + strcmp(name, "item8") == 0 || + strcmp(name, "item9") == 0 || + strcmp(name, "item10") == 0 )) + { + pData->curElement = ELEMENT_PROPERTY; + + pData->maxReadDepth++; //we are not skipping this element + } + + pData->szCharData[0] = '\0'; + } + + pData->currentDepth++; + +} + +static void XMLCALL +randomitemCharacterDataHandle(void *userData, const XML_Char *str, int len) +{ + randomitemParseData * pData = (randomitemParseData *)userData; + + if ( (pData->currentDepth <= pData->maxReadDepth) && (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH) ) + { + strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData))); + } +} + + +static void XMLCALL +randomitemEndElementHandle(void *userData, const XML_Char *name) +{ + randomitemParseData * pData = (randomitemParseData *)userData; + + if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading + { + if(strcmp(name, "RANDOMITEMLIST") == 0) + { + pData->curElement = ELEMENT_NONE; + } + else if(strcmp(name, "RANDOMITEM") == 0) + { + pData->curElement = ELEMENT_LIST; + + if(pData->curRandomItemClass.uiIndex < pData->maxArraySize) + { + pData->curArray[pData->curRandomItemClass.uiIndex] = pData->curRandomItemClass; //write the randomitem into the table + } + } + else if(strcmp(name, "uiIndex") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.uiIndex = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "szName") == 0) + { + pData->curElement = ELEMENT; + // not needed, but it's there for informational purposes + } + else if(strcmp(name, "randomitem1") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.randomitem[0] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "randomitem2") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.randomitem[1] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "randomitem3") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.randomitem[2] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "randomitem4") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.randomitem[3] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "randomitem5") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.randomitem[4] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "randomitem6") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.randomitem[5] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "randomitem7") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.randomitem[6] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "randomitem8") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.randomitem[7] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "randomitem9") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.randomitem[8] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "randomitem10") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.randomitem[9] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "item1") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.item[0] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "item2") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.item[1] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "item3") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.item[2] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "item4") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.item[3] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "item5") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.item[4] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "item6") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.item[5] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "item7") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.item[6] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "item8") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.item[7] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "item9") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.item[8] = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "item10") == 0) + { + pData->curElement = ELEMENT; + pData->curRandomItemClass.item[9] = (UINT16) atol(pData->szCharData); + } + + pData->maxReadDepth--; + } + + pData->currentDepth--; +} + + +BOOLEAN ReadInRandomItemStats(STR fileName) +{ + HWFILE hFile; + UINT32 uiBytesRead; + UINT32 uiFSize; + CHAR8 * lpcBuffer; + XML_Parser parser = XML_ParserCreate(NULL); + + randomitemParseData pData; + + DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading RandomItem.xml" ); + + // Open randomitem file + hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE ); + if ( !hFile ) + return( FALSE ); + + uiFSize = FileGetSize(hFile); + lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1); + + //Read in block + if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) ) + { + MemFree(lpcBuffer); + return( FALSE ); + } + + lpcBuffer[uiFSize] = 0; //add a null terminator + + FileClose( hFile ); + + + XML_SetElementHandler(parser, randomitemStartElementHandle, randomitemEndElementHandle); + XML_SetCharacterDataHandler(parser, randomitemCharacterDataHandle); + + + memset(&pData,0,sizeof(pData)); + pData.curArray = gRandomItemClass; + pData.maxArraySize = 200; + + XML_SetUserData(parser, &pData); + + if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE)) + { + CHAR8 errorBuf[511]; + + sprintf(errorBuf, "XML Parser Error in RandomItem.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); + LiveMessage(errorBuf); + + MemFree(lpcBuffer); + return FALSE; + } + + MemFree(lpcBuffer); + + XML_ParserFree(parser); + + return( TRUE ); +} + +BOOLEAN WriteRandomItemStats() +{ + //DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"writerandomitemstats"); + HWFILE hFile; + + //Debug code; make sure that what we got from the file is the same as what's there + // Open a new file + hFile = FileOpen( "TABLEDATA\\RandomItem out.xml", FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE ); + if ( !hFile ) + return( FALSE ); + + { + UINT32 cnt; + + FilePrintf(hFile,"\r\n"); + for(cnt = 0; cnt < 200; ++cnt) + { + FilePrintf(hFile,"\t\r\n"); + + FilePrintf(hFile,"\t\t%d\r\n", cnt ); + for (int i=0; i<10; ++i) + FilePrintf(hFile,"\t\t%d\r\n",i+1, gRandomItemClass[cnt].randomitem[i],i+1 ); + + for (int i=0; i<10; ++i) + FilePrintf(hFile,"\t\t%d\r\n",i+1, gRandomItemClass[cnt].item[i],i+1 ); + + FilePrintf(hFile,"\t\r\n"); + } + FilePrintf(hFile,"\r\n"); + } + FileClose( hFile ); + + return( TRUE ); +} diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp index c4a75839..5652117e 100644 --- a/Utils/XML_Items.cpp +++ b/Utils/XML_Items.cpp @@ -278,7 +278,9 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at strcmp(name, "DisarmModifier") == 0 || strcmp(name, "RepairModifier") == 0 || strcmp(name, "usActionItemFlag") == 0 || - strcmp(name, "clothestype") == 0 )) + strcmp(name, "clothestype") == 0 || + strcmp(name, "randomitem") == 0 || + strcmp(name, "randomitemcoolnessmodificator") == 0 )) { pData->curElement = ELEMENT_PROPERTY; //DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("itemStartElementHandle: going into element, name = %s",name) ); @@ -1399,7 +1401,21 @@ itemEndElementHandle(void *userData, const XML_Char *name) pData->curElement = ELEMENT; pData->curItem.clothestype = (UINT32) atol(pData->szCharData); } - + else if(strcmp(name, "randomitem") == 0) + { + pData->curElement = ELEMENT; + pData->curItem.randomitem = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "randomitemcoolnessmodificator") == 0) + { + pData->curElement = ELEMENT; + pData->curItem.randomitemcoolnessmodificator = (INT8) atol(pData->szCharData); + + // no nonsense, only values between -20 and + 20 + pData->curItem.randomitemcoolnessmodificator = min(20, max(-20, pData->curItem.randomitemcoolnessmodificator) ); + } + + pData->maxReadDepth--; } @@ -2034,7 +2050,9 @@ BOOLEAN WriteItemStats() FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usActionItemFlag ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].clothestype ); - + FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].randomitem ); + FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].randomitemcoolnessmodificator ); + FilePrintf(hFile,"\t\r\n"); } FilePrintf(hFile,"\r\n");