From 6ff06a530e3645389dbedd0c2529bd698380308b Mon Sep 17 00:00:00 2001 From: Flugente Date: Mon, 3 Dec 2012 23:07:00 +0000 Subject: [PATCH] - 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 --- Tactical/Interface Enhanced.cpp | 2 +- Tactical/Item Types.h | 4 +-- Tactical/LOS.cpp | 43 +++++++++++------------ Tactical/Overhead Types.h | 7 ++-- Tactical/Soldier Control.cpp | 60 +++++++++++++++++++++++++++++++++ Tactical/Weapons.cpp | 2 +- Tactical/Weapons.h | 4 +-- 7 files changed, 92 insertions(+), 30 deletions(-) diff --git a/Tactical/Interface Enhanced.cpp b/Tactical/Interface Enhanced.cpp index 98f2d623..8b502d85 100644 --- a/Tactical/Interface Enhanced.cpp +++ b/Tactical/Interface Enhanced.cpp @@ -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; diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index a0e0a834..ee930514 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -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 diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp index a784b825..7371b46e 100644 --- a/Tactical/LOS.cpp +++ b/Tactical/LOS.cpp @@ -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; + } + } } } diff --git a/Tactical/Overhead Types.h b/Tactical/Overhead Types.h index 0fdca13f..efd02edc 100644 --- a/Tactical/Overhead Types.h +++ b/Tactical/Overhead Types.h @@ -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 diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index e3cf9df8..a9077b22 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -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 diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index c046aed1..04da73eb 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -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; } diff --git a/Tactical/Weapons.h b/Tactical/Weapons.h index 9302fa18..ce05ef62 100644 --- a/Tactical/Weapons.h +++ b/Tactical/Weapons.h @@ -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