mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
- fixed an error that could cause clothes to spwan that were not worn
- upon shooting/stabbing someone, their vest/pants will get unusable. It can be taken off, but no item will appear. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5572 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -805,8 +805,10 @@ extern OBJECTTYPE gTempObject;
|
||||
|
||||
#define CORPSE_PANTS_BLUE 0x10000000 //268435456
|
||||
#define CORPSE_PANTS_BEIGE 0x20000000 //536870912
|
||||
#define CORPSE_STRIPPED 0x40000000 //1073741824
|
||||
#define TRIPWIRE_ACTIVATED 0x80000000 //2147483648 // for tripwire activation (gets set and unset when activating tripwire)
|
||||
#define CORPSE_NO_VEST 0x40000000 //1073741824 // corpse has no vest item (it has been either taken or been destroyed)
|
||||
#define CORPSE_NO_PANTS_AND_TRIPWIRE_ACTIVATED 0x80000000 //2147483648 // corpse has no pants item/for tripwire activation (gets set and unset when activating tripwire)
|
||||
|
||||
// Flugente TODO 2012-09-17: next time we break savegame compatibility, extend the flagmasks from UINT32 to UINT64. I didn't do it this time (see double-used flag above), as we try to minimise those breaks. But it is needed.
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// -------- added by Flugente: flags for action items --------
|
||||
|
||||
@@ -899,8 +899,11 @@ BOOLEAN TurnSoldierIntoCorpse( SOLDIERTYPE *pSoldier, BOOLEAN fRemoveMerc, BOOLE
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
if ( pSoldier->bSoldierFlagMask & SOLDIER_DAMAGED_VEST )
|
||||
Corpse.usFlags |= ROTTING_CORPSE_NO_VEST;
|
||||
|
||||
if ( pSoldier->bSoldierFlagMask & SOLDIER_DAMAGED_PANTS )
|
||||
Corpse.usFlags |= ROTTING_CORPSE_NO_PANTS;
|
||||
|
||||
// Determine corpse type!
|
||||
ubType = (UINT8)gubAnimSurfaceCorpseID[ pSoldier->ubBodyType][ pSoldier->usAnimState ];
|
||||
@@ -1951,7 +1954,7 @@ void GutCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
// Flugente: can clothes be taken off of this corpse?
|
||||
BOOLEAN IsValidStripCorpse( ROTTING_CORPSE *pCorpse )
|
||||
{
|
||||
if ( pCorpse->def.ubType == ROTTING_STAGE2 || (pCorpse->def.usFlags & ROTTING_CORPSE_CLOTHES_TAKEN) )
|
||||
if ( pCorpse->def.ubType == ROTTING_STAGE2 || ((pCorpse->def.usFlags & ROTTING_CORPSE_NO_VEST) && (pCorpse->def.usFlags & ROTTING_CORPSE_NO_PANTS)) )
|
||||
return( FALSE );
|
||||
|
||||
return( CorpseOkToDress(pCorpse) );
|
||||
@@ -1970,28 +1973,34 @@ void StripCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
if ( IsValidStripCorpse( pCorpse ) )
|
||||
{
|
||||
// determine which clothes to spawn
|
||||
UINT16 vestitem = 0;
|
||||
if ( GetFirstClothesItemWithSpecificData(&vestitem, pCorpse->def.VestPal, "blank") )
|
||||
if ( !(pCorpse->def.usFlags & ROTTING_CORPSE_NO_VEST) )
|
||||
{
|
||||
CreateItem( vestitem, 100, &gTempObject );
|
||||
if ( !AutoPlaceObject( pSoldier, &gTempObject, FALSE ) )
|
||||
AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, 0, 0, -1 );
|
||||
UINT16 vestitem = 0;
|
||||
if ( GetFirstClothesItemWithSpecificData(&vestitem, pCorpse->def.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] );
|
||||
}
|
||||
else
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_CLOTHES_ITEM] );
|
||||
|
||||
UINT16 pantsitem = 0;
|
||||
if ( GetFirstClothesItemWithSpecificData(&pantsitem, "blank", pCorpse->def.PantsPal) )
|
||||
if ( !(pCorpse->def.usFlags & ROTTING_CORPSE_NO_PANTS) )
|
||||
{
|
||||
CreateItem( pantsitem, 100, &gTempObject );
|
||||
if ( !AutoPlaceObject( pSoldier, &gTempObject, FALSE ) )
|
||||
AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, 0, 0, -1 );
|
||||
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] );
|
||||
}
|
||||
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;
|
||||
pCorpse->def.usFlags |= (ROTTING_CORPSE_NO_VEST|ROTTING_CORPSE_NO_PANTS);
|
||||
}
|
||||
else
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCorpseTextStr[STR_CORPSE_NO_CLOTHESFOUND] );
|
||||
@@ -2038,8 +2047,11 @@ void TakeCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
if ( pCorpse->def.usFlags & ROTTING_CORPSE_HEAD_TAKEN )
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_NO_HEAD;
|
||||
|
||||
if ( pCorpse->def.usFlags & ROTTING_CORPSE_CLOTHES_TAKEN )
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_STRIPPED;
|
||||
if ( pCorpse->def.usFlags & ROTTING_CORPSE_NO_VEST )
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_NO_VEST;
|
||||
|
||||
if ( pCorpse->def.usFlags & ROTTING_CORPSE_NO_PANTS )
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_NO_PANTS_AND_TRIPWIRE_ACTIVATED;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( pCorpse->def.usFlags & ROTTING_CORPSE_NEVER_RISE_AGAIN )
|
||||
@@ -2297,8 +2309,11 @@ BOOLEAN AddCorpseFromObject(OBJECTTYPE* pObj, INT32 sGridNo, INT8 bLevel )
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_NO_HEAD )
|
||||
gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_HEAD_TAKEN;
|
||||
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_STRIPPED )
|
||||
gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_CLOTHES_TAKEN;
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_NO_VEST )
|
||||
gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_NO_VEST;
|
||||
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_NO_PANTS_AND_TRIPWIRE_ACTIVATED )
|
||||
gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_NO_PANTS;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_NO_ZOMBIE_RISE )
|
||||
|
||||
@@ -92,7 +92,8 @@ enum RottingCorpseDefines
|
||||
// Flugente: corpses can now be gutted after they have been decapitated. Atm there is no corpse that can be both gutted and decapitated (to be done later)
|
||||
#define ROTTING_CORPSE_HEAD_TAKEN 0x00001000 // head has been taken off
|
||||
#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_NO_VEST 0x00004000 // corpse has no vest (atm not visually)
|
||||
#define ROTTING_CORPSE_NO_PANTS 0x00008000 // corpse has no vest (atm not visually)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
@@ -6315,9 +6315,11 @@ void SoldierGotHitGunFire( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sD
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: if hit in legs or torso, blood will be on our uniform - this unifrom can't be used to disguise someone anymore
|
||||
if ( ubHitLocation == AIM_SHOT_TORSO || ubHitLocation == AIM_SHOT_LEGS )
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_DAMAGED_UNIFORM;
|
||||
// Flugente: if hit in legs or torso, blood will be on our uniform - parts of the clothes cannot be worn anymore
|
||||
if ( ubHitLocation == AIM_SHOT_TORSO )
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_DAMAGED_VEST;
|
||||
else if ( ubHitLocation == AIM_SHOT_LEGS )
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_DAMAGED_PANTS;
|
||||
|
||||
// IF HERE AND GUY IS DEAD, RETURN!
|
||||
if ( pSoldier->flags.uiStatusFlags & SOLDIER_DEAD )
|
||||
@@ -6365,9 +6367,11 @@ void SoldierGotHitGunFire( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sD
|
||||
|
||||
void SoldierGotHitExplosion( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDamage, UINT16 bDirection, UINT16 sRange, UINT8 ubAttackerID, UINT8 ubSpecial, UINT8 ubHitLocation )
|
||||
{
|
||||
// Flugente: if hit in legs or torso, blood will be on our uniform - this unifrom can't be used to disguise someone anymore
|
||||
if ( ubHitLocation == AIM_SHOT_TORSO || ubHitLocation == AIM_SHOT_LEGS )
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_DAMAGED_UNIFORM;
|
||||
// Flugente: if hit in legs or torso, blood will be on our uniform - parts of the clothes cannot be worn anymore
|
||||
if ( ubHitLocation == AIM_SHOT_TORSO )
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_DAMAGED_VEST;
|
||||
else if ( ubHitLocation == AIM_SHOT_LEGS )
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_DAMAGED_PANTS;
|
||||
|
||||
INT32 sNewGridNo;
|
||||
|
||||
@@ -6537,9 +6541,11 @@ void SoldierGotHitExplosion( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16
|
||||
|
||||
void SoldierGotHitBlade( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDamage, UINT16 bDirection, UINT16 sRange, UINT8 ubAttackerID, UINT8 ubSpecial, UINT8 ubHitLocation )
|
||||
{
|
||||
// Flugente: if hit in legs or torso, blood will be on our uniform - this unifrom can't be used to disguise someone anymore
|
||||
if ( ubHitLocation == AIM_SHOT_TORSO || ubHitLocation == AIM_SHOT_LEGS )
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_DAMAGED_UNIFORM;
|
||||
// Flugente: if hit in legs or torso, blood will be on our uniform - parts of the clothes cannot be worn anymore
|
||||
if ( ubHitLocation == AIM_SHOT_TORSO )
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_DAMAGED_VEST;
|
||||
else if ( ubHitLocation == AIM_SHOT_LEGS )
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_DAMAGED_PANTS;
|
||||
|
||||
// IF HERE AND GUY IS DEAD, RETURN!
|
||||
if ( pSoldier->flags.uiStatusFlags & SOLDIER_DEAD )
|
||||
@@ -15086,29 +15092,37 @@ void SOLDIERTYPE::Strip()
|
||||
// if already not covert, take off clothes
|
||||
else if ( this->bSoldierFlagMask & (SOLDIER_NEW_VEST|SOLDIER_NEW_PANTS) )
|
||||
{
|
||||
// if having a new vest that is undamaged, take it off
|
||||
if ( (this->bSoldierFlagMask & SOLDIER_NEW_VEST) && !(this->bSoldierFlagMask & SOLDIER_DAMAGED_VEST) )
|
||||
{
|
||||
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] );
|
||||
}
|
||||
|
||||
// if having new pants that are undamaged, take them off
|
||||
if ( (this->bSoldierFlagMask & SOLDIER_NEW_PANTS) && !(this->bSoldierFlagMask & SOLDIER_DAMAGED_PANTS) )
|
||||
{
|
||||
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] );
|
||||
}
|
||||
|
||||
// loose any clothes flags
|
||||
this->bSoldierFlagMask &= ~(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 );
|
||||
|
||||
|
||||
@@ -348,13 +348,13 @@ enum
|
||||
#define SOLDIER_COVERT_CIV 0x00000004 //4 // Soldier is currently disguised as a civilian
|
||||
#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_DAMAGED_VEST 0x00000010 //16 // Soldier's vest is damaged (and thus can't be taken off)
|
||||
#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_SEAL 0x00000200 //512
|
||||
#define SOLDIER_DAMAGED_PANTS 0x00000100 //256 // Soldier's vest is damaged (and thus can't be taken off)
|
||||
/*#define WH40K_SEAL 0x00000200 //512
|
||||
#define WH40K_POWER_WEAPON 0x00000400 //1024
|
||||
#define ENEMY_NET_4_LVL_3 0x00000800 //2048
|
||||
|
||||
|
||||
@@ -3690,7 +3690,7 @@ BOOLEAN ActivateSurroundingTripwire( UINT8 ubID, INT32 sGridNo, INT8 bLevel, UIN
|
||||
if ( Item[usBombItem].tripwire == 1 )
|
||||
{
|
||||
// this is important - we have to check wether the wire has already been activated
|
||||
if ( ( (*pObj)[0]->data.sObjectFlag & TRIPWIRE_ACTIVATED ) == 0 )
|
||||
if ( ( (*pObj)[0]->data.sObjectFlag & CORPSE_NO_PANTS_AND_TRIPWIRE_ACTIVATED ) == 0 )
|
||||
{
|
||||
// determine this tripwire's flag
|
||||
UINT32 ubWireNetworkFlag = (*pObj)[0]->data.ubWireNetworkFlag;
|
||||
@@ -3740,7 +3740,7 @@ BOOLEAN ActivateSurroundingTripwire( UINT8 ubID, INT32 sGridNo, INT8 bLevel, UIN
|
||||
// Flugente hack: the tripwire will get removed in HandleExplosionQueue (it is still needed in there until the bomb gets called).
|
||||
// Because of this, ActivateSurroundingTripwire would normally find this wire again, thus a loop would occur.
|
||||
// So we mark the wire with this flag
|
||||
(*pObj)[0]->data.sObjectFlag |= TRIPWIRE_ACTIVATED;
|
||||
(*pObj)[0]->data.sObjectFlag |= CORPSE_NO_PANTS_AND_TRIPWIRE_ACTIVATED;
|
||||
|
||||
// activate surrounding tripwires, unless tripwire is too much damaged and we are unlucky..
|
||||
if ( (*pObj)[0]->data.objectStatus > (INT16)Random(50) )
|
||||
@@ -3910,7 +3910,7 @@ void HandleExplosionQueue( void )
|
||||
}
|
||||
|
||||
// delete the flag, otherwise wire will only work once
|
||||
(newtripwireObject)[0]->data.sObjectFlag &= ~TRIPWIRE_ACTIVATED;
|
||||
(newtripwireObject)[0]->data.sObjectFlag &= ~CORPSE_NO_PANTS_AND_TRIPWIRE_ACTIVATED;
|
||||
|
||||
// now add a tripwire item to the floor, simulating that activating tripwire deactivates it
|
||||
AddItemToPool( sGridNo, &newtripwireObject, 1, ubLevel, 0, -1 );
|
||||
@@ -3941,7 +3941,7 @@ void HandleExplosionQueue( void )
|
||||
}
|
||||
|
||||
// delete the flag, otherwise wire will only work once
|
||||
(newtripwireObject)[0]->data.sObjectFlag &= ~TRIPWIRE_ACTIVATED;
|
||||
(newtripwireObject)[0]->data.sObjectFlag &= ~CORPSE_NO_PANTS_AND_TRIPWIRE_ACTIVATED;
|
||||
|
||||
// now add a tripwire item to the floor, simulating that activating tripwire deactivates it
|
||||
AddItemToPool( sGridNo, &newtripwireObject, 1, ubLevel, 0, -1 );
|
||||
@@ -4425,7 +4425,7 @@ BOOLEAN SetOffBombsInGridNo( UINT8 ubID, INT32 sGridNo, BOOLEAN fAllBombs, INT8
|
||||
// Flugente hack: the tripwire will get removed in HandleExplosionQueue (it is still needed in there until the bomb gets called).
|
||||
// Because of this, ActivateSurroundingTripwire would normally find this wire again, thus a loop would occur.
|
||||
// So we mark the wire with this flag
|
||||
(*pObj)[0]->data.sObjectFlag |= TRIPWIRE_ACTIVATED;
|
||||
(*pObj)[0]->data.sObjectFlag |= CORPSE_NO_PANTS_AND_TRIPWIRE_ACTIVATED;
|
||||
|
||||
// activate surrounding tripwires and tripwire-activated mines, unless tripwire is too much damaged and we are unlucky..
|
||||
if ( (*pObj)[0]->data.objectStatus > (INT16)Random(50) )
|
||||
|
||||
Reference in New Issue
Block a user