- 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:
Flugente
2012-09-17 20:42:38 +00:00
parent a2b757d76a
commit 3fdecfbcf4
6 changed files with 94 additions and 62 deletions
+4 -2
View File
@@ -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 --------
+37 -22
View File
@@ -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 )
+2 -1
View File
@@ -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
{
+43 -29
View File
@@ -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 );
+3 -3
View File
@@ -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
+5 -5
View File
@@ -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) )