mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
- New Feature: Allow attaching and using underbarrel weapons (by Flugente & JMich)
o You can now attach weapons to other weapons (only one at a time). Comes with additional fire modes (by cycling in tactical with key 'b') o A new item, the KAC masterkey, demonstrates this. Raider and Kelly have one in their starting kit 4. (pics by smeagol) o works both in OCTh and NCTH. Aiming is done via the main gun, but all physical values of the attached gun are considered. o reload an underbarrel gun while it is attached by dropping the ammo on the main gun while an underbarrel fire mode is active. Cycle firemodes in tactical by pressing 'b' o Attachments to underbarrel weapons are inseparable while weapon is attached, but they do work. - Overheating weapons additions (by Flugente) o New option OVERHEATING_DISPLAY_THERMOMETER_RED_OFFSET controls how red the temperature bar is at the beginning. o New option OVERHEATING_SET_ZERO_UPON_NEW_SECTOR sets temperature of items on the floor to zero if loading a new sector git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5133 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+3
-1
@@ -1320,8 +1320,10 @@ void LoadGameExternalOptions()
|
||||
// Flugente FTW 1: These settings control the behavior of Weapon Overheating, its severity, and its display.
|
||||
|
||||
gGameExternalOptions.fDisplayOverheatThermometer = iniReader.ReadBoolean("Tactical Weapon Overheating Settings","OVERHEATING_DISPLAY_THERMOMETER",TRUE);
|
||||
gGameExternalOptions.ubOverheatThermometerRedOffset = iniReader.ReadInteger("Tactical Weapon Overheating Settings","OVERHEATING_DISPLAY_THERMOMETER_RED_OFFSET", 100, 0, 255);
|
||||
gGameExternalOptions.iCooldownModificatorLonelyBarrel = iniReader.ReadFloat ("Tactical Weapon Overheating Settings","OVERHEATING_COOLDOWN_MODIFICATOR_LONELYBARREL", 1.15f, 1.0f, 10.0f);
|
||||
|
||||
gGameExternalOptions.fSetZeroUponNewSector = iniReader.ReadBoolean("Tactical Weapon Overheating Settings","OVERHEATING_SET_ZERO_UPON_NEW_SECTOR",TRUE);
|
||||
|
||||
//################# Strategic Gamestart Settings ##################
|
||||
|
||||
//Lalien: Game starting time
|
||||
|
||||
+3
-1
@@ -1072,8 +1072,10 @@ typedef struct
|
||||
|
||||
// Flugente FTW 1: Weapon Overheating
|
||||
BOOLEAN fDisplayOverheatThermometer; // Should a 'thermometer' for guns and replacable barrels be displayed?
|
||||
UINT8 ubOverheatThermometerRedOffset; // amount of red colour while temperature is below threshold
|
||||
FLOAT iCooldownModificatorLonelyBarrel; // Cooldown modificator for barrels alone in the landscape ;-)
|
||||
|
||||
BOOLEAN fSetZeroUponNewSector; // Should loading a new sector set the temperatures of all items in the old sector to zero? (this doesn't apply to inventories)
|
||||
|
||||
BOOLEAN fWeaponResting; // Should it be possible to rest your weapon on structures in crouched position?
|
||||
BOOLEAN fDisplayWeaponRestingIndicator; // Should a little indicator show if the weapon is currently rested on something?
|
||||
UINT8 ubProneModifierPercentage; // for boni, use ubProneModifierPercentage*boni[PRONE] + (100 - ubProneModifierPercentage)*boni[CROUCHED]
|
||||
|
||||
@@ -6113,6 +6113,8 @@ BOOLEAN HandleDefiniteUnloadingOfWorld( UINT8 ubUnloadCode )
|
||||
//if we arent loading a saved game
|
||||
if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
|
||||
{
|
||||
// Flugente: Set temperares of all items in the old sector to zero before entering a new sector
|
||||
CoolDownWorldItems( TRUE );
|
||||
|
||||
// Save the current sectors Item list to a temporary file, if its not the first time in
|
||||
SaveCurrentSectorsInformationToTempItemFile();
|
||||
|
||||
@@ -594,7 +594,9 @@ void DisplayRangeToTarget( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
|
||||
pSoldier->bTargetLevel = bTempTargetLevel;
|
||||
|
||||
// HEADROCK HAM 3.6: Calculate Gun Range using formula.
|
||||
UINT16 usGunRange = GunRange(&pSoldier->inv[HANDPOS], pSoldier ); // SANDRO - added argument
|
||||
// Flugente: we might be equipped with an underbarrel gun....
|
||||
OBJECTTYPE* pObjhand = pSoldier->GetUsedWeapon(&pSoldier->inv[HANDPOS]);
|
||||
UINT16 usGunRange = GunRange(pObjhand, pSoldier ); // SANDRO - added argument
|
||||
|
||||
swprintf( zOutputString, gzDisplayCoverText[title], usRange / 10, usGunRange / 10, uiHitChance );
|
||||
//Display the msg
|
||||
|
||||
+10
-9
@@ -2531,15 +2531,18 @@ void UIHandleMercAttack( SOLDIERTYPE *pSoldier , SOLDIERTYPE *pTargetSoldier, IN
|
||||
INT32 iHandleReturn;
|
||||
INT32 sTargetGridNo;
|
||||
INT8 bTargetLevel;
|
||||
UINT16 usItem;
|
||||
LEVELNODE *pIntNode;
|
||||
STRUCTURE *pStructure;
|
||||
INT32 sGridNo, sNewGridNo;
|
||||
UINT8 ubItemCursor;
|
||||
UINT16 usItem;
|
||||
LEVELNODE* pIntNode;
|
||||
STRUCTURE* pStructure;
|
||||
INT32 sGridNo, sNewGridNo;
|
||||
UINT8 ubItemCursor;
|
||||
|
||||
// get cursor
|
||||
ubItemCursor = GetActionModeCursor( pSoldier );
|
||||
|
||||
OBJECTTYPE* pObj = pSoldier->GetUsedWeapon(&pSoldier->inv[HANDPOS]);
|
||||
usItem = pSoldier->GetUsedWeaponNumber(&pSoldier->inv[HANDPOS]);
|
||||
|
||||
if ( !(gTacticalStatus.uiFlags & INCOMBAT) && pTargetSoldier && Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass & IC_WEAPON )
|
||||
{
|
||||
if ( NPCFirstDraw( pSoldier, pTargetSoldier ) )
|
||||
@@ -2555,8 +2558,6 @@ void UIHandleMercAttack( SOLDIERTYPE *pSoldier , SOLDIERTYPE *pTargetSoldier, IN
|
||||
|
||||
// Set aim time to one in UI
|
||||
pSoldier->aiData.bAimTime = (pSoldier->aiData.bShownAimTime );
|
||||
usItem = pSoldier->inv[ HANDPOS ].usItem;
|
||||
|
||||
// ATE: Check if we are targeting an interactive tile, and adjust gridno accordingly...
|
||||
pIntNode = GetCurInteractiveTileGridNoAndStructure( &sGridNo, &pStructure );
|
||||
|
||||
@@ -2642,11 +2643,11 @@ void UIHandleMercAttack( SOLDIERTYPE *pSoldier , SOLDIERTYPE *pTargetSoldier, IN
|
||||
|
||||
if (pSoldier->bWeaponMode == WM_ATTACHED_GL || pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST || pSoldier->bWeaponMode == WM_ATTACHED_GL_AUTO )
|
||||
{
|
||||
iHandleReturn = HandleItem( pSoldier, sTargetGridNo, bTargetLevel, GetAttachedGrenadeLauncher(&pSoldier->inv[ HANDPOS ]), TRUE );
|
||||
iHandleReturn = HandleItem( pSoldier, sTargetGridNo, bTargetLevel, GetAttachedGrenadeLauncher(pObj), TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
iHandleReturn = HandleItem( pSoldier, sTargetGridNo, bTargetLevel, pSoldier->inv[ HANDPOS ].usItem, TRUE );
|
||||
iHandleReturn = HandleItem( pSoldier, sTargetGridNo, bTargetLevel, usItem, TRUE );
|
||||
}
|
||||
|
||||
if ( iHandleReturn < 0 )
|
||||
|
||||
@@ -2646,7 +2646,7 @@ void INVRenderSilhouette( UINT32 uiBuffer, INT16 PocketIndex, INT16 SilIndex, IN
|
||||
// Flugente FTW 1: Function to get the number of the item condition string
|
||||
UINT8 GetTemperatureString( FLOAT overheatpercentage, UINT32* apRed, UINT32* apGreen, UINT32* abBlue )
|
||||
{
|
||||
*apRed = (UINT32) ( 100 + 155 * ( (max(1.0, overheatpercentage) - 1.0)/(max(1.0, overheatpercentage)) ) );
|
||||
*apRed = (UINT32) ( gGameExternalOptions.ubOverheatThermometerRedOffset + (255 - gGameExternalOptions.ubOverheatThermometerRedOffset) * ( (max(1.0, overheatpercentage) - 1.0)/(max(1.0, overheatpercentage)) ) );
|
||||
*apGreen = 0;
|
||||
*abBlue = 0;
|
||||
|
||||
@@ -2769,7 +2769,7 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
|
||||
|
||||
}
|
||||
#endif
|
||||
// FIRST DISPLAY FREE ROUNDS REMIANING
|
||||
|
||||
if ( pItem->usItemClass == IC_GUN && !Item[pObject->usItem].rocketlauncher )
|
||||
{
|
||||
sNewY = sY + sHeight - 10;
|
||||
@@ -2779,75 +2779,76 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
|
||||
if ( gGameOptions.fWeaponOverheating == TRUE && gGameExternalOptions.fDisplayOverheatThermometer == TRUE )
|
||||
sNewX = sX + 6;
|
||||
|
||||
SetFontForeground ( AmmoTypes[(*pObject)[iter]->data.gun.ubGunAmmoType].fontColour );
|
||||
//switch ((*pObject)[iter]->data.gun.ubGunAmmoType)
|
||||
//{
|
||||
// case AMMO_AP:
|
||||
// case AMMO_SUPER_AP:
|
||||
// SetFontForeground( ITEMDESC_FONTAPFORE );
|
||||
// break;
|
||||
// case AMMO_HP:
|
||||
// SetFontForeground( ITEMDESC_FONTHPFORE );
|
||||
// break;
|
||||
// case AMMO_BUCKSHOT:
|
||||
// SetFontForeground( ITEMDESC_FONTBSFORE );
|
||||
// break;
|
||||
// case AMMO_HE:
|
||||
// case AMMO_GRENADE:
|
||||
// SetFontForeground( ITEMDESC_FONTHEFORE );
|
||||
// break;
|
||||
// case AMMO_HEAT:
|
||||
// SetFontForeground( ITEMDESC_FONTHEAPFORE );
|
||||
// break;
|
||||
// default:
|
||||
// SetFontForeground( FONT_MCOLOR_DKGRAY );
|
||||
// break;
|
||||
//}
|
||||
|
||||
// HEADROCK HAM 3.4: Get estimate of bullets left.
|
||||
if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) )
|
||||
// Flugente: check for underbarrel weapons and use that object if necessary
|
||||
OBJECTTYPE* pObjShown = pObject;
|
||||
INVTYPE *pItemShown = pItem;
|
||||
if ( pItem->usItemClass == IC_GUN && pSoldier && ( pSoldier->bWeaponMode == WM_ATTACHED_UB || pSoldier->bWeaponMode == WM_ATTACHED_UB_BURST || pSoldier->bWeaponMode == WM_ATTACHED_UB_AUTO ) )
|
||||
{
|
||||
// Soldier doesn't know.
|
||||
EstimateBulletsLeft( pSoldier, pObject );
|
||||
swprintf( pStr, L"%s", gBulletCount );
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( pStr, L"%d", (*pObject)[iter]->data.gun.ubGunShotsLeft );
|
||||
}
|
||||
OBJECTTYPE *pObjectUnderBarrel = FindAttachment_UnderBarrel( pObject );
|
||||
|
||||
//swprintf( pStr, L"%d", (*pObject)[iter]->data.gun.ubGunShotsLeft );
|
||||
//swprintf( pStr, L"%d", GetEstimateBulletsLeft(pSoldier, pObject) );
|
||||
|
||||
if ( uiBuffer == guiSAVEBUFFER )
|
||||
{
|
||||
RestoreExternBackgroundRect( sNewX, sNewY, 20, 15 );
|
||||
}
|
||||
mprintf( sNewX, sNewY, pStr );
|
||||
gprintfinvalidate( sNewX, sNewY, pStr );
|
||||
|
||||
sNewX = sX + 1;
|
||||
|
||||
SetFontForeground( FONT_MCOLOR_DKGRAY );
|
||||
|
||||
// Display 'JAMMED' if we are jammed
|
||||
if ( (*pObject)[iter]->data.gun.bGunAmmoStatus < 0 )
|
||||
{
|
||||
SetFontForeground( FONT_MCOLOR_RED );
|
||||
|
||||
if ( sWidth >= ( BIG_INV_SLOT_WIDTH - 10 ) )
|
||||
if ( pObjectUnderBarrel )
|
||||
{
|
||||
swprintf( pStr, TacticalStr[ JAMMED_ITEM_STR ] );
|
||||
INVTYPE *pItemUnderBarrel;
|
||||
if ( ubStatusIndex < RENDER_ITEM_ATTACHMENT1 )
|
||||
{
|
||||
pItemUnderBarrel = &Item[ pObjectUnderBarrel->usItem ];
|
||||
}
|
||||
else
|
||||
{
|
||||
pItemUnderBarrel = &Item[ (*pObjectUnderBarrel)[iter]->GetAttachmentAtIndex( ubStatusIndex - RENDER_ITEM_ATTACHMENT1 )->usItem ];
|
||||
}
|
||||
|
||||
pObjShown = pObjectUnderBarrel;
|
||||
pItemShown = pItemUnderBarrel;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pItemShown->usItemClass == IC_GUN && !Item[pObjShown->usItem].rocketlauncher )
|
||||
{
|
||||
SetFontForeground ( AmmoTypes[(*pObjShown)[iter]->data.gun.ubGunAmmoType].fontColour );
|
||||
|
||||
// HEADROCK HAM 3.4: Get estimate of bullets left.
|
||||
if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) )
|
||||
{
|
||||
// Soldier doesn't know.
|
||||
EstimateBulletsLeft( pSoldier, pObjShown );
|
||||
swprintf( pStr, L"%s", gBulletCount );
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( pStr, TacticalStr[ SHORT_JAMMED_GUN ] );
|
||||
swprintf( pStr, L"%d", (*pObjShown)[iter]->data.gun.ubGunShotsLeft );
|
||||
}
|
||||
|
||||
if ( uiBuffer == guiSAVEBUFFER )
|
||||
{
|
||||
RestoreExternBackgroundRect( sNewX, sNewY, 20, 15 );
|
||||
}
|
||||
|
||||
VarFindFontCenterCoordinates( sX, sY, sWidth, sHeight , ITEM_FONT, &sNewX, &sNewY, pStr );
|
||||
|
||||
mprintf( sNewX, sNewY, pStr );
|
||||
gprintfinvalidate( sNewX, sNewY, pStr );
|
||||
|
||||
sNewX = sX + 1;
|
||||
|
||||
SetFontForeground( FONT_MCOLOR_DKGRAY );
|
||||
|
||||
// Display 'JAMMED' if we are jammed
|
||||
if ( (*pObjShown)[iter]->data.gun.bGunAmmoStatus < 0 )
|
||||
{
|
||||
SetFontForeground( FONT_MCOLOR_RED );
|
||||
|
||||
if ( sWidth >= ( BIG_INV_SLOT_WIDTH - 10 ) )
|
||||
{
|
||||
swprintf( pStr, TacticalStr[ JAMMED_ITEM_STR ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( pStr, TacticalStr[ SHORT_JAMMED_GUN ] );
|
||||
}
|
||||
|
||||
VarFindFontCenterCoordinates( sX, sY, sWidth, sHeight , ITEM_FONT, &sNewX, &sNewY, pStr );
|
||||
|
||||
mprintf( sNewX, sNewY, pStr );
|
||||
gprintfinvalidate( sNewX, sNewY, pStr );
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
@@ -2908,20 +2909,25 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
|
||||
|
||||
// Flugente FTW 1
|
||||
if ( gGameOptions.fWeaponOverheating == TRUE && gGameExternalOptions.fDisplayOverheatThermometer == TRUE && ( pItem->usItemClass & (IC_GUN | IC_LAUNCHER) || Item[pObject->usItem].barrel == TRUE ) )
|
||||
{
|
||||
FLOAT overheatjampercentage = GetGunOverheatJamPercentage( pObject);
|
||||
{
|
||||
OBJECTTYPE* pObjShown = pObject;
|
||||
|
||||
if ( pSoldier )
|
||||
pObjShown = pSoldier->GetUsedWeapon(pObject);
|
||||
|
||||
FLOAT overheatjampercentage = GetGunOverheatJamPercentage( pObjShown );
|
||||
|
||||
UINT32 red, green, blue;
|
||||
UINT8 TemperatureStringNum = GetTemperatureString( overheatjampercentage, &red, &green, &blue );
|
||||
|
||||
UINT16 colour = Get16BPPColor( FROMRGB( red, green, blue ) );
|
||||
|
||||
DrawItemUIBarEx( pObject, DRAW_ITEM_TEMPERATURE, sX, sY + sHeight-1, ITEMDESC_ITEM_STATUS_WIDTH, sHeight-1, colour, colour, TRUE, guiSAVEBUFFER );
|
||||
DrawItemUIBarEx( pObjShown, DRAW_ITEM_TEMPERATURE, sX, sY + sHeight-1, ITEMDESC_ITEM_STATUS_WIDTH, sHeight-1, colour, colour, TRUE, guiSAVEBUFFER );
|
||||
}
|
||||
|
||||
// display symbol if we are leaning our weapon on something
|
||||
// display only if eapon resting is allowed, display is allowed, item is a gun/launcher, we are a person, we hold the gun in our hand, and we are resting the gun
|
||||
if ( gGameExternalOptions.fWeaponResting && gGameExternalOptions.fDisplayWeaponRestingIndicator && pItem->usItemClass & (IC_GUN | IC_LAUNCHER) && pSoldier && pSoldier->bActive && pSoldier->bInSector && &(pSoldier->inv[pSoldier->ubAttackingHand]) == pObject && pSoldier->IsWeaponMounted() )
|
||||
if ( gGameExternalOptions.fWeaponResting && gGameExternalOptions.fDisplayWeaponRestingIndicator && pItem->usItemClass & (IC_GUN | IC_LAUNCHER) && pSoldier && &(pSoldier->inv[pSoldier->ubAttackingHand]) == pObject && pSoldier->IsWeaponMounted() )
|
||||
{
|
||||
SetRGBFontForeground( 95, 160, 154 );
|
||||
|
||||
@@ -2994,6 +3000,21 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
|
||||
swprintf( pStr, New113Message[MSG113_GL_AUTO] );
|
||||
SetFontForeground( FONT_YELLOW );
|
||||
}
|
||||
else if(pSoldier->bWeaponMode == WM_ATTACHED_UB)
|
||||
{
|
||||
swprintf( pStr, New113Message[MSG113_UB] );
|
||||
SetFontForeground( FONT_ORANGE );
|
||||
}
|
||||
else if(pSoldier->bWeaponMode == WM_ATTACHED_UB_BURST)
|
||||
{
|
||||
swprintf( pStr, New113Message[MSG113_UB_BRST] );
|
||||
SetFontForeground( FONT_ORANGE );
|
||||
}
|
||||
else if(pSoldier->bWeaponMode == WM_ATTACHED_UB_AUTO)
|
||||
{
|
||||
swprintf( pStr, New113Message[MSG113_UB_AUTO] );
|
||||
SetFontForeground( FONT_ORANGE );
|
||||
}
|
||||
|
||||
// Get length of string
|
||||
uiStringLength=StringPixLength(pStr, ITEM_FONT );
|
||||
|
||||
@@ -2167,12 +2167,15 @@ BOOLEAN CreateSMPanelButtons( )
|
||||
|
||||
iSMPanelImages[ OPTIONS_IMAGES ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ] ,-1,24,-1,25,-1 );
|
||||
|
||||
iBurstButtonImages[ WM_NORMAL ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 7, -1, -1, -1 );
|
||||
iBurstButtonImages[ WM_NORMAL ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 7, -1, -1, -1 );
|
||||
iBurstButtonImages[ WM_BURST ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
|
||||
iBurstButtonImages[ WM_AUTOFIRE ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
|
||||
iBurstButtonImages[ WM_ATTACHED_GL ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 26, -1, -1, -1 );
|
||||
iBurstButtonImages[ WM_ATTACHED_GL_BURST ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
|
||||
iBurstButtonImages[ WM_ATTACHED_GL_AUTO ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
|
||||
iBurstButtonImages[ WM_ATTACHED_GL ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 26, -1, -1, -1 );
|
||||
iBurstButtonImages[ WM_ATTACHED_GL_BURST ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
|
||||
iBurstButtonImages[ WM_ATTACHED_GL_AUTO ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
|
||||
iBurstButtonImages[ WM_ATTACHED_UB ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 7, -1, -1, -1 );
|
||||
iBurstButtonImages[ WM_ATTACHED_UB_BURST ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
|
||||
iBurstButtonImages[ WM_ATTACHED_UB_AUTO ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
|
||||
|
||||
FilenameForBPP("INTERFACE\\invadd-ons.sti", ubString);
|
||||
// Load button Graphics
|
||||
@@ -2396,6 +2399,9 @@ void RemoveSMPanelButtons( )
|
||||
UnloadButtonImage( iBurstButtonImages[ WM_ATTACHED_GL ] );
|
||||
UnloadButtonImage( iBurstButtonImages[ WM_ATTACHED_GL_BURST ] );
|
||||
UnloadButtonImage( iBurstButtonImages[ WM_ATTACHED_GL_AUTO ] );
|
||||
UnloadButtonImage( iBurstButtonImages[ WM_ATTACHED_UB ] );
|
||||
UnloadButtonImage( iBurstButtonImages[ WM_ATTACHED_UB_BURST ] );
|
||||
UnloadButtonImage( iBurstButtonImages[ WM_ATTACHED_UB_AUTO ] );
|
||||
|
||||
}
|
||||
|
||||
|
||||
+176
-13
@@ -3587,7 +3587,9 @@ INT8 FindAmmoToReload( SOLDIERTYPE * pSoldier, INT8 bWeaponIn, INT8 bExcludeSlot
|
||||
{
|
||||
return( NO_SLOT );
|
||||
}
|
||||
pObj = &(pSoldier->inv[bWeaponIn]);
|
||||
|
||||
// Flugente: check for underbarrel weapons and use that object if necessary
|
||||
pObj = pSoldier->GetUsedWeapon( &(pSoldier->inv[bWeaponIn]) );
|
||||
|
||||
//<SB> manual recharge
|
||||
if ((*pObj)[0]->data.gun.ubGunShotsLeft && !((*pObj)[0]->data.gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER) )
|
||||
@@ -3656,7 +3658,9 @@ BOOLEAN AutoReload( SOLDIERTYPE * pSoldier )
|
||||
BOOLEAN fRet;
|
||||
|
||||
CHECKF( pSoldier );
|
||||
pObj = &(pSoldier->inv[HANDPOS]);
|
||||
|
||||
// Flugente: check for underbarrel weapons and use that object if necessary
|
||||
pObj = pSoldier->GetUsedWeapon( &(pSoldier->inv[HANDPOS]) );
|
||||
|
||||
//<SB> manual recharge
|
||||
if ((*pObj)[0]->data.gun.ubGunShotsLeft && !((*pObj)[0]->data.gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER) )
|
||||
@@ -3746,7 +3750,9 @@ BOOLEAN AutoReload( SOLDIERTYPE * pSoldier )
|
||||
// then do a reload of both guns!
|
||||
if ( (fRet == TRUE) && pSoldier->IsValidSecondHandShotForReloadingPurposes( ) )
|
||||
{
|
||||
pObj = &(pSoldier->inv[SECONDHANDPOS]);
|
||||
// Flugente: check for underbarrel weapons and use that object if necessary
|
||||
pObj = pSoldier->GetUsedWeapon( &(pSoldier->inv[SECONDHANDPOS]) );
|
||||
|
||||
bSlot = FindAmmoToReload( pSoldier, SECONDHANDPOS, NO_SLOT );
|
||||
if (bSlot != NO_SLOT)
|
||||
{
|
||||
@@ -4612,7 +4618,9 @@ BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac
|
||||
{
|
||||
//Make sure it's actually on that gun..
|
||||
//if(FindAttachment_GrenadeLauncher(this)->usItem == attachmentObject.usItem){
|
||||
if(FindAttachment(this, attachmentObject.usItem, subObject)->usItem == attachmentObject.usItem){
|
||||
// Flugente: if we attach a gun to another gun, do not transfer attachments
|
||||
if( Item[attachmentObject.usItem].usItemClass != IC_GUN && FindAttachment(this, attachmentObject.usItem, subObject)->usItem == attachmentObject.usItem)
|
||||
{
|
||||
// transfer the grenade from the grenade launcher to the gun
|
||||
|
||||
//To know wether this grenade is valid, we need to correct the slots, because they may have changed when attaching the UGL
|
||||
@@ -5861,7 +5869,10 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
|
||||
case IC_GUN:
|
||||
if (Item[pObj->usItem].usItemClass == IC_AMMO)
|
||||
{
|
||||
if (Weapon[pInSlot->usItem].ubCalibre == Magazine[Item[pObj->usItem].ubClassIndex].ubCalibre)
|
||||
// Flugente: if we have an underbarrel weapon, we can reload that
|
||||
OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon(pInSlot);
|
||||
|
||||
if (Weapon[pObjUsed->usItem].ubCalibre == Magazine[Item[pObj->usItem].ubClassIndex].ubCalibre)
|
||||
{
|
||||
//CHRISL: Work differently with ammo crates but only when not in combat
|
||||
if(Magazine[Item[pObj->usItem].ubClassIndex].ubMagType >= AMMO_BOX)
|
||||
@@ -5881,7 +5892,7 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
|
||||
{
|
||||
if(Item[loop].usItemClass == IC_AMMO)
|
||||
{
|
||||
if(Magazine[Item[loop].ubClassIndex].ubCalibre == Weapon[pInSlot->usItem].ubCalibre && Magazine[Item[loop].ubClassIndex].ubAmmoType == Magazine[Item[pObj->usItem].ubClassIndex].ubAmmoType && Magazine[Item[loop].ubClassIndex].ubMagSize == GetMagSize(pInSlot))
|
||||
if(Magazine[Item[loop].ubClassIndex].ubCalibre == Weapon[pObjUsed->usItem].ubCalibre && Magazine[Item[loop].ubClassIndex].ubAmmoType == Magazine[Item[pObj->usItem].ubClassIndex].ubAmmoType && Magazine[Item[loop].ubClassIndex].ubMagSize == GetMagSize(pObjUsed))
|
||||
newItem = loop;
|
||||
}
|
||||
}
|
||||
@@ -5891,7 +5902,7 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
|
||||
ubShotsLeft = (*pObj)[0]->data.ubShotsLeft;
|
||||
for(UINT8 clip = 0; clip < 5; clip++)
|
||||
{
|
||||
magSize = GetMagSize(pInSlot);
|
||||
magSize = GetMagSize(pObjUsed);
|
||||
if(ubShotsLeft < magSize)
|
||||
magSize = ubShotsLeft;
|
||||
if(CreateAmmo(newItem, &tempClip, magSize))
|
||||
@@ -5963,7 +5974,7 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
|
||||
}
|
||||
}
|
||||
else
|
||||
return( ReloadGun( pSoldier, pInSlot, pObj ) );
|
||||
return( ReloadGun( pSoldier, pObjUsed, pObj ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -7470,6 +7481,24 @@ BOOLEAN OBJECTTYPE::RemoveAttachment( OBJECTTYPE* pAttachment, OBJECTTYPE * pNew
|
||||
}
|
||||
}
|
||||
|
||||
// if in attached weapon mode and don't have weapon with GL attached in hand, reset weapon mode
|
||||
if ( ( (pSoldier->bWeaponMode == WM_ATTACHED_GL || pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST || pSoldier->bWeaponMode == WM_ATTACHED_GL_AUTO )&& !IsGrenadeLauncherAttached( &(pSoldier->inv[ HANDPOS ]) ) ) ||
|
||||
( (pSoldier->bWeaponMode == WM_ATTACHED_UB || pSoldier->bWeaponMode == WM_ATTACHED_UB_BURST || pSoldier->bWeaponMode == WM_ATTACHED_UB_AUTO )&& !IsUnderBarrelAttached( &(pSoldier->inv[ HANDPOS ] ) ) ) )
|
||||
{
|
||||
if ( !Weapon[pSoldier->inv[ HANDPOS ].usItem].NoSemiAuto )
|
||||
{
|
||||
pSoldier->bWeaponMode = WM_NORMAL;
|
||||
pSoldier->bDoBurst = FALSE;
|
||||
pSoldier->bDoAutofire = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSoldier->bWeaponMode = WM_AUTOFIRE;
|
||||
pSoldier->bDoBurst = TRUE;
|
||||
pSoldier->bDoAutofire = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(Item[this->usItem].usItemClass == IC_GUN && oldMagSize != GetMagSize(this, subObject)){
|
||||
fInterfacePanelDirty = DIRTYLEVEL2;
|
||||
RenderBulletIcon(this, subObject);
|
||||
@@ -9477,9 +9506,13 @@ void GetRecoil( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 *bRecoilX, INT8 *b
|
||||
{
|
||||
*bRecoilX = 0;
|
||||
*bRecoilY = 0;
|
||||
|
||||
// Flugente: get weapon actually used (might be an underbarrel shotgun)
|
||||
OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon(pObj);
|
||||
OBJECTTYPE* pObjUsedInHand = pSoldier->GetUsedWeapon( &(pSoldier->inv[HANDPOS]) );
|
||||
|
||||
//if (ubNumBullet < 2)
|
||||
if (ubNumBullet < Weapon[pObj->usItem].ubRecoilDelay)
|
||||
if (ubNumBullet < Weapon[pObjUsed->usItem].ubRecoilDelay)
|
||||
{
|
||||
// The first bullet in a volley never has recoil - it hasn't "set in" yet. Only the second+ bullets
|
||||
// will have any recoil.
|
||||
@@ -9488,13 +9521,15 @@ void GetRecoil( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 *bRecoilX, INT8 *b
|
||||
return;
|
||||
}
|
||||
|
||||
*bRecoilX = Weapon[pObj->usItem].bRecoilX;
|
||||
*bRecoilY = Weapon[pObj->usItem].bRecoilY;
|
||||
*bRecoilX = Weapon[pObjUsed->usItem].bRecoilX;
|
||||
*bRecoilY = Weapon[pObjUsed->usItem].bRecoilY;
|
||||
|
||||
// Apply a percentage-based modifier. This can increase or decrease BOTH axes. At most, it can eliminate
|
||||
// recoil on the gun.
|
||||
|
||||
INT16 sPercentRecoilModifier = GetPercentRecoilModifier( pObj );
|
||||
//INT16 sPercentRecoilModifier = GetPercentRecoilModifier( pObj );
|
||||
INT16 sPercentRecoilModifier = __max(-100, (GetBasePercentRecoilModifier( pObjUsed ) + GetAttachmentPercentRecoilModifier( pObjUsedInHand ) ));
|
||||
|
||||
|
||||
*bRecoilX += (*bRecoilX * sPercentRecoilModifier ) / 100;
|
||||
*bRecoilY += (*bRecoilY * sPercentRecoilModifier ) / 100;
|
||||
@@ -9505,7 +9540,10 @@ void GetRecoil( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 *bRecoilX, INT8 *b
|
||||
INT8 bRecoilAdjustX = 0;
|
||||
INT8 bRecoilAdjustY = 0;
|
||||
|
||||
GetFlatRecoilModifier( pObj, &bRecoilAdjustX, &bRecoilAdjustY );
|
||||
//GetFlatRecoilModifier( pObj, &bRecoilAdjustX, &bRecoilAdjustY );
|
||||
GetBaseFlatRecoilModifier( pObj, &bRecoilAdjustX, &bRecoilAdjustY );
|
||||
GetAttachmentFlatRecoilModifier( &pSoldier->inv[HANDPOS], &bRecoilAdjustX, &bRecoilAdjustY);
|
||||
//JMich TODO: Currently no check for dual wielding
|
||||
|
||||
*bRecoilX = __max(0, *bRecoilX + bRecoilAdjustX);
|
||||
*bRecoilY = __max(0, *bRecoilY + bRecoilAdjustY);
|
||||
@@ -9517,6 +9555,44 @@ void GetRecoil( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 *bRecoilX, INT8 *b
|
||||
// HEADROCK HAM 4: This function calculates the flat recoil adjustment for a gun. Flat adjustment increases
|
||||
// or decreases recoil by a specific number of points in either the vertical or horizontal axes (or both).
|
||||
// It can potentially cause a weapon it reverse its recoil direction.
|
||||
void GetBaseFlatRecoilModifier( OBJECTTYPE *pObj, INT8 *bRecoilModifierX, INT8 *bRecoilModifierY )
|
||||
{
|
||||
INT8 bRecoilAdjustX = 0;
|
||||
INT8 bRecoilAdjustY = 0;
|
||||
if (pObj->exists() == true && UsingNewCTHSystem() == true)
|
||||
{
|
||||
// Inherent item modifiers
|
||||
bRecoilAdjustX += BonusReduceMore( Item[pObj->usItem].RecoilModifierX, (*pObj)[0]->data.objectStatus );
|
||||
bRecoilAdjustY += BonusReduceMore( Item[pObj->usItem].RecoilModifierY, (*pObj)[0]->data.objectStatus );
|
||||
|
||||
// Ammo item modifiers
|
||||
bRecoilAdjustX += Item[(*pObj)[0]->data.gun.usGunAmmoItem].RecoilModifierX;
|
||||
bRecoilAdjustY += Item[(*pObj)[0]->data.gun.usGunAmmoItem].RecoilModifierY;
|
||||
}
|
||||
|
||||
*bRecoilModifierX = bRecoilAdjustX;
|
||||
*bRecoilModifierY = bRecoilAdjustY;
|
||||
}
|
||||
void GetAttachmentFlatRecoilModifier( OBJECTTYPE *pObj, INT8 *bRecoilModifierX, INT8 *bRecoilModifierY )
|
||||
{
|
||||
INT8 bRecoilAdjustX = 0;
|
||||
INT8 bRecoilAdjustY = 0;
|
||||
if (pObj->exists() == true && UsingNewCTHSystem() == true)
|
||||
{
|
||||
// Attachment item modifiers
|
||||
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
|
||||
{
|
||||
if (iter->exists())
|
||||
{
|
||||
bRecoilAdjustX += BonusReduceMore( Item[iter->usItem].RecoilModifierX, (*iter)[0]->data.objectStatus );
|
||||
bRecoilAdjustY += BonusReduceMore( Item[iter->usItem].RecoilModifierY, (*iter)[0]->data.objectStatus );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*bRecoilModifierX += bRecoilAdjustX;
|
||||
*bRecoilModifierY += bRecoilAdjustY;
|
||||
}
|
||||
void GetFlatRecoilModifier( OBJECTTYPE *pObj, INT8 *bRecoilModifierX, INT8 *bRecoilModifierY )
|
||||
{
|
||||
|
||||
@@ -9553,6 +9629,39 @@ void GetFlatRecoilModifier( OBJECTTYPE *pObj, INT8 *bRecoilModifierX, INT8 *bRec
|
||||
// This adjustment either increases or decreases the gun's vertical and horizontal recoil at the same time. Due to
|
||||
// the percentage-based nature of this modifier, it cannot cause a gun to reverse its recoil - only diminish it to
|
||||
// zero.
|
||||
INT16 GetBasePercentRecoilModifier( OBJECTTYPE *pObj)
|
||||
{
|
||||
INT16 sRecoilAdjust = 0;
|
||||
|
||||
if (pObj->exists() == true && UsingNewCTHSystem() == true)
|
||||
{
|
||||
// Inherent item modifiers
|
||||
sRecoilAdjust += BonusReduceMore( Item[pObj->usItem].PercentRecoilModifier, (*pObj)[0]->data.objectStatus );
|
||||
|
||||
// Ammo item modifiers
|
||||
sRecoilAdjust += Item[(*pObj)[0]->data.gun.usGunAmmoItem].PercentRecoilModifier;
|
||||
}
|
||||
|
||||
return (sRecoilAdjust);
|
||||
}
|
||||
INT16 GetAttachmentPercentRecoilModifier( OBJECTTYPE *pObj)
|
||||
{
|
||||
INT16 sRecoilAdjust = 0;
|
||||
|
||||
if (pObj->exists() == true && UsingNewCTHSystem() == true)
|
||||
{
|
||||
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
|
||||
{
|
||||
if (iter->exists())
|
||||
{
|
||||
sRecoilAdjust += BonusReduceMore( Item[iter->usItem].PercentRecoilModifier, (*iter)[0]->data.objectStatus );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (sRecoilAdjust);
|
||||
|
||||
}
|
||||
INT16 GetPercentRecoilModifier( OBJECTTYPE *pObj )
|
||||
{
|
||||
INT16 sRecoilAdjust = 0;
|
||||
@@ -10550,6 +10659,60 @@ UINT16 GetAttachedGrenadeLauncher( OBJECTTYPE * pObj )
|
||||
return( NONE );
|
||||
}
|
||||
|
||||
UINT16 GetAttachedUnderBarrel( OBJECTTYPE * pObj )
|
||||
{
|
||||
if (pObj->exists() == true) {
|
||||
|
||||
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
|
||||
if ((Item[iter->usItem].usItemClass & (IC_GUN | IC_BLADE) ) && iter->exists())
|
||||
{
|
||||
return( (UINT16) Item[iter->usItem].uiIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
return( NONE );
|
||||
}
|
||||
BOOLEAN IsUnderBarrelAttached( OBJECTTYPE * pObj, UINT8 subObject )
|
||||
{
|
||||
if (pObj->exists() == true) {
|
||||
|
||||
for (attachmentList::iterator iter = (*pObj)[subObject]->attachments.begin(); iter != (*pObj)[subObject]->attachments.end(); ++iter) {
|
||||
if (Item[iter->usItem].usItemClass & (IC_GUN | IC_BLADE) && iter->exists() )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
OBJECTTYPE* FindAttachment_UnderBarrel( OBJECTTYPE * pObj )
|
||||
{
|
||||
if (pObj->exists() == true) {
|
||||
|
||||
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
|
||||
if (Item[iter->usItem].usItemClass & (IC_GUN | IC_BLADE) && iter->exists() )
|
||||
{
|
||||
return( &(*iter) );
|
||||
}
|
||||
}
|
||||
}
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
INT16 GetUnderBarrelStatus( OBJECTTYPE * pObj )
|
||||
{
|
||||
if (pObj->exists() == true) {
|
||||
|
||||
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
|
||||
if (Item[iter->usItem].usItemClass & (IC_GUN | IC_BLADE) && iter->exists())
|
||||
{
|
||||
return( (*iter)[0]->data.objectStatus );
|
||||
}
|
||||
}
|
||||
}
|
||||
return( ITEM_NOT_FOUND );
|
||||
}
|
||||
|
||||
INT16 GetAttachedArmourBonus( OBJECTTYPE * pObj )
|
||||
{
|
||||
|
||||
@@ -300,7 +300,11 @@ INT16 GetMagSizeBonus( OBJECTTYPE * pObj, UINT8 subObject = 0 );
|
||||
|
||||
// HEADROCK HAM 4: This function now calculates and returns the weapon's recoil as X/Y offsets.
|
||||
void GetRecoil( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 *bRecoilX, INT8 *bRecoilY, UINT8 ubNumBullet );
|
||||
void GetBaseFlatRecoilModifier( OBJECTTYPE *pObj, INT8 *bRecoilModifierX, INT8 *bRecoilModifierY);
|
||||
void GetAttachmentFlatRecoilModifier( OBJECTTYPE *pObj, INT8 *bRecoilModifierX, INT8 *bRecoilModifierY);
|
||||
void GetFlatRecoilModifier( OBJECTTYPE *pObj, INT8 *bRecoilModifierX, INT8 *bRecoilModifierY );
|
||||
INT16 GetBasePercentRecoilModifier( OBJECTTYPE *pObj );
|
||||
INT16 GetAttachmentPercentRecoilModifier( OBJECTTYPE *pObj);
|
||||
INT16 GetPercentRecoilModifier( OBJECTTYPE *pObj );
|
||||
// HEADROCK HAM 4: This function returns whether the last bullet in a burst/autofire volley was a tracer.
|
||||
BOOLEAN WasPrevBulletATracer( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon );
|
||||
@@ -337,6 +341,14 @@ INT16 GetGrenadeLauncherStatus( OBJECTTYPE * pObj );
|
||||
BOOLEAN IsGrenadeLauncherAttached( OBJECTTYPE * pObj, UINT8 subObject = 0 );
|
||||
OBJECTTYPE* FindAttachment_GrenadeLauncher( OBJECTTYPE * pObj );
|
||||
UINT16 GetAttachedGrenadeLauncher( OBJECTTYPE * pObj );
|
||||
|
||||
// JMich & Flugente: functions for underbarrel weapons
|
||||
INT16 GetUnderBarrelStatus( OBJECTTYPE * pObj );
|
||||
BOOLEAN IsUnderBarrelAttached( OBJECTTYPE * pObj, UINT8 subObject = 0 );
|
||||
OBJECTTYPE* FindAttachment_UnderBarrel( OBJECTTYPE * pObj );
|
||||
UINT16 GetAttachedUnderBarrel( OBJECTTYPE * pObj );
|
||||
OBJECTTYPE* GetUsedWeapon( OBJECTTYPE * pObj );
|
||||
|
||||
INT8 FindRocketLauncher( SOLDIERTYPE * pSoldier );
|
||||
INT8 FindRocketLauncherOrCannon( SOLDIERTYPE * pSoldier );
|
||||
INT8 FindNonSmokeLaunchable( SOLDIERTYPE * pSoldier, UINT16 usWeapon );
|
||||
|
||||
+36
-24
@@ -3988,12 +3988,15 @@ INT8 FireBullet( SOLDIERTYPE * pFirer, BULLET * pBullet, BOOLEAN fFake )
|
||||
}
|
||||
else
|
||||
{
|
||||
OBJECTTYPE* pObjAttHand = pFirer->GetUsedWeapon( &pFirer->inv[pFirer->ubAttackingHand] );
|
||||
UINT16 usItemUsed = pFirer->GetUsedWeaponNumber( &pFirer->inv[pFirer->ubAttackingHand] );
|
||||
|
||||
//afp-start //always a fast bullet
|
||||
if ( pBullet->usFlags & ( BULLET_FLAG_CREATURE_SPIT | BULLET_FLAG_KNIFE | BULLET_FLAG_MISSILE | BULLET_FLAG_SMALL_MISSILE | BULLET_FLAG_TANK_CANNON | BULLET_FLAG_FLAME /*| BULLET_FLAG_TRACER*/ ) )
|
||||
pBullet->usClockTicksPerUpdate = (Weapon[ pFirer->usAttackingWeapon ].ubBulletSpeed + GetBulletSpeedBonus(&pFirer->inv[pFirer->ubAttackingHand]) ) / 10;
|
||||
pBullet->usClockTicksPerUpdate = (Weapon[ usItemUsed ].ubBulletSpeed + GetBulletSpeedBonus( pObjAttHand ) ) / 10;
|
||||
else
|
||||
if (gGameSettings.fOptions[TOPTION_ALTERNATE_BULLET_GRAPHICS])
|
||||
pBullet->usClockTicksPerUpdate = (Weapon[ pFirer->usAttackingWeapon ].ubBulletSpeed + GetBulletSpeedBonus(&pFirer->inv[pFirer->ubAttackingHand]) ) / 10;
|
||||
pBullet->usClockTicksPerUpdate = (Weapon[ usItemUsed ].ubBulletSpeed + GetBulletSpeedBonus( pObjAttHand ) ) / 10;
|
||||
else
|
||||
pBullet->usClockTicksPerUpdate = 1;
|
||||
//afp-end
|
||||
@@ -4068,6 +4071,8 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
|
||||
UINT16 usBulletFlags = 0;
|
||||
int n=0;
|
||||
|
||||
OBJECTTYPE* pObjAttHand = pFirer->GetUsedWeapon( &(pFirer->inv[pFirer->ubAttackingHand]) );
|
||||
|
||||
//DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBulletGivenTarget"));
|
||||
|
||||
CalculateSoldierZPos( pFirer, FIRING_POS, &dStartZ );
|
||||
@@ -4132,11 +4137,11 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
|
||||
// HEADROCK HAM B2.5: Set tracer effect on/off for individual bullets in a Tracer Magazine, as part of the
|
||||
// New Tracer System.
|
||||
else if (gGameExternalOptions.ubRealisticTracers > 0 && gGameExternalOptions.ubNumBulletsPerTracer > 0 && (pFirer->bDoAutofire > 0 || pFirer->bDoBurst > 0)
|
||||
&& AmmoTypes[ pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType ].tracerEffect )
|
||||
&& AmmoTypes[ (*pObjAttHand)[0]->data.gun.ubGunAmmoType ].tracerEffect )
|
||||
{
|
||||
UINT16 iBulletsLeft, iBulletsPerTracer;
|
||||
iBulletsPerTracer = gGameExternalOptions.ubNumBulletsPerTracer;
|
||||
iBulletsLeft = pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunShotsLeft + pFirer->bDoBurst;
|
||||
iBulletsLeft = (*pObjAttHand)[0]->data.gun.ubGunShotsLeft + pFirer->bDoBurst;
|
||||
|
||||
if ((((iBulletsLeft - (pFirer->bDoBurst - 1)) / iBulletsPerTracer) - ((iBulletsLeft - pFirer->bDoBurst) / iBulletsPerTracer)) == 1)
|
||||
{
|
||||
@@ -4147,7 +4152,7 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
|
||||
fTracer = FALSE;
|
||||
}
|
||||
}
|
||||
else if ( AmmoTypes[ pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType ].tracerEffect && (pFirer->bDoBurst || gGameSettings.fOptions[ TOPTION_TRACERS_FOR_SINGLE_FIRE ]) )
|
||||
else if ( AmmoTypes[ (*pObjAttHand)[0]->data.gun.ubGunAmmoType ].tracerEffect && (pFirer->bDoBurst || gGameSettings.fOptions[ TOPTION_TRACERS_FOR_SINGLE_FIRE ]) )
|
||||
{
|
||||
//usBulletFlags |= BULLET_FLAG_TRACER;
|
||||
fTracer = TRUE;
|
||||
@@ -4156,9 +4161,9 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
|
||||
ubImpact =(UINT8) GetDamage(&pFirer->inv[pFirer->ubAttackingHand]);
|
||||
//zilpin: Begin new code block for spread patterns, number of projectiles, impact adjustment, etc.
|
||||
{
|
||||
ObjectData *weapon = &(pFirer->inv[pFirer->ubAttackingHand][0]->data);
|
||||
ObjectData *weapon = &((*pObjAttHand)[0]->data);
|
||||
ubShots = AmmoTypes[ weapon->gun.ubGunAmmoType].numberOfBullets;
|
||||
ubSpreadIndex = GetSpreadPattern( &pFirer->inv[pFirer->ubAttackingHand] );
|
||||
ubSpreadIndex = GetSpreadPattern( pObjAttHand );
|
||||
if( ubShots>1 && !fFake )
|
||||
{
|
||||
fBuckshot = true;
|
||||
@@ -4407,7 +4412,7 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
|
||||
|
||||
if ( pBullet->usFlags & BULLET_FLAG_KNIFE )
|
||||
{
|
||||
pBullet->ubItemStatus = pFirer->inv[pFirer->ubAttackingHand][0]->data.objectStatus;
|
||||
pBullet->ubItemStatus = (*pObjAttHand)[0]->data.objectStatus;
|
||||
}
|
||||
|
||||
// apply increments for first move
|
||||
@@ -4435,7 +4440,7 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
|
||||
|
||||
pBullet->iImpact = ubImpact;
|
||||
|
||||
pBullet->iRange = GunRange( &(pFirer->inv[pFirer->ubAttackingHand]), pFirer ); // SANDRO - added argument
|
||||
pBullet->iRange = GunRange( pObjAttHand, pFirer ); // SANDRO - added argument
|
||||
pBullet->sTargetGridNo = ((INT32)dEndX) / CELL_X_SIZE + ((INT32)dEndY) / CELL_Y_SIZE * WORLD_COLS;
|
||||
|
||||
pBullet->bStartCubesAboveLevelZ = (INT8) CONVERT_HEIGHTUNITS_TO_INDEX( (INT32)dStartZ - CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ pFirer->sGridNo ].sHeight ) );
|
||||
@@ -4447,11 +4452,11 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
|
||||
// HEADROCK HAM BETA2.5: New method for signifying whether a bullet is a tracer or not, using an individual
|
||||
// bullet structure flag. Hehehehe, I think this is kind of reverting to old code, isn't it?
|
||||
if (gGameExternalOptions.ubRealisticTracers > 0 && gGameExternalOptions.ubNumBulletsPerTracer > 0 && (pFirer->bDoAutofire > 0 || pFirer->bDoBurst > 0)
|
||||
&& AmmoTypes[ pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType ].tracerEffect )
|
||||
&& AmmoTypes[ (*pObjAttHand)[0]->data.gun.ubGunAmmoType ].tracerEffect )
|
||||
{
|
||||
UINT16 iBulletsLeft, iBulletsPerTracer;
|
||||
iBulletsPerTracer = gGameExternalOptions.ubNumBulletsPerTracer;
|
||||
iBulletsLeft = pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunShotsLeft + pFirer->bDoBurst;
|
||||
iBulletsLeft = (*pObjAttHand)[0]->data.gun.ubGunShotsLeft + pFirer->bDoBurst;
|
||||
|
||||
// Is this specific bullet a tracer? - based on how many tracers there are per regular bullets in
|
||||
// a tracer magazine (INI-settable).
|
||||
@@ -4540,6 +4545,8 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
|
||||
UINT16 usBulletFlags = 0;
|
||||
int n=0;
|
||||
|
||||
OBJECTTYPE* pObjAttHand = pFirer->GetUsedWeapon( &(pFirer->inv[pFirer->ubAttackingHand]) );
|
||||
|
||||
//DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBulletGivenTarget"));
|
||||
|
||||
CalculateSoldierZPos( pFirer, FIRING_POS, &dStartZ );
|
||||
@@ -4574,7 +4581,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
|
||||
|
||||
ubShots = 1;
|
||||
fTracer = FALSE;
|
||||
|
||||
|
||||
// Check if we have spit as a weapon!
|
||||
if ( Weapon[ usHandItem ].ubWeaponClass == MONSTERCLASS )
|
||||
{
|
||||
@@ -4604,11 +4611,11 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
|
||||
// HEADROCK HAM B2.5: Set tracer effect on/off for individual bullets in a Tracer Magazine, as part of the
|
||||
// New Tracer System.
|
||||
else if (gGameExternalOptions.ubRealisticTracers > 0 && gGameExternalOptions.ubNumBulletsPerTracer > 0 && (pFirer->bDoAutofire > 0 || pFirer->bDoBurst > 0)
|
||||
&& AmmoTypes[ pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType ].tracerEffect )
|
||||
&& AmmoTypes[ (*pObjAttHand)[0]->data.gun.ubGunAmmoType ].tracerEffect )
|
||||
{
|
||||
UINT16 iBulletsLeft, iBulletsPerTracer;
|
||||
iBulletsPerTracer = gGameExternalOptions.ubNumBulletsPerTracer;
|
||||
iBulletsLeft = pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunShotsLeft + pFirer->bDoBurst;
|
||||
iBulletsLeft = (*pObjAttHand)[0]->data.gun.ubGunShotsLeft + pFirer->bDoBurst;
|
||||
|
||||
if ((((iBulletsLeft - (pFirer->bDoBurst - 1)) / iBulletsPerTracer) - ((iBulletsLeft - pFirer->bDoBurst) / iBulletsPerTracer)) == 1)
|
||||
{
|
||||
@@ -4625,7 +4632,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
|
||||
fTracer = TRUE;
|
||||
}
|
||||
|
||||
ubImpact =(UINT8) GetDamage(&pFirer->inv[pFirer->ubAttackingHand]);
|
||||
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.
|
||||
Left in comments for reference, but the new handling is after it.
|
||||
@@ -4661,9 +4668,9 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
|
||||
*/
|
||||
//zilpin: Begin new code block for spread patterns, number of projectiles, impact adjustment, etc.
|
||||
{
|
||||
ObjectData *weapon = &(pFirer->inv[pFirer->ubAttackingHand][0]->data);
|
||||
ObjectData *weapon = &((*pObjAttHand)[0]->data);
|
||||
ubShots = AmmoTypes[ weapon->gun.ubGunAmmoType].numberOfBullets;
|
||||
ubSpreadIndex = GetSpreadPattern( &pFirer->inv[pFirer->ubAttackingHand] );
|
||||
ubSpreadIndex = GetSpreadPattern( pObjAttHand );
|
||||
if( ubShots>1 && !fFake )
|
||||
{
|
||||
fBuckshot = true;
|
||||
@@ -4905,7 +4912,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
|
||||
|
||||
if ( pBullet->usFlags & BULLET_FLAG_KNIFE )
|
||||
{
|
||||
pBullet->ubItemStatus = pFirer->inv[pFirer->ubAttackingHand][0]->data.objectStatus;
|
||||
pBullet->ubItemStatus = (*pObjAttHand)[0]->data.objectStatus;
|
||||
}
|
||||
|
||||
// apply increments for first move
|
||||
@@ -4933,7 +4940,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
|
||||
|
||||
pBullet->iImpact = ubImpact;
|
||||
|
||||
pBullet->iRange = GunRange( &(pFirer->inv[pFirer->ubAttackingHand]), pFirer ); // SANDRO - added argument
|
||||
pBullet->iRange = GunRange( pObjAttHand, pFirer ); // SANDRO - added argument
|
||||
pBullet->sTargetGridNo = ((INT32)dEndX) / CELL_X_SIZE + ((INT32)dEndY) / CELL_Y_SIZE * WORLD_COLS;
|
||||
|
||||
pBullet->bStartCubesAboveLevelZ = (INT8) CONVERT_HEIGHTUNITS_TO_INDEX( (INT32)dStartZ - CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ pFirer->sGridNo ].sHeight ) );
|
||||
@@ -4945,11 +4952,11 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
|
||||
// HEADROCK HAM BETA2.5: New method for signifying whether a bullet is a tracer or not, using an individual
|
||||
// bullet structure flag. Hehehehe, I think this is kind of reverting to old code, isn't it?
|
||||
if (gGameExternalOptions.ubRealisticTracers > 0 && gGameExternalOptions.ubNumBulletsPerTracer > 0 && (pFirer->bDoAutofire > 0 || pFirer->bDoBurst > 0)
|
||||
&& AmmoTypes[ pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType ].tracerEffect )
|
||||
&& AmmoTypes[ (*pObjAttHand)[0]->data.gun.ubGunAmmoType ].tracerEffect )
|
||||
{
|
||||
UINT16 iBulletsLeft, iBulletsPerTracer;
|
||||
iBulletsPerTracer = gGameExternalOptions.ubNumBulletsPerTracer;
|
||||
iBulletsLeft = pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunShotsLeft + pFirer->bDoBurst;
|
||||
iBulletsLeft = (*pObjAttHand)[0]->data.gun.ubGunShotsLeft + pFirer->bDoBurst;
|
||||
|
||||
// Is this specific bullet a tracer? - based on how many tracers there are per regular bullets in
|
||||
// a tracer magazine (INI-settable).
|
||||
@@ -5008,10 +5015,12 @@ INT8 ChanceToGetThrough( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOAT d
|
||||
{
|
||||
BOOLEAN fBuckShot = FALSE;
|
||||
|
||||
OBJECTTYPE* pObjHand = pFirer->GetUsedWeapon( &pFirer->inv[HANDPOS] );
|
||||
|
||||
// if shotgun, shotgun would have to be in main hand
|
||||
if ( pFirer->inv[ HANDPOS ].usItem == pFirer->usAttackingWeapon )
|
||||
if ( pObjHand->usItem == pFirer->usAttackingWeapon )
|
||||
{
|
||||
if ( AmmoTypes[pFirer->inv[ HANDPOS ][0]->data.gun.ubGunAmmoType].numberOfBullets > 1 )
|
||||
if ( AmmoTypes[ (*pObjHand)[0]->data.gun.ubGunAmmoType].numberOfBullets > 1 )
|
||||
{
|
||||
fBuckShot = TRUE;
|
||||
}
|
||||
@@ -7332,8 +7341,11 @@ FLOAT CalcBulletDeviation( SOLDIERTYPE *pShooter, FLOAT *dShotOffsetX, FLOAT *dS
|
||||
|
||||
// We start by reading the gun's Accuracy value. We'll use that as the basis for everything else.
|
||||
|
||||
// Flugente: determine used gun
|
||||
OBJECTTYPE* pObjAttHand = pShooter->GetUsedWeapon( &pShooter->inv[ pShooter->ubAttackingHand ] );
|
||||
|
||||
INT16 sAccuracy = GetGunAccuracy( pWeapon );
|
||||
UINT16 sEffRange = Weapon[Item[pShooter->inv[pShooter->ubAttackingHand].usItem].ubClassIndex].usRange + GetRangeBonus(&(pShooter->inv[ pShooter->ubAttackingHand ]));
|
||||
UINT16 sEffRange = Weapon[Item[pObjAttHand->usItem].ubClassIndex].usRange + GetRangeBonus( pObjAttHand );
|
||||
|
||||
// WANNE: I got a CTD in a multiplayer test game, because sEffRange was 0 (division to zero).
|
||||
// I don't know why this happend?
|
||||
|
||||
+62
-52
@@ -1478,8 +1478,12 @@ INT16 CalcTotalAPsToAttack( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTur
|
||||
BOOLEAN fAddingRaiseGunCost = FALSE;
|
||||
|
||||
// LOOK IN BUDDY'S HAND TO DETERMINE WHAT TO DO HERE
|
||||
// Flugente: check for underbarrel weapons and use that object if necessary
|
||||
OBJECTTYPE* AttackingWeapon = pSoldier->GetUsedWeapon( &(pSoldier->inv[HANDPOS]) );
|
||||
UINT16 usUBItemNum = pSoldier->GetUsedWeaponNumber( &(pSoldier->inv[HANDPOS]) );
|
||||
|
||||
usItemNum = pSoldier->inv[HANDPOS].usItem;
|
||||
uiItemClass = Item[ usItemNum ].usItemClass;
|
||||
uiItemClass = Item[ usUBItemNum ].usItemClass;
|
||||
|
||||
if ( uiItemClass == IC_GUN || uiItemClass == IC_LAUNCHER || uiItemClass == IC_TENTACLES || uiItemClass == IC_THROWING_KNIFE )
|
||||
{
|
||||
@@ -1487,10 +1491,10 @@ INT16 CalcTotalAPsToAttack( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTur
|
||||
|
||||
if ( pSoldier->bDoBurst )
|
||||
{
|
||||
if(pSoldier->bDoAutofire && GetAutofireShotsPerFiveAPs(&pSoldier->inv[HANDPOS]) > 0 )
|
||||
sAPCost += CalcAPsToAutofire( pSoldier->CalcActionPoints( ), &(pSoldier->inv[HANDPOS]), pSoldier->bDoAutofire );
|
||||
if(pSoldier->bDoAutofire && GetAutofireShotsPerFiveAPs(AttackingWeapon) > 0 )
|
||||
sAPCost += CalcAPsToAutofire( pSoldier->CalcActionPoints( ), AttackingWeapon, pSoldier->bDoAutofire );
|
||||
else
|
||||
sAPCost += CalcAPsToBurst( pSoldier->CalcActionPoints( ), &(pSoldier->inv[HANDPOS]) );
|
||||
sAPCost += CalcAPsToBurst( pSoldier->CalcActionPoints( ), AttackingWeapon );
|
||||
}
|
||||
//else //ddd comment for aimed burst
|
||||
{
|
||||
@@ -1513,7 +1517,7 @@ INT16 CalcTotalAPsToAttack( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTur
|
||||
UINT16 usWeaponReadyTime;
|
||||
UINT8 ubReadyTimeDivisor;
|
||||
|
||||
usWeaponReadyTime = Weapon[ usItemNum ].ubReadyTime * (100 - GetPercentReadyTimeAPReduction(&pSoldier->inv[HANDPOS])) / 100;
|
||||
usWeaponReadyTime = Weapon[ pSoldier->inv[HANDPOS].usItem ].ubReadyTime * (100 - GetPercentReadyTimeAPReduction(&pSoldier->inv[HANDPOS])) / 100;
|
||||
ubReadyTimeDivisor = gGameExternalOptions.ubFirstAimReadyCostDivisor;
|
||||
sAPCost += usWeaponReadyTime / ubReadyTimeDivisor;
|
||||
}
|
||||
@@ -1696,8 +1700,10 @@ INT16 MinAPsToAttack(SOLDIERTYPE *pSoldier, INT32 sGridno, UINT8 ubAddTurningCos
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT16 undbarItem = pSoldier->GetUsedWeaponNumber( &(pSoldier->inv[ HANDPOS ]) );
|
||||
|
||||
// LOOK IN BUDDY'S HAND TO DETERMINE WHAT TO DO HERE
|
||||
uiItemClass = Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass;
|
||||
uiItemClass = Item[ undbarItem ].usItemClass;
|
||||
}
|
||||
|
||||
if ( uiItemClass == IC_BLADE || uiItemClass == IC_GUN || uiItemClass == IC_LAUNCHER || uiItemClass == IC_TENTACLES || uiItemClass == IC_THROWING_KNIFE )
|
||||
@@ -1936,16 +1942,21 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTurni
|
||||
UINT16 usRaiseGunCost = 0;
|
||||
UINT16 usTurningCost = 0;
|
||||
|
||||
|
||||
UINT16 usUBItem = 0;
|
||||
if ( pSoldier->bWeaponMode == WM_ATTACHED_GL || pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST || pSoldier->bWeaponMode == WM_ATTACHED_GL_AUTO )
|
||||
{
|
||||
usItem = GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS] );//UNDER_GLAUNCHER;
|
||||
usUBItem = usItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
usItem = pSoldier->inv[ HANDPOS ].usItem;
|
||||
|
||||
// Flugente: we need a secon temnr in case we are using an underbarrel weapon. Not all checks should apply for that one, as aiming is still done with the main weapon
|
||||
usUBItem = pSoldier->GetUsedWeaponNumber(&pSoldier->inv[HANDPOS]);
|
||||
}
|
||||
|
||||
OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon( &(pSoldier->inv[HANDPOS]) );
|
||||
|
||||
GetAPChargeForShootOrStabWRTGunRaises( pSoldier, sGridNo, ubAddTurningCost, &fAddingTurningCost, &fAddingRaiseGunCost );
|
||||
|
||||
@@ -2013,51 +2024,53 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTurni
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
//CHRISL: When prone and using a bipod, bipod should help compensate for recoil. To reflect this, our shot AP cost should be minimially reduced
|
||||
if(gGameExternalOptions.ubFlatAFTHBtoPrecentMultiplier > 0 && gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE && GetBipodBonus(&(pSoldier->inv[HANDPOS])) > 0){
|
||||
bAPCost += (BaseAPsToShootOrStab( bFullAPs, bAimSkill, &(pSoldier->inv[HANDPOS]) ) * (100 - GetBipodBonus(&(pSoldier->inv[HANDPOS]))) / 100);
|
||||
} else {
|
||||
bAPCost += BaseAPsToShootOrStab( bFullAPs, bAimSkill, &(pSoldier->inv[HANDPOS]) );
|
||||
if(gGameExternalOptions.ubFlatAFTHBtoPrecentMultiplier > 0 && gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE && GetBipodBonus(&(pSoldier->inv[HANDPOS])) > 0)
|
||||
{
|
||||
bAPCost += (BaseAPsToShootOrStab( bFullAPs, bAimSkill, pObjUsed ) * (100 - GetBipodBonus(&(pSoldier->inv[HANDPOS]))) / 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
bAPCost += BaseAPsToShootOrStab( bFullAPs, bAimSkill, pObjUsed );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// SANDRO - STOMP traits
|
||||
////////////////////////////////////////////////////
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
// Decreased APs needed for LMG - Auto Weapons
|
||||
if (Weapon[usItem].ubWeaponType == GUN_LMG && (pSoldier->bDoBurst || pSoldier->bDoAutofire) && ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) ) )
|
||||
if (Weapon[usUBItem].ubWeaponType == GUN_LMG && (pSoldier->bDoBurst || pSoldier->bDoAutofire) && ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) ) )
|
||||
{
|
||||
bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubAWFiringSpeedBonusLMGs ) / 100)+ 0.5);
|
||||
}
|
||||
// Decreased APs needed for melee attacks - Melee
|
||||
if ( Item[ usItem ].usItemClass == IC_BLADE && ( HAS_SKILL_TRAIT( pSoldier, MELEE_NT ) ) )
|
||||
if ( Item[ usUBItem ].usItemClass == IC_BLADE && ( HAS_SKILL_TRAIT( pSoldier, MELEE_NT ) ) )
|
||||
{
|
||||
bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubMEBladesAPsReduction ) / 100)+ 0.5);
|
||||
}
|
||||
// Decreased APs needed for throwing knives - Throwing
|
||||
else if ( Item[ usItem ].usItemClass == IC_THROWING_KNIFE && ( HAS_SKILL_TRAIT( pSoldier, THROWING_NT ) ) )
|
||||
else if ( Item[ usUBItem ].usItemClass == IC_THROWING_KNIFE && ( HAS_SKILL_TRAIT( pSoldier, THROWING_NT ) ) )
|
||||
{
|
||||
bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubTHBladesAPsReduction ) / 100)+ 0.5);
|
||||
}
|
||||
// Decreased APs needed for launchers - Heavy Eeapons
|
||||
else if ( (Item[ usItem ].usItemClass == IC_LAUNCHER || Item[usItem].grenadelauncher ) && !(Item[usItem].rocketlauncher) && !(Item[usItem].mortar) && ( HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ) ))
|
||||
else if ( (Item[ usUBItem ].usItemClass == IC_LAUNCHER || Item[usUBItem].grenadelauncher ) && !(Item[usUBItem].rocketlauncher) && !(Item[usUBItem].mortar) && ( HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ) ))
|
||||
{
|
||||
bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubHWGrenadeLaunchersAPsReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ) ) / 100)+ 0.5);
|
||||
}
|
||||
// Decreased APs needed for launchers - Heavy Eeapons
|
||||
else if (( Item[usItem].rocketlauncher || Item[usItem].singleshotrocketlauncher ) && !(Item[usItem].mortar) && ( HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ) ))
|
||||
else if (( Item[usUBItem].rocketlauncher || Item[usUBItem].singleshotrocketlauncher ) && !(Item[usUBItem].mortar) && ( HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ) ))
|
||||
{
|
||||
bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubHWRocketLaunchersAPsReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ) ) / 100)+ 0.5);
|
||||
}
|
||||
// Decreased APs needed for mortar - Heavy Eeapons
|
||||
else if ( Item[usItem].mortar && HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ) )
|
||||
else if ( Item[usUBItem].mortar && HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ) )
|
||||
{
|
||||
bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubHWMortarAPsReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ) ) / 100)+ 0.5);
|
||||
}
|
||||
// Decreased APs needed for pistols and machine pistols - Gunslinger
|
||||
else if (Weapon[ usItem ].ubWeaponType == GUN_PISTOL && HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) )
|
||||
else if (Weapon[ usUBItem ].ubWeaponType == GUN_PISTOL && HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) )
|
||||
{
|
||||
bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubGSFiringSpeedBonusPistols * NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT ) ) / 100)+ 0.5);
|
||||
}
|
||||
@@ -2073,7 +2086,7 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTurni
|
||||
fAddingRaiseGunCost = TRUE;
|
||||
}
|
||||
|
||||
if ( Item[ usItem ].usItemClass == IC_THROWING_KNIFE )
|
||||
if ( Item[ usUBItem ].usItemClass == IC_THROWING_KNIFE )
|
||||
{
|
||||
// Do we need to stand up?
|
||||
bAPCost += GetAPsToChangeStance( pSoldier, ANIM_STAND );
|
||||
@@ -2120,7 +2133,7 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTurni
|
||||
|
||||
// if attacking a new target (or if the specific target is uncertain)
|
||||
// Added check if the weapon is a throwing knife - otherwise it would add APs for change taregt on cursor but not actually deduct them afterwards - SANDRO
|
||||
if (ubForceRaiseGunCost || (( sGridNo != pSoldier->sLastTarget ) && !Item[usItem].rocketlauncher && (Item[ usItem ].usItemClass != IC_THROWING_KNIFE) ))
|
||||
if (ubForceRaiseGunCost || (( sGridNo != pSoldier->sLastTarget ) && !Item[usUBItem].rocketlauncher && (Item[ usUBItem ].usItemClass != IC_THROWING_KNIFE) ))
|
||||
{
|
||||
bAPCost += APBPConstants[AP_CHANGE_TARGET];
|
||||
}
|
||||
@@ -2134,7 +2147,7 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTurni
|
||||
if ( bAPCost < 1 )
|
||||
bAPCost = 1;
|
||||
|
||||
if ( Item[pSoldier->inv[HANDPOS].usItem].rocketlauncher )
|
||||
if ( Item[(*pObjUsed).usItem].rocketlauncher )
|
||||
{
|
||||
bAPCost += GetAPsToChangeStance( pSoldier, ANIM_STAND );
|
||||
}
|
||||
@@ -2347,33 +2360,36 @@ BOOLEAN EnoughAmmo( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay, INT8 bInvPos )
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Item[pSoldier->inv[ bInvPos ].usItem].singleshotrocketlauncher )
|
||||
OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon( &(pSoldier->inv[bInvPos]) );
|
||||
UINT16 usItemUsed = pSoldier->GetUsedWeaponNumber( &(pSoldier->inv[bInvPos]) );
|
||||
|
||||
if ( Item[usItemUsed].singleshotrocketlauncher )
|
||||
{
|
||||
// hack... they turn empty afterwards anyways
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
if (Item[ pSoldier->inv[ bInvPos ].usItem ].usItemClass == IC_LAUNCHER || Item[pSoldier->inv[ bInvPos ].usItem].cannon )
|
||||
if (Item[ usItemUsed ].usItemClass == IC_LAUNCHER || Item[usItemUsed].cannon )
|
||||
{
|
||||
if ( FindAttachmentByClass( &(pSoldier->inv[ bInvPos ]), IC_GRENADE ) != 0 )
|
||||
if ( FindAttachmentByClass( pObjUsed, IC_GRENADE ) != 0 )
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
|
||||
if (Item[pSoldier->inv[bInvPos].usItem].usItemClass == IC_BOMB)
|
||||
if (Item[usItemUsed].usItemClass == IC_BOMB)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
// ATE: Did an else if here...
|
||||
if ( FindAttachmentByClass( &(pSoldier->inv[ bInvPos ]), IC_BOMB ) != 0 )
|
||||
if ( FindAttachmentByClass( pObjUsed, IC_BOMB ) != 0 )
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
// WANNE: If there is a tank, it always have ammo to shoot, no check!
|
||||
if (Item[pSoldier->inv[bInvPos].usItem].cannon)
|
||||
if (Item[usItemUsed].cannon)
|
||||
{
|
||||
return ( TRUE );
|
||||
}
|
||||
@@ -2385,9 +2401,9 @@ BOOLEAN EnoughAmmo( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay, INT8 bInvPos )
|
||||
|
||||
return( FALSE );
|
||||
}
|
||||
else if (Item[ pSoldier->inv[ bInvPos ].usItem ].usItemClass == IC_GUN)
|
||||
else if (Item[ usItemUsed ].usItemClass == IC_GUN)
|
||||
{
|
||||
if ( pSoldier->inv[ bInvPos ][0]->data.gun.ubGunShotsLeft == 0 )
|
||||
if ( (*pObjUsed)[0]->data.gun.ubGunShotsLeft == 0 )
|
||||
{
|
||||
if ( fDisplay )
|
||||
{
|
||||
@@ -2399,7 +2415,7 @@ BOOLEAN EnoughAmmo( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay, INT8 bInvPos )
|
||||
//<SB> manual recharge
|
||||
if( pSoldier->bTeam == OUR_TEAM )
|
||||
{
|
||||
if ( !( pSoldier->inv[ bInvPos ][0]->data.gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER ) )
|
||||
if ( !( (*pObjUsed)[0]->data.gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER ) )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
@@ -2435,24 +2451,14 @@ void DeductAmmo( SOLDIERTYPE *pSoldier, INT8 bInvPos )
|
||||
}
|
||||
else if ( Item[ pObj->usItem ].usItemClass == IC_GUN && !Item[pObj->usItem].cannon && pSoldier->bWeaponMode != WM_ATTACHED_GL && pSoldier->bWeaponMode != WM_ATTACHED_GL_BURST && pSoldier->bWeaponMode != WM_ATTACHED_GL_AUTO )
|
||||
{
|
||||
if ( pSoldier->usAttackingWeapon == pObj->usItem)
|
||||
// Flugente: check for underbarrel weapons and use that object if necessary
|
||||
OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon( &(pSoldier->inv[bInvPos]) );
|
||||
|
||||
// OK, let's see, don't overrun...
|
||||
if ( (*pObjUsed)[0]->data.gun.ubGunShotsLeft != 0 )
|
||||
{
|
||||
// OK, let's see, don't overrun...
|
||||
if ( (*pObj)[0]->data.gun.ubGunShotsLeft != 0 )
|
||||
{
|
||||
(*pObj)[0]->data.gun.ubGunShotsLeft--;
|
||||
//Pulmu: Update weight after firing gun to account for bullets fired
|
||||
if( gGameExternalOptions.fAmmoDynamicWeight == TRUE)
|
||||
{
|
||||
//ADB ubWeight has been removed, see comments in OBJECTTYPE
|
||||
//pSoldier->inv[HANDPOS].ubWeight = CalculateObjectWeight( &(pSoldier->inv[HANDPOS]));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// firing an attachment?
|
||||
}
|
||||
(*pObjUsed)[0]->data.gun.ubGunShotsLeft--;
|
||||
}
|
||||
}
|
||||
else if ( Item[ pObj->usItem ].usItemClass == IC_LAUNCHER || Item[pObj->usItem].cannon || pSoldier->bWeaponMode == WM_ATTACHED_GL || pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST || pSoldier->bWeaponMode == WM_ATTACHED_GL_AUTO )
|
||||
{
|
||||
@@ -2645,7 +2651,9 @@ INT16 GetAPsToAutoReload( SOLDIERTYPE * pSoldier )
|
||||
INT16 bAPCost = 0, bAPCost2 = 0;;
|
||||
|
||||
CHECKF( pSoldier );
|
||||
pObj = &(pSoldier->inv[HANDPOS]);
|
||||
|
||||
// Flugente: check for underbarrel weapons and use that object if necessary
|
||||
pObj = pSoldier->GetUsedWeapon( &(pSoldier->inv[HANDPOS]) );
|
||||
|
||||
//<SB> manual recharge
|
||||
if ((*pObj)[0]->data.gun.ubGunShotsLeft && !((*pObj)[0]->data.gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER) )
|
||||
@@ -2682,7 +2690,9 @@ INT16 GetAPsToAutoReload( SOLDIERTYPE * pSoldier )
|
||||
|
||||
if ( pSoldier->IsValidSecondHandShotForReloadingPurposes( ) )
|
||||
{
|
||||
pObj = &(pSoldier->inv[SECONDHANDPOS]);
|
||||
// Flugente: check for underbarrel weapons and use that object if necessary
|
||||
pObj = pSoldier->GetUsedWeapon( &(pSoldier->inv[SECONDHANDPOS]) );
|
||||
|
||||
bExcludeSlot = NO_SLOT;
|
||||
bSlot2 = NO_SLOT;
|
||||
|
||||
|
||||
+180
-161
@@ -358,67 +358,77 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
|
||||
break;
|
||||
|
||||
case 430:
|
||||
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: case 430");
|
||||
// SHOOT GUN
|
||||
// MAKE AN EVENT, BUT ONLY DO STUFF IF WE OWN THE GUY!
|
||||
SFireWeapon.usSoldierID = pSoldier->ubID;
|
||||
SFireWeapon.uiUniqueId = pSoldier->uiUniqueSoldierIdValue;
|
||||
SFireWeapon.sTargetGridNo = pSoldier->sTargetGridNo;
|
||||
SFireWeapon.bTargetLevel = pSoldier->bTargetLevel;
|
||||
SFireWeapon.bTargetCubeLevel= pSoldier->bTargetCubeLevel;
|
||||
if((is_server && pSoldier->ubID<120) || (!is_server && is_client && pSoldier->ubID<20) || (!is_server && !is_client) )
|
||||
{
|
||||
//only carry on if own werc
|
||||
AddGameEvent( S_FIREWEAPON, 0, &SFireWeapon );
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: case 430");
|
||||
// SHOOT GUN
|
||||
// MAKE AN EVENT, BUT ONLY DO STUFF IF WE OWN THE GUY!
|
||||
SFireWeapon.usSoldierID = pSoldier->ubID;
|
||||
SFireWeapon.uiUniqueId = pSoldier->uiUniqueSoldierIdValue;
|
||||
SFireWeapon.sTargetGridNo = pSoldier->sTargetGridNo;
|
||||
SFireWeapon.bTargetLevel = pSoldier->bTargetLevel;
|
||||
SFireWeapon.bTargetCubeLevel= pSoldier->bTargetCubeLevel;
|
||||
if((is_server && pSoldier->ubID<120) || (!is_server && is_client && pSoldier->ubID<20) || (!is_server && !is_client) )
|
||||
{
|
||||
//only carry on if own werc
|
||||
AddGameEvent( S_FIREWEAPON, 0, &SFireWeapon );
|
||||
|
||||
//hayden
|
||||
if(is_server || (is_client && pSoldier->ubID <20) )
|
||||
send_fireweapon( &SFireWeapon );
|
||||
}
|
||||
//DIGICRAB: Burst UnCap
|
||||
//Loop around in the animation if we still have burst rounds to fire
|
||||
if (pSoldier->bDoBurst && (pSoldier->bDoBurst <= ((pSoldier->bDoAutofire)?(pSoldier->bDoAutofire):(GetShotsPerBurst(&pSoldier->inv[HANDPOS]))) || (( pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST && pSoldier->bDoBurst <= Weapon[GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS])].ubShotsPerBurst)) ))
|
||||
{
|
||||
if(pSoldier->usAnimState == 44 || pSoldier->usAnimState == 109 || pSoldier->usAnimState == 108 && pSoldier->usAniCode == 33) //we are standing, crounching or prone, firing the fast shot
|
||||
pSoldier->usAniCode = 3;
|
||||
else if(pSoldier->usAnimState == 175 && pSoldier->usAniCode == 37) //we are firing down to something very close, last shot
|
||||
pSoldier->usAniCode = 14;
|
||||
}
|
||||
|
||||
//DIGICRAB: Burst Sound
|
||||
//This code is stolen from Tactical\Weapons.c - UseGun(...)
|
||||
if (pSoldier->bDoBurst && pSoldier->iBurstSoundID == NO_SAMPLE && Weapon[ pSoldier->usAttackingWeapon ].sSound != 0 && Item[ pSoldier->usAttackingWeapon ].usItemClass != IC_THROWING_KNIFE )
|
||||
{
|
||||
// Switch on silencer...
|
||||
INT16 noisefactor = GetPercentNoiseVolume( &pSoldier->inv[ pSoldier->ubAttackingHand ] );
|
||||
if( noisefactor < MAX_PERCENT_NOISE_VOLUME_FOR_SILENCED_SOUND || Weapon[ pSoldier->usAttackingWeapon ].ubAttackVolume <= 10 )
|
||||
{
|
||||
INT32 uiSound;
|
||||
|
||||
uiSound = Weapon [ pSoldier->usAttackingWeapon ].silencedSound;
|
||||
//if ( Weapon[ pSoldier->usAttackingWeapon ].ubCalibre == AMMO9 || Weapon[ pSoldier->usAttackingWeapon ].ubCalibre == AMMO38 || Weapon[ pSoldier->usAttackingWeapon ].ubCalibre == AMMO57 )
|
||||
//{
|
||||
// uiSound = S_SILENCER_1;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// uiSound = S_SILENCER_2;
|
||||
//}
|
||||
|
||||
//randomize the rate a bit so that the sound is more believable
|
||||
PlayJA2Sample( uiSound, 44100-Random(5000)-Random(5000)-Random(5000), SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
|
||||
|
||||
//hayden
|
||||
if(is_server || (is_client && pSoldier->ubID <20) )
|
||||
send_fireweapon( &SFireWeapon );
|
||||
}
|
||||
else
|
||||
|
||||
OBJECTTYPE* pObjHand = pSoldier->GetUsedWeapon( &pSoldier->inv[HANDPOS] );
|
||||
|
||||
//DIGICRAB: Burst UnCap
|
||||
//Loop around in the animation if we still have burst rounds to fire
|
||||
if (pSoldier->bDoBurst
|
||||
&& (
|
||||
pSoldier->bDoBurst <= ( (pSoldier->bDoAutofire)?(pSoldier->bDoAutofire):(GetShotsPerBurst( pObjHand )) )
|
||||
|| (( pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST && pSoldier->bDoBurst <= Weapon[GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS])].ubShotsPerBurst))
|
||||
)
|
||||
)
|
||||
{
|
||||
INT8 volume = HIGHVOLUME;
|
||||
if ( noisefactor < 100 ) volume = (volume * noisefactor) / 100;
|
||||
//randomize the rate a bit so that the sound is more believable
|
||||
PlayJA2Sample( Weapon[ pSoldier->usAttackingWeapon ].sSound, 44100-Random(5000)-Random(5000)-Random(5000), SoundVolume( volume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
|
||||
if(pSoldier->usAnimState == 44 || pSoldier->usAnimState == 109 || pSoldier->usAnimState == 108 && pSoldier->usAniCode == 33) //we are standing, crounching or prone, firing the fast shot
|
||||
pSoldier->usAniCode = 3;
|
||||
else if(pSoldier->usAnimState == 175 && pSoldier->usAniCode == 37) //we are firing down to something very close, last shot
|
||||
pSoldier->usAniCode = 14;
|
||||
}
|
||||
|
||||
OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon( &pSoldier->inv[ pSoldier->ubAttackingHand ] );
|
||||
UINT16 usedGun = pSoldier->GetUsedWeaponNumber( &pSoldier->inv[ pSoldier->ubAttackingHand ] );
|
||||
//DIGICRAB: Burst Sound
|
||||
//This code is stolen from Tactical\Weapons.c - UseGun(...)
|
||||
if (pSoldier->bDoBurst && pSoldier->iBurstSoundID == NO_SAMPLE && Weapon[ usedGun ].sSound != 0 && Item[ usedGun ].usItemClass != IC_THROWING_KNIFE )
|
||||
{
|
||||
// Switch on silencer...
|
||||
INT16 noisefactor = GetPercentNoiseVolume( pObjUsed );
|
||||
if( noisefactor < MAX_PERCENT_NOISE_VOLUME_FOR_SILENCED_SOUND || Weapon[ usedGun ].ubAttackVolume <= 10 )
|
||||
{
|
||||
INT32 uiSound;
|
||||
|
||||
uiSound = Weapon [ usedGun ].silencedSound;
|
||||
//if ( Weapon[ pSoldier->usAttackingWeapon ].ubCalibre == AMMO9 || Weapon[ pSoldier->usAttackingWeapon ].ubCalibre == AMMO38 || Weapon[ pSoldier->usAttackingWeapon ].ubCalibre == AMMO57 )
|
||||
//{
|
||||
// uiSound = S_SILENCER_1;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// uiSound = S_SILENCER_2;
|
||||
//}
|
||||
|
||||
//randomize the rate a bit so that the sound is more believable
|
||||
PlayJA2Sample( uiSound, 44100-Random(5000)-Random(5000)-Random(5000), SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
INT8 volume = HIGHVOLUME;
|
||||
if ( noisefactor < 100 ) volume = (volume * noisefactor) / 100;
|
||||
//randomize the rate a bit so that the sound is more believable
|
||||
PlayJA2Sample( Weapon[ usedGun ].sSound, 44100-Random(5000)-Random(5000)-Random(5000), SoundVolume( volume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 431:
|
||||
@@ -764,133 +774,137 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
|
||||
|
||||
|
||||
case 448:
|
||||
|
||||
// CODE: HANDLE BURST
|
||||
// FIRST CHECK IF WE'VE REACHED MAX FOR GUN
|
||||
fStop = FALSE;
|
||||
|
||||
if ( ( pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST && pSoldier->bDoBurst > Weapon[GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS])].ubShotsPerBurst) || (pSoldier->bWeaponMode != WM_ATTACHED_GL_BURST && pSoldier->bDoBurst > ((pSoldier->bDoAutofire)?(pSoldier->bDoAutofire):(GetShotsPerBurst(&pSoldier->inv[HANDPOS])))) )
|
||||
{
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because burst size too large");
|
||||
fStop = TRUE;
|
||||
fFreeUpAttacker = TRUE;
|
||||
}
|
||||
// CODE: HANDLE BURST
|
||||
// FIRST CHECK IF WE'VE REACHED MAX FOR GUN
|
||||
fStop = FALSE;
|
||||
|
||||
// CHECK IF WE HAVE AMMO LEFT, IF NOT, END ANIMATION!
|
||||
if ( !EnoughAmmo( pSoldier, FALSE, pSoldier->ubAttackingHand ) )
|
||||
{
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because not enough ammo");
|
||||
fStop = TRUE;
|
||||
fFreeUpAttacker = TRUE;
|
||||
if ( pSoldier->bTeam == gbPlayerNum )
|
||||
OBJECTTYPE* pObjHand = pSoldier->GetUsedWeapon( &pSoldier->inv[HANDPOS] );
|
||||
|
||||
if ( ( pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST && pSoldier->bDoBurst > Weapon[GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS])].ubShotsPerBurst)
|
||||
|| (pSoldier->bWeaponMode != WM_ATTACHED_GL_BURST && pSoldier->bDoBurst > ((pSoldier->bDoAutofire)?(pSoldier->bDoAutofire):(GetShotsPerBurst( pObjHand )))) )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ BURST_FIRE_DEPLETED_CLIP_STR ] );
|
||||
}
|
||||
}
|
||||
// Why only check for a jam on the first bullet?
|
||||
else if (pSoldier->bDoBurst == 1)
|
||||
{
|
||||
// CHECK FOR GUN JAM
|
||||
bWeaponJammed = CheckForGunJam( pSoldier );
|
||||
if ( bWeaponJammed == TRUE )
|
||||
{
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because weapon jammed");
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because burst size too large");
|
||||
fStop = TRUE;
|
||||
fFreeUpAttacker = TRUE;
|
||||
// stop shooting!
|
||||
// Yeah, but what does this have to do with that?
|
||||
// pSoldier->bBulletsLeft = 0;
|
||||
|
||||
// OK, Stop burst sound...
|
||||
if ( pSoldier->iBurstSoundID != NO_SAMPLE )
|
||||
{
|
||||
SoundStop( pSoldier->iBurstSoundID );
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK IF WE HAVE AMMO LEFT, IF NOT, END ANIMATION!
|
||||
if ( !EnoughAmmo( pSoldier, FALSE, pSoldier->ubAttackingHand ) )
|
||||
{
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because not enough ammo");
|
||||
fStop = TRUE;
|
||||
fFreeUpAttacker = TRUE;
|
||||
if ( pSoldier->bTeam == gbPlayerNum )
|
||||
{
|
||||
PlayJA2Sample( S_DRYFIRE1, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
|
||||
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Gun jammed!" );
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ BURST_FIRE_DEPLETED_CLIP_STR ] );
|
||||
}
|
||||
}
|
||||
// Why only check for a jam on the first bullet?
|
||||
else if (pSoldier->bDoBurst == 1)
|
||||
{
|
||||
// CHECK FOR GUN JAM
|
||||
bWeaponJammed = CheckForGunJam( pSoldier );
|
||||
if ( bWeaponJammed == TRUE )
|
||||
{
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because weapon jammed");
|
||||
fStop = TRUE;
|
||||
fFreeUpAttacker = TRUE;
|
||||
// stop shooting!
|
||||
// Yeah, but what does this have to do with that?
|
||||
// pSoldier->bBulletsLeft = 0;
|
||||
|
||||
// OK, Stop burst sound...
|
||||
if ( pSoldier->iBurstSoundID != NO_SAMPLE )
|
||||
{
|
||||
SoundStop( pSoldier->iBurstSoundID );
|
||||
}
|
||||
|
||||
if ( pSoldier->bTeam == gbPlayerNum )
|
||||
{
|
||||
PlayJA2Sample( S_DRYFIRE1, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
|
||||
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Gun jammed!" );
|
||||
}
|
||||
|
||||
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - aborting start of attack due to burst gun jam") );
|
||||
FreeUpAttacker( );
|
||||
}
|
||||
else if ( bWeaponJammed == 255 )
|
||||
{
|
||||
// Play intermediate animation...
|
||||
if ( HandleUnjamAnimation( pSoldier ) )
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( fStop )
|
||||
{
|
||||
if(pSoldier->bDoAutofire) //reset the autofire cursor after firing
|
||||
{
|
||||
pSoldier->flags.autofireLastStep = FALSE;
|
||||
pSoldier->bDoAutofire = 1;
|
||||
}
|
||||
|
||||
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - aborting start of attack due to burst gun jam") );
|
||||
FreeUpAttacker( );
|
||||
}
|
||||
else if ( bWeaponJammed == 255 )
|
||||
{
|
||||
// Play intermediate animation...
|
||||
if ( HandleUnjamAnimation( pSoldier ) )
|
||||
pSoldier->flags.fDoSpread = FALSE;
|
||||
pSoldier->bDoBurst = 1;
|
||||
// pSoldier->flags.fBurstCompleted = TRUE;
|
||||
if ( fFreeUpAttacker )
|
||||
{
|
||||
// DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - aborting start of attack") );
|
||||
// FreeUpAttacker( pSoldier->ubID );
|
||||
}
|
||||
|
||||
// ATE; Reduce it due to animation being stopped...
|
||||
// 0verhaul: No longer necessary or desired
|
||||
// DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - Burst animation ended") );
|
||||
// ReduceAttackBusyCount( pSoldier->ubID, FALSE );
|
||||
|
||||
|
||||
if ( CheckForImproperFireGunEnd( pSoldier ) )
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( fStop )
|
||||
{
|
||||
if(pSoldier->bDoAutofire) //reset the autofire cursor after firing
|
||||
{
|
||||
pSoldier->flags.autofireLastStep = FALSE;
|
||||
pSoldier->bDoAutofire = 1;
|
||||
}
|
||||
// END: GOTO AIM STANCE BASED ON HEIGHT
|
||||
// If we are a robot - we need to do stuff different here
|
||||
// 0verhaul: Ya know, if the robot simply used the same animation for standing and rifle standing,
|
||||
// we probably wouldn't need this special case code.
|
||||
if ( AM_A_ROBOT( pSoldier ) )
|
||||
{
|
||||
pSoldier->ChangeSoldierState( STANDING, 0 , FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight )
|
||||
{
|
||||
case ANIM_STAND:
|
||||
pSoldier->ChangeSoldierState( AIM_RIFLE_STAND, 0 , FALSE );
|
||||
break;
|
||||
|
||||
pSoldier->flags.fDoSpread = FALSE;
|
||||
pSoldier->bDoBurst = 1;
|
||||
// pSoldier->flags.fBurstCompleted = TRUE;
|
||||
if ( fFreeUpAttacker )
|
||||
{
|
||||
// DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - aborting start of attack") );
|
||||
// FreeUpAttacker( pSoldier->ubID );
|
||||
}
|
||||
case ANIM_PRONE:
|
||||
pSoldier->ChangeSoldierState( AIM_RIFLE_PRONE, 0 , FALSE );
|
||||
break;
|
||||
|
||||
// ATE; Reduce it due to animation being stopped...
|
||||
// 0verhaul: No longer necessary or desired
|
||||
// DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - Burst animation ended") );
|
||||
// ReduceAttackBusyCount( pSoldier->ubID, FALSE );
|
||||
case ANIM_CROUCH:
|
||||
pSoldier->ChangeSoldierState( AIM_RIFLE_CROUCH, 0 , FALSE );
|
||||
break;
|
||||
|
||||
|
||||
if ( CheckForImproperFireGunEnd( pSoldier ) )
|
||||
{
|
||||
}
|
||||
}
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
// END: GOTO AIM STANCE BASED ON HEIGHT
|
||||
// If we are a robot - we need to do stuff different here
|
||||
// 0verhaul: Ya know, if the robot simply used the same animation for standing and rifle standing,
|
||||
// we probably wouldn't need this special case code.
|
||||
if ( AM_A_ROBOT( pSoldier ) )
|
||||
// MOVETO CURRENT SPREAD LOCATION
|
||||
if ( pSoldier->flags.fDoSpread )
|
||||
{
|
||||
pSoldier->ChangeSoldierState( STANDING, 0 , FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight )
|
||||
if ( pSoldier->sSpreadLocations[ pSoldier->flags.fDoSpread - 1 ] != 0 )
|
||||
{
|
||||
case ANIM_STAND:
|
||||
pSoldier->ChangeSoldierState( AIM_RIFLE_STAND, 0 , FALSE );
|
||||
break;
|
||||
|
||||
case ANIM_PRONE:
|
||||
pSoldier->ChangeSoldierState( AIM_RIFLE_PRONE, 0 , FALSE );
|
||||
break;
|
||||
|
||||
case ANIM_CROUCH:
|
||||
pSoldier->ChangeSoldierState( AIM_RIFLE_CROUCH, 0 , FALSE );
|
||||
break;
|
||||
|
||||
pSoldier->EVENT_SetSoldierDirection( (INT8)GetDirectionToGridNoFromGridNo( pSoldier->sGridNo, pSoldier->sSpreadLocations[ pSoldier->flags.fDoSpread - 1 ] ) );
|
||||
pSoldier->EVENT_SetSoldierDesiredDirection( pSoldier->ubDirection );
|
||||
}
|
||||
}
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
// MOVETO CURRENT SPREAD LOCATION
|
||||
if ( pSoldier->flags.fDoSpread )
|
||||
{
|
||||
if ( pSoldier->sSpreadLocations[ pSoldier->flags.fDoSpread - 1 ] != 0 )
|
||||
{
|
||||
pSoldier->EVENT_SetSoldierDirection( (INT8)GetDirectionToGridNoFromGridNo( pSoldier->sGridNo, pSoldier->sSpreadLocations[ pSoldier->flags.fDoSpread - 1 ] ) );
|
||||
pSoldier->EVENT_SetSoldierDesiredDirection( pSoldier->ubDirection );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2381,9 +2395,12 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
|
||||
|
||||
usItem = pSoldier->inv[ HANDPOS ].usItem;
|
||||
|
||||
if ( pSoldier->inv[ HANDPOS ].exists() == true )
|
||||
OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon( &pSoldier->inv[ HANDPOS ] );
|
||||
UINT16 usItemUsemUsed = pSoldier->GetUsedWeaponNumber( &pSoldier->inv[ HANDPOS ] );
|
||||
|
||||
if ( pObjUsed->exists() == true )
|
||||
{
|
||||
usSoundID = Weapon[ usItem ].sLocknLoadSound;
|
||||
usSoundID = Weapon[ usItemUsemUsed ].sLocknLoadSound;
|
||||
|
||||
if ( usSoundID != 0 )
|
||||
{
|
||||
@@ -3977,8 +3994,10 @@ BOOLEAN CheckForImproperFireGunEnd( SOLDIERTYPE *pSoldier )
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
OBJECTTYPE* pObjHand = pSoldier->GetUsedWeapon( &pSoldier->inv[ HANDPOS ] );
|
||||
|
||||
// Check single hand for jammed status, ( or ammo is out.. )
|
||||
if ( pSoldier->inv[ HANDPOS ][0]->data.gun.bGunAmmoStatus < 0 || pSoldier->inv[ HANDPOS ][0]->data.gun.ubGunShotsLeft == 0 )
|
||||
if ( (*pObjHand)[0]->data.gun.bGunAmmoStatus < 0 || (*pObjHand)[0]->data.gun.ubGunShotsLeft == 0 )
|
||||
{
|
||||
// If we have 2 pistols, donot go back!
|
||||
if ( Item[ pSoldier->inv[ SECONDHANDPOS ].usItem ].usItemClass != IC_GUN )
|
||||
|
||||
@@ -12911,7 +12911,7 @@ void SOLDIERTYPE::SoldierInventoryCoolDown(void)
|
||||
attachmentList::iterator iterend = (*pObj)[i]->attachments.end();
|
||||
for (attachmentList::iterator iter = (*pObj)[i]->attachments.begin(); iter != iterend; ++iter)
|
||||
{
|
||||
if ( iter->exists() && Item[ iter->usItem ].usItemClass & (IC_LAUNCHER|IC_LAUNCHER) )
|
||||
if ( iter->exists() && Item[ iter->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) )
|
||||
{
|
||||
FLOAT temperature = (*iter)[i]->data.bTemperature; // ... get temperature of item ...
|
||||
|
||||
@@ -12934,11 +12934,19 @@ void SOLDIERTYPE::SoldierInventoryCoolDown(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: determien if we can rest our weapon on something. This can only happen when STANDING/CROUCHED. As a result, we get superior handling modifiers (we apply the PRONE modfiers)
|
||||
// Flugente: determine if we can rest our weapon on something. This can only happen when STANDING/CROUCHED. As a result, we get superior handling modifiers (we apply the PRONE modfiers)
|
||||
BOOLEAN SOLDIERTYPE::IsWeaponMounted( void )
|
||||
{
|
||||
BOOLEAN applybipod = FALSE;
|
||||
|
||||
// we must be active
|
||||
if ( !bActive)
|
||||
return( FALSE );
|
||||
|
||||
// we must be in a sector (not travelling)
|
||||
if ( !bInSector )
|
||||
return( FALSE );
|
||||
|
||||
// not possible if already prone
|
||||
if ( gAnimControl[ this->usAnimState ].ubEndHeight == ANIM_PRONE )
|
||||
return( FALSE );
|
||||
@@ -13022,6 +13030,33 @@ BOOLEAN SOLDIERTYPE::IsWeaponMounted( void )
|
||||
return( applybipod );
|
||||
}
|
||||
|
||||
// Flugente: return weapon currently used
|
||||
OBJECTTYPE* SOLDIERTYPE::GetUsedWeapon( OBJECTTYPE * pObj )
|
||||
{
|
||||
if ( bWeaponMode == WM_ATTACHED_UB || bWeaponMode == WM_ATTACHED_UB_BURST || bWeaponMode == WM_ATTACHED_UB_AUTO )
|
||||
{
|
||||
OBJECTTYPE* pObjUnderBarrel = FindAttachment_UnderBarrel(pObj);
|
||||
|
||||
if ( pObjUnderBarrel )
|
||||
return( pObjUnderBarrel );
|
||||
}
|
||||
|
||||
return( pObj );
|
||||
}
|
||||
|
||||
UINT16 SOLDIERTYPE::GetUsedWeaponNumber( OBJECTTYPE * pObj )
|
||||
{
|
||||
if ( bWeaponMode == WM_ATTACHED_UB || bWeaponMode == WM_ATTACHED_UB_BURST || bWeaponMode == WM_ATTACHED_UB_AUTO )
|
||||
{
|
||||
UINT16 weaponnr = GetAttachedUnderBarrel(pObj);
|
||||
|
||||
if ( weaponnr != NONE )
|
||||
return( weaponnr );
|
||||
}
|
||||
|
||||
return( pObj->usItem );
|
||||
}
|
||||
|
||||
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
INT8 bBandaged; //,savedOurTurn;
|
||||
|
||||
@@ -1319,7 +1319,9 @@ public:
|
||||
BOOLEAN IsValidSecondHandShotForReloadingPurposes( void );
|
||||
BOOLEAN SoldierCarriesTwoHandedWeapon( void );
|
||||
void SoldierInventoryCoolDown( void ); // Flugente FTW 1: Cool down all items in inventory
|
||||
BOOLEAN IsWeaponMounted( void );
|
||||
BOOLEAN IsWeaponMounted( void ); // determine if we receive a bonus for mouning our weapon on something
|
||||
OBJECTTYPE* GetUsedWeapon( OBJECTTYPE * pObj ); // if in an underbarrel fire mode, return underbarrel weapon
|
||||
UINT16 GetUsedWeaponNumber( OBJECTTYPE * pObj ); // if in an underbarrel fire mode, return number of underbarrel weapon
|
||||
|
||||
}; // SOLDIERTYPE;
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@ void HandleTacticalEndTurn( )
|
||||
#endif
|
||||
|
||||
// Flugente FTW 1: Cool down all items not in a soldier's inventory
|
||||
CoolDownWorldItems();
|
||||
CoolDownWorldItems( FALSE );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3959,6 +3959,44 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsUnderBarrelAttached(pGun))
|
||||
{
|
||||
OBJECTTYPE *pGun2 = FindAttachment_UnderBarrel(pGun);
|
||||
if ( (*pGun2)[0]->data.gun.ubGunShotsLeft < GetMagSize( pGun2 ) )
|
||||
{
|
||||
|
||||
// Search for ammo in sector
|
||||
for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; uiLoop++ )
|
||||
{
|
||||
if ( (gWorldItems[ uiLoop ].bVisible == TRUE) && (gWorldItems[ uiLoop ].fExists) && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) && !(gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_ARMED_BOMB) )//item exists, is reachable, is visible and is not trapped
|
||||
{
|
||||
if ( ( Item[ gWorldItems[ uiLoop ].object.usItem ].usItemClass & IC_AMMO ) ) // the item is ammo
|
||||
{
|
||||
pAmmo = &( gWorldItems[ uiLoop ].object );
|
||||
|
||||
if ( CompatibleAmmoForGun( pAmmo, pGun2 ) ) // can use the ammo with this gun
|
||||
{
|
||||
// same ammo type in gun and magazine
|
||||
if ( Magazine[Item[(*pGun2)[0]->data.gun.usGunAmmoItem].ubClassIndex].ubAmmoType == Magazine[Item[pAmmo->usItem].ubClassIndex].ubAmmoType )
|
||||
{
|
||||
ReloadGun( pTeamSoldier, pGun2, pAmmo );
|
||||
}
|
||||
|
||||
if ((*pAmmo)[0]->data.ubShotsLeft == 0)
|
||||
{
|
||||
RemoveItemFromPool( gWorldItems[ uiLoop ].sGridNo, uiLoop, gWorldItems[ uiLoop ].ubLevel );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//CHRISL: if not enough ammo in sector, reload using ammo carried in inventory
|
||||
if ( (*pGun2)[0]->data.gun.ubGunShotsLeft < GetMagSize( pGun2 ) )
|
||||
{
|
||||
AutoReload( pTeamSoldier );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3978,7 +4016,8 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
|
||||
{
|
||||
if ( ( gTacticalStatus.uiFlags & INCOMBAT ) )
|
||||
{
|
||||
pGun = &(pTeamSoldier->inv[HANDPOS]);
|
||||
// Flugente: check for underbarrel weapons and use that object if necessary
|
||||
pGun = pTeamSoldier->GetUsedWeapon( &(pTeamSoldier->inv[HANDPOS]) );
|
||||
|
||||
//magazine is not full
|
||||
if ( (*pGun)[0]->data.gun.ubGunShotsLeft < GetMagSize( pGun ) )
|
||||
|
||||
@@ -2574,8 +2574,7 @@ UINT8 GetActionModeCursor( SOLDIERTYPE *pSoldier )
|
||||
return ( TRAJECTORYCURS );
|
||||
}
|
||||
|
||||
usInHand = pSoldier->inv[HANDPOS].usItem;
|
||||
|
||||
usInHand = pSoldier->GetUsedWeaponNumber( &pSoldier->inv[HANDPOS] );
|
||||
// Start off with what is in our hand
|
||||
ubCursor = Item[ usInHand ].ubCursor;
|
||||
|
||||
|
||||
+260
-229
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,9 @@ enum WeaponMode
|
||||
WM_ATTACHED_GL,
|
||||
WM_ATTACHED_GL_BURST,
|
||||
WM_ATTACHED_GL_AUTO,
|
||||
WM_ATTACHED_UB,
|
||||
WM_ATTACHED_UB_BURST,
|
||||
WM_ATTACHED_UB_AUTO,
|
||||
NUM_WEAPON_MODES
|
||||
} ;
|
||||
|
||||
|
||||
+24
-11
@@ -812,7 +812,8 @@ void RefreshWorldItemsIntoItemPools( WORLDITEM * pItemList, INT32 iNumberOfItems
|
||||
|
||||
|
||||
// Flugente FTW 1: Cool down all items in the world (no, really)
|
||||
void CoolDownWorldItems( void )
|
||||
// fSetZero sets all temperatures to 0 (used in old sector upon loading a new sector)
|
||||
void CoolDownWorldItems( BOOLEAN fSetZero )
|
||||
{
|
||||
if ( gGameOptions.fWeaponOverheating ) // if Overheating is used ...
|
||||
{
|
||||
@@ -829,15 +830,21 @@ void CoolDownWorldItems( void )
|
||||
{
|
||||
for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ...
|
||||
{
|
||||
FLOAT guntemperature = (*pObj)[i]->data.bTemperature; // ... get temperature ...
|
||||
FLOAT newguntemperature = 0.0;
|
||||
|
||||
FLOAT cooldownfactor = GetItemCooldownFactor(pObj); // ... get item cooldown factor provided of attachments ...
|
||||
if ( !fSetZero && gGameExternalOptions.fSetZeroUponNewSector )
|
||||
{
|
||||
FLOAT guntemperature = (*pObj)[i]->data.bTemperature; // ... get temperature ...
|
||||
|
||||
if ( Item[gWorldItems[ uiCount ].object.usItem].barrel == TRUE ) // ... a barrel lying around cools down a bit faster ...
|
||||
cooldownfactor *= gGameExternalOptions.iCooldownModificatorLonelyBarrel;
|
||||
FLOAT cooldownfactor = GetItemCooldownFactor(pObj); // ... get item cooldown factor provided of attachments ...
|
||||
|
||||
FLOAT newguntemperatre = max(0.0, guntemperature - cooldownfactor); // ... calculate new temperature ...
|
||||
(*pObj)[i]->data.bTemperature = newguntemperatre; // ... set new temperature
|
||||
if ( Item[gWorldItems[ uiCount ].object.usItem].barrel == TRUE ) // ... a barrel lying around cools down a bit faster ...
|
||||
cooldownfactor *= gGameExternalOptions.iCooldownModificatorLonelyBarrel;
|
||||
|
||||
newguntemperature = max(0.0, guntemperature - cooldownfactor); // ... calculate new temperature ...
|
||||
}
|
||||
|
||||
(*pObj)[i]->data.bTemperature = newguntemperature; // ... set new temperature
|
||||
|
||||
#if 0//def JA2TESTVERSION
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"World: Item temperature lowered from %4.2f to %4.2f", guntemperature, newguntemperatre );
|
||||
@@ -846,13 +853,19 @@ void CoolDownWorldItems( void )
|
||||
attachmentList::iterator iterend = (*pObj)[i]->attachments.end();
|
||||
for (attachmentList::iterator iter = (*pObj)[i]->attachments.begin(); iter != iterend; ++iter)
|
||||
{
|
||||
if ( iter->exists() && Item[ iter->usItem ].usItemClass & (IC_LAUNCHER|IC_LAUNCHER) )
|
||||
if ( iter->exists() && Item[ iter->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) )
|
||||
{
|
||||
FLOAT temperature = (*iter)[i]->data.bTemperature; // ... get temperature of item ...
|
||||
FLOAT newtemperature = 0.0;
|
||||
|
||||
FLOAT cooldownfactor = GetItemCooldownFactor( &(*iter) ); // ... get cooldown factor ...
|
||||
if ( !fSetZero && gGameExternalOptions.fSetZeroUponNewSector )
|
||||
{
|
||||
FLOAT temperature = (*iter)[i]->data.bTemperature; // ... get temperature of item ...
|
||||
|
||||
FLOAT cooldownfactor = GetItemCooldownFactor( &(*iter) ); // ... get cooldown factor ...
|
||||
|
||||
newtemperature = max(0.0, temperature - cooldownfactor); // ... calculate new temperature ...
|
||||
}
|
||||
|
||||
FLOAT newtemperature = max(0.0, temperature - cooldownfactor); // ... calculate new temperature ...
|
||||
(*iter)[i]->data.bTemperature = newtemperature; // ... set new temperature
|
||||
|
||||
#if 0//def JA2TESTVERSION
|
||||
|
||||
@@ -119,6 +119,6 @@ extern void FindPanicBombsAndTriggers( void );
|
||||
extern INT32 FindWorldItemForBombInGridNo( INT32 sGridNo, INT8 bLevel);
|
||||
|
||||
void RefreshWorldItemsIntoItemPools( WORLDITEM * pItemList, INT32 iNumberOfItems );
|
||||
void CoolDownWorldItems( void ); // Flugente FTW 1: Cool down all items in the world (no, really)
|
||||
void CoolDownWorldItems( BOOLEAN fSetZero = FALSE ); // Flugente FTW 1: Cool down all items in the world (no, really)
|
||||
|
||||
#endif
|
||||
@@ -2060,6 +2060,9 @@ enum
|
||||
MSG113_GL,
|
||||
MSG113_GL_BRST,
|
||||
MSG113_GL_AUTO,
|
||||
MSG113_UB,
|
||||
MSG113_UB_BRST,
|
||||
MSG113_UB_AUTO,
|
||||
MSG113_SNIPER,
|
||||
MSG113_UNABLETOSPLITMONEY,
|
||||
MSG113_ARRIVINGREROUTED,
|
||||
|
||||
@@ -6051,6 +6051,9 @@ STR16 New113Message[] =
|
||||
L"榴弹",
|
||||
L"榴弹点射",
|
||||
L"榴弹自动",
|
||||
L"UB", // TODO.Translate, INFO: UB = Under Barrel
|
||||
L"UBRST",
|
||||
L"UAUTO",
|
||||
L"狙击手!",
|
||||
L"已经点选物品,此时无法分钱。",
|
||||
L"新兵的会合地被挪至 %s, 因降落地点 %s 目前由敌人占据。",
|
||||
|
||||
@@ -6053,6 +6053,9 @@ STR16 New113Message[] =
|
||||
L"GL",
|
||||
L"GL BRST",
|
||||
L"GL AUTO",
|
||||
L"UB",
|
||||
L"UBRST",
|
||||
L"UAUTO",
|
||||
L"Sniper!",
|
||||
L"Unable to split money due to having an item on your cursor.",
|
||||
L"Arrival of new recruits is being rerouted to sector %s, as scheduled drop-off point of sector %s is enemy occupied.",
|
||||
|
||||
@@ -6051,6 +6051,9 @@ STR16 New113Message[] =
|
||||
L"GL",
|
||||
L"GL BRST",
|
||||
L"GL AUTO",
|
||||
L"UB",
|
||||
L"UBRST",
|
||||
L"UAUTO",
|
||||
L"Sniper!",
|
||||
L"Unable to split money due to having an item on your cursor.",
|
||||
L"Arrival of new recruits is being rerouted to sector %s, as scheduled drop-off point of sector %s is enemy occupied.",
|
||||
|
||||
@@ -6035,6 +6035,9 @@ STR16 New113Message[] =
|
||||
L"LG",
|
||||
L"RAF. LG",
|
||||
L"LG AUTO",
|
||||
L"UB", // TODO.Translate
|
||||
L"UBRST",
|
||||
L"UAUTO",
|
||||
L"Tireur embusqué !",
|
||||
L"Unable to split money due to having an item on your cursor.",
|
||||
L"Arrivée de nouvelles recrues est déroutée au secteur %s, car le point d'arrivée prévu %s est sous contrôle ennemi.",
|
||||
|
||||
@@ -5880,6 +5880,9 @@ STR16 New113Message[] =
|
||||
L"GL",
|
||||
L"GL BRST",
|
||||
L"GL AUTO",
|
||||
L"UB",
|
||||
L"UBRST",
|
||||
L"UAUTO",
|
||||
L"Scharfschütze!",
|
||||
L"Geld kann nicht aufgeteilt werden, weil ein Gegenstand am Cursor ist.",
|
||||
L"Ankunft der neuen Söldner wurde in den Sektor %s verlegt, weil der geplante Sektor %s von Feinden belagert ist.",
|
||||
|
||||
@@ -6042,6 +6042,9 @@ STR16 New113Message[] =
|
||||
L"GL",
|
||||
L"GL BRST",
|
||||
L"GL AUTO",
|
||||
L"UB",
|
||||
L"UBRST",
|
||||
L"UAUTO",
|
||||
L"Sniper!",
|
||||
L"Unable to split money due to having an item on your cursor.",
|
||||
L"Arrival of new recruits is being rerouted to sector %s, as scheduled drop-off point of sector %s is enemy occupied.",
|
||||
|
||||
@@ -6048,6 +6048,9 @@ STR16 New113Message[] =
|
||||
L"GL",
|
||||
L"GL BRST",
|
||||
L"GL AUTO",
|
||||
L"UB", // TODO.Translate
|
||||
L"UBRST",
|
||||
L"UAUTO",
|
||||
L"Snajper!",
|
||||
L"Nie można podzielić pieniędzy z powodu przedmiotu na kursorze.",
|
||||
L"Przybycie nowych rekrutów zostało przekierowane do sektora %s , z uwagi na to, że poprzedni punkt zrzutu w sektorze %s jest zajęty przez wroga.",
|
||||
|
||||
@@ -6028,6 +6028,9 @@ STR16 New113Message[] =
|
||||
L"ГР",
|
||||
L"ГР *",
|
||||
L"ГР ***",
|
||||
L"UB", // TODO.Translate
|
||||
L"UBRST",
|
||||
L"UAUTO",
|
||||
L"Снайпер!",
|
||||
L"Невозможно разделить деньги из-за предмета на курсоре.",
|
||||
L"Точка высадки новых наемников перенесена в %s, так как предыдущая точка высадки %s захвачена противником.",
|
||||
|
||||
@@ -6055,6 +6055,9 @@ STR16 New113Message[] =
|
||||
L"GL",
|
||||
L"GL BRST",
|
||||
L"GL AUTO",
|
||||
L"UB",
|
||||
L"UBRST",
|
||||
L"UAUTO",
|
||||
L"Sniper!",
|
||||
L"Unable to split money due to having an item on your cursor.",
|
||||
L"Arrival of new recruits is being rerouted to sector %s, as scheduled drop-off point of sector %s is enemy occupied.",
|
||||
|
||||
Reference in New Issue
Block a user