mirror of
https://github.com/1dot13/source.git
synced 2026-07-29 13:52:17 +02:00
New feature: clothes items allow colouring of your mercs. See http://www.bears-pit.com/board/ubbthreads.php/topics/310208.html#Post310208 for more information.
This feature requires GameDir r1540 or greater to work. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5566 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
+171
-10
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 );
|
||||
}
|
||||
|
||||
+4
-1
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
+31
-175
@@ -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;
|
||||
|
||||
+20
-10
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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,"<CLOTHESLIST>\r\n");
|
||||
for(cnt = 0; cnt < MAXITEMS; ++cnt)
|
||||
{
|
||||
FilePrintf(hFile,"\t<CLOTHES>\r\n");
|
||||
|
||||
FilePrintf(hFile,"\t\t<uiIndex>%d</uiIndex>\r\n", cnt );
|
||||
FilePrintf(hFile,"\t\t<vest>%d</vest>\r\n", Clothes[cnt].vest );
|
||||
FilePrintf(hFile,"\t\t<pants>%d</pants>\r\n", Clothes[cnt].pants );
|
||||
|
||||
FilePrintf(hFile,"\t</CLOTHES>\r\n");
|
||||
}
|
||||
FilePrintf(hFile,"</CLOTHESLIST>\r\n");
|
||||
}
|
||||
FileClose( hFile );
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
+9
-2
@@ -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<RepairModifier>%d</RepairModifier>\r\n", Item[cnt].RepairModifier );
|
||||
|
||||
// Flugente poison system
|
||||
FilePrintf(hFile,"\t\t<PoisonPercentage>%d</PoisonPercentage>\r\n", Item[cnt].bPoisonPercentage );
|
||||
FilePrintf(hFile,"\t\t<PoisonPercentage>%d</PoisonPercentage>\r\n", Item[cnt].bPoisonPercentage );
|
||||
|
||||
FilePrintf(hFile,"\t\t<DamageChance>%d</DamageChance>\r\n", Item[cnt].usDamageChance );
|
||||
FilePrintf(hFile,"\t\t<DirtIncreaseFactor>%4.2f</DirtIncreaseFactor>\r\n", Item[cnt].dirtIncreaseFactor );
|
||||
|
||||
FilePrintf(hFile,"\t\t<usActionItemFlag>%d</usActionItemFlag>\r\n", Item[cnt].usActionItemFlag );
|
||||
FilePrintf(hFile,"\t\t<clothestype>%d</clothestype>\r\n", Item[cnt].clothestype );
|
||||
|
||||
FilePrintf(hFile,"\t</ITEM>\r\n");
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user