diff --git a/GameSettings.cpp b/GameSettings.cpp
index 57cd4aab..52e04281 100644
--- a/GameSettings.cpp
+++ b/GameSettings.cpp
@@ -463,6 +463,8 @@ void LoadGameExternalOptions()
gGameExternalOptions.gfHardAggressiveQueen = iniReader.ReadBoolean("JA2 Gameplay Settings","EXPERT_QUEEN_AGGRESSIVE",FALSE);
gGameExternalOptions.gfInsaneAggressiveQueen = iniReader.ReadBoolean("JA2 Gameplay Settings","INSANE_QUEEN_AGGRESSIVE",TRUE);
+ // WANNE: Drop Items
+ gGameExternalOptions.ubEnemiesItemDrop = iniReader.ReadInteger("JA2 Gameplay Settings","ENEMIES_ITEM_DROP", 0);
// Militia settings
gGameExternalOptions.gfAllowMilitiaGroups = iniReader.ReadBoolean("JA2 Gameplay Settings","ALLOW_MILITIA_MOBILE_GROUPS",0);
@@ -517,6 +519,9 @@ void LoadGameExternalOptions()
gGameExternalOptions.fEnableAllTerrorists = iniReader.ReadBoolean("JA2 Gameplay Settings", "ENABLE_ALL_TERRORISTS", FALSE);
gGameExternalOptions.fEnableAllWeaponCaches = iniReader.ReadBoolean("JA2 Gameplay Settings", "ENABLE_ALL_WEAPON_CACHES", FALSE);
+
+ // Kaiden: Vehicle Inventory change - Added INI file Option VEHICLE_INVENTORY
+ gGameExternalOptions.fVehicleInventory = iniReader.ReadBoolean("JA2 Gameplay Settings", "VEHICLE_INVENTORY", TRUE);
}
diff --git a/GameSettings.h b/GameSettings.h
index d20c85de..7dbcbd78 100644
--- a/GameSettings.h
+++ b/GameSettings.h
@@ -185,7 +185,8 @@ typedef struct
INT8 iExperiencedAPBonus;
INT8 iExpertAPBonus;
INT8 iInsaneAPBonus;
-
+ // Kaiden: Vehicle Inventory change - Added for INI Option
+ BOOLEAN fVehicleInventory;
// System settings
UINT8 gubDeadLockDelay;
@@ -304,6 +305,9 @@ typedef struct
BOOLEAN gfHardAggressiveQueen;
BOOLEAN gfInsaneAggressiveQueen;
+ // WANNE
+ INT32 ubEnemiesItemDrop;
+
//Merc Assignment settings
INT32 ubAssignmentUnitsPerDay;
INT32 ubMinutesForAssignmentToCount;
diff --git a/Init.cpp b/Init.cpp
index a68d423e..f055da35 100644
--- a/Init.cpp
+++ b/Init.cpp
@@ -87,6 +87,46 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
{
char fileName[MAX_PATH];
+ // WANNE: Enemy drops
+ strcpy(fileName, directoryName);
+ strcat(fileName, ENEMYMISCDROPSFILENAME);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInEnemyMiscDropsStats(gEnemyMiscDrops, fileName))
+ return FALSE;
+
+ strcpy(fileName, directoryName);
+ strcat(fileName, ENEMYEXPLOSIVEDROPSFILENAME);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInEnemyExplosiveDropsStats(gEnemyExplosiveDrops, fileName))
+ return FALSE;
+
+ strcpy(fileName, directoryName);
+ strcat(fileName, ENEMYWEAPONDROPSFILENAME);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInEnemyWeaponDropsStats(gEnemyWeaponDrops, fileName))
+ return FALSE;
+
+ strcpy(fileName, directoryName);
+ strcat(fileName, ENEMYAMMODROPSFILENAME);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInEnemyAmmoDropsStats(gEnemyAmmoDrops, fileName))
+ return FALSE;
+
+ strcpy(fileName, directoryName);
+ strcat(fileName, ENEMYARMOURDROPSFILENAME);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInEnemyArmourDropsStats(gEnemyArmourDrops, fileName))
+ return FALSE;
+
+
+
+
+
+
+
+
+ // --------
+
strcpy(fileName, directoryName);
strcat(fileName, AMMOTYPESFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
diff --git a/JA2.suo b/JA2.suo
index d6b6bfb7..fb2507e6 100644
Binary files a/JA2.suo and b/JA2.suo differ
diff --git a/Strategic/mapscreen.cpp b/Strategic/mapscreen.cpp
index a21efac2..c48503d5 100644
--- a/Strategic/mapscreen.cpp
+++ b/Strategic/mapscreen.cpp
@@ -11462,7 +11462,10 @@ BOOLEAN MapCharacterHasAccessibleInventory( INT8 bCharNumber )
if( ( pSoldier->bAssignment == IN_TRANSIT ) ||
( pSoldier->bAssignment == ASSIGNMENT_POW ) ||
- ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ||
+ // Kaiden: Vehicle Inventory change - Commented the following line
+ // ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ||
+ // And added this instead:
+ ( (!gGameExternalOptions.fVehicleInventory) && (pSoldier->uiStatusFlags & SOLDIER_VEHICLE) ) ||
( AM_A_ROBOT( pSoldier ) ) ||
( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__EPC ) ||
( pSoldier->bLife < OKLIFE )
diff --git a/Tactical/Animation Data.cpp b/Tactical/Animation Data.cpp
index 16cb2def..05b51ba4 100644
--- a/Tactical/Animation Data.cpp
+++ b/Tactical/Animation Data.cpp
@@ -448,14 +448,21 @@ AnimationSurfaceType gAnimSurfaceDatabase[ NUMANIMATIONSURFACETYPES ] =
TANKNE_READY, "ANIMS\\VEHICLES\\TNK2_ROT.STI", S_STRUCT, ANIM_DATA_FLAG_NOFRAMES, 32, TO_INIT, NULL, NULL, 0, -1,
TANKNE_SHOOT, "ANIMS\\VEHICLES\\TNK2_SHT.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
TANKNE_DIE, "ANIMS\\VEHICLES\\TK2_WREK.STI", S_STRUCT, 0, 1, TO_INIT, NULL, NULL, 0, -1,
-
- ELDORADO_BASIC, "ANIMS\\VEHICLES\\HUMMER.STI", S_STRUCT, ANIM_DATA_FLAG_NOFRAMES, 32, TO_INIT, NULL, NULL, 0, -1,
+ //Kaiden: Below, I have replaced HUMMER2.STI with
+ // ELDORADO.STI and JEEP.STI respectively,
+ // This has not been tested for effect, however,
+ // It should not result in anything worse than
+ // Bad animations if it's not going to work.
+ // And in that case, anyone comfortable with STI
+ // Animations should be able to make them presentable.
+ // Test it and remove it if neccessary.
+ ELDORADO_BASIC, "ANIMS\\VEHICLES\\ELDRDO.STI", S_STRUCT, ANIM_DATA_FLAG_NOFRAMES, 32, TO_INIT, NULL, NULL, 0, -1,
ELDORADO_DIE, "ANIMS\\VEHICLES\\HM_WREK.STI", NO_STRUCT, 0, 2, TO_INIT, NULL, NULL, 0, -1,
ICECREAMTRUCK_BASIC,"ANIMS\\VEHICLES\\ICECRM.STI", S_STRUCT, ANIM_DATA_FLAG_NOFRAMES, 32, TO_INIT, NULL, NULL, 0, -1,
ICECREAMTRUCK_DIE, "ANIMS\\VEHICLES\\HM_WREK.STI", NO_STRUCT, 0, 2, TO_INIT, NULL, NULL, 0, -1,
- JEEP_BASIC, "ANIMS\\VEHICLES\\HUMMER.STI", S_STRUCT, ANIM_DATA_FLAG_NOFRAMES, 32, TO_INIT, NULL, NULL, 0, -1,
+ JEEP_BASIC, "ANIMS\\VEHICLES\\JEEP.STI", S_STRUCT, ANIM_DATA_FLAG_NOFRAMES, 32, TO_INIT, NULL, NULL, 0, -1,
JEEP_DIE, "ANIMS\\VEHICLES\\HM_WREK.STI", NO_STRUCT, 0, 2, TO_INIT, NULL, NULL, 0, -1,
BODYEXPLODE, "ANIMS\\S_MERC\\BOD_BLOW.STI", NO_STRUCT, 0, 1, TO_INIT, NULL, NULL, 0, -1,
diff --git a/Tactical/EnemyItemDrops.cpp b/Tactical/EnemyItemDrops.cpp
new file mode 100644
index 00000000..55b35e13
--- /dev/null
+++ b/Tactical/EnemyItemDrops.cpp
@@ -0,0 +1,14 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "Types.h"
+ #include "Item Types.h"
+ #include "DEbug.h"
+ #include "EnemyItemDrops.h"
+#endif
+
+WEAPON_DROPS gEnemyWeaponDrops[MAX_DROP_ITEMS];
+AMMO_DROPS gEnemyAmmoDrops[MAX_DROP_ITEMS];
+EXPLOSIVE_DROPS gEnemyExplosiveDrops[MAX_DROP_ITEMS];
+ARMOUR_DROPS gEnemyArmourDrops[MAX_DROP_ITEMS];
+MISC_DROPS gEnemyMiscDrops[MAX_DROP_ITEMS];
\ No newline at end of file
diff --git a/Tactical/EnemyItemDrops.h b/Tactical/EnemyItemDrops.h
new file mode 100644
index 00000000..d31f3831
--- /dev/null
+++ b/Tactical/EnemyItemDrops.h
@@ -0,0 +1,47 @@
+#ifndef _ENEMY_ITEM_DROPS__H_
+#define _ENEMY_ITEM_DROPS__H_
+
+#define MAX_DROP_ITEMS 100
+
+typedef struct
+{
+ UINT8 ubWeaponType;
+ UINT8 ubDropRate;
+ UINT32 uiIndex;
+} WEAPON_DROPS;
+
+typedef struct
+{
+ UINT32 uiType;
+ UINT8 ubDropRate;
+ UINT32 uiIndex;
+} AMMO_DROPS;
+
+typedef struct
+{
+ UINT8 ubType;
+ UINT8 ubDropRate;
+ UINT32 uiIndex;
+} EXPLOSIVE_DROPS;
+
+typedef struct
+{
+ UINT8 ubArmourClass;
+ UINT8 ubDropRate;
+ UINT32 uiIndex;
+} ARMOUR_DROPS;
+
+typedef struct
+{
+ UINT32 usItemClass;
+ UINT8 ubDropRate;
+ UINT32 uiIndex;
+} MISC_DROPS;
+
+extern WEAPON_DROPS gEnemyWeaponDrops[MAX_DROP_ITEMS];
+extern AMMO_DROPS gEnemyAmmoDrops[MAX_DROP_ITEMS];
+extern EXPLOSIVE_DROPS gEnemyExplosiveDrops[MAX_DROP_ITEMS];
+extern ARMOUR_DROPS gEnemyArmourDrops[MAX_DROP_ITEMS];
+extern MISC_DROPS gEnemyMiscDrops[MAX_DROP_ITEMS];
+
+#endif
\ No newline at end of file
diff --git a/Tactical/Interface Items.cpp b/Tactical/Interface Items.cpp
index 00530d94..4443d523 100644
--- a/Tactical/Interface Items.cpp
+++ b/Tactical/Interface Items.cpp
@@ -558,7 +558,8 @@ MOUSE_REGION gSMInvCamoRegion;
INT8 gbCompatibleAmmo[ NUM_INV_SLOTS ];
INT8 gbInvalidPlacementSlot[ NUM_INV_SLOTS ];
UINT16 us16BPPItemCyclePlacedItemColors[ 20 ];
-UINT32 guiBodyInvVO[ 4 ][ 2 ];
+// Kaiden: Vehicle Inventory change - Increase this from 4-2 to 5-2
+UINT32 guiBodyInvVO[ 5 ][ 2 ];
UINT32 guiGoldKeyVO;
INT8 gbCompatibleApplyItem = FALSE;
@@ -890,6 +891,19 @@ BOOLEAN InitInvSlotInterface( INV_REGION_DESC *pRegionDesc , INV_REGION_DESC *pC
FilenameForBPP("INTERFACE\\inventory_figure_female_H.sti", VObjectDesc.ImageFile);
CHECKF( AddVideoObject( &VObjectDesc, &(guiBodyInvVO[ 3 ][ 1 ] ) ) );
+ // Kaiden: Vehicle Inventory change - Added two new STI's for Vehicle Inventory
+ // Feel free to change them to more appropriate pictures, I just blanked out
+ // the body image for now, I'm no graphics artist.
+ VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
+ FilenameForBPP("INTERFACE\\inventory_figure_Vehicle.sti",
+VObjectDesc.ImageFile);
+ CHECKF( AddVideoObject( &VObjectDesc, &(guiBodyInvVO[ 4 ][ 0 ] ) ) );
+
+ VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
+ FilenameForBPP("INTERFACE\\inventory_figure_Vehicle_h.sti",
+VObjectDesc.ImageFile);
+ CHECKF( AddVideoObject( &VObjectDesc, &(guiBodyInvVO[ 4 ][ 1 ] ) ) );
+
// add gold key graphic
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
FilenameForBPP("INTERFACE\\gold_key_button.sti", VObjectDesc.ImageFile);
@@ -993,15 +1007,20 @@ void ShutdownInvSlotInterface( )
{
UINT32 cnt;
+ // Kaiden: Vehicle Inventory change - Added 4-0 and 4-1
+ // to be deleted as well.
+
// Remove all body type panels
DeleteVideoObjectFromIndex( guiBodyInvVO[ 0 ][ 0 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 2 ][ 0 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 1 ][ 0 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 3 ][ 0 ] );
+ DeleteVideoObjectFromIndex( guiBodyInvVO[ 4 ][ 0 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 0 ][ 1 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 2 ][ 1 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 1 ][ 1 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 3 ][ 1 ] );
+ DeleteVideoObjectFromIndex( guiBodyInvVO[ 4 ][ 1 ] );
DeleteVideoObjectFromIndex( guiGoldKeyVO );
@@ -1023,9 +1042,18 @@ void RenderInvBodyPanel( SOLDIERTYPE *pSoldier, INT16 sX, INT16 sY )
// Blit body inv, based on body type
INT8 bSubImageIndex = gbCompatibleApplyItem;
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiBodyInvVO[ pSoldier->ubBodyType ][ bSubImageIndex ], 0, sX, sY, VO_BLT_SRCTRANSPARENCY, NULL );
-}
+ // Kaiden: Vehicle Inventory change - Added IF Test, Else function call was
+ // the original statement
+ if ( (gGameExternalOptions.fVehicleInventory) && (pSoldier->uiStatusFlags & SOLDIER_VEHICLE) )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiBodyInvVO[4][0], 0, sX, sY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ else
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiBodyInvVO[ pSoldier->ubBodyType ][ bSubImageIndex ], 0, sX, sY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+}
void HandleRenderInvSlots( SOLDIERTYPE *pSoldier, UINT8 fDirtyLevel )
{
@@ -5018,7 +5046,11 @@ BOOLEAN HandleItemPointerClick( UINT16 usMapPos )
{
sGridNo = usMapPos;
- if ( sDist <= PASSING_ITEM_DISTANCE_OKLIFE && gfUIFullTargetFound && MercPtrs[ gusUIFullTargetID ]->bTeam == gbPlayerNum && !AM_AN_EPC( MercPtrs[ gusUIFullTargetID ] ) && !( MercPtrs[ gusUIFullTargetID ]->uiStatusFlags & SOLDIER_VEHICLE ) )
+ // Kaiden: Vehicle Inventory change - Commented the following If test:
+ //if ( sDist <= PASSING_ITEM_DISTANCE_OKLIFE && gfUIFullTargetFound && MercPtrs[ gusUIFullTargetID ]->bTeam == gbPlayerNum && !AM_AN_EPC( MercPtrs[ gusUIFullTargetID ] ) && !( MercPtrs[ gusUIFullTargetID ]->uiStatusFlags & SOLDIER_VEHICLE ) )
+
+ // And added this one instead:
+ if ( ( sDist <= PASSING_ITEM_DISTANCE_OKLIFE && gfUIFullTargetFound && MercPtrs[ gusUIFullTargetID ]->bTeam == gbPlayerNum && !AM_AN_EPC( MercPtrs[ gusUIFullTargetID ] ) ) && !( (!gGameExternalOptions.fVehicleInventory) && (MercPtrs[ gusUIFullTargetID ]->uiStatusFlags & SOLDIER_VEHICLE) ) )
{
// OK, do the transfer...
{
@@ -5119,7 +5151,11 @@ BOOLEAN HandleItemPointerClick( UINT16 usMapPos )
{
pSoldier = MercPtrs[ gusUIFullTargetID ];
- if ( pSoldier->bTeam == gbPlayerNum && pSoldier->bLife >= OKLIFE && !AM_AN_EPC( pSoldier ) && !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) )
+ // Kaiden: Vehicle Inventory change - Commented the following If Test:
+ //if ( pSoldier->bTeam == gbPlayerNum && pSoldier->bLife >= OKLIFE && !AM_AN_EPC( pSoldier ) && !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) )
+
+ // And replaced it with this one:
+ if ( ( pSoldier->bTeam == gbPlayerNum && pSoldier->bLife >= OKLIFE && !AM_AN_EPC( pSoldier ) ) && !( ( !gGameExternalOptions.fVehicleInventory ) && ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) )
{
// OK, on our team,
diff --git a/Tactical/Inventory Choosing.cpp b/Tactical/Inventory Choosing.cpp
index a848efeb..2d1060dd 100644
--- a/Tactical/Inventory Choosing.cpp
+++ b/Tactical/Inventory Choosing.cpp
@@ -2005,6 +2005,7 @@ BOOLEAN PlaceObjectInSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, OBJECTTYPE *
void RandomlyChooseWhichItemsAreDroppable( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass )
{
INT32 i;
+ INT32 j;
// UINT16 usRandomNum;
UINT32 uiItemClass;
UINT8 ubNumMatches = 0;
@@ -2020,6 +2021,7 @@ void RandomlyChooseWhichItemsAreDroppable( SOLDIERCREATE_STRUCT *pp, INT8 bSoldi
BOOLEAN fKit = FALSE;
BOOLEAN fFace = FALSE;
BOOLEAN fMisc = FALSE;
+ UINT32 uiRandomValue = 0;
//Madd
if ( gGameSettings.fOptions[TOPTION_DROP_ALL] )
@@ -2033,12 +2035,27 @@ if ( gGameSettings.fOptions[TOPTION_DROP_ALL] )
}
else
{
- ENEMYAMMODROPRATE = 50;
- ENEMYGRENADEDROPRATE = 25;
- ENEMYEQUIPDROPRATE = 15;
- MILITIAAMMODROPRATE = 5;
- MILITIAGRENADEDROPRATE = 3;
- MILITIAEQUIPDROPRATE = 2;
+ // Default random drop
+ if (gGameExternalOptions.ubEnemiesItemDrop == 0)
+ {
+ ENEMYAMMODROPRATE = 50;
+ ENEMYGRENADEDROPRATE = 25;
+ ENEMYEQUIPDROPRATE = 15;
+ MILITIAAMMODROPRATE = 5;
+ MILITIAGRENADEDROPRATE = 3;
+ MILITIAEQUIPDROPRATE = 2;
+ }
+ // Get drop rate from XML-Files
+ else
+ {
+ // Reset, because it is not used anymore
+ ENEMYAMMODROPRATE = -1;
+ ENEMYGRENADEDROPRATE = -1;
+ ENEMYEQUIPDROPRATE = -1;
+ MILITIAAMMODROPRATE = -1;
+ MILITIAGRENADEDROPRATE = -1;
+ MILITIAEQUIPDROPRATE = -1;
+ }
}
/*
@@ -2132,20 +2149,24 @@ else
}
else
{
- // if it's a weapon (monster parts included - they won't drop due to checks elsewhere!)
- if ((usItem > NONE) && (usItem < MAXITEMS )) // Madd -- this should be ok set to maxitems instead of max_Weapons
+ // Default random drop
+ if (gGameExternalOptions.ubEnemiesItemDrop == 0)
{
- // and we're allowed to change its flags
- if(! (pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE ))
+ // if it's a weapon (monster parts included - they won't drop due to checks elsewhere!)
+ if ((usItem > NONE) && (usItem < MAXITEMS )) // Madd -- this should be ok set to maxitems instead of max_Weapons
{
- // and it's never been dropped before in this game
- if (!gStrategicStatus.fWeaponDroppedAlready[usItem])
+ // and we're allowed to change its flags
+ if(! (pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE ))
{
- // mark it as droppable, and remember we did so. If the player never kills this particular dude, oh well,
- // tough luck, he missed his chance for an easy reward, he'll have to wait til next time and need some luck...
- pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ // and it's never been dropped before in this game
+ if (!gStrategicStatus.fWeaponDroppedAlready[usItem])
+ {
+ // mark it as droppable, and remember we did so. If the player never kills this particular dude, oh well,
+ // tough luck, he missed his chance for an easy reward, he'll have to wait til next time and need some luck...
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
- MarkAllWeaponsOfSameGunClassAsDropped( usItem );
+ MarkAllWeaponsOfSameGunClassAsDropped( usItem );
+ }
}
}
}
@@ -2157,71 +2178,60 @@ else
return;
-//Madd
- if( gGameSettings.fOptions[TOPTION_DROP_ALL] || Random(100) < ubAmmoDropRate )
- fAmmo = TRUE;
-//Madd
- if( gGameSettings.fOptions[TOPTION_DROP_ALL] || Random(100) < ubOtherDropRate )
- fWeapon = TRUE;
-
- if( Random(100) < ubOtherDropRate )
- fArmour = TRUE;
-
- if( Random(100) < ubOtherDropRate )
- fKnife = TRUE;
-
- if( Random(100) < ubGrenadeDropRate )
- fGrenades = TRUE;
-
- if( Random(100) < ubOtherDropRate )
- fKit = TRUE;
-
- if( Random(100) < (UINT32)(ubOtherDropRate / 3) )
- fFace = TRUE;
-
- if( Random(100) < ubOtherDropRate )
- fMisc = TRUE;
-
-
- //Now, that the flags are set for each item, we now have to search through the item slots to
- //see if we can find a matching item, however, if we find any items in a particular class that
- //have the OBJECT_NO_OVERWRITE flag set, we will not make any items droppable for that class
- //because the editor would have specified it already.
- if( fAmmo )
+ // WANNE: Randomly choose which type of items should be dropped
+ if (gGameExternalOptions.ubEnemiesItemDrop == 0)
{
- // now drops ALL ammo found, not just the first slot
- for( i = 0; i < NUM_INV_SLOTS; i++ )
+ if( /*gGameSettings.fOptions[TOPTION_DROP_ALL] ||*/ Random(100) < ubAmmoDropRate )
+ fAmmo = TRUE;
+
+ if( /*gGameSettings.fOptions[TOPTION_DROP_ALL] ||*/ Random(100) < ubOtherDropRate )
+ fWeapon = TRUE;
+
+ if( Random(100) < ubOtherDropRate )
+ fArmour = TRUE;
+
+ if( Random(100) < ubOtherDropRate )
+ fKnife = TRUE;
+
+ if( Random(100) < ubGrenadeDropRate )
+ fGrenades = TRUE;
+
+ if( Random(100) < ubOtherDropRate )
+ fKit = TRUE;
+
+ if( Random(100) < (UINT32)(ubOtherDropRate / 3) )
+ fFace = TRUE;
+
+ if( Random(100) < ubOtherDropRate )
+ fMisc = TRUE;
+
+
+ //Now, that the flags are set for each item, we now have to search through the item slots to
+ //see if we can find a matching item, however, if we find any items in a particular class that
+ //have the OBJECT_NO_OVERWRITE flag set, we will not make any items droppable for that class
+ //because the editor would have specified it already.
+ if( fAmmo )
{
- uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
- if( uiItemClass == IC_AMMO )
+ // now drops ALL ammo found, not just the first slot
+ for( i = 0; i < NUM_INV_SLOTS; i++ )
{
- if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
- continue;
- else
+ uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
+ if( uiItemClass == IC_AMMO )
{
- pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
+ continue;
+ else
+ {
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ }
}
}
}
- }
- if( fWeapon )
- {
- ubNumMatches = 0;
- for( i = 0; i < NUM_INV_SLOTS; i++ )
- {
- uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
- if( uiItemClass == IC_GUN || uiItemClass == IC_LAUNCHER )
- {
- if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
- break;
- else
- ubNumMatches++;
- }
- }
- if ( ubNumMatches > 0 )
+ if( fWeapon )
{
+ ubNumMatches = 0;
for( i = 0; i < NUM_INV_SLOTS; i++ )
{
uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
@@ -2229,32 +2239,32 @@ else
{
if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
break;
- else if( !Random( ubNumMatches-- ) )
+ else
+ ubNumMatches++;
+ }
+ }
+ if ( ubNumMatches > 0 )
+ {
+ for( i = 0; i < NUM_INV_SLOTS; i++ )
+ {
+ uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
+ if( uiItemClass == IC_GUN || uiItemClass == IC_LAUNCHER )
{
- pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
- break;
+ if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
+ break;
+ else if( !Random( ubNumMatches-- ) )
+ {
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ break;
+ }
}
}
}
}
- }
- if( fArmour )
- {
- ubNumMatches = 0;
- for( i = 0; i < NUM_INV_SLOTS; i++ )
- {
- uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
- if( uiItemClass == IC_ARMOUR )
- {
- if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
- break;
- else
- ubNumMatches++;
- }
- }
- if ( ubNumMatches > 0 )
+ if( fArmour )
{
+ ubNumMatches = 0;
for( i = 0; i < NUM_INV_SLOTS; i++ )
{
uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
@@ -2262,60 +2272,40 @@ else
{
if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
break;
- else if( !Random( ubNumMatches-- ) )
+ else
+ ubNumMatches++;
+ }
+ }
+ if ( ubNumMatches > 0 )
+ {
+ for( i = 0; i < NUM_INV_SLOTS; i++ )
+ {
+ uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
+ if( uiItemClass == IC_ARMOUR )
{
- pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
- break;
+ if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
+ break;
+ else if( !Random( ubNumMatches-- ) )
+ {
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ break;
+ }
}
}
}
}
- }
- if( fKnife)
- {
- for( i = 0; i < NUM_INV_SLOTS; i++ )
- {
- // drops FIRST knife found
- uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
- if( uiItemClass == IC_BLADE || uiItemClass == IC_THROWING_KNIFE )
- {
- if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
- break;
- else
- {
- pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
- break;
- }
- }
- }
- }
-
- // note that they'll only drop ONE TYPE of grenade if they have multiple types (very common)
- if( fGrenades )
- {
- ubNumMatches = 0;
- for( i = 0; i < NUM_INV_SLOTS; i++ )
- {
- uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
- if( uiItemClass & IC_GRENADE )
- {
- if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
- break;
- else
- ubNumMatches++;
- }
- }
- if ( ubNumMatches > 0 )
+ if( fKnife)
{
for( i = 0; i < NUM_INV_SLOTS; i++ )
{
+ // drops FIRST knife found
uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
- if( uiItemClass & IC_GRENADE )
+ if( uiItemClass == IC_BLADE || uiItemClass == IC_THROWING_KNIFE )
{
if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
break;
- else if( !Random( ubNumMatches-- ) )
+ else
{
pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
break;
@@ -2323,24 +2313,44 @@ else
}
}
}
- }
- if( fKit )
- {
- ubNumMatches = 0;
- for( i = 0; i < NUM_INV_SLOTS; i++ )
+ // note that they'll only drop ONE TYPE of grenade if they have multiple types (very common)
+ if( fGrenades )
{
- uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
- if( uiItemClass == IC_MEDKIT || uiItemClass == IC_KIT )
+ ubNumMatches = 0;
+ for( i = 0; i < NUM_INV_SLOTS; i++ )
{
- if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
- break;
- else
- ubNumMatches++;
+ uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
+ if( uiItemClass == IC_GRENADE )
+ {
+ if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
+ break;
+ else
+ ubNumMatches++;
+ }
+ }
+ if ( ubNumMatches > 0 )
+ {
+ for( i = 0; i < NUM_INV_SLOTS; i++ )
+ {
+ uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
+ if( uiItemClass == IC_GRENADE )
+ {
+ if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
+ break;
+ else if( !Random( ubNumMatches-- ) )
+ {
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ break;
+ }
+ }
+ }
}
}
- if ( ubNumMatches > 0 )
+
+ if( fKit )
{
+ ubNumMatches = 0;
for( i = 0; i < NUM_INV_SLOTS; i++ )
{
uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
@@ -2348,32 +2358,32 @@ else
{
if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
break;
- else if( !Random( ubNumMatches-- ) )
+ else
+ ubNumMatches++;
+ }
+ }
+ if ( ubNumMatches > 0 )
+ {
+ for( i = 0; i < NUM_INV_SLOTS; i++ )
+ {
+ uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
+ if( uiItemClass == IC_MEDKIT || uiItemClass == IC_KIT )
{
- pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
- break;
+ if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
+ break;
+ else if( !Random( ubNumMatches-- ) )
+ {
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ break;
+ }
}
}
}
}
- }
- if( fFace )
- {
- ubNumMatches = 0;
- for( i = 0; i < NUM_INV_SLOTS; i++ )
- {
- uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
- if( uiItemClass == IC_FACE )
- {
- if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
- break;
- else
- ubNumMatches++;
- }
- }
- if ( ubNumMatches > 0 )
+ if( fFace )
{
+ ubNumMatches = 0;
for( i = 0; i < NUM_INV_SLOTS; i++ )
{
uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
@@ -2381,32 +2391,32 @@ else
{
if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
break;
- else if( !Random( ubNumMatches-- ) )
+ else
+ ubNumMatches++;
+ }
+ }
+ if ( ubNumMatches > 0 )
+ {
+ for( i = 0; i < NUM_INV_SLOTS; i++ )
+ {
+ uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
+ if( uiItemClass == IC_FACE )
{
- pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
- break;
+ if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
+ break;
+ else if( !Random( ubNumMatches-- ) )
+ {
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ break;
+ }
}
}
}
}
- }
- if( fMisc )
- {
- ubNumMatches = 0;
- for( i = 0; i < NUM_INV_SLOTS; i++ )
- {
- uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
- if( uiItemClass == IC_MISC )
- {
- if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
- break;
- else
- ubNumMatches++;
- }
- }
- if ( ubNumMatches > 0 )
+ if( fMisc )
{
+ ubNumMatches = 0;
for( i = 0; i < NUM_INV_SLOTS; i++ )
{
uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
@@ -2414,15 +2424,183 @@ else
{
if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
break;
- else if( !Random( ubNumMatches-- ) )
+ else
+ ubNumMatches++;
+ }
+ }
+ if ( ubNumMatches > 0 )
+ {
+ for( i = 0; i < NUM_INV_SLOTS; i++ )
+ {
+ uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
+ if( uiItemClass == IC_MISC )
{
- pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
- break;
+ if( pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
+ break;
+ else if( !Random( ubNumMatches-- ) )
+ {
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ break;
+ }
}
}
}
}
}
+ // WANNE: Drop-rate from different XML-Files
+ else if (gGameExternalOptions.ubEnemiesItemDrop == 1)
+ {
+ // Loop through the enemy inter
+ for( i = 0; i < NUM_INV_SLOTS; i++ )
+ {
+ uiItemClass = Item[ pp->Inv[ i ].usItem ].usItemClass;
+
+ // We are allowed to change the object and it is not the first (nothing) object
+ if(! (pp->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE ) && pp->Inv[ i ].usItem != 0)
+ {
+ // Weapon
+ if( uiItemClass == IC_GUN || uiItemClass == IC_BLADE ||
+ uiItemClass == IC_THROWING_KNIFE || uiItemClass == IC_LAUNCHER ||
+ uiItemClass == IC_TENTACLES || uiItemClass == IC_THROWN ||
+ uiItemClass == IC_PUNCH)
+ {
+ // Find matching weaponType in the XML
+ for (j = 0; j < MAX_DROP_ITEMS; j++)
+ {
+ // We have no more weapon items -> exit from loop
+ if (j > 0 && gEnemyWeaponDrops[j].uiIndex == 0)
+ break;
+
+ // We found the matching weapon type
+ if (Weapon[ Item[ pp->Inv[ i ].usItem ].ubClassIndex ].ubWeaponType == gEnemyWeaponDrops[j].ubWeaponType)
+ {
+ uiRandomValue = Random(100);
+
+ if (uiRandomValue == 0)
+ uiRandomValue++;
+
+ // Drop the weapon!
+ if (uiRandomValue <= gEnemyWeaponDrops[j].ubDropRate)
+ {
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ }
+ break;
+ }
+ }
+ }
+ // Ammo
+ else if (uiItemClass == IC_AMMO)
+ {
+ // Find matching ammo in the XML
+ for (j = 0; j < MAX_DROP_ITEMS; j++)
+ {
+ // We have no more ammo items -> exit from loop
+ if (j > 0 && gEnemyAmmoDrops[j].uiIndex == 0)
+ break;
+
+ // We found the matching ammo type
+ if (Magazine[ Item[ pp->Inv[ i ].usItem ].ubClassIndex ].ubAmmoType == gEnemyAmmoDrops[j].uiType)
+ {
+ uiRandomValue = Random(100);
+
+ if (uiRandomValue == 0)
+ uiRandomValue++;
+
+ // Drop the weapon!
+ if (uiRandomValue <= gEnemyAmmoDrops[j].ubDropRate)
+ {
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ }
+ break;
+ }
+ }
+ }
+ // Explosive
+ else if (uiItemClass == IC_GRENADE || uiItemClass == IC_BOMB)
+ {
+ // Find matching explosive in the XML
+ for (j = 0; j < MAX_DROP_ITEMS; j++)
+ {
+ // We have no more explosive items -> exit from loop
+ if (j > 0 && gEnemyExplosiveDrops[j].uiIndex == 0)
+ break;
+
+ // We found the matching explosive type
+ if (Explosive[Item[ pp->Inv[ i ].usItem ].ubClassIndex].ubType == gEnemyExplosiveDrops[j].ubType)
+ {
+ uiRandomValue = Random(100);
+
+ if (uiRandomValue == 0)
+ uiRandomValue++;
+
+ // Drop the weapon!
+ if (uiRandomValue <= gEnemyExplosiveDrops[j].ubDropRate)
+ {
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ }
+ break;
+ }
+ }
+ }
+ // Armour
+ else if (uiItemClass == IC_ARMOUR)
+ {
+ // Find matching armour in the XML
+ for (j = 0; j < MAX_DROP_ITEMS; j++)
+ {
+ // We have no more armour items -> exit from loop
+ if (j > 0 && gEnemyArmourDrops[j].uiIndex == 0)
+ break;
+
+ // We found the matching armour type
+ if (Armour[ Item[ pp->Inv[ i ].usItem ].ubClassIndex ].ubArmourClass == gEnemyArmourDrops[j].ubArmourClass)
+ {
+ uiRandomValue = Random(100);
+
+ if (uiRandomValue == 0)
+ uiRandomValue++;
+
+ // Drop the weapon!
+ if (uiRandomValue <= gEnemyArmourDrops[j].ubDropRate)
+ {
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ }
+ break;
+ }
+ }
+ }
+ // Misc
+ else if (uiItemClass == IC_MEDKIT || uiItemClass == IC_KIT ||
+ uiItemClass == IC_APPLIABLE || uiItemClass == IC_FACE ||
+ uiItemClass == IC_KEY || uiItemClass == IC_MISC || uiItemClass == IC_MONEY)
+ {
+ // Find matching armour in the XML
+ for (j = 0; j < MAX_DROP_ITEMS; j++)
+ {
+ // We have no more armour items -> exit from loop
+ if (j > 0 && gEnemyMiscDrops[j].uiIndex == 0)
+ break;
+
+ // We found the matching armour type
+ if (Item[ pp->Inv[ i ].usItem ].usItemClass == gEnemyMiscDrops[j].usItemClass)
+ {
+ uiRandomValue = Random(100);
+
+ if (uiRandomValue == 0)
+ uiRandomValue++;
+
+ // Drop the weapon!
+ if (uiRandomValue <= gEnemyMiscDrops[j].ubDropRate)
+ {
+ pp->Inv[ i ].fFlags &= ~OBJECT_UNDROPPABLE;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
}
diff --git a/Tactical/Tactical All.h b/Tactical/Tactical All.h
index a715c663..6bf473cb 100644
--- a/Tactical/Tactical All.h
+++ b/Tactical/Tactical All.h
@@ -210,6 +210,8 @@
#include "Game Events.h"
#include "BobbyR.h"
+#include "EnemyItemDrops.h"
+
#ifdef JA2BETAVERSION
#include "Quest Debug System.h"
#endif
diff --git a/Tactical/Tactical.vcproj b/Tactical/Tactical.vcproj
index 3bc17bf4..cafa517b 100644
--- a/Tactical/Tactical.vcproj
+++ b/Tactical/Tactical.vcproj
@@ -1638,6 +1638,9 @@
BrowseInformation="1"/>
+
+
+
+
+
+
+
+
+
+
+
+
@@ -5640,6 +5658,9 @@
+
+
diff --git a/Tactical/XML.h b/Tactical/XML.h
index 53a3d339..543f3ca7 100644
--- a/Tactical/XML.h
+++ b/Tactical/XML.h
@@ -2,6 +2,7 @@
#define __XML_H
#include "armsdealerinvinit.h"
+#include "EnemyItemDrops.h"
enum
{
@@ -67,6 +68,14 @@ typedef PARSE_STAGE;
#define EXPLOSIONDATAFILENAME "ExplosionData.xml"
#define CITYTABLEFILENAME "Cities.xml"
+// WANNE: drops filename
+#define ENEMYWEAPONDROPSFILENAME "EnemyWeaponDrops.xml"
+#define ENEMYAMMODROPSFILENAME "EnemyAmmoDrops.xml"
+#define ENEMYEXPLOSIVEDROPSFILENAME "EnemyExplosiveDrops.xml"
+#define ENEMYARMOURDROPSFILENAME "EnemyArmourDrops.xml"
+#define ENEMYMISCDROPSFILENAME "EnemyMiscDrops.xml"
+
+
extern BOOLEAN ReadInItemStats(STR fileName, BOOLEAN localizedVersion);
extern BOOLEAN WriteItemStats();
@@ -124,6 +133,18 @@ extern BOOLEAN ReadInSoundArray(STR fileName);
extern BOOLEAN ReadInAmmoTypeStats(STR fileName);
extern BOOLEAN WriteAmmoTypeStats();
+// WANNE: Enemy drops
+extern BOOLEAN ReadInEnemyWeaponDropsStats(WEAPON_DROPS *pEnemyWeaponDrops, STR fileName);
+extern BOOLEAN WriteEnemyWeaponDropsStats(WEAPON_DROPS *pEnemyWeaponDrops, STR fileName);
+extern BOOLEAN ReadInEnemyAmmoDropsStats(AMMO_DROPS *pEnemyAmmoDrops, STR fileName);
+extern BOOLEAN WriteEnemyAmmoDropsStats(AMMO_DROPS *pEnemyAmmoDrops, STR fileName);
+extern BOOLEAN ReadInEnemyExplosiveDropsStats(EXPLOSIVE_DROPS *pEnemyExplosiveDrops, STR fileName);
+extern BOOLEAN WriteEnemyExplosiveDropsStats(EXPLOSIVE_DROPS *pEnemyExplosiveDrops, STR fileName);
+extern BOOLEAN ReadInEnemyArmourDropsStats(ARMOUR_DROPS *pEnemyArmourDrops, STR fileName);
+extern BOOLEAN WriteEnemyArmourDropsStats(ARMOUR_DROPS *pEnemyArmourDrops, STR fileName);
+extern BOOLEAN ReadInEnemyMiscDropsStats(MISC_DROPS *pEnemyMiscDrops, STR fileName);
+extern BOOLEAN WriteEnemyMiscDropsStats(MISC_DROPS *pEnemyMiscDrops, STR fileName);
+
// Lesh: 2 lines added
extern BOOLEAN ReadInBurstSoundArray(STR fileName);
extern BOOLEAN WriteBurstSoundArray();
diff --git a/Tactical/XML_EnemyAmmoDrops.cpp b/Tactical/XML_EnemyAmmoDrops.cpp
new file mode 100644
index 00000000..b7e26fd7
--- /dev/null
+++ b/Tactical/XML_EnemyAmmoDrops.cpp
@@ -0,0 +1,254 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "overhead types.h"
+ #include "Sound Control.h"
+ #include "Soldier Control.h"
+ #include "overhead.h"
+ #include "Event Pump.h"
+ #include "weapons.h"
+ #include "Animation Control.h"
+ #include "sys globals.h"
+ #include "Handle UI.h"
+ #include "Isometric Utils.h"
+ #include "worldman.h"
+ #include "math.h"
+ #include "points.h"
+ #include "ai.h"
+ #include "los.h"
+ #include "renderworld.h"
+ #include "opplist.h"
+ #include "interface.h"
+ #include "message.h"
+ #include "campaign.h"
+ #include "items.h"
+ #include "text.h"
+ #include "Soldier Profile.h"
+ #include "tile animation.h"
+ #include "Dialogue Control.h"
+ #include "SkillCheck.h"
+ #include "explosion control.h"
+ #include "Quests.h"
+ #include "Physics.h"
+ #include "Random.h"
+ #include "Vehicles.h"
+ #include "bullets.h"
+ #include "morale.h"
+ #include "meanwhile.h"
+ #include "SkillCheck.h"
+ #include "gamesettings.h"
+ #include "SaveLoadMap.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "EnemyItemDrops.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ INT8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ AMMO_DROPS curAmmoDrop;
+ AMMO_DROPS * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef ammoDropParseData;
+
+static void XMLCALL
+ammoDropStartElementHandle(void *userData, const char *name, const char **atts)
+{
+ ammoDropParseData * pData = (ammoDropParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "AMMODROPLIST") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ memset(pData->curArray,0,sizeof(AMMO_DROPS)*pData->maxArraySize);
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "DROPITEM") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ memset(&pData->curAmmoDrop,0,sizeof(AMMO_DROPS));
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "uiType") == 0 ||
+ strcmp(name, "ubDropRate") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+ammoDropCharacterDataHandle(void *userData, const char *str, int len)
+{
+ ammoDropParseData * pData = (ammoDropParseData *)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
+ammoDropEndElementHandle(void *userData, const char *name)
+{
+ ammoDropParseData * pData = (ammoDropParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "AMMODROPLIST") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "DROPITEM") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if(pData->curAmmoDrop.uiIndex < pData->maxArraySize)
+ {
+ pData->curArray[pData->curAmmoDrop.uiIndex] = pData->curAmmoDrop; //write the inventory into the table
+ }
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAmmoDrop.uiIndex = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "uiType") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAmmoDrop.uiType = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ubDropRate") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAmmoDrop.ubDropRate = (UINT8) atol(pData->szCharData);
+ }
+
+ pData->maxReadDepth--;
+ }
+
+ pData->currentDepth--;
+}
+
+
+
+
+BOOLEAN ReadInEnemyAmmoDropsStats(AMMO_DROPS *pEnemyAmmoDrops, STR fileName)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ ammoDropParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading EnemyAmmoDrops.xml" );
+
+ // Open inventory 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, ammoDropStartElementHandle, ammoDropEndElementHandle);
+ XML_SetCharacterDataHandler(parser, ammoDropCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ pData.curArray = pEnemyAmmoDrops;
+ pData.maxArraySize = MAX_DROP_ITEMS;
+
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in EnemyAmmoDrops.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 WriteEnemyAmmoDropsStats(AMMO_DROPS *pEnemyAmmoDrops, STR fileName)
+{
+ 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( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < MAXITEMS;cnt++)
+ {
+
+ FilePrintf(hFile,"\t\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ FilePrintf(hFile,"\t\t%d\r\n", pEnemyAmmoDrops[cnt].uiType);
+ FilePrintf(hFile,"\t\t%d\r\n", pEnemyAmmoDrops[cnt].ubDropRate);
+
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
\ No newline at end of file
diff --git a/Tactical/XML_EnemyArmourDrops.cpp b/Tactical/XML_EnemyArmourDrops.cpp
new file mode 100644
index 00000000..c2c7067f
--- /dev/null
+++ b/Tactical/XML_EnemyArmourDrops.cpp
@@ -0,0 +1,254 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "overhead types.h"
+ #include "Sound Control.h"
+ #include "Soldier Control.h"
+ #include "overhead.h"
+ #include "Event Pump.h"
+ #include "weapons.h"
+ #include "Animation Control.h"
+ #include "sys globals.h"
+ #include "Handle UI.h"
+ #include "Isometric Utils.h"
+ #include "worldman.h"
+ #include "math.h"
+ #include "points.h"
+ #include "ai.h"
+ #include "los.h"
+ #include "renderworld.h"
+ #include "opplist.h"
+ #include "interface.h"
+ #include "message.h"
+ #include "campaign.h"
+ #include "items.h"
+ #include "text.h"
+ #include "Soldier Profile.h"
+ #include "tile animation.h"
+ #include "Dialogue Control.h"
+ #include "SkillCheck.h"
+ #include "explosion control.h"
+ #include "Quests.h"
+ #include "Physics.h"
+ #include "Random.h"
+ #include "Vehicles.h"
+ #include "bullets.h"
+ #include "morale.h"
+ #include "meanwhile.h"
+ #include "SkillCheck.h"
+ #include "gamesettings.h"
+ #include "SaveLoadMap.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "EnemyItemDrops.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ INT8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ ARMOUR_DROPS curArmourDrop;
+ ARMOUR_DROPS * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef armourDropParseData;
+
+static void XMLCALL
+armourDropStartElementHandle(void *userData, const char *name, const char **atts)
+{
+ armourDropParseData * pData = (armourDropParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "ARMOURDROPLIST") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ memset(pData->curArray,0,sizeof(ARMOUR_DROPS)*pData->maxArraySize);
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "DROPITEM") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ memset(&pData->curArmourDrop,0,sizeof(ARMOUR_DROPS));
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "ubArmourClass") == 0 ||
+ strcmp(name, "ubDropRate") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+armourDropCharacterDataHandle(void *userData, const char *str, int len)
+{
+ armourDropParseData * pData = (armourDropParseData *)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
+armourDropEndElementHandle(void *userData, const char *name)
+{
+ armourDropParseData * pData = (armourDropParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "ARMOURDROPLIST") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "DROPITEM") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if(pData->curArmourDrop.uiIndex < pData->maxArraySize)
+ {
+ pData->curArray[pData->curArmourDrop.uiIndex] = pData->curArmourDrop; //write the inventory into the table
+ }
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curArmourDrop.uiIndex = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ubArmourClass") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curArmourDrop.ubArmourClass = (UINT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ubDropRate") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curArmourDrop.ubDropRate = (UINT8) atol(pData->szCharData);
+ }
+
+ pData->maxReadDepth--;
+ }
+
+ pData->currentDepth--;
+}
+
+
+
+
+BOOLEAN ReadInEnemyArmourDropsStats(ARMOUR_DROPS *pEnemyArmourDrops, STR fileName)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ armourDropParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading EnemyArmourDrops.xml" );
+
+ // Open inventory 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, armourDropStartElementHandle, armourDropEndElementHandle);
+ XML_SetCharacterDataHandler(parser, armourDropCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ pData.curArray = pEnemyArmourDrops;
+ pData.maxArraySize = MAX_DROP_ITEMS;
+
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in EnemyArmourDrops.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 WriteEnemyArmourDropsStats(ARMOUR_DROPS *pEnemyArmourDrops, STR fileName)
+{
+ 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( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < MAXITEMS;cnt++)
+ {
+
+ FilePrintf(hFile,"\t\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ FilePrintf(hFile,"\t\t%d\r\n", pEnemyArmourDrops[cnt].ubArmourClass);
+ FilePrintf(hFile,"\t\t%d\r\n", pEnemyArmourDrops[cnt].ubDropRate);
+
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
\ No newline at end of file
diff --git a/Tactical/XML_EnemyExplosiveDrops.cpp b/Tactical/XML_EnemyExplosiveDrops.cpp
new file mode 100644
index 00000000..b641253e
--- /dev/null
+++ b/Tactical/XML_EnemyExplosiveDrops.cpp
@@ -0,0 +1,254 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "overhead types.h"
+ #include "Sound Control.h"
+ #include "Soldier Control.h"
+ #include "overhead.h"
+ #include "Event Pump.h"
+ #include "weapons.h"
+ #include "Animation Control.h"
+ #include "sys globals.h"
+ #include "Handle UI.h"
+ #include "Isometric Utils.h"
+ #include "worldman.h"
+ #include "math.h"
+ #include "points.h"
+ #include "ai.h"
+ #include "los.h"
+ #include "renderworld.h"
+ #include "opplist.h"
+ #include "interface.h"
+ #include "message.h"
+ #include "campaign.h"
+ #include "items.h"
+ #include "text.h"
+ #include "Soldier Profile.h"
+ #include "tile animation.h"
+ #include "Dialogue Control.h"
+ #include "SkillCheck.h"
+ #include "explosion control.h"
+ #include "Quests.h"
+ #include "Physics.h"
+ #include "Random.h"
+ #include "Vehicles.h"
+ #include "bullets.h"
+ #include "morale.h"
+ #include "meanwhile.h"
+ #include "SkillCheck.h"
+ #include "gamesettings.h"
+ #include "SaveLoadMap.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "EnemyItemDrops.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ INT8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ EXPLOSIVE_DROPS curExplosiveDrop;
+ EXPLOSIVE_DROPS * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef explosiveDropParseData;
+
+static void XMLCALL
+explosiveDropStartElementHandle(void *userData, const char *name, const char **atts)
+{
+ explosiveDropParseData * pData = (explosiveDropParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "EXPLOSIVEDROPLIST") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ memset(pData->curArray,0,sizeof(EXPLOSIVE_DROPS)*pData->maxArraySize);
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "DROPITEM") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ memset(&pData->curExplosiveDrop,0,sizeof(EXPLOSIVE_DROPS));
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "ubType") == 0 ||
+ strcmp(name, "ubDropRate") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+explosiveDropCharacterDataHandle(void *userData, const char *str, int len)
+{
+ explosiveDropParseData * pData = (explosiveDropParseData *)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
+explosiveDropEndElementHandle(void *userData, const char *name)
+{
+ explosiveDropParseData * pData = (explosiveDropParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "EXPLOSIVEDROPLIST") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "DROPITEM") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if(pData->curExplosiveDrop.uiIndex < pData->maxArraySize)
+ {
+ pData->curArray[pData->curExplosiveDrop.uiIndex] = pData->curExplosiveDrop; //write the inventory into the table
+ }
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curExplosiveDrop.uiIndex = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ubType") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curExplosiveDrop.ubType = (UINT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ubDropRate") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curExplosiveDrop.ubDropRate = (UINT8) atol(pData->szCharData);
+ }
+
+ pData->maxReadDepth--;
+ }
+
+ pData->currentDepth--;
+}
+
+
+
+
+BOOLEAN ReadInEnemyExplosiveDropsStats(EXPLOSIVE_DROPS *pEnemyExplosiveDrops, STR fileName)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ explosiveDropParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading EnemyExplosiveDrops.xml" );
+
+ // Open inventory 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, explosiveDropStartElementHandle, explosiveDropEndElementHandle);
+ XML_SetCharacterDataHandler(parser, explosiveDropCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ pData.curArray = pEnemyExplosiveDrops;
+ pData.maxArraySize = MAX_DROP_ITEMS;
+
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in EnemyExplosiveDrops.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 WriteEnemyExplosiveDropsStats(EXPLOSIVE_DROPS *pEnemyExplosiveDrops, STR fileName)
+{
+ 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( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < MAXITEMS;cnt++)
+ {
+
+ FilePrintf(hFile,"\t\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ FilePrintf(hFile,"\t\t%d\r\n", pEnemyExplosiveDrops[cnt].ubType);
+ FilePrintf(hFile,"\t\t%d\r\n", pEnemyExplosiveDrops[cnt].ubDropRate);
+
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
\ No newline at end of file
diff --git a/Tactical/XML_EnemyMiscDrops.cpp b/Tactical/XML_EnemyMiscDrops.cpp
new file mode 100644
index 00000000..d8c96537
--- /dev/null
+++ b/Tactical/XML_EnemyMiscDrops.cpp
@@ -0,0 +1,254 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "overhead types.h"
+ #include "Sound Control.h"
+ #include "Soldier Control.h"
+ #include "overhead.h"
+ #include "Event Pump.h"
+ #include "weapons.h"
+ #include "Animation Control.h"
+ #include "sys globals.h"
+ #include "Handle UI.h"
+ #include "Isometric Utils.h"
+ #include "worldman.h"
+ #include "math.h"
+ #include "points.h"
+ #include "ai.h"
+ #include "los.h"
+ #include "renderworld.h"
+ #include "opplist.h"
+ #include "interface.h"
+ #include "message.h"
+ #include "campaign.h"
+ #include "items.h"
+ #include "text.h"
+ #include "Soldier Profile.h"
+ #include "tile animation.h"
+ #include "Dialogue Control.h"
+ #include "SkillCheck.h"
+ #include "explosion control.h"
+ #include "Quests.h"
+ #include "Physics.h"
+ #include "Random.h"
+ #include "Vehicles.h"
+ #include "bullets.h"
+ #include "morale.h"
+ #include "meanwhile.h"
+ #include "SkillCheck.h"
+ #include "gamesettings.h"
+ #include "SaveLoadMap.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "EnemyItemDrops.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ INT8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ MISC_DROPS curMiscDrop;
+ MISC_DROPS * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef miscDropParseData;
+
+static void XMLCALL
+miscDropStartElementHandle(void *userData, const char *name, const char **atts)
+{
+ miscDropParseData * pData = (miscDropParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "MISCDROPLIST") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ memset(pData->curArray,0,sizeof(MISC_DROPS)*pData->maxArraySize);
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "DROPITEM") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ memset(&pData->curMiscDrop,0,sizeof(MISC_DROPS));
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "usItemClass") == 0 ||
+ strcmp(name, "ubDropRate") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+miscDropCharacterDataHandle(void *userData, const char *str, int len)
+{
+ miscDropParseData * pData = (miscDropParseData *)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
+miscDropEndElementHandle(void *userData, const char *name)
+{
+ miscDropParseData * pData = (miscDropParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "MISCDROPLIST") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "DROPITEM") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if(pData->curMiscDrop.uiIndex < pData->maxArraySize)
+ {
+ pData->curArray[pData->curMiscDrop.uiIndex] = pData->curMiscDrop; //write the inventory into the table
+ }
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curMiscDrop.uiIndex = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "usItemClass") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curMiscDrop.usItemClass = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ubDropRate") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curMiscDrop.ubDropRate = (UINT8) atol(pData->szCharData);
+ }
+
+ pData->maxReadDepth--;
+ }
+
+ pData->currentDepth--;
+}
+
+
+
+
+BOOLEAN ReadInEnemyMiscDropsStats(MISC_DROPS *pEnemyMiscDrops, STR fileName)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ miscDropParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading EnemyMiscDrops.xml" );
+
+ // Open inventory 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, miscDropStartElementHandle, miscDropEndElementHandle);
+ XML_SetCharacterDataHandler(parser, miscDropCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ pData.curArray = pEnemyMiscDrops;
+ pData.maxArraySize = MAX_DROP_ITEMS;
+
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in EnemyMiscDrops.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 WriteEnemyMiscDropsStats(MISC_DROPS *pEnemyMiscDrops, STR fileName)
+{
+ 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( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < MAXITEMS;cnt++)
+ {
+
+ FilePrintf(hFile,"\t\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ FilePrintf(hFile,"\t\t%d\r\n", pEnemyMiscDrops[cnt].usItemClass);
+ FilePrintf(hFile,"\t\t%d\r\n", pEnemyMiscDrops[cnt].ubDropRate);
+
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
\ No newline at end of file
diff --git a/Tactical/XML_EnemyWeaponDrops.cpp b/Tactical/XML_EnemyWeaponDrops.cpp
new file mode 100644
index 00000000..6f17b3f8
--- /dev/null
+++ b/Tactical/XML_EnemyWeaponDrops.cpp
@@ -0,0 +1,254 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "overhead types.h"
+ #include "Sound Control.h"
+ #include "Soldier Control.h"
+ #include "overhead.h"
+ #include "Event Pump.h"
+ #include "weapons.h"
+ #include "Animation Control.h"
+ #include "sys globals.h"
+ #include "Handle UI.h"
+ #include "Isometric Utils.h"
+ #include "worldman.h"
+ #include "math.h"
+ #include "points.h"
+ #include "ai.h"
+ #include "los.h"
+ #include "renderworld.h"
+ #include "opplist.h"
+ #include "interface.h"
+ #include "message.h"
+ #include "campaign.h"
+ #include "items.h"
+ #include "text.h"
+ #include "Soldier Profile.h"
+ #include "tile animation.h"
+ #include "Dialogue Control.h"
+ #include "SkillCheck.h"
+ #include "explosion control.h"
+ #include "Quests.h"
+ #include "Physics.h"
+ #include "Random.h"
+ #include "Vehicles.h"
+ #include "bullets.h"
+ #include "morale.h"
+ #include "meanwhile.h"
+ #include "SkillCheck.h"
+ #include "gamesettings.h"
+ #include "SaveLoadMap.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "EnemyItemDrops.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ INT8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ WEAPON_DROPS curWeaponDrop;
+ WEAPON_DROPS * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef weaponDropParseData;
+
+static void XMLCALL
+weaponDropStartElementHandle(void *userData, const char *name, const char **atts)
+{
+ weaponDropParseData * pData = (weaponDropParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "WEAPONDROPLIST") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ memset(pData->curArray,0,sizeof(WEAPON_DROPS)*pData->maxArraySize);
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "DROPITEM") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ memset(&pData->curWeaponDrop,0,sizeof(WEAPON_DROPS));
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "ubWeaponType") == 0 ||
+ strcmp(name, "ubDropRate") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+weaponDropCharacterDataHandle(void *userData, const char *str, int len)
+{
+ weaponDropParseData * pData = (weaponDropParseData *)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
+weaponDropEndElementHandle(void *userData, const char *name)
+{
+ weaponDropParseData * pData = (weaponDropParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "WEAPONDROPLIST") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "DROPITEM") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if(pData->curWeaponDrop.uiIndex < pData->maxArraySize)
+ {
+ pData->curArray[pData->curWeaponDrop.uiIndex] = pData->curWeaponDrop; //write the inventory into the table
+ }
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curWeaponDrop.uiIndex = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ubWeaponType") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curWeaponDrop.ubWeaponType = (UINT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ubDropRate") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curWeaponDrop.ubDropRate = (UINT8) atol(pData->szCharData);
+ }
+
+ pData->maxReadDepth--;
+ }
+
+ pData->currentDepth--;
+}
+
+
+
+
+BOOLEAN ReadInEnemyWeaponDropsStats(WEAPON_DROPS *pEnemyWeaponDrops, STR fileName)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ weaponDropParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading EnemyWeaponDrops.xml" );
+
+ // Open inventory 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, weaponDropStartElementHandle, weaponDropEndElementHandle);
+ XML_SetCharacterDataHandler(parser, weaponDropCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ pData.curArray = pEnemyWeaponDrops;
+ pData.maxArraySize = MAX_DROP_ITEMS;
+
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in EnemyWeaponDrops.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 WriteEnemyWeaponDropsStats(WEAPON_DROPS *pEnemyWeaponDrops, STR fileName)
+{
+ 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( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < MAXITEMS;cnt++)
+ {
+
+ FilePrintf(hFile,"\t\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ FilePrintf(hFile,"\t\t%d\r\n", pEnemyWeaponDrops[cnt].ubWeaponType);
+ FilePrintf(hFile,"\t\t%d\r\n", pEnemyWeaponDrops[cnt].ubDropRate);
+
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
\ No newline at end of file