diff --git a/GameSettings.cpp b/GameSettings.cpp
index dcc4eb24..85af7cf3 100644
--- a/GameSettings.cpp
+++ b/GameSettings.cpp
@@ -2146,7 +2146,7 @@ void LoadSkillTraitsExternalSettings()
// Flugente: COVERT OPS
gSkillTraitValues.sCOMeleeCTHBonus = iniReader.ReadInteger("Covert Ops","COVERT_MELEE_CTH_BONUS", 40, 0, 200);
gSkillTraitValues.sCoMeleeInstakillBonus = iniReader.ReadInteger("Covert Ops","COVERT_MELEE_INSTAKILL_BONUS", 35, 0, 200);
- gSkillTraitValues.sCODisguiseAPReduction = iniReader.ReadInteger("Covert Ops","COVERT_DISGUISE_PERCENT_AP_REDUCTION", 20, 0, 100);
+ gSkillTraitValues.sCODisguiseAPReduction = iniReader.ReadInteger("Covert Ops","COVERT_DISGUISE_PERCENT_AP_REDUCTION", 20, 0, 50);
gSkillTraitValues.sCOCloseDetectionRange = iniReader.ReadInteger("Covert Ops","COVERT_CLOSE_DETECTION_RANGE", 10, 0, 100);
gSkillTraitValues.sCOCloseDetectionRangeSoldierCorpse = iniReader.ReadInteger("Covert Ops","COVERT_CLOSE_DETECTION_RANGE_SOLDIER_CORPSE", 5, 0, 100);
}
diff --git a/Init.cpp b/Init.cpp
index 71c6d2fd..a6998e4c 100644
--- a/Init.cpp
+++ b/Init.cpp
@@ -384,6 +384,10 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
strcat(fileName, FOODFILENAME);
SGP_THROW_IFFALSE(ReadInFoodStats(fileName),FOODFILENAME);
+ strcpy(fileName, directoryName);
+ strcat(fileName, CLOTHESFILENAME);
+ SGP_THROW_IFFALSE(ReadInClothesStats(fileName),CLOTHESFILENAME);
+
strcpy(fileName, directoryName);
strcat(fileName, ARMOURSFILENAME);
SGP_THROW_IFFALSE(ReadInArmourStats(fileName),ARMOURSFILENAME);
diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp
index d9eb658b..f2d9dd01 100644
--- a/Tactical/Handle Items.cpp
+++ b/Tactical/Handle Items.cpp
@@ -131,10 +131,12 @@ INT8 gbTrapDifficulty;
BOOLEAN gfJustFoundBoobyTrap = FALSE;
void StartBombMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo );
-void StartTacticalFunctionSelectionMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bLevel ); // added by Flugente
-void CleanWeapons( BOOLEAN fCleanAll );
-void StartCorpseMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bLevel ); // added by Flugente
+// added by Flugente
+void StartTacticalFunctionSelectionMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bLevel );
+void CleanWeapons( BOOLEAN fCleanAll );
+void Strip( SOLDIERTYPE * pSoldier );
+void StartCorpseMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bLevel );
BOOLEAN HandleCheckForBadChangeToGetThrough( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pTargetSoldier, INT32 sTargetGridNo , INT8 bLevel )
{
@@ -4592,6 +4594,12 @@ void CleanWeapons( BOOLEAN fCleanAll )
}
}
+// take off custom clothes
+void Strip( SOLDIERTYPE * pSoldier )
+{
+ pSoldier->Strip();
+}
+
void BombMessageBoxCallBack( UINT8 ubExitValue )
{
if (gpTempSoldier)
@@ -4710,6 +4718,10 @@ void TacticalFunctionSelectionMessageBoxCallBack( UINT8 ubExitValue )
// clean all weapons
CleanWeapons(TRUE);
break;
+ case 4:
+ // take off custom clothes
+ Strip(gpTempSoldier);
+ break;
default:
break;
}
diff --git a/Tactical/Interface Panels.cpp b/Tactical/Interface Panels.cpp
index 1ec1b0ce..c6585ae0 100644
--- a/Tactical/Interface Panels.cpp
+++ b/Tactical/Interface Panels.cpp
@@ -3357,7 +3357,7 @@ void SMInvClickCamoCallback( MOUSE_REGION * pRegion, INT32 iReason )
// Say OK acknowledge....
gpSMCurrentMerc->DoMercBattleSound( BATTLE_SOUND_COOL1 );
}
- else if ( ApplySpyKit( gpSMCurrentMerc, gpItemPointer ) )
+ else if ( ApplyClothes( gpSMCurrentMerc, gpItemPointer ) )
{
// Dirty
fInterfacePanelDirty = DIRTYLEVEL2;
diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h
index 6704a0e2..c52982f2 100644
--- a/Tactical/Item Types.h
+++ b/Tactical/Item Types.h
@@ -859,6 +859,8 @@ extern OBJECTTYPE gTempObject;
#define ITEM_DIRECTION_ANY 0x0000FF00
// ----------------------------------------------------------------
+
+
// replaces candamage
//#define ITEM_DAMAGEABLE 0x0001
//// replaces canrepair
@@ -1131,6 +1133,9 @@ typedef struct
// Flugente: a flag that is necessary for transforming action items to objects with new abilities (for now, tripwire networks and directional explosives)
UINT32 usActionItemFlag;
+ // Flugente: clothes type that 'links' to an entry in Clothes.xml
+ UINT32 clothestype;
+
} INVTYPE;
// CHRISL: Added new structures to handle LBE gear and the two new XML files that will be needed to deal
diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp
index 6276f0f8..2c857f20 100644
--- a/Tactical/Items.cpp
+++ b/Tactical/Items.cpp
@@ -9191,20 +9191,128 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP
return( TRUE );
}
- // Flugente: apply disguise
-BOOLEAN ApplySpyKit( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj)
-{
- if (pObj->exists() == false || !HasItemFlag(pObj->usItem, (CLOTHES_CIVILIAN)) )
+// Flugente: apply clothes, and eventually disguise
+BOOLEAN ApplyClothes( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj)
+{
+ // this will only work with the new trait system
+ if (!gGameOptions.fNewTraitSystem)
{
- return( FALSE );
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_ERROR_OLDTRAITS] );
+ return FALSE;
}
- // we get the civilian disguise. AP costs will be checked and deducted here
- if ( !pSoldier->DisguiseAsCivilian() )
- return FALSE;
+ if ( !pSoldier || pObj->exists() == false )
+ return( FALSE );
- UseKitPoints( pObj, 100, pSoldier );
+ UINT8 skilllevel = NUM_SKILL_TRAITS( pSoldier, COVERT_NT );
+
+ INT16 apcost = (APBPConstants[AP_DISGUISE] * ( 100 - gSkillTraitValues.sCODisguiseAPReduction * skilllevel))/100;
+ if ( !EnoughPoints( pSoldier, apcost, 0, TRUE ) )
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NOT_ENOUGH_APS] );
+ return( FALSE );
+ }
+
+ // determine clothes type
+ UINT32 clothestype = Item[pObj->usItem].clothestype;
+
+ // if not a clothes item, nothing to see here
+ if ( clothestype == 0 || clothestype > CLOTHES_MAX )
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_UNIFORM_FOUND] );
+ return( FALSE);
+ }
+ UINT8 filler = 0;
+ // if it has a vest, wear it
+ bool newvest = FALSE;
+ if ( GetPaletteRepIndexFromID(Clothes[clothestype].vest, &filler) )
+ newvest = TRUE;
+
+ // if it has pants, wear them
+ bool newpants = FALSE;
+ if ( GetPaletteRepIndexFromID(Clothes[clothestype].pants, &filler) )
+ newpants = TRUE;
+
+ if ( newvest || newpants )
+ {
+ UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( pSoldier, pSoldier->usAnimState );
+
+ if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE )
+ {
+ if ( newvest )
+ {
+ // if we are already wearing a vest, give us back that item
+ if ( pSoldier->bSoldierFlagMask & SOLDIER_NEW_VEST )
+ {
+ UINT16 vestitem = 0;
+ if ( GetFirstClothesItemWithSpecificData(&vestitem, pSoldier->VestPal, "blank") )
+ {
+ CreateItem( vestitem, 100, &gTempObject );
+ if ( !AutoPlaceObject( pSoldier, &gTempObject, FALSE ) )
+ AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, 0, 0, -1 );
+ }
+ else
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_CLOTHES_ITEM] );
+ }
+
+ SET_PALETTEREP_ID( pSoldier->VestPal, Clothes[clothestype].vest );
+ pSoldier->bSoldierFlagMask |= SOLDIER_NEW_VEST;
+ }
+
+ if ( newpants )
+ {
+ // if we are already wearing a vest, give us back that item
+ if ( pSoldier->bSoldierFlagMask & SOLDIER_NEW_PANTS )
+ {
+ UINT16 pantsitem = 0;
+ if ( GetFirstClothesItemWithSpecificData(&pantsitem, "blank", pSoldier->PantsPal) )
+ {
+ CreateItem( pantsitem, 100, &gTempObject );
+ if ( !AutoPlaceObject( pSoldier, &gTempObject, FALSE ) )
+ AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, 0, 0, -1 );
+ }
+ else
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_CLOTHES_ITEM] );
+ }
+
+ SET_PALETTEREP_ID( pSoldier->PantsPal, Clothes[clothestype].pants );
+ pSoldier->bSoldierFlagMask |= SOLDIER_NEW_PANTS;
+ }
+
+ // Use palette from HVOBJECT, then use substitution for pants, etc
+ memcpy( pSoldier->p8BPPPalette, gAnimSurfaceDatabase[ usPaletteAnimSurface ].hVideoObject->pPaletteEntry, sizeof( pSoldier->p8BPPPalette ) * 256 );
+
+ SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->HeadPal );
+ SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->VestPal );
+ SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->PantsPal );
+ SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->SkinPal );
+
+ pSoldier->CreateSoldierPalettes();
+
+ UseKitPoints( pObj, 100, pSoldier );
+
+ DeductPoints( pSoldier, apcost, 0 );
+ }
+
+ if ( pSoldier->bSoldierFlagMask & SOLDIER_NEW_VEST && pSoldier->bSoldierFlagMask & SOLDIER_NEW_PANTS )
+ {
+ // first, remove the covert flags, adn then reapply the correct ones, in case we switch between civilina and military garb
+ pSoldier->bSoldierFlagMask &= ~(SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER);
+
+ // we now have to determine wether we are currently wearing civilian or military clothes
+ for ( int i = UNIFORM_ENEMY_ADMIN; i <= UNIFORM_ENEMY_ELITE; ++i )
+ {
+ if ( pSoldier->VestPal == gUniformColors[ i ].vest && pSoldier->PantsPal == gUniformColors[ i ].pants )
+ pSoldier->bSoldierFlagMask |= SOLDIER_COVERT_SOLDIER;
+ }
+
+ // if not dressed as a soldier, we must be dressed as a civilian
+ if ( !(pSoldier->bSoldierFlagMask & SOLDIER_COVERT_SOLDIER) )
+ pSoldier->bSoldierFlagMask |= SOLDIER_COVERT_CIV;
+ }
+ }
+
return( TRUE );
}
@@ -14529,4 +14637,57 @@ FLOAT GetItemDirtIncreaseFactor( OBJECTTYPE * pObj, BOOLEAN fConsiderAmmo )
dirtincreasefactor = max(0.0f, dirtincreasefactor);
return dirtincreasefactor;
-}
\ No newline at end of file
+}
+
+// Flugente: retrieve a specific clothes item, if such a thing exists
+BOOLEAN GetFirstClothesItemWithSpecificData( UINT16* pusItem, PaletteRepID aPalVest, PaletteRepID aPalPants )
+{
+ bool vestok = FALSE;
+ bool pantsok = FALSE;
+
+ UINT8 filler = 0;
+ if ( !GetPaletteRepIndexFromID(aPalVest, &filler) )
+ vestok = TRUE;
+
+ if ( !GetPaletteRepIndexFromID(aPalPants, &filler) )
+ pantsok = TRUE;
+
+ register UINT16 i;
+ for (i = 1; i < MAXITEMS; ++i)
+ {
+ if ( Item[i].clothestype > 0 )
+ {
+ bool tmpvestok = vestok;
+ bool tmppantsok = pantsok;
+
+ UINT8 vestpalid = 0;
+ GetPaletteRepIndexFromID(aPalVest, &vestpalid);
+
+ // if we are looking for vests, do so
+ if ( !tmpvestok )
+ {
+ if ( COMPARE_PALETTEREP_ID(aPalVest, Clothes[Item[i].clothestype].vest) )
+ {
+ tmpvestok = TRUE;
+ }
+ }
+
+ // if we are looking for pants, do so
+ if ( !tmppantsok )
+ {
+ if ( COMPARE_PALETTEREP_ID(aPalPants, Clothes[Item[i].clothestype].pants) )
+ {
+ tmppantsok = TRUE;
+ }
+ }
+
+ if ( tmpvestok && tmppantsok )
+ {
+ *pusItem = i;
+ return( TRUE );
+ }
+ }
+ }
+
+ return( FALSE );
+}
diff --git a/Tactical/Items.h b/Tactical/Items.h
index d9d3e435..4d1bdfe5 100644
--- a/Tactical/Items.h
+++ b/Tactical/Items.h
@@ -196,7 +196,7 @@ void WaterDamage( SOLDIERTYPE *pSoldier );
INT8 FindObj( SOLDIERTYPE * pSoldier, UINT16 usItem, INT8 bLower = 0, INT8 bUpper = NUM_INV_SLOTS );
BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAPs );
-BOOLEAN ApplySpyKit( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj); // Flugente: apply disguise
+BOOLEAN ApplyClothes( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj); // Flugente: apply clothes, and eventually disguise
UINT32 ConvertProfileMoneyValueToObjectTypeMoneyValue( UINT8 ubStatus );
UINT8 ConvertObjectTypeMoneyValueToProfileMoneyValue( UINT32 uiMoneyAmount );
@@ -498,6 +498,9 @@ UINT8 GetFirstPocketOnItem(UINT16 usIndex);
INT8 GetNumberAltFireAimLevels( SOLDIERTYPE * pSoldier, INT32 iGridNo );
+// Flugente: retrieve a specific clothes item, if such a thing exists
+BOOLEAN GetFirstClothesItemWithSpecificData( UINT16* pusItem, PaletteRepID aPalVest, PaletteRepID aPalPants );
+
#endif
diff --git a/Tactical/Rotting Corpses.cpp b/Tactical/Rotting Corpses.cpp
index 22cd697d..7154a9bb 100644
--- a/Tactical/Rotting Corpses.cpp
+++ b/Tactical/Rotting Corpses.cpp
@@ -897,15 +897,7 @@ BOOLEAN TurnSoldierIntoCorpse( SOLDIERTYPE *pSoldier, BOOLEAN fRemoveMerc, BOOLE
memcpy( &(Corpse.name), &(pSoldier->name), sizeof(CHAR16) * 10 );
Corpse.name[9] = '\0';
#endif
-
- // Flugente: mark if this was an army soldier ( we use this to steal his clothes later on )
- if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR )
- Corpse.usFlags |= ROTTING_CORPSE_FROM_ADMIN;
- else if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ARMY )
- Corpse.usFlags |= ROTTING_CORPSE_FROM_TROOP;
- else if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE )
- Corpse.usFlags |= ROTTING_CORPSE_FROM_ELITE;
-
+
// if this soldier's uniform was damaged (gunfire, blade attacks, explosions) then don't allow to take the uniform. We can't stay hidden if we're covered in blood :-)
if ( pSoldier->bSoldierFlagMask &SOLDIER_DAMAGED_UNIFORM )
Corpse.usFlags |= ROTTING_CORPSE_CLOTHES_TAKEN;
@@ -1962,15 +1954,11 @@ BOOLEAN IsValidStripCorpse( ROTTING_CORPSE *pCorpse )
if ( pCorpse->def.ubType == ROTTING_STAGE2 || (pCorpse->def.usFlags & ROTTING_CORPSE_CLOTHES_TAKEN) )
return( FALSE );
- // is there a uniform we can take?
- if ( !(pCorpse->def.usFlags & (ROTTING_CORPSE_FROM_ADMIN|ROTTING_CORPSE_FROM_TROOP|ROTTING_CORPSE_FROM_ELITE)) )
- return( FALSE );
-
- return( CorpseOkToDress(pCorpse, NULL) );
+ return( CorpseOkToDress(pCorpse) );
}
-// Flugente: take the clothes off a corpse and wear them
+// Flugente: take the clothes off a corpse
void StripCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
{
ROTTING_CORPSE *pCorpse = GetCorpseAtGridNo( sGridNo, bLevel );
@@ -1981,20 +1969,35 @@ void StripCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
// can this thing be stripped?
if ( IsValidStripCorpse( pCorpse ) )
{
- // if this fits our body, try to wear it
- if ( CorpseOkToDress(pCorpse, pSoldier) && pSoldier->DisguiseAsSoldierFromCorpse( pCorpse->def.usFlags ) )
+ // determine which clothes to spawn
+ UINT16 vestitem = 0;
+ if ( GetFirstClothesItemWithSpecificData(&vestitem, pCorpse->def.VestPal, "blank") )
{
- // we took the clothes, mark this
- pCorpse->def.usFlags |= ROTTING_CORPSE_CLOTHES_TAKEN;
+ CreateItem( vestitem, 100, &gTempObject );
+ if ( !AutoPlaceObject( pSoldier, &gTempObject, FALSE ) )
+ AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, 0, 0, -1 );
}
else
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCorpseTextStr[STR_CORPSE_NO_STRIPPING_POSSIBLE], pSoldier->name );
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_CLOTHES_ITEM] );
+
+ UINT16 pantsitem = 0;
+ if ( GetFirstClothesItemWithSpecificData(&pantsitem, "blank", pCorpse->def.PantsPal) )
+ {
+ CreateItem( pantsitem, 100, &gTempObject );
+ if ( !AutoPlaceObject( pSoldier, &gTempObject, FALSE ) )
+ AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, 0, 0, -1 );
+ }
+ else
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_CLOTHES_ITEM] );
+
+ // we took the clothes, mark this
+ pCorpse->def.usFlags |= ROTTING_CORPSE_CLOTHES_TAKEN;
}
else
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCorpseTextStr[STR_CORPSE_NO_CLOTHESFOUND] );
}
-// Flugente: can clothes be taken off of this corpse?
+// Flugente: can this corpse be carried?
BOOLEAN IsValidTakeCorpse( ROTTING_CORPSE *pCorpse )
{
if ( pCorpse->def.ubType >= BLOODCAT_DEAD || pCorpse->def.ubType == NO_CORPSE )
@@ -2271,10 +2274,7 @@ BOOLEAN AddCorpseFromObject(OBJECTTYPE* pObj, INT32 sGridNo, INT8 bLevel )
SET_PALETTEREP_ID( Corpse.PantsPal, "BLUEPANTS" );
else
SET_PALETTEREP_ID( Corpse.PantsPal, "BEIGEPANTS" );
-
- //SET_PALETTEREP_ID( Corpse.VestPal, gUniformColors[ UNIFORM_ENEMY_TROOP ].vest );
- //SET_PALETTEREP_ID( Corpse.PantsPal, gUniformColors[ UNIFORM_ENEMY_TROOP ].pants );
-
+
Corpse.ubDirection = NORTH;
Corpse.uiTimeOfDeath = GetWorldTotalMin();
@@ -2299,15 +2299,7 @@ BOOLEAN AddCorpseFromObject(OBJECTTYPE* pObj, INT32 sGridNo, INT8 bLevel )
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_STRIPPED )
gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_CLOTHES_TAKEN;
-
- // TODO: change this so it always fits, not dependant these colours
- if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_YELLOW && (*pObj)[0]->data.sObjectFlag & CORPSE_PANTS_GREEN )
- gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_FROM_ADMIN;
- else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_RED && (*pObj)[0]->data.sObjectFlag & CORPSE_PANTS_GREEN )
- gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_FROM_TROOP;
- else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_BLACK && (*pObj)[0]->data.sObjectFlag & CORPSE_PANTS_BLACK )
- gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_FROM_ELITE;
-
+
#ifdef ENABLE_ZOMBIES
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_NO_ZOMBIE_RISE )
gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_NEVER_RISE_AGAIN;
@@ -2984,7 +2976,7 @@ UINT8 GetNearestRottingCorpseAIWarning( INT32 sGridNo )
// Flugente: can we take the clothes of this corpse?
// calling this with NULL for soldier will give a general answer for any bodytype
-BOOLEAN CorpseOkToDress( ROTTING_CORPSE * pCorpse, SOLDIERTYPE* pSoldier )
+BOOLEAN CorpseOkToDress( ROTTING_CORPSE* pCorpse )
{
if ( !pCorpse )
return FALSE;
@@ -3007,16 +2999,6 @@ BOOLEAN CorpseOkToDress( ROTTING_CORPSE * pCorpse, SOLDIERTYPE* pSoldier )
case S_DEAD2:
case C_DEAD1:
case C_DEAD2:
- if ( pSoldier )
- {
- if ( pSoldier->ubBodyType == REGMALE )
- return TRUE;
- }
- else
- return TRUE;
-
- break;
-
case MMERC_JFK:
case MMERC_BCK:
case MMERC_FWD:
@@ -3026,17 +3008,7 @@ BOOLEAN CorpseOkToDress( ROTTING_CORPSE * pCorpse, SOLDIERTYPE* pSoldier )
case MMERC_FALL:
case MMERC_FALLF:
case FT_DEAD1:
- case FT_DEAD2:
- if ( pSoldier )
- {
- if ( pSoldier->ubBodyType == BIGMALE || pSoldier->ubBodyType == STOCKYMALE )
- return TRUE;
- }
- else
- return TRUE;
-
- break;
-
+ case FT_DEAD2:
case FMERC_JFK:
case FMERC_BCK:
case FMERC_FWD:
@@ -3047,14 +3019,7 @@ BOOLEAN CorpseOkToDress( ROTTING_CORPSE * pCorpse, SOLDIERTYPE* pSoldier )
case FMERC_FALLF:
case W_DEAD1:
case W_DEAD2:
- if ( pSoldier )
- {
- if ( pSoldier->ubBodyType == REGFEMALE )
- return TRUE;
- }
- else
- return TRUE;
-
+ return TRUE;
break;
default:
diff --git a/Tactical/Rotting Corpses.h b/Tactical/Rotting Corpses.h
index 19c9bf91..edc66917 100644
--- a/Tactical/Rotting Corpses.h
+++ b/Tactical/Rotting Corpses.h
@@ -94,9 +94,6 @@ enum RottingCorpseDefines
#define ROTTING_CORPSE_GUTTED 0x00002000 // corpse has been gutted
#define ROTTING_CORPSE_CLOTHES_TAKEN 0x00004000 // corpse is without clothes (atm not visually)
-#define ROTTING_CORPSE_FROM_ADMIN 0x00010000 // corpse is from a admin (used to take his clothes)
-#define ROTTING_CORPSE_FROM_TROOP 0x00020000 // corpse is from a regular soldier (used to take his clothes)
-#define ROTTING_CORPSE_FROM_ELITE 0x00040000 // corpse is from a elite soldier (used to take his clothes)
typedef struct
{
UINT8 ubType;
@@ -236,6 +233,6 @@ UINT8 GetNearestRottingCorpseAIWarning( INT32 sGridNo );
#endif
// Flugente: can we take the clothes of this corpse?
-BOOLEAN CorpseOkToDress( ROTTING_CORPSE * pCorpse, SOLDIERTYPE* pSoldier );
+BOOLEAN CorpseOkToDress( ROTTING_CORPSE* pCorpse );
#endif
\ No newline at end of file
diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp
index ef058122..a7394d81 100644
--- a/Tactical/Soldier Control.cpp
+++ b/Tactical/Soldier Control.cpp
@@ -15068,7 +15068,38 @@ BOOLEAN SOLDIERTYPE::RecognizeAsCombatant(UINT8 ubTargetID)
// dress up in our natural state
void SOLDIERTYPE::LooseDisguise( void )
+{
+ // loose any covert flags
+ this->bSoldierFlagMask &= ~(SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER);
+}
+
+// take off any clothes item and switch back to original clothes
+// no - this function does not want you think it does. Leave Fox alone, you perv.
+void SOLDIERTYPE::Strip()
{
+ // loose any covert and clothes flags
+ this->bSoldierFlagMask &= ~(SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER|SOLDIER_NEW_VEST|SOLDIER_NEW_PANTS);
+
+ UINT16 vestitem = 0;
+ if ( GetFirstClothesItemWithSpecificData(&vestitem, this->VestPal, "blank") )
+ {
+ CreateItem( vestitem, 100, &gTempObject );
+ if ( !AutoPlaceObject( this, &gTempObject, FALSE ) )
+ AddItemToPool( this->sGridNo, &gTempObject, 1, 0, 0, -1 );
+ }
+ else
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_CLOTHES_ITEM] );
+
+ UINT16 pantsitem = 0;
+ if ( GetFirstClothesItemWithSpecificData(&pantsitem, "blank", this->PantsPal) )
+ {
+ CreateItem( pantsitem, 100, &gTempObject );
+ if ( !AutoPlaceObject( this, &gTempObject, FALSE ) )
+ AddItemToPool( this->sGridNo, &gTempObject, 1, 0, 0, -1 );
+ }
+ else
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_CLOTHES_ITEM] );
+
// show our true colours
UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( this, this->usAnimState );
@@ -15093,183 +15124,8 @@ void SOLDIERTYPE::LooseDisguise( void )
this->CreateSoldierPalettes();
}
-
- // loose any covert flags
- // if we are disguised as a civilian, remove that flag, and give us back a civilian clothes item
- if ( this->bSoldierFlagMask & SOLDIER_COVERT_CIV )
- {
- this->bSoldierFlagMask &= ~SOLDIER_COVERT_CIV;
-
- UINT16 civilianclothesitem = 0;
- if ( GetFirstItemWithFlag(&civilianclothesitem, CLOTHES_CIVILIAN) )
- {
- CreateItem( civilianclothesitem, 100, &gTempObject );
-
- if ( !AutoPlaceObject( this, &gTempObject, FALSE ) )
- AddItemToPool( sGridNo, &gTempObject, 1, 0, 0, -1 );
- }
- else
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_CLOTHES_ITEM] );
- }
-
- // if we are also disguised as a soldier, remove that flag
- if ( this->bSoldierFlagMask & SOLDIER_COVERT_SOLDIER )
- {
- this->bSoldierFlagMask &= ~SOLDIER_COVERT_SOLDIER;
- }
}
-// dress up like a civilian
-BOOLEAN SOLDIERTYPE::DisguiseAsCivilian( void )
-{
- // this will only work with the new trait system
- if (!gGameOptions.fNewTraitSystem)
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_ERROR_OLDTRAITS] );
- return FALSE;
- }
-
- UINT8 skilllevel = NUM_SKILL_TRAITS( this, COVERT_NT );
-
- INT16 apcost = (APBPConstants[AP_DISGUISE] * ( gSkillTraitValues.sCODisguiseAPReduction * skilllevel))/100;
- if ( !EnoughPoints( this, apcost, 0, TRUE ) )
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NOT_ENOUGH_APS] );
- return( FALSE );
- }
-
- this->bSoldierFlagMask |= SOLDIER_COVERT_CIV;
-
- // wear an enemy uniform
- UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( this, this->usAnimState );
-
- if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE )
- {
- // wear something random
- switch( Random( 7 ) )
- {
- case 0: SET_PALETTEREP_ID( this->VestPal, "WHITEVEST" ); break;
- case 1: SET_PALETTEREP_ID( this->VestPal, "BLACKSHIRT" ); break;
- case 2: SET_PALETTEREP_ID( this->VestPal, "PURPLESHIRT" ); break;
- case 3: SET_PALETTEREP_ID( this->VestPal, "BLUEVEST" ); break;
- case 4: SET_PALETTEREP_ID( this->VestPal, "BROWNVEST" ); break;
- case 5: SET_PALETTEREP_ID( this->VestPal, "JEANVEST" ); break;
- case 6: SET_PALETTEREP_ID( this->VestPal, "REDVEST" ); break;
- }
-
- switch( Random( 3 ) )
- {
- case 0: SET_PALETTEREP_ID( this->PantsPal, "TANPANTS" ); break;
- case 1: SET_PALETTEREP_ID( this->PantsPal, "BEIGEPANTS" ); break;
- case 2: SET_PALETTEREP_ID( this->PantsPal, "GREENPANTS" ); break;
- }
-
- // Use palette from HVOBJECT, then use substitution for pants, etc
- memcpy( this->p8BPPPalette, gAnimSurfaceDatabase[ usPaletteAnimSurface ].hVideoObject->pPaletteEntry, sizeof( this->p8BPPPalette ) * 256 );
-
- SetPaletteReplacement( this->p8BPPPalette, this->HeadPal );
- SetPaletteReplacement( this->p8BPPPalette, this->VestPal );
- SetPaletteReplacement( this->p8BPPPalette, this->PantsPal );
- SetPaletteReplacement( this->p8BPPPalette, this->SkinPal );
-
- this->CreateSoldierPalettes();
- }
- else
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_BAD_PALETTE] );
-
- // if we are also disguised as a soldier, remove that flag
- if ( this->bSoldierFlagMask & SOLDIER_COVERT_SOLDIER )
- {
- this->bSoldierFlagMask &= ~SOLDIER_COVERT_SOLDIER;
- }
-
- DeductPoints( this, apcost, 0 );
-
- return TRUE;
-}
-
-// dress up like an enemy soldier
-BOOLEAN SOLDIERTYPE::DisguiseAsSoldierFromCorpse( UINT32 usFlag )
-{
- // this will only work with the new trait system
- if (!gGameOptions.fNewTraitSystem)
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_ERROR_OLDTRAITS] );
- return FALSE;
- }
-
- // action is only possible if we have the covert ops trait
- UINT8 skilllevel = NUM_SKILL_TRAITS( this, COVERT_NT );
- if ( skilllevel < 1)
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_SKILL] );
- return FALSE;
- }
-
- INT16 apcost = (APBPConstants[AP_DISGUISE] * ( gSkillTraitValues.sCODisguiseAPReduction * skilllevel))/100;
- if ( !EnoughPoints( this, apcost, 0, TRUE ) )
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NOT_ENOUGH_APS] );
- return( FALSE );
- }
-
- UINT8 uniformtype = 0;
-
- if ( usFlag & ROTTING_CORPSE_FROM_ADMIN )
- uniformtype = UNIFORM_ENEMY_ADMIN;
- else if ( usFlag & ROTTING_CORPSE_FROM_TROOP )
- uniformtype = UNIFORM_ENEMY_TROOP;
- else if ( usFlag & ROTTING_CORPSE_FROM_ELITE )
- uniformtype = UNIFORM_ENEMY_ELITE;
- else
- {
- // no uniform here, so nothing to wear
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_UNIFORM_FOUND] );
- return FALSE;
- }
-
- this->bSoldierFlagMask |= SOLDIER_COVERT_SOLDIER;
-
- // wear an enemy uniform
- UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( this, this->usAnimState );
-
- if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE )
- {
- SET_PALETTEREP_ID(this->VestPal, gUniformColors[ uniformtype ].vest );
- SET_PALETTEREP_ID(this->PantsPal, gUniformColors[ uniformtype ].pants );
-
- // Use palette from HVOBJECT, then use substitution for pants, etc
- memcpy( this->p8BPPPalette, gAnimSurfaceDatabase[ usPaletteAnimSurface ].hVideoObject->pPaletteEntry, sizeof( this->p8BPPPalette ) * 256 );
-
- SetPaletteReplacement( this->p8BPPPalette, this->HeadPal );
- SetPaletteReplacement( this->p8BPPPalette, this->VestPal );
- SetPaletteReplacement( this->p8BPPPalette, this->PantsPal );
- SetPaletteReplacement( this->p8BPPPalette, this->SkinPal );
-
- this->CreateSoldierPalettes();
- }
-
- // if we are disguised as a civilian, remove that flag, and give us back a civilian clothes item
- if ( this->bSoldierFlagMask & SOLDIER_COVERT_CIV )
- {
- this->bSoldierFlagMask &= ~SOLDIER_COVERT_CIV;
-
- UINT16 civilianclothesitem = 0;
- if ( GetFirstItemWithFlag(&civilianclothesitem, CLOTHES_CIVILIAN) )
- {
- CreateItem( civilianclothesitem, 100, &gTempObject );
- AddItemToPool( sGridNo, &gTempObject, 1, 0, 0, -1 );
- }
- else
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_CLOTHES_ITEM] );
- }
-
- DeductPoints( this, apcost, 0 );
-
- return TRUE;
-}
-
-
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
{
INT8 bBandaged; //,savedOurTurn;
diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h
index 2b61a674..4d007463 100644
--- a/Tactical/Soldier Control.h
+++ b/Tactical/Soldier Control.h
@@ -349,11 +349,11 @@ enum
#define SOLDIER_COVERT_SOLDIER 0x00000008 //8 // Soldier is currently disguised as an enemy soldier
#define SOLDIER_DAMAGED_UNIFORM 0x00000010 //16 // Soldier's uniform is damged (and thus can't be taken off of his corpse)
-#define SOLDIER_COVERT_NPC_SPECIAL 0x00000020 //32 // Special flag for NPCs wehn recruited (used for covert stuff)
-/*#define WH40K_JUMPPACK 0x00000040 //64
-#define WH40K_DISPLACER 0x00000080 //128
+#define SOLDIER_COVERT_NPC_SPECIAL 0x00000020 //32 // Special flag for NPCs when recruited (used for covert stuff)
+#define SOLDIER_NEW_VEST 0x00000040 //64 // Soldier is wearing new vest. if having both vest and pants, he can disguise
+#define SOLDIER_NEW_PANTS 0x00000080 //128 // Soldier is wearing new pants
-#define WH40K_ROSARIUS 0x00000100 //256
+/*#define WH40K_ROSARIUS 0x00000100 //256
#define WH40K_SEAL 0x00000200 //512
#define WH40K_POWER_WEAPON 0x00000400 //1024
#define ENEMY_NET_4_LVL_3 0x00000800 //2048
@@ -394,6 +394,19 @@ typedef struct
// HEADROCK HAM 3.6: Uniform colors for the different soldier classes
extern UNIFORMCOLORS gUniformColors[NUM_UNIFORMS];
+// Flugente: a structure for clothing items
+typedef struct
+{
+ UINT16 uiIndex;
+ CHAR16 szName[80]; // name of these clothes
+ PaletteRepID vest;
+ PaletteRepID pants;
+} CLOTHES_STRUCT;
+
+#define CLOTHES_MAX 50
+
+extern CLOTHES_STRUCT Clothes[CLOTHES_MAX];
+
// This macro should be used whenever we want to see if someone is neutral
// IF WE ARE CONSIDERING ATTACKING THEM. Creatures & bloodcats will attack neutrals
// but they can't attack empty vehicles!!
@@ -1476,13 +1489,10 @@ public:
BOOLEAN RecognizeAsCombatant(UINT8 ubTargetID);
// loose disguise, dress up in our natural state
- void LooseDisguise( void );
+ void LooseDisguise( void );
- // dress up like a civilian
- BOOLEAN DisguiseAsCivilian( void );
-
- // dress up like an enemy soldier
- BOOLEAN DisguiseAsSoldierFromCorpse( UINT32 usFlag );
+ // take off any clothes item and switch back to original clothes
+ void Strip();
//////////////////////////////////////////////////////////////////////////////
}; // SOLDIERTYPE;
diff --git a/Tactical/XML.h b/Tactical/XML.h
index d7c95c11..b21e5208 100644
--- a/Tactical/XML.h
+++ b/Tactical/XML.h
@@ -67,6 +67,7 @@ typedef PARSE_STAGE;
#define EXPLOSIVESFILENAME "Explosives.xml"
#define DRUGSFILENAME "Drugs.xml"
#define FOODFILENAME "Food.xml"
+#define CLOTHESFILENAME "Clothes.xml"
#define AMMOFILENAME "AmmoStrings.xml"
#define AMMOTYPESFILENAME "AmmoTypes.xml"
#define INCOMPATIBLEATTACHMENTSFILENAME "IncompatibleAttachments.xml"
@@ -306,6 +307,10 @@ extern BOOLEAN WriteDrugsStats();
extern BOOLEAN ReadInFoodStats(STR fileName);
extern BOOLEAN WriteFoodStats();
+// Flugente: clothes
+extern BOOLEAN ReadInClothesStats(STR fileName);
+extern BOOLEAN WriteClothesStats();
+
extern BOOLEAN ReadInAmmoStats(STR fileName);
extern BOOLEAN WriteAmmoStats();
diff --git a/Tactical/XML_Clothes.cpp b/Tactical/XML_Clothes.cpp
new file mode 100644
index 00000000..31c80927
--- /dev/null
+++ b/Tactical/XML_Clothes.cpp
@@ -0,0 +1,228 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "overhead.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ CLOTHES_STRUCT curClothes;
+ CLOTHES_STRUCT* curArray;
+ UINT32 maxArraySize;
+
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef clothesParseData;
+
+// Array to hold clothes data
+CLOTHES_STRUCT Clothes[CLOTHES_MAX];
+
+static void XMLCALL
+clothesStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ clothesParseData * pData = (clothesParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "CLOTHESLIST") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ memset(pData->curArray,0,sizeof(CLOTHES_STRUCT)*pData->maxArraySize);
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "CLOTHES") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ memset(&pData->curClothes,0,sizeof(CLOTHES_STRUCT));
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "szName") == 0 ||
+ strcmp(name, "Vest") == 0 ||
+ strcmp(name, "Pants") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+clothesCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ clothesParseData * pData = (clothesParseData *)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
+clothesEndElementHandle(void *userData, const XML_Char *name)
+{
+ clothesParseData * pData = (clothesParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "CLOTHESLIST") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "CLOTHES") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ // we do NOT want to read the first entry -> move stuff by 1
+ if(pData->curClothes.uiIndex < pData->maxArraySize)
+ {
+ pData->curArray[pData->curClothes.uiIndex] = pData->curClothes; //write the clothes into the table
+ }
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curClothes.uiIndex = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "szName") == 0)
+ {
+ pData->curElement = ELEMENT;
+ // not needed, but it's there for informational purposes
+ }
+ else if(strcmp(name, "Vest") == 0 )
+ {
+ pData->curElement = ELEMENT;
+
+ strcpy(pData->curClothes.vest, pData->szCharData);
+ }
+ else if(strcmp(name, "Pants") == 0 )
+ {
+ pData->curElement = ELEMENT;
+
+ strcpy(pData->curClothes.pants, pData->szCharData);
+ }
+
+ pData->maxReadDepth--;
+ }
+
+ pData->currentDepth--;
+}
+
+
+
+
+BOOLEAN ReadInClothesStats(STR fileName)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ clothesParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading Clothes.xml" );
+
+ // Open clothess 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, clothesStartElementHandle, clothesEndElementHandle);
+ XML_SetCharacterDataHandler(parser, clothesCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ pData.curArray = Clothes;
+ pData.maxArraySize = CLOTHES_MAX;
+
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in Clothes.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 WriteClothesStats()
+{
+ //DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"writeclothessstats");
+ HWFILE hFile;
+
+ //Debug code; make sure that what we got from the file is the same as what's there
+ // Open a new file
+ hFile = FileOpen( "TABLEDATA\\Clothes out.xml", 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", Clothes[cnt].vest );
+ FilePrintf(hFile,"\t\t%d\r\n", Clothes[cnt].pants );
+
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp
index 19d0968d..c4a75839 100644
--- a/Utils/XML_Items.cpp
+++ b/Utils/XML_Items.cpp
@@ -277,7 +277,8 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at
strcmp(name, "CrowbarModifier") == 0 ||
strcmp(name, "DisarmModifier") == 0 ||
strcmp(name, "RepairModifier") == 0 ||
- strcmp(name, "usActionItemFlag") == 0 ))
+ strcmp(name, "usActionItemFlag") == 0 ||
+ strcmp(name, "clothestype") == 0 ))
{
pData->curElement = ELEMENT_PROPERTY;
//DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("itemStartElementHandle: going into element, name = %s",name) );
@@ -1393,6 +1394,11 @@ itemEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curItem.usActionItemFlag = (UINT32) atol(pData->szCharData);
}
+ else if(strcmp(name, "clothestype") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curItem.clothestype = (UINT32) atol(pData->szCharData);
+ }
pData->maxReadDepth--;
}
@@ -2021,12 +2027,13 @@ BOOLEAN WriteItemStats()
FilePrintf(hFile, "\t\t%d\r\n", Item[cnt].RepairModifier );
// Flugente poison system
- FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].bPoisonPercentage );
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].bPoisonPercentage );
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usDamageChance );
FilePrintf(hFile,"\t\t%4.2f\r\n", Item[cnt].dirtIncreaseFactor );
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usActionItemFlag );
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].clothestype );
FilePrintf(hFile,"\t\r\n");
}
diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp
index fd1d6dae..4c167d27 100644
--- a/Utils/_EnglishText.cpp
+++ b/Utils/_EnglishText.cpp
@@ -2900,7 +2900,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
L"Health: %d/%d\nPoison: %d/%d\nEnergy: %d/%d\nMorale: %s\nWater: %d%s\nFood: %d%s",
// added by Flugente: selection of a function to call in tactical
- L"1 - Fill Canteens 2 - Clean one gun 3 - Clean all guns 4 - Nothing",
+ L"1 - Fill Canteens 2 - Clean one gun 3 - Clean all guns 4 - Take off clothes",
// added by Flugente: decide what to do with the corpses
L"1 - Decapitate 2 - Gut 3 - Take Clothes 4 - Take Body",