mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
- New Item: Stun gun (#1626) needs batteries and does no damage but knocks out an enemy. Uses new item flag TASER (/1048576)
- New Item: Pepper Spray (#1627) blinds anyone for a few turns if hit in the face, ammo is (#1628), uses ammoflag AMMO_BLIND (2) - Fix: possible division by zero in ammotype description git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5711 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -7501,7 +7501,7 @@ void DrawAmmoValues( OBJECTTYPE * gpItemDescObject, int shotsLeft )
|
||||
sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
|
||||
|
||||
// Get final Penetration
|
||||
FLOAT fArmourImpactReduction = 1.0f / ((FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].armourImpactReductionMultiplier / (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].armourImpactReductionDivisor);
|
||||
FLOAT fArmourImpactReduction = ((FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].armourImpactReductionMultiplier / (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].armourImpactReductionDivisor);
|
||||
|
||||
// Get base Penetration
|
||||
FLOAT fFinalArmourImpactReduction = fArmourImpactReduction;
|
||||
|
||||
@@ -752,8 +752,8 @@ extern OBJECTTYPE gTempObject;
|
||||
#define JUMP_GRENADE 0x00040000 //262144 // add +25 heigth to explosion, used for bouncing grenades and jumping mines
|
||||
#define HANDCUFFS 0x00080000 //524288 // item can be used to capture soldiers
|
||||
|
||||
/*#define PLAYER_NET_1_LVL_2 0x00100000 //1048576
|
||||
#define PLAYER_NET_2_LVL_2 0x00200000 //2097152
|
||||
#define TASER 0x00100000 //1048576 // item is a taser, melee hits with this will drain breath (if batteries are supplied)
|
||||
/*#define PLAYER_NET_2_LVL_2 0x00200000 //2097152
|
||||
#define PLAYER_NET_3_LVL_2 0x00400000 //4194304
|
||||
#define PLAYER_NET_4_LVL_2 0x00800000 //8388608
|
||||
|
||||
|
||||
+22
-21
@@ -2555,7 +2555,7 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( AmmoTypes[ubAmmoType].monsterSpit ) && (ubHitLocation == AIM_SHOT_HEAD) && ( ! (pTarget->flags.uiStatusFlags & SOLDIER_MONSTER) ) )
|
||||
if ( ( AmmoTypes[ubAmmoType].monsterSpit || ( AmmoTypes[ubAmmoType].ammoflag & AMMO_BLIND ) ) && (ubHitLocation == AIM_SHOT_HEAD) && ( ! (pTarget->flags.uiStatusFlags & SOLDIER_MONSTER) ) )
|
||||
{
|
||||
UINT8 ubOppositeDirection;
|
||||
|
||||
@@ -2563,27 +2563,28 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend
|
||||
ubAttackDirection = (UINT8) GetDirectionToGridNoFromGridNo( pBullet->sOrigGridNo, pTarget->sGridNo );
|
||||
ubOppositeDirection = gOppositeDirection[ ubAttackDirection ];
|
||||
|
||||
if ( ! ( ubOppositeDirection == pTarget->ubDirection || ubAttackDirection == gOneCCDirection[ pTarget->ubDirection ] || ubAttackDirection == gOneCDirection[ pTarget->ubDirection ] ) )
|
||||
{
|
||||
// lucky bastard was facing away!
|
||||
}
|
||||
// else if ( ( (pTarget->inv[HEAD1POS].usItem == NIGHTGOGGLES) || (pTarget->inv[HEAD1POS].usItem == SUNGOGGLES) || (pTarget->inv[HEAD1POS].usItem == GASMASK) ) && ( PreRandom( 100 ) < (UINT32) (pTarget->inv[HEAD1POS][0]->data.objectStatus) ) )
|
||||
else if ( ( (pTarget->inv[HEAD1POS].exists() == true) ) && ( PreRandom( 100 ) < (UINT32) (pTarget->inv[HEAD1POS][0]->data.objectStatus) ) )
|
||||
{
|
||||
// lucky bastard was wearing protective stuff
|
||||
bHeadSlot = HEAD1POS;
|
||||
}
|
||||
else if ( ( (pTarget->inv[HEAD2POS].exists() == true) ) && ( PreRandom( 100 ) < (UINT32) (pTarget->inv[HEAD2POS][0]->data.objectStatus) ) )
|
||||
{
|
||||
// lucky bastard was wearing protective stuff
|
||||
bHeadSlot = HEAD2POS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// splat!!
|
||||
ubSpecial = FIRE_WEAPON_BLINDED_BY_SPIT_SPECIAL;
|
||||
}
|
||||
if ( ubOppositeDirection == pTarget->ubDirection || ubOppositeDirection == gOneCCDirection[ pTarget->ubDirection ] || ubOppositeDirection == gOneCDirection[ pTarget->ubDirection ] )
|
||||
{
|
||||
if ( (pTarget->inv[HEAD1POS].exists() == true) && ( PreRandom( 100 ) < (UINT32) (pTarget->inv[HEAD1POS][0]->data.objectStatus) ) && AmmoTypes[ubAmmoType].monsterSpit )
|
||||
{
|
||||
// lucky bastard was wearing protective stuff
|
||||
bHeadSlot = HEAD1POS;
|
||||
}
|
||||
else if ( (pTarget->inv[HEAD2POS].exists() == true) && ( PreRandom( 100 ) < (UINT32) (pTarget->inv[HEAD2POS][0]->data.objectStatus) ) && AmmoTypes[ubAmmoType].monsterSpit )
|
||||
{
|
||||
// lucky bastard was wearing protective stuff
|
||||
bHeadSlot = HEAD2POS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// splat!!
|
||||
ubSpecial = FIRE_WEAPON_BLINDED_BY_SPIT_SPECIAL;
|
||||
|
||||
// damage independent calculation of blindness (for pepper spray etc.)
|
||||
if ( AmmoTypes[ubAmmoType].ammoflag & AMMO_BLIND )
|
||||
ubSpecial = FIRE_WEAPON_BLINDED_SPECIAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -173,18 +173,19 @@ enum
|
||||
};
|
||||
|
||||
// DEFINES FOR WEAPON HIT EVENT SPECIAL PARAM
|
||||
#define FIRE_WEAPON_NO_SPECIAL 0
|
||||
#define FIRE_WEAPON_BURST_SPECIAL 1
|
||||
#define FIRE_WEAPON_NO_SPECIAL 0
|
||||
#define FIRE_WEAPON_BURST_SPECIAL 1
|
||||
#define FIRE_WEAPON_HEAD_EXPLODE_SPECIAL 2
|
||||
#define FIRE_WEAPON_CHEST_EXPLODE_SPECIAL 3
|
||||
#define FIRE_WEAPON_LEG_FALLDOWN_SPECIAL 4
|
||||
#define FIRE_WEAPON_HIT_BY_KNIFE_SPECIAL 5
|
||||
#define FIRE_WEAPON_SLEEP_DART_SPECIAL 6
|
||||
#define FIRE_WEAPON_BLINDED_BY_SPIT_SPECIAL 7
|
||||
#define FIRE_WEAPON_TOSSED_OBJECT_SPECIAL 8
|
||||
#define FIRE_WEAPON_TOSSED_OBJECT_SPECIAL 8
|
||||
#define FIRE_WEAPON_BLINDED 9
|
||||
#define FIRE_WEAPON_DEAFENED 10
|
||||
#define FIRE_WEAPON_BLINDED_AND_DEAFENED 11
|
||||
#define FIRE_WEAPON_BLINDED_SPECIAL 12 // Flugente: works like FIRE_WEAPON_BLINDED_BY_SPIT_SPECIAL but without the damage dependency
|
||||
|
||||
|
||||
#define NO_INTERRUPTS 0
|
||||
|
||||
@@ -5671,6 +5671,25 @@ void SOLDIERTYPE::EVENT_SoldierGotHit( UINT16 usWeaponIndex, INT16 sDamage, INT1
|
||||
// Dirty panel
|
||||
fInterfacePanelDirty = DIRTYLEVEL2;
|
||||
}
|
||||
// Flugente: like FIRE_WEAPON_BLINDED_BY_SPIT_SPECIAL but without the damage dependency
|
||||
else if ( ubSpecial == FIRE_WEAPON_BLINDED_SPECIAL )
|
||||
{
|
||||
// blinded!!
|
||||
if ( (this->bBlindedCounter == 0) )
|
||||
{
|
||||
// say quote
|
||||
if (this->flags.uiStatusFlags & SOLDIER_PC)
|
||||
{
|
||||
TacticalCharacterDialogue( this, QUOTE_BLINDED );
|
||||
}
|
||||
DecayIndividualOpplist( this );
|
||||
}
|
||||
|
||||
this->bBlindedCounter += 2* Random(3) + 2;
|
||||
|
||||
// Dirty panel
|
||||
fInterfacePanelDirty = DIRTYLEVEL2;
|
||||
}
|
||||
sBreathLoss += APBPConstants[BP_GET_HIT];
|
||||
ubReason = TAKE_DAMAGE_GUNFIRE;
|
||||
}
|
||||
@@ -5753,6 +5772,47 @@ void SOLDIERTYPE::EVENT_SoldierGotHit( UINT16 usWeaponIndex, INT16 sDamage, INT1
|
||||
}
|
||||
#endif
|
||||
ubReason = TAKE_DAMAGE_HANDTOHAND;
|
||||
|
||||
// Flugente: if the weapon is a taser and has enough batteries, the damage will be 0, but the breathdamage will knock out anyone
|
||||
if ( HasItemFlag(usWeaponIndex, TASER) )
|
||||
{
|
||||
if ( !Item[usWeaponIndex].needsbatteries )
|
||||
{
|
||||
// a taser without batteries is odd, but why not, perhaps the thing has a 1000 pund battery or sth
|
||||
sDamage = 0;
|
||||
sBreathLoss = 20000;
|
||||
ubReason = TAKE_DAMAGE_ELECTRICITY;
|
||||
}
|
||||
// if we need batteries, lets see if we can find some...
|
||||
else
|
||||
{
|
||||
// check for batteries
|
||||
OBJECTTYPE* pBatteries = FindAttachedBatteries( &(MercPtrs[ubAttackerID]->inv[HANDPOS]) );
|
||||
if ( pBatteries )
|
||||
{
|
||||
sDamage = 0;
|
||||
sBreathLoss = 20000;
|
||||
ubReason = TAKE_DAMAGE_ELECTRICITY;
|
||||
|
||||
// use up 8-12 percent of batteries
|
||||
if ( Item[pBatteries->usItem].percentstatusdrainreduction > 0 )
|
||||
(*pBatteries)[0]->data.objectStatus -= (INT8)( (8 + Random( 5 )) * (100 - Item[(*pBatteries)[0]->data.objectStatus].percentstatusdrainreduction)/100 );
|
||||
else
|
||||
(*pBatteries)[0]->data.objectStatus -= (INT8)( (8 + Random( 5 )) );
|
||||
if ( (*pBatteries)[0]->data.objectStatus <= 0 )
|
||||
{
|
||||
// destroy batteries
|
||||
pBatteries->RemoveObjectsFromStack(1);
|
||||
if (pBatteries->exists() == false) {
|
||||
MercPtrs[ubAttackerID]->inv[HANDPOS].RemoveAttachment(pBatteries);
|
||||
}
|
||||
}
|
||||
|
||||
// insert electrical sound effect here
|
||||
PlayJA2Sample( DOOR_ELECTRICITY, RATE_11025, SoundVolume( MIDVOLUME, this->sGridNo ), 1, SoundDir( this->sGridNo ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// marke added one 'or' for explosive ammo. variation of: AmmoTypes[this->inv[this->ubAttackingHand ][0]->data.gun.ubGunAmmoType].explosionSize > 1
|
||||
// extracting attacker´s ammo type
|
||||
|
||||
@@ -8942,7 +8942,7 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
|
||||
}
|
||||
}
|
||||
|
||||
if (pubSpecial && *pubSpecial == FIRE_WEAPON_BLINDED_BY_SPIT_SPECIAL)
|
||||
if (pubSpecial && (*pubSpecial == FIRE_WEAPON_BLINDED_BY_SPIT_SPECIAL || *pubSpecial == FIRE_WEAPON_BLINDED_SPECIAL) )
|
||||
{
|
||||
iImpact = iOrigImpact;
|
||||
}
|
||||
|
||||
+2
-2
@@ -175,8 +175,8 @@ enum
|
||||
// -------- added by Flugente: various ammo flags --------
|
||||
// flags used for various ammo properties (easier than adding 32 differently named variables). DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
|
||||
#define AMMO_NEUROTOXIN 0x00000001 //1 // this ammo adds the cyanide drug effect to its target, killing it in a few turns
|
||||
/*#define FULL_SANDBAG 0x00000002 //2
|
||||
#define SHOVEL 0x00000004 //4
|
||||
#define AMMO_BLIND 0x00000002 //2 // this ammo will blind if it hits the head
|
||||
/*#define SHOVEL 0x00000004 //4
|
||||
#define CONCERTINA 0x00000008 //8
|
||||
|
||||
#define WATER_DRUM 0x00000010 //16 // water drums allow to refill canteens in the sector they are in
|
||||
|
||||
Reference in New Issue
Block a user