- New feature: Ammotype flag AMMO_ANTIMATERIEL (<ammoflag>4</ammoflag>) gives bullets the ability to destroy walls and other structures.

- Fix: SoldierToSoldierLineOfSightTest was called against NOBODY

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7069 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2014-03-15 17:54:04 +00:00
parent bc94c319c6
commit 69f4b2cf34
17 changed files with 118 additions and 35 deletions
+1
View File
@@ -16,6 +16,7 @@
#define BULLET_FLAG_BUCKSHOT 0x0040
#define BULLET_FLAG_FLAME 0x0080
#define BULLET_FLAG_TRACER 0x0100
#define BULLET_FLAG_ANTIMATERIEL 0x0200 // Flugente: bullet can destroy structures
//afp-start calculate line points between two point
#define BULLET_TRACER_MAX_LENGTH 60
+16
View File
@@ -2378,6 +2378,15 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
cnt++;
}
////////////////// ANTI-MATERIEL AMMO
if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].ammoflag & AMMO_ANTIMATERIEL )
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 37 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 37 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
cnt++;
}
}
if (Item[ gpItemDescObject->usItem ].usItemClass & IC_EXPLOSV)
@@ -5724,6 +5733,13 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 4, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
////////////////// ANTI-MATERIEL AMMO
if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].ammoflag & AMMO_ANTIMATERIEL )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 36, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
}
if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_EXPLOSV))
+22
View File
@@ -4442,6 +4442,10 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
fTracer = TRUE;
}
// Flugente: anti-materiel ammo
if ( AmmoTypes[(*pObjAttHand)[0]->data.gun.ubGunAmmoType].ammoflag & AMMO_ANTIMATERIEL )
usBulletFlags |= BULLET_FLAG_ANTIMATERIEL;
ubImpact =(UINT8) GetDamage(&pFirer->inv[pFirer->ubAttackingHand]);
//zilpin: Begin new code block for spread patterns, number of projectiles, impact adjustment, etc.
{
@@ -4922,6 +4926,10 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
fTracer = TRUE;
}
// Flugente: anti-materiel ammo
if ( AmmoTypes[ pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType ].ammoflag & AMMO_ANTIMATERIEL )
usBulletFlags |= BULLET_FLAG_ANTIMATERIEL;
ubImpact =(UINT8) GetDamage(pObjAttHand);
//zilpin: pellet spread patterns externalized in XML
/* zilpin: The section below, including line comments, is the original adjustment made to multiple projectile stats.
@@ -5573,6 +5581,10 @@ INT8 FireBulletGivenTargetTrapOnly( SOLDIERTYPE* pThrower, OBJECTTYPE* pObj, INT
ubSpreadIndex = 2;
}
// Flugente: anti-materiel ammo
if ( AmmoTypes[(*pObj)[0]->data.gun.ubGunAmmoType].ammoflag & AMMO_ANTIMATERIEL )
usBulletFlags |= BULLET_FLAG_ANTIMATERIEL;
// no option to use fire bursts or autofire yet
/*// HEADROCK HAM B2.5: Set tracer effect on/off for individual bullets in a Tracer Magazine, as part of the
// New Tracer System.
@@ -6872,6 +6884,16 @@ void MoveBullet( INT32 iBullet )
// play animation to indicate structure being hit
BulletHitStructure( pBullet, pStructure->usStructureID, 1, pBullet->qCurrX, pBullet->qCurrY, pBullet->qCurrZ, FALSE );
gubLocalStructureNumTimesHit[iStructureLoop] = 1;
// Flugente: anti-materiel rifles have to be handled slightly different - we have to remove the bullet after impact.
// Otherwise we might destroy a structure, but this function won't 'realize' it, leading to invalid memory access
if ( pBullet->usFlags & BULLET_FLAG_ANTIMATERIEL )
{
// Moved here to keep ABC >0 as long as possible
RemoveBullet( iBullet );
// ReduceAttackBusyCount( );
return;
}
}
}
}
+20 -13
View File
@@ -728,7 +728,7 @@ weaponEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = WEAPON_ELEMENT_WEAPON;
pData->curWeapon.HeavyGun = (BOOLEAN) atof(pData->szCharData);
}
pData->maxReadDepth--;
}
@@ -896,16 +896,16 @@ BOOLEAN WriteWeaponStats()
FilePrintf(hFile,"\t\t<APsToReload>%d</APsToReload>\r\n", Weapon[cnt].APsToReload);
FilePrintf(hFile,"\t\t<SwapClips>%d</SwapClips>\r\n", Weapon[cnt].swapClips );
FilePrintf(hFile,"\t\t<MaxDistForMessyDeath>%d</MaxDistForMessyDeath>\r\n", Weapon[cnt].maxdistformessydeath);
FilePrintf(hFile,"\t\t<AutoPenalty>%d</AutoPenalty>\r\n", Weapon[cnt].AutoPenalty);
FilePrintf(hFile,"\t\t<NoSemiAuto>%d</NoSemiAuto>\r\n", Weapon[cnt].NoSemiAuto);
FilePrintf(hFile,"\t\t<AutoPenalty>%d</AutoPenalty>\r\n", Weapon[cnt].AutoPenalty);
FilePrintf(hFile,"\t\t<NoSemiAuto>%d</NoSemiAuto>\r\n", Weapon[cnt].NoSemiAuto);
FilePrintf(hFile,"\t\t<ubAimLevels>%d</ubAimLevels>\r\n", Weapon[cnt].ubAimLevels );
FilePrintf(hFile,"\t\t<EasyUnjam>%d</EasyUnjam>\r\n", Weapon[cnt].EasyUnjam);
FilePrintf(hFile,"\t\t<Handling>%d</Handling>\r\n", Weapon[cnt].ubHandling);
FilePrintf(hFile,"\t\t<EasyUnjam>%d</EasyUnjam>\r\n", Weapon[cnt].EasyUnjam);
FilePrintf(hFile,"\t\t<Handling>%d</Handling>\r\n", Weapon[cnt].ubHandling);
FilePrintf(hFile,"\t\t<usOverheatingJamThreshold>%4.2f</usOverheatingJamThreshold>\r\n", Weapon[cnt].usOverheatingJamThreshold); // Flugente FTW 1
FilePrintf(hFile,"\t\t<usOverheatingDamageThreshold>%4.2f</usOverheatingDamageThreshold>\r\n", Weapon[cnt].usOverheatingDamageThreshold);
FilePrintf(hFile,"\t\t<usOverheatingSingleShotTemperature>%4.2f</usOverheatingSingleShotTemperature>\r\n", Weapon[cnt].usOverheatingSingleShotTemperature);
FilePrintf(hFile,"\t\t<HeavyGun>%d</HeavyGun>\r\n", Weapon[cnt].HeavyGun);
FilePrintf(hFile,"\t\t<HeavyGun>%d</HeavyGun>\r\n", Weapon[cnt].HeavyGun);
FilePrintf(hFile,"\t</WEAPON>\r\n");
}
@@ -4661,7 +4661,7 @@ void StructureHit( INT32 iBullet, UINT16 usWeaponIndex, INT16 bWeaponStatus, UIN
{
pStructure = FindStructureByID( sGridNo, usStructureID );
DamageStructure( pStructure, (UINT8)iImpact, STRUCTURE_DAMAGE_GUNFIRE, sGridNo, sXPos, sYPos, ubAttackerID );
DamageStructure( pStructure, (UINT8)iImpact, STRUCTURE_DAMAGE_GUNFIRE, sGridNo, sXPos, sYPos, ubAttackerID, pBullet->usFlags & BULLET_FLAG_ANTIMATERIEL ? pBullet->iImpact - pBullet->iImpactReduction : 0 );
}
// HEADROCK HAM 5: Fragments are not fired from guns, so they need a special case.
@@ -6784,21 +6784,28 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
sDistVis = pSoldier->GetMaxDistanceVisible(sGridNo, pSoldier->bTargetLevel, CALC_FROM_ALL_DIRS ) * CELL_X_SIZE;
iScopeVisionRangeBonus = GetTotalVisionRangeBonus(pSoldier, bLightLevel); // not an actual range value, simply a modifier for range calculations
if (ubTargetID != NOBODY && pSoldier->aiData.bOppList[ubTargetID] == SEEN_CURRENTLY || gbPublicOpplist[pSoldier->bTeam][ubTargetID] == SEEN_CURRENTLY)
iSightRange = SoldierToSoldierLineOfSightTest( pSoldier, MercPtrs[ubTargetID], TRUE, NO_DISTANCE_LIMIT, pSoldier->bAimShotLocation, false );
if (iSightRange == 0) { // didn't do a bodypart-based test or can't see specific body part aimed at
if (iSightRange == 0)
{
// didn't do a bodypart-based test or can't see specific body part aimed at
iSightRange = SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, pSoldier->bTargetLevel, pSoldier->bTargetCubeLevel, TRUE, NO_DISTANCE_LIMIT, false );
fCoverObscured = true;
}
if (iSightRange == 0) { // Can't see the target but we still need to know what the sight range would be if we could so we can deal with cover penalties
if (ubTargetID != NOBODY && iSightRange == 0 )
{ // Can't see the target but we still need to know what the sight range would be if we could so we can deal with cover penalties
iSightRange = SoldierToSoldierLineOfSightTest( pSoldier, MercPtrs[ubTargetID], TRUE, NO_DISTANCE_LIMIT, pSoldier->bAimShotLocation, false, true );
fCantSeeTarget = true;
fCoverObscured = false;
}
gbForceWeaponReady = false;
gbForceWeaponNotReady = true;
gbForceWeaponReady = false;
gbForceWeaponNotReady = true;
sDistVisNoScope = pSoldier->GetMaxDistanceVisible(sGridNo, pSoldier->bTargetLevel, CALC_FROM_ALL_DIRS ) * CELL_X_SIZE;
gbForceWeaponNotReady = false;
gbForceWeaponNotReady = false;
// Flugente: blind soldiers have sDistVisNoScope = 0...
if ( sDistVisNoScope )
+2 -2
View File
@@ -178,8 +178,8 @@ enum
// 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 AMMO_BLIND 0x00000002 //2 // this ammo will blind if it hits the head
/*#define SHOVEL 0x00000004 //4
#define CONCERTINA 0x00000008 //8
#define AMMO_ANTIMATERIEL 0x00000004 //4 // this ammo is anti-materiel, bullets can destroy structures
/*#define CONCERTINA 0x00000008 //8
#define WATER_DRUM 0x00000010 //16 // water drums allow to refill canteens in the sector they are in
#define MEAT_BLOODCAT 0x00000020 //32 // retrieve this by gutting a bloodcat