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");