From c4c355f4b6a5dfd01140b43e3d1206f727b706ef Mon Sep 17 00:00:00 2001 From: Wanne Date: Fri, 25 Aug 2006 08:06:11 +0000 Subject: [PATCH] - Added Kaiden's Vehicle Inventory code -> VEHICLE_INVENTORY = TRUE (Ja2_Options.ini) - Bug fix: Vehicles sharing same animations - Added additional enemy item drop system -> New XML-Drop files (EnemyWeaponDrops.xml, ...) -> Set ENEMIES_ITEM_DROP = 1 (Ja2_Options.ini) to use the new drop system -> Disable "Enemies drop all items" to use the new drop system git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@466 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameSettings.cpp | 5 + GameSettings.h | 6 +- Init.cpp | 40 ++ JA2.suo | Bin 94720 -> 87040 bytes Strategic/mapscreen.cpp | 5 +- Tactical/Animation Data.cpp | 13 +- Tactical/EnemyItemDrops.cpp | 14 + Tactical/EnemyItemDrops.h | 47 +++ Tactical/Interface Items.cpp | 46 ++- Tactical/Inventory Choosing.cpp | 546 ++++++++++++++++++--------- Tactical/Tactical All.h | 2 + Tactical/Tactical.vcproj | 21 ++ Tactical/XML.h | 21 ++ Tactical/XML_EnemyAmmoDrops.cpp | 254 +++++++++++++ Tactical/XML_EnemyArmourDrops.cpp | 254 +++++++++++++ Tactical/XML_EnemyExplosiveDrops.cpp | 254 +++++++++++++ Tactical/XML_EnemyMiscDrops.cpp | 254 +++++++++++++ Tactical/XML_EnemyWeaponDrops.cpp | 254 +++++++++++++ 18 files changed, 1842 insertions(+), 194 deletions(-) create mode 100644 Tactical/EnemyItemDrops.cpp create mode 100644 Tactical/EnemyItemDrops.h create mode 100644 Tactical/XML_EnemyAmmoDrops.cpp create mode 100644 Tactical/XML_EnemyArmourDrops.cpp create mode 100644 Tactical/XML_EnemyExplosiveDrops.cpp create mode 100644 Tactical/XML_EnemyMiscDrops.cpp create mode 100644 Tactical/XML_EnemyWeaponDrops.cpp 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 d6b6bfb72093a08e226c67fbaf94ce6a0a76e926..fb2507e696543eb31e67887962bc908d2910eea3 100644 GIT binary patch delta 2058 zcmb_dZA)B76h7zftGc^t+|8~VUsf?TN!7SpDF!96QJX|;)snu@8gFe9G-;HQLNNW7QpA@0fCenI8h885-ZfH*&`Rg>%$$4X z+-J_5Ip@yUL(AAz%e4w^w~vU@feauM$O2;Vc-)QA18fJpK&m)qeO5oGJ!DsTZm2Qm zhdDMuJ$6Ub!b;JSj zRVdXCR45|b&>e+kS3=nZsb8rTK|OWDP7w?%mEN7+ZgNsCWW}}eaYj~vdsvR z1+W4(zz(DUu?yjRj_F+dEl>N+(|ha?+X&s_)OcZ4({&cHO?~ zPZq!X9lE2s-=*EN>!S^A;b)fNsY;<0jE|L^e9u%%sD0s`G!j>CW$V5#I(=e%_ONKY zvquhCxR_ffuk#^MJiA@a_pw&Q&cqFIO)( zRorbV+_jLh=I(KQGS*IZrNFxlp#HuqzQD`4JpipNPg@WR2x_elC(<2H7nu z`}h@k+szZviB!J9_B61r#XCCU;PXyyk{7%zq8I)A4fDQeOAg;pW1FG;dKX_bu{rS~ ze=Fe+`LH2tWso&PF5C-wuOS~ShrA;pM>~V8Wl8Y1RvEvYrFiucfz9YlEoE zUg%Fy8H!S!1W|{o^W+#ZcomE1sVwrAp9^Gr3p?b;P3)8R`Z)2+5y4=+2<$BTx1o~= zUE|KpTq?wIsiww?b(boi>e8kgn@KTPW>VyYm!}f3`HvJglN2|%PVpc~@nGu|naOZu zrfzv7OGz)5w(iCMzY%^zKJxI9e08kqE?CdW*Nu}SHD*6afMVHjh--F4aAkDidOU?> eR@bLW=n-6x_#D@&M-Jt1hWIH^qW6~`<-Y+(6%SAV delta 6912 zcmc&(Yj9L&8UEh0w_G;2y^zg?uni$lr-W>>#FShJ2?^7bmJn>6PN*f9ZAcAC8Uh0; zcB7-6{-~XXuk@?pj1?~}wq>wuiQ_m*g`#6eC4aQzXeT<%*!~emK`jXD^PatsLpCR! zv74TqXU}&z=j`*o=e>R3PQ7BAx@0>Y)S7aI5P3j8Pyo1ro6%@=CC*-81yBh1fFht6 zC;>`=tjOcqb;{i{@b$j;&tD)5hQw2mN$Ul&ULzqQTkTU?gB^nvz@RuF_KOZNB*t-` z5cdEfu@C1FF@V+~TvMLBZoB9e`yb|!t4i5LSRj`R4Rzvjj1 zIR7k*GzOtZ@r@ywpXX~l?nLte3=WB5h=gGmzCMF1`}M(ow1#<@AJ7gFhx7-G^H5|U z?-5H5@r%j7svzhfdaq< zxB(B~1y%qzBU^kg(}`lM{7KL$pS+PP=k6+#b9dS!%{4!FM5r=K6g{y?J5iP)U#e)9 zV{5AA#jBOFzN|Cy-n#P4HyRJ+YFU|)$g4#v`UIiKz=b)B(~7&4H?Py1bL6KNY*ekPt<>>?MqggTJb#EA zz5{$0_#W^w@CtAe_&)HaJlVIp;M-{N)n{;?;r0)DSCjl^u1{Sg%0D(o9qN*m{-~O5 zRDoWFdfGu%>a2}gHm7zrcFKek_UO);=-qP3hjGn>+H9wWyqGi9Lw8$Pf4Vc^tOpIf z$1WnWgizC4X@k1tAXmfuAMhI-U>6MgAY7M!>QT5vm1xCxA3ldgH|7qj>FwlJemnVk zZqe}zCR7J}7Wc9{jpF_u;r|GN@SWYa-C3TL0u%FODnneg}B;UJ$Kjfb`zK zp$8k{hehvw2+_0Qcd_1|U}t{?VtU$V6Ji7?(XXt;_{QYi&(Jyt=yRdp;HuvPiR0I= z23;RbzAC)JKGBA7fyjx^?OIDb5oh&*gGyi{o`TCief>R-aW@R)FQX@tqKus;|6+NR|8|isfz5%1Q*l24t+GVj@`vRo7)%|UBP@QU} zLu$%PR@GHZ`D(72zEpHhw@2s}XHHn0#8~MuF+Koseq*uTKXfq=uJrfw4aB>X9P_y6 zJA*fTma|0s;5Wi*oB5Z6rl=jss14Wx)QB(Onm|o$a3f5#P^`0lRl|d$(GpE09&oy+ zN&DsQCXJamSXVfFB&Ytlz3_Sq$|!;`iuYO5t2$^+jO#Y#?;vOR5g5S%lmY!>FDeBtoF>w$ zWCQJ0+A339t}~(C0lNqxUM~-E18x8RL3p>lZz2ZQBwPazEtCEY;d^Z?ey=vCZ)WpddTd-S-5ZRj zVhQ6h(|WgF5AOd&wZ6t&>w8I#ZQ=m=Rs-sX78^=yv_DN>3Eu}(8B1$OT#(@_=W%^F zMT+mHC$RJlASG8LAtMpn^ra<|CLe|3Y0CxDO9d>J7B3YvvB{9XcDB*u;q=r621~-~ zZBbHOt9szSCIt-A?6&YAUdld1(qT9RuYl8;Y7OME>;!qP08=O07hy+1wxfb_s#Px$ zHOK7eUS6bCh4&+PrkCvkW5OaiscvryWAZPl?t8-=^AAAfgHX921w#m{tRZBA5VAlO z@<4j5CRz8!11FaHNl8)&vcg;t6uvvc4}vmp7!AQ{M$$yxU@zF3n8(?@pjyu|C#@Sh z8+mN&CVjd#kj7q$Dd}Q!(kV5a&a&M=9-BZQzqp6CE?ji}y;|?jaRyru;N5*$kS)R+}lg3cU8zi-=o=Yb*sK!yM9SAh^%@Uj zMGN>F=$9_(T!U$`RD+I-O*vWwR_-awr5-MwTs!>OQMl*hOUmlBgDTXi0D07@OzJ-7 zCqFMg4&g%LfD3#P< 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