mirror of
https://github.com/1dot13/source.git
synced 2026-09-16 14:47:17 +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:
@@ -1320,7 +1320,9 @@ void LoadGameExternalOptions()
|
|||||||
// Flugente FTW 1: These settings control the behavior of Weapon Overheating, its severity, and its display.
|
// 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.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.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 ##################
|
//################# Strategic Gamestart Settings ##################
|
||||||
|
|
||||||
|
|||||||
@@ -1072,7 +1072,9 @@ typedef struct
|
|||||||
|
|
||||||
// Flugente FTW 1: Weapon Overheating
|
// Flugente FTW 1: Weapon Overheating
|
||||||
BOOLEAN fDisplayOverheatThermometer; // Should a 'thermometer' for guns and replacable barrels be displayed?
|
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 ;-)
|
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 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?
|
BOOLEAN fDisplayWeaponRestingIndicator; // Should a little indicator show if the weapon is currently rested on something?
|
||||||
|
|||||||
@@ -6113,6 +6113,8 @@ BOOLEAN HandleDefiniteUnloadingOfWorld( UINT8 ubUnloadCode )
|
|||||||
//if we arent loading a saved game
|
//if we arent loading a saved game
|
||||||
if( !(gTacticalStatus.uiFlags & LOADING_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
|
// Save the current sectors Item list to a temporary file, if its not the first time in
|
||||||
SaveCurrentSectorsInformationToTempItemFile();
|
SaveCurrentSectorsInformationToTempItemFile();
|
||||||
|
|||||||
@@ -594,7 +594,9 @@ void DisplayRangeToTarget( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
|
|||||||
pSoldier->bTargetLevel = bTempTargetLevel;
|
pSoldier->bTargetLevel = bTempTargetLevel;
|
||||||
|
|
||||||
// HEADROCK HAM 3.6: Calculate Gun Range using formula.
|
// 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 );
|
swprintf( zOutputString, gzDisplayCoverText[title], usRange / 10, usGunRange / 10, uiHitChance );
|
||||||
//Display the msg
|
//Display the msg
|
||||||
|
|||||||
+10
-9
@@ -2531,15 +2531,18 @@ void UIHandleMercAttack( SOLDIERTYPE *pSoldier , SOLDIERTYPE *pTargetSoldier, IN
|
|||||||
INT32 iHandleReturn;
|
INT32 iHandleReturn;
|
||||||
INT32 sTargetGridNo;
|
INT32 sTargetGridNo;
|
||||||
INT8 bTargetLevel;
|
INT8 bTargetLevel;
|
||||||
UINT16 usItem;
|
UINT16 usItem;
|
||||||
LEVELNODE *pIntNode;
|
LEVELNODE* pIntNode;
|
||||||
STRUCTURE *pStructure;
|
STRUCTURE* pStructure;
|
||||||
INT32 sGridNo, sNewGridNo;
|
INT32 sGridNo, sNewGridNo;
|
||||||
UINT8 ubItemCursor;
|
UINT8 ubItemCursor;
|
||||||
|
|
||||||
// get cursor
|
// get cursor
|
||||||
ubItemCursor = GetActionModeCursor( pSoldier );
|
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 ( !(gTacticalStatus.uiFlags & INCOMBAT) && pTargetSoldier && Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass & IC_WEAPON )
|
||||||
{
|
{
|
||||||
if ( NPCFirstDraw( pSoldier, pTargetSoldier ) )
|
if ( NPCFirstDraw( pSoldier, pTargetSoldier ) )
|
||||||
@@ -2555,8 +2558,6 @@ void UIHandleMercAttack( SOLDIERTYPE *pSoldier , SOLDIERTYPE *pTargetSoldier, IN
|
|||||||
|
|
||||||
// Set aim time to one in UI
|
// Set aim time to one in UI
|
||||||
pSoldier->aiData.bAimTime = (pSoldier->aiData.bShownAimTime );
|
pSoldier->aiData.bAimTime = (pSoldier->aiData.bShownAimTime );
|
||||||
usItem = pSoldier->inv[ HANDPOS ].usItem;
|
|
||||||
|
|
||||||
// ATE: Check if we are targeting an interactive tile, and adjust gridno accordingly...
|
// ATE: Check if we are targeting an interactive tile, and adjust gridno accordingly...
|
||||||
pIntNode = GetCurInteractiveTileGridNoAndStructure( &sGridNo, &pStructure );
|
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 )
|
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
|
else
|
||||||
{
|
{
|
||||||
iHandleReturn = HandleItem( pSoldier, sTargetGridNo, bTargetLevel, pSoldier->inv[ HANDPOS ].usItem, TRUE );
|
iHandleReturn = HandleItem( pSoldier, sTargetGridNo, bTargetLevel, usItem, TRUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( iHandleReturn < 0 )
|
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
|
// Flugente FTW 1: Function to get the number of the item condition string
|
||||||
UINT8 GetTemperatureString( FLOAT overheatpercentage, UINT32* apRed, UINT32* apGreen, UINT32* abBlue )
|
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;
|
*apGreen = 0;
|
||||||
*abBlue = 0;
|
*abBlue = 0;
|
||||||
|
|
||||||
@@ -2769,7 +2769,7 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
|
|||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// FIRST DISPLAY FREE ROUNDS REMIANING
|
|
||||||
if ( pItem->usItemClass == IC_GUN && !Item[pObject->usItem].rocketlauncher )
|
if ( pItem->usItemClass == IC_GUN && !Item[pObject->usItem].rocketlauncher )
|
||||||
{
|
{
|
||||||
sNewY = sY + sHeight - 10;
|
sNewY = sY + sHeight - 10;
|
||||||
@@ -2779,75 +2779,76 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
|
|||||||
if ( gGameOptions.fWeaponOverheating == TRUE && gGameExternalOptions.fDisplayOverheatThermometer == TRUE )
|
if ( gGameOptions.fWeaponOverheating == TRUE && gGameExternalOptions.fDisplayOverheatThermometer == TRUE )
|
||||||
sNewX = sX + 6;
|
sNewX = sX + 6;
|
||||||
|
|
||||||
SetFontForeground ( AmmoTypes[(*pObject)[iter]->data.gun.ubGunAmmoType].fontColour );
|
// Flugente: check for underbarrel weapons and use that object if necessary
|
||||||
//switch ((*pObject)[iter]->data.gun.ubGunAmmoType)
|
OBJECTTYPE* pObjShown = pObject;
|
||||||
//{
|
INVTYPE *pItemShown = pItem;
|
||||||
// case AMMO_AP:
|
if ( pItem->usItemClass == IC_GUN && pSoldier && ( pSoldier->bWeaponMode == WM_ATTACHED_UB || pSoldier->bWeaponMode == WM_ATTACHED_UB_BURST || pSoldier->bWeaponMode == WM_ATTACHED_UB_AUTO ) )
|
||||||
// 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) )
|
|
||||||
{
|
{
|
||||||
// Soldier doesn't know.
|
OBJECTTYPE *pObjectUnderBarrel = FindAttachment_UnderBarrel( pObject );
|
||||||
EstimateBulletsLeft( pSoldier, pObject );
|
|
||||||
swprintf( pStr, L"%s", gBulletCount );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
swprintf( pStr, L"%d", (*pObject)[iter]->data.gun.ubGunShotsLeft );
|
|
||||||
}
|
|
||||||
|
|
||||||
//swprintf( pStr, L"%d", (*pObject)[iter]->data.gun.ubGunShotsLeft );
|
if ( pObjectUnderBarrel )
|
||||||
//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 ) )
|
|
||||||
{
|
{
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
swprintf( pStr, TacticalStr[ SHORT_JAMMED_GUN ] );
|
swprintf( pStr, L"%d", (*pObjShown)[iter]->data.gun.ubGunShotsLeft );
|
||||||
}
|
}
|
||||||
|
|
||||||
VarFindFontCenterCoordinates( sX, sY, sWidth, sHeight , ITEM_FONT, &sNewX, &sNewY, pStr );
|
if ( uiBuffer == guiSAVEBUFFER )
|
||||||
|
{
|
||||||
|
RestoreExternBackgroundRect( sNewX, sNewY, 20, 15 );
|
||||||
|
}
|
||||||
mprintf( sNewX, sNewY, pStr );
|
mprintf( sNewX, sNewY, pStr );
|
||||||
gprintfinvalidate( 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
|
#if 0
|
||||||
@@ -2909,19 +2910,24 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
|
|||||||
// Flugente FTW 1
|
// Flugente FTW 1
|
||||||
if ( gGameOptions.fWeaponOverheating == TRUE && gGameExternalOptions.fDisplayOverheatThermometer == TRUE && ( pItem->usItemClass & (IC_GUN | IC_LAUNCHER) || Item[pObject->usItem].barrel == TRUE ) )
|
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;
|
UINT32 red, green, blue;
|
||||||
UINT8 TemperatureStringNum = GetTemperatureString( overheatjampercentage, &red, &green, &blue );
|
UINT8 TemperatureStringNum = GetTemperatureString( overheatjampercentage, &red, &green, &blue );
|
||||||
|
|
||||||
UINT16 colour = Get16BPPColor( FROMRGB( 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 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
|
// 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 );
|
SetRGBFontForeground( 95, 160, 154 );
|
||||||
|
|
||||||
@@ -2994,6 +3000,21 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
|
|||||||
swprintf( pStr, New113Message[MSG113_GL_AUTO] );
|
swprintf( pStr, New113Message[MSG113_GL_AUTO] );
|
||||||
SetFontForeground( FONT_YELLOW );
|
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
|
// Get length of string
|
||||||
uiStringLength=StringPixLength(pStr, ITEM_FONT );
|
uiStringLength=StringPixLength(pStr, ITEM_FONT );
|
||||||
|
|||||||
@@ -2167,12 +2167,15 @@ BOOLEAN CreateSMPanelButtons( )
|
|||||||
|
|
||||||
iSMPanelImages[ OPTIONS_IMAGES ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ] ,-1,24,-1,25,-1 );
|
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_BURST ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
|
||||||
iBurstButtonImages[ WM_AUTOFIRE ] = 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 ] = 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_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_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);
|
FilenameForBPP("INTERFACE\\invadd-ons.sti", ubString);
|
||||||
// Load button Graphics
|
// Load button Graphics
|
||||||
@@ -2396,6 +2399,9 @@ void RemoveSMPanelButtons( )
|
|||||||
UnloadButtonImage( iBurstButtonImages[ WM_ATTACHED_GL ] );
|
UnloadButtonImage( iBurstButtonImages[ WM_ATTACHED_GL ] );
|
||||||
UnloadButtonImage( iBurstButtonImages[ WM_ATTACHED_GL_BURST ] );
|
UnloadButtonImage( iBurstButtonImages[ WM_ATTACHED_GL_BURST ] );
|
||||||
UnloadButtonImage( iBurstButtonImages[ WM_ATTACHED_GL_AUTO ] );
|
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 );
|
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
|
//<SB> manual recharge
|
||||||
if ((*pObj)[0]->data.gun.ubGunShotsLeft && !((*pObj)[0]->data.gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER) )
|
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;
|
BOOLEAN fRet;
|
||||||
|
|
||||||
CHECKF( pSoldier );
|
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
|
//<SB> manual recharge
|
||||||
if ((*pObj)[0]->data.gun.ubGunShotsLeft && !((*pObj)[0]->data.gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER) )
|
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!
|
// then do a reload of both guns!
|
||||||
if ( (fRet == TRUE) && pSoldier->IsValidSecondHandShotForReloadingPurposes( ) )
|
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 );
|
bSlot = FindAmmoToReload( pSoldier, SECONDHANDPOS, NO_SLOT );
|
||||||
if (bSlot != 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..
|
//Make sure it's actually on that gun..
|
||||||
//if(FindAttachment_GrenadeLauncher(this)->usItem == attachmentObject.usItem){
|
//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
|
// 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
|
//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:
|
case IC_GUN:
|
||||||
if (Item[pObj->usItem].usItemClass == IC_AMMO)
|
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
|
//CHRISL: Work differently with ammo crates but only when not in combat
|
||||||
if(Magazine[Item[pObj->usItem].ubClassIndex].ubMagType >= AMMO_BOX)
|
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(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;
|
newItem = loop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5891,7 +5902,7 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
|
|||||||
ubShotsLeft = (*pObj)[0]->data.ubShotsLeft;
|
ubShotsLeft = (*pObj)[0]->data.ubShotsLeft;
|
||||||
for(UINT8 clip = 0; clip < 5; clip++)
|
for(UINT8 clip = 0; clip < 5; clip++)
|
||||||
{
|
{
|
||||||
magSize = GetMagSize(pInSlot);
|
magSize = GetMagSize(pObjUsed);
|
||||||
if(ubShotsLeft < magSize)
|
if(ubShotsLeft < magSize)
|
||||||
magSize = ubShotsLeft;
|
magSize = ubShotsLeft;
|
||||||
if(CreateAmmo(newItem, &tempClip, magSize))
|
if(CreateAmmo(newItem, &tempClip, magSize))
|
||||||
@@ -5963,7 +5974,7 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return( ReloadGun( pSoldier, pInSlot, pObj ) );
|
return( ReloadGun( pSoldier, pObjUsed, pObj ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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)){
|
if(Item[this->usItem].usItemClass == IC_GUN && oldMagSize != GetMagSize(this, subObject)){
|
||||||
fInterfacePanelDirty = DIRTYLEVEL2;
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
||||||
RenderBulletIcon(this, subObject);
|
RenderBulletIcon(this, subObject);
|
||||||
@@ -9478,8 +9507,12 @@ void GetRecoil( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 *bRecoilX, INT8 *b
|
|||||||
*bRecoilX = 0;
|
*bRecoilX = 0;
|
||||||
*bRecoilY = 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 < 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
|
// The first bullet in a volley never has recoil - it hasn't "set in" yet. Only the second+ bullets
|
||||||
// will have any recoil.
|
// will have any recoil.
|
||||||
@@ -9488,13 +9521,15 @@ void GetRecoil( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 *bRecoilX, INT8 *b
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*bRecoilX = Weapon[pObj->usItem].bRecoilX;
|
*bRecoilX = Weapon[pObjUsed->usItem].bRecoilX;
|
||||||
*bRecoilY = Weapon[pObj->usItem].bRecoilY;
|
*bRecoilY = Weapon[pObjUsed->usItem].bRecoilY;
|
||||||
|
|
||||||
// Apply a percentage-based modifier. This can increase or decrease BOTH axes. At most, it can eliminate
|
// Apply a percentage-based modifier. This can increase or decrease BOTH axes. At most, it can eliminate
|
||||||
// recoil on the gun.
|
// recoil on the gun.
|
||||||
|
|
||||||
INT16 sPercentRecoilModifier = GetPercentRecoilModifier( pObj );
|
//INT16 sPercentRecoilModifier = GetPercentRecoilModifier( pObj );
|
||||||
|
INT16 sPercentRecoilModifier = __max(-100, (GetBasePercentRecoilModifier( pObjUsed ) + GetAttachmentPercentRecoilModifier( pObjUsedInHand ) ));
|
||||||
|
|
||||||
|
|
||||||
*bRecoilX += (*bRecoilX * sPercentRecoilModifier ) / 100;
|
*bRecoilX += (*bRecoilX * sPercentRecoilModifier ) / 100;
|
||||||
*bRecoilY += (*bRecoilY * sPercentRecoilModifier ) / 100;
|
*bRecoilY += (*bRecoilY * sPercentRecoilModifier ) / 100;
|
||||||
@@ -9505,7 +9540,10 @@ void GetRecoil( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 *bRecoilX, INT8 *b
|
|||||||
INT8 bRecoilAdjustX = 0;
|
INT8 bRecoilAdjustX = 0;
|
||||||
INT8 bRecoilAdjustY = 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);
|
*bRecoilX = __max(0, *bRecoilX + bRecoilAdjustX);
|
||||||
*bRecoilY = __max(0, *bRecoilY + bRecoilAdjustY);
|
*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
|
// 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).
|
// 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.
|
// 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 )
|
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
|
// 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
|
// the percentage-based nature of this modifier, it cannot cause a gun to reverse its recoil - only diminish it to
|
||||||
// zero.
|
// 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 GetPercentRecoilModifier( OBJECTTYPE *pObj )
|
||||||
{
|
{
|
||||||
INT16 sRecoilAdjust = 0;
|
INT16 sRecoilAdjust = 0;
|
||||||
@@ -10550,6 +10659,60 @@ UINT16 GetAttachedGrenadeLauncher( OBJECTTYPE * pObj )
|
|||||||
return( NONE );
|
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 )
|
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.
|
// 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 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 );
|
void GetFlatRecoilModifier( OBJECTTYPE *pObj, INT8 *bRecoilModifierX, INT8 *bRecoilModifierY );
|
||||||
|
INT16 GetBasePercentRecoilModifier( OBJECTTYPE *pObj );
|
||||||
|
INT16 GetAttachmentPercentRecoilModifier( OBJECTTYPE *pObj);
|
||||||
INT16 GetPercentRecoilModifier( OBJECTTYPE *pObj );
|
INT16 GetPercentRecoilModifier( OBJECTTYPE *pObj );
|
||||||
// HEADROCK HAM 4: This function returns whether the last bullet in a burst/autofire volley was a tracer.
|
// HEADROCK HAM 4: This function returns whether the last bullet in a burst/autofire volley was a tracer.
|
||||||
BOOLEAN WasPrevBulletATracer( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon );
|
BOOLEAN WasPrevBulletATracer( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon );
|
||||||
@@ -337,6 +341,14 @@ INT16 GetGrenadeLauncherStatus( OBJECTTYPE * pObj );
|
|||||||
BOOLEAN IsGrenadeLauncherAttached( OBJECTTYPE * pObj, UINT8 subObject = 0 );
|
BOOLEAN IsGrenadeLauncherAttached( OBJECTTYPE * pObj, UINT8 subObject = 0 );
|
||||||
OBJECTTYPE* FindAttachment_GrenadeLauncher( OBJECTTYPE * pObj );
|
OBJECTTYPE* FindAttachment_GrenadeLauncher( OBJECTTYPE * pObj );
|
||||||
UINT16 GetAttachedGrenadeLauncher( 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 FindRocketLauncher( SOLDIERTYPE * pSoldier );
|
||||||
INT8 FindRocketLauncherOrCannon( SOLDIERTYPE * pSoldier );
|
INT8 FindRocketLauncherOrCannon( SOLDIERTYPE * pSoldier );
|
||||||
INT8 FindNonSmokeLaunchable( SOLDIERTYPE * pSoldier, UINT16 usWeapon );
|
INT8 FindNonSmokeLaunchable( SOLDIERTYPE * pSoldier, UINT16 usWeapon );
|
||||||
|
|||||||
+35
-23
@@ -3988,12 +3988,15 @@ INT8 FireBullet( SOLDIERTYPE * pFirer, BULLET * pBullet, BOOLEAN fFake )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
OBJECTTYPE* pObjAttHand = pFirer->GetUsedWeapon( &pFirer->inv[pFirer->ubAttackingHand] );
|
||||||
|
UINT16 usItemUsed = pFirer->GetUsedWeaponNumber( &pFirer->inv[pFirer->ubAttackingHand] );
|
||||||
|
|
||||||
//afp-start //always a fast bullet
|
//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*/ ) )
|
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
|
else
|
||||||
if (gGameSettings.fOptions[TOPTION_ALTERNATE_BULLET_GRAPHICS])
|
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
|
else
|
||||||
pBullet->usClockTicksPerUpdate = 1;
|
pBullet->usClockTicksPerUpdate = 1;
|
||||||
//afp-end
|
//afp-end
|
||||||
@@ -4068,6 +4071,8 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
|
|||||||
UINT16 usBulletFlags = 0;
|
UINT16 usBulletFlags = 0;
|
||||||
int n=0;
|
int n=0;
|
||||||
|
|
||||||
|
OBJECTTYPE* pObjAttHand = pFirer->GetUsedWeapon( &(pFirer->inv[pFirer->ubAttackingHand]) );
|
||||||
|
|
||||||
//DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBulletGivenTarget"));
|
//DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBulletGivenTarget"));
|
||||||
|
|
||||||
CalculateSoldierZPos( pFirer, FIRING_POS, &dStartZ );
|
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
|
// HEADROCK HAM B2.5: Set tracer effect on/off for individual bullets in a Tracer Magazine, as part of the
|
||||||
// New Tracer System.
|
// New Tracer System.
|
||||||
else if (gGameExternalOptions.ubRealisticTracers > 0 && gGameExternalOptions.ubNumBulletsPerTracer > 0 && (pFirer->bDoAutofire > 0 || pFirer->bDoBurst > 0)
|
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;
|
UINT16 iBulletsLeft, iBulletsPerTracer;
|
||||||
iBulletsPerTracer = gGameExternalOptions.ubNumBulletsPerTracer;
|
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)
|
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;
|
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;
|
//usBulletFlags |= BULLET_FLAG_TRACER;
|
||||||
fTracer = TRUE;
|
fTracer = TRUE;
|
||||||
@@ -4156,9 +4161,9 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
|
|||||||
ubImpact =(UINT8) GetDamage(&pFirer->inv[pFirer->ubAttackingHand]);
|
ubImpact =(UINT8) GetDamage(&pFirer->inv[pFirer->ubAttackingHand]);
|
||||||
//zilpin: Begin new code block for spread patterns, number of projectiles, impact adjustment, etc.
|
//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;
|
ubShots = AmmoTypes[ weapon->gun.ubGunAmmoType].numberOfBullets;
|
||||||
ubSpreadIndex = GetSpreadPattern( &pFirer->inv[pFirer->ubAttackingHand] );
|
ubSpreadIndex = GetSpreadPattern( pObjAttHand );
|
||||||
if( ubShots>1 && !fFake )
|
if( ubShots>1 && !fFake )
|
||||||
{
|
{
|
||||||
fBuckshot = true;
|
fBuckshot = true;
|
||||||
@@ -4407,7 +4412,7 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
|
|||||||
|
|
||||||
if ( pBullet->usFlags & BULLET_FLAG_KNIFE )
|
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
|
// apply increments for first move
|
||||||
@@ -4435,7 +4440,7 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
|
|||||||
|
|
||||||
pBullet->iImpact = ubImpact;
|
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->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 ) );
|
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
|
// 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?
|
// 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)
|
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;
|
UINT16 iBulletsLeft, iBulletsPerTracer;
|
||||||
iBulletsPerTracer = gGameExternalOptions.ubNumBulletsPerTracer;
|
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
|
// Is this specific bullet a tracer? - based on how many tracers there are per regular bullets in
|
||||||
// a tracer magazine (INI-settable).
|
// a tracer magazine (INI-settable).
|
||||||
@@ -4540,6 +4545,8 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
|
|||||||
UINT16 usBulletFlags = 0;
|
UINT16 usBulletFlags = 0;
|
||||||
int n=0;
|
int n=0;
|
||||||
|
|
||||||
|
OBJECTTYPE* pObjAttHand = pFirer->GetUsedWeapon( &(pFirer->inv[pFirer->ubAttackingHand]) );
|
||||||
|
|
||||||
//DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBulletGivenTarget"));
|
//DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBulletGivenTarget"));
|
||||||
|
|
||||||
CalculateSoldierZPos( pFirer, FIRING_POS, &dStartZ );
|
CalculateSoldierZPos( pFirer, FIRING_POS, &dStartZ );
|
||||||
@@ -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
|
// HEADROCK HAM B2.5: Set tracer effect on/off for individual bullets in a Tracer Magazine, as part of the
|
||||||
// New Tracer System.
|
// New Tracer System.
|
||||||
else if (gGameExternalOptions.ubRealisticTracers > 0 && gGameExternalOptions.ubNumBulletsPerTracer > 0 && (pFirer->bDoAutofire > 0 || pFirer->bDoBurst > 0)
|
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;
|
UINT16 iBulletsLeft, iBulletsPerTracer;
|
||||||
iBulletsPerTracer = gGameExternalOptions.ubNumBulletsPerTracer;
|
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)
|
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;
|
fTracer = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ubImpact =(UINT8) GetDamage(&pFirer->inv[pFirer->ubAttackingHand]);
|
ubImpact =(UINT8) GetDamage(pObjAttHand);
|
||||||
//zilpin: pellet spread patterns externalized in XML
|
//zilpin: pellet spread patterns externalized in XML
|
||||||
/* zilpin: The section below, including line comments, is the original adjustment made to multiple projectile stats.
|
/* 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.
|
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.
|
//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;
|
ubShots = AmmoTypes[ weapon->gun.ubGunAmmoType].numberOfBullets;
|
||||||
ubSpreadIndex = GetSpreadPattern( &pFirer->inv[pFirer->ubAttackingHand] );
|
ubSpreadIndex = GetSpreadPattern( pObjAttHand );
|
||||||
if( ubShots>1 && !fFake )
|
if( ubShots>1 && !fFake )
|
||||||
{
|
{
|
||||||
fBuckshot = true;
|
fBuckshot = true;
|
||||||
@@ -4905,7 +4912,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
|
|||||||
|
|
||||||
if ( pBullet->usFlags & BULLET_FLAG_KNIFE )
|
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
|
// apply increments for first move
|
||||||
@@ -4933,7 +4940,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
|
|||||||
|
|
||||||
pBullet->iImpact = ubImpact;
|
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->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 ) );
|
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
|
// 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?
|
// 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)
|
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;
|
UINT16 iBulletsLeft, iBulletsPerTracer;
|
||||||
iBulletsPerTracer = gGameExternalOptions.ubNumBulletsPerTracer;
|
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
|
// Is this specific bullet a tracer? - based on how many tracers there are per regular bullets in
|
||||||
// a tracer magazine (INI-settable).
|
// a tracer magazine (INI-settable).
|
||||||
@@ -5008,10 +5015,12 @@ INT8 ChanceToGetThrough( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOAT d
|
|||||||
{
|
{
|
||||||
BOOLEAN fBuckShot = FALSE;
|
BOOLEAN fBuckShot = FALSE;
|
||||||
|
|
||||||
|
OBJECTTYPE* pObjHand = pFirer->GetUsedWeapon( &pFirer->inv[HANDPOS] );
|
||||||
|
|
||||||
// if shotgun, shotgun would have to be in main hand
|
// 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;
|
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.
|
// 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 );
|
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).
|
// WANNE: I got a CTD in a multiplayer test game, because sEffRange was 0 (division to zero).
|
||||||
// I don't know why this happend?
|
// I don't know why this happend?
|
||||||
|
|||||||
+59
-49
@@ -1478,8 +1478,12 @@ INT16 CalcTotalAPsToAttack( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTur
|
|||||||
BOOLEAN fAddingRaiseGunCost = FALSE;
|
BOOLEAN fAddingRaiseGunCost = FALSE;
|
||||||
|
|
||||||
// LOOK IN BUDDY'S HAND TO DETERMINE WHAT TO DO HERE
|
// 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;
|
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 )
|
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->bDoBurst )
|
||||||
{
|
{
|
||||||
if(pSoldier->bDoAutofire && GetAutofireShotsPerFiveAPs(&pSoldier->inv[HANDPOS]) > 0 )
|
if(pSoldier->bDoAutofire && GetAutofireShotsPerFiveAPs(AttackingWeapon) > 0 )
|
||||||
sAPCost += CalcAPsToAutofire( pSoldier->CalcActionPoints( ), &(pSoldier->inv[HANDPOS]), pSoldier->bDoAutofire );
|
sAPCost += CalcAPsToAutofire( pSoldier->CalcActionPoints( ), AttackingWeapon, pSoldier->bDoAutofire );
|
||||||
else
|
else
|
||||||
sAPCost += CalcAPsToBurst( pSoldier->CalcActionPoints( ), &(pSoldier->inv[HANDPOS]) );
|
sAPCost += CalcAPsToBurst( pSoldier->CalcActionPoints( ), AttackingWeapon );
|
||||||
}
|
}
|
||||||
//else //ddd comment for aimed burst
|
//else //ddd comment for aimed burst
|
||||||
{
|
{
|
||||||
@@ -1513,7 +1517,7 @@ INT16 CalcTotalAPsToAttack( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTur
|
|||||||
UINT16 usWeaponReadyTime;
|
UINT16 usWeaponReadyTime;
|
||||||
UINT8 ubReadyTimeDivisor;
|
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;
|
ubReadyTimeDivisor = gGameExternalOptions.ubFirstAimReadyCostDivisor;
|
||||||
sAPCost += usWeaponReadyTime / ubReadyTimeDivisor;
|
sAPCost += usWeaponReadyTime / ubReadyTimeDivisor;
|
||||||
}
|
}
|
||||||
@@ -1696,8 +1700,10 @@ INT16 MinAPsToAttack(SOLDIERTYPE *pSoldier, INT32 sGridno, UINT8 ubAddTurningCos
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
UINT16 undbarItem = pSoldier->GetUsedWeaponNumber( &(pSoldier->inv[ HANDPOS ]) );
|
||||||
|
|
||||||
// LOOK IN BUDDY'S HAND TO DETERMINE WHAT TO DO HERE
|
// 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 )
|
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 usRaiseGunCost = 0;
|
||||||
UINT16 usTurningCost = 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 )
|
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;
|
usItem = GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS] );//UNDER_GLAUNCHER;
|
||||||
|
usUBItem = usItem;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
usItem = pSoldier->inv[ HANDPOS ].usItem;
|
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 );
|
GetAPChargeForShootOrStabWRTGunRaises( pSoldier, sGridNo, ubAddTurningCost, &fAddingTurningCost, &fAddingRaiseGunCost );
|
||||||
|
|
||||||
@@ -2015,49 +2026,51 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTurni
|
|||||||
else
|
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
|
//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){
|
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, pObjUsed ) * (100 - GetBipodBonus(&(pSoldier->inv[HANDPOS]))) / 100);
|
||||||
bAPCost += BaseAPsToShootOrStab( bFullAPs, bAimSkill, &(pSoldier->inv[HANDPOS]) );
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bAPCost += BaseAPsToShootOrStab( bFullAPs, bAimSkill, pObjUsed );
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
// SANDRO - STOMP traits
|
// SANDRO - STOMP traits
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
if ( gGameOptions.fNewTraitSystem )
|
if ( gGameOptions.fNewTraitSystem )
|
||||||
{
|
{
|
||||||
// Decreased APs needed for LMG - Auto Weapons
|
// 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);
|
bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubAWFiringSpeedBonusLMGs ) / 100)+ 0.5);
|
||||||
}
|
}
|
||||||
// Decreased APs needed for melee attacks - Melee
|
// 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);
|
bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubMEBladesAPsReduction ) / 100)+ 0.5);
|
||||||
}
|
}
|
||||||
// Decreased APs needed for throwing knives - Throwing
|
// 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);
|
bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubTHBladesAPsReduction ) / 100)+ 0.5);
|
||||||
}
|
}
|
||||||
// Decreased APs needed for launchers - Heavy Eeapons
|
// 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);
|
bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubHWGrenadeLaunchersAPsReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ) ) / 100)+ 0.5);
|
||||||
}
|
}
|
||||||
// Decreased APs needed for launchers - Heavy Eeapons
|
// 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);
|
bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubHWRocketLaunchersAPsReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ) ) / 100)+ 0.5);
|
||||||
}
|
}
|
||||||
// Decreased APs needed for mortar - Heavy Eeapons
|
// 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);
|
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
|
// 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);
|
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;
|
fAddingRaiseGunCost = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Item[ usItem ].usItemClass == IC_THROWING_KNIFE )
|
if ( Item[ usUBItem ].usItemClass == IC_THROWING_KNIFE )
|
||||||
{
|
{
|
||||||
// Do we need to stand up?
|
// Do we need to stand up?
|
||||||
bAPCost += GetAPsToChangeStance( pSoldier, ANIM_STAND );
|
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)
|
// 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
|
// 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];
|
bAPCost += APBPConstants[AP_CHANGE_TARGET];
|
||||||
}
|
}
|
||||||
@@ -2134,7 +2147,7 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTurni
|
|||||||
if ( bAPCost < 1 )
|
if ( bAPCost < 1 )
|
||||||
bAPCost = 1;
|
bAPCost = 1;
|
||||||
|
|
||||||
if ( Item[pSoldier->inv[HANDPOS].usItem].rocketlauncher )
|
if ( Item[(*pObjUsed).usItem].rocketlauncher )
|
||||||
{
|
{
|
||||||
bAPCost += GetAPsToChangeStance( pSoldier, ANIM_STAND );
|
bAPCost += GetAPsToChangeStance( pSoldier, ANIM_STAND );
|
||||||
}
|
}
|
||||||
@@ -2347,33 +2360,36 @@ BOOLEAN EnoughAmmo( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay, INT8 bInvPos )
|
|||||||
}
|
}
|
||||||
else
|
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
|
// hack... they turn empty afterwards anyways
|
||||||
return( TRUE );
|
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 );
|
return( TRUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (Item[pSoldier->inv[bInvPos].usItem].usItemClass == IC_BOMB)
|
if (Item[usItemUsed].usItemClass == IC_BOMB)
|
||||||
{
|
{
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ATE: Did an else if here...
|
// ATE: Did an else if here...
|
||||||
if ( FindAttachmentByClass( &(pSoldier->inv[ bInvPos ]), IC_BOMB ) != 0 )
|
if ( FindAttachmentByClass( pObjUsed, IC_BOMB ) != 0 )
|
||||||
{
|
{
|
||||||
return( TRUE );
|
return( TRUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
// WANNE: If there is a tank, it always have ammo to shoot, no check!
|
// 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 );
|
return ( TRUE );
|
||||||
}
|
}
|
||||||
@@ -2385,9 +2401,9 @@ BOOLEAN EnoughAmmo( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay, INT8 bInvPos )
|
|||||||
|
|
||||||
return( FALSE );
|
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 )
|
if ( fDisplay )
|
||||||
{
|
{
|
||||||
@@ -2399,7 +2415,7 @@ BOOLEAN EnoughAmmo( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay, INT8 bInvPos )
|
|||||||
//<SB> manual recharge
|
//<SB> manual recharge
|
||||||
if( pSoldier->bTeam == OUR_TEAM )
|
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 );
|
return( FALSE );
|
||||||
}
|
}
|
||||||
@@ -2435,23 +2451,13 @@ 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 )
|
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...
|
(*pObjUsed)[0]->data.gun.ubGunShotsLeft--;
|
||||||
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?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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 )
|
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;;
|
INT16 bAPCost = 0, bAPCost2 = 0;;
|
||||||
|
|
||||||
CHECKF( pSoldier );
|
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
|
//<SB> manual recharge
|
||||||
if ((*pObj)[0]->data.gun.ubGunShotsLeft && !((*pObj)[0]->data.gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER) )
|
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( ) )
|
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;
|
bExcludeSlot = NO_SLOT;
|
||||||
bSlot2 = NO_SLOT;
|
bSlot2 = NO_SLOT;
|
||||||
|
|
||||||
|
|||||||
+179
-160
@@ -358,67 +358,77 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 430:
|
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
|
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: case 430");
|
||||||
AddGameEvent( S_FIREWEAPON, 0, &SFireWeapon );
|
// SHOOT GUN
|
||||||
|
// MAKE AN EVENT, BUT ONLY DO STUFF IF WE OWN THE GUY!
|
||||||
//hayden
|
SFireWeapon.usSoldierID = pSoldier->ubID;
|
||||||
if(is_server || (is_client && pSoldier->ubID <20) )
|
SFireWeapon.uiUniqueId = pSoldier->uiUniqueSoldierIdValue;
|
||||||
send_fireweapon( &SFireWeapon );
|
SFireWeapon.sTargetGridNo = pSoldier->sTargetGridNo;
|
||||||
}
|
SFireWeapon.bTargetLevel = pSoldier->bTargetLevel;
|
||||||
//DIGICRAB: Burst UnCap
|
SFireWeapon.bTargetCubeLevel= pSoldier->bTargetCubeLevel;
|
||||||
//Loop around in the animation if we still have burst rounds to fire
|
if((is_server && pSoldier->ubID<120) || (!is_server && is_client && pSoldier->ubID<20) || (!is_server && !is_client) )
|
||||||
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;
|
//only carry on if own werc
|
||||||
|
AddGameEvent( S_FIREWEAPON, 0, &SFireWeapon );
|
||||||
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(pSoldier->usAnimState == 44 || pSoldier->usAnimState == 109 || pSoldier->usAnimState == 108 && pSoldier->usAniCode == 33) //we are standing, crounching or prone, firing the fast shot
|
||||||
if ( noisefactor < 100 ) volume = (volume * noisefactor) / 100;
|
pSoldier->usAniCode = 3;
|
||||||
//randomize the rate a bit so that the sound is more believable
|
else if(pSoldier->usAnimState == 175 && pSoldier->usAniCode == 37) //we are firing down to something very close, last shot
|
||||||
PlayJA2Sample( Weapon[ pSoldier->usAttackingWeapon ].sSound, 44100-Random(5000)-Random(5000)-Random(5000), SoundVolume( volume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
|
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;
|
break;
|
||||||
|
|
||||||
case 431:
|
case 431:
|
||||||
@@ -764,133 +774,137 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
|
|||||||
|
|
||||||
|
|
||||||
case 448:
|
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");
|
// CODE: HANDLE BURST
|
||||||
fStop = TRUE;
|
// FIRST CHECK IF WE'VE REACHED MAX FOR GUN
|
||||||
fFreeUpAttacker = TRUE;
|
fStop = FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
// CHECK IF WE HAVE AMMO LEFT, IF NOT, END ANIMATION!
|
OBJECTTYPE* pObjHand = pSoldier->GetUsedWeapon( &pSoldier->inv[HANDPOS] );
|
||||||
if ( !EnoughAmmo( pSoldier, FALSE, pSoldier->ubAttackingHand ) )
|
|
||||||
{
|
if ( ( pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST && pSoldier->bDoBurst > Weapon[GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS])].ubShotsPerBurst)
|
||||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because not enough ammo");
|
|| (pSoldier->bWeaponMode != WM_ATTACHED_GL_BURST && pSoldier->bDoBurst > ((pSoldier->bDoAutofire)?(pSoldier->bDoAutofire):(GetShotsPerBurst( pObjHand )))) )
|
||||||
fStop = TRUE;
|
|
||||||
fFreeUpAttacker = TRUE;
|
|
||||||
if ( pSoldier->bTeam == gbPlayerNum )
|
|
||||||
{
|
{
|
||||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ BURST_FIRE_DEPLETED_CLIP_STR ] );
|
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because burst size too large");
|
||||||
}
|
|
||||||
}
|
|
||||||
// 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;
|
fStop = TRUE;
|
||||||
fFreeUpAttacker = 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 )
|
if ( pSoldier->bTeam == gbPlayerNum )
|
||||||
{
|
{
|
||||||
PlayJA2Sample( S_DRYFIRE1, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ BURST_FIRE_DEPLETED_CLIP_STR ] );
|
||||||
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Gun jammed!" );
|
}
|
||||||
|
}
|
||||||
|
// 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") );
|
pSoldier->flags.fDoSpread = FALSE;
|
||||||
FreeUpAttacker( );
|
pSoldier->bDoBurst = 1;
|
||||||
}
|
// pSoldier->flags.fBurstCompleted = TRUE;
|
||||||
else if ( bWeaponJammed == 255 )
|
if ( fFreeUpAttacker )
|
||||||
{
|
{
|
||||||
// Play intermediate animation...
|
// DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - aborting start of attack") );
|
||||||
if ( HandleUnjamAnimation( pSoldier ) )
|
// 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 );
|
return( TRUE );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( fStop )
|
// END: GOTO AIM STANCE BASED ON HEIGHT
|
||||||
{
|
// If we are a robot - we need to do stuff different here
|
||||||
if(pSoldier->bDoAutofire) //reset the autofire cursor after firing
|
// 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.
|
||||||
pSoldier->flags.autofireLastStep = FALSE;
|
if ( AM_A_ROBOT( pSoldier ) )
|
||||||
pSoldier->bDoAutofire = 1;
|
{
|
||||||
}
|
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;
|
case ANIM_PRONE:
|
||||||
pSoldier->bDoBurst = 1;
|
pSoldier->ChangeSoldierState( AIM_RIFLE_PRONE, 0 , FALSE );
|
||||||
// pSoldier->flags.fBurstCompleted = TRUE;
|
break;
|
||||||
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...
|
case ANIM_CROUCH:
|
||||||
// 0verhaul: No longer necessary or desired
|
pSoldier->ChangeSoldierState( AIM_RIFLE_CROUCH, 0 , FALSE );
|
||||||
// DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - Burst animation ended") );
|
break;
|
||||||
// ReduceAttackBusyCount( pSoldier->ubID, FALSE );
|
|
||||||
|
|
||||||
|
}
|
||||||
if ( CheckForImproperFireGunEnd( pSoldier ) )
|
}
|
||||||
{
|
|
||||||
return( TRUE );
|
return( TRUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
// END: GOTO AIM STANCE BASED ON HEIGHT
|
// MOVETO CURRENT SPREAD LOCATION
|
||||||
// If we are a robot - we need to do stuff different here
|
if ( pSoldier->flags.fDoSpread )
|
||||||
// 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 );
|
if ( pSoldier->sSpreadLocations[ pSoldier->flags.fDoSpread - 1 ] != 0 )
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight )
|
|
||||||
{
|
{
|
||||||
case ANIM_STAND:
|
pSoldier->EVENT_SetSoldierDirection( (INT8)GetDirectionToGridNoFromGridNo( pSoldier->sGridNo, pSoldier->sSpreadLocations[ pSoldier->flags.fDoSpread - 1 ] ) );
|
||||||
pSoldier->ChangeSoldierState( AIM_RIFLE_STAND, 0 , FALSE );
|
pSoldier->EVENT_SetSoldierDesiredDirection( pSoldier->ubDirection );
|
||||||
break;
|
|
||||||
|
|
||||||
case ANIM_PRONE:
|
|
||||||
pSoldier->ChangeSoldierState( AIM_RIFLE_PRONE, 0 , FALSE );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ANIM_CROUCH:
|
|
||||||
pSoldier->ChangeSoldierState( AIM_RIFLE_CROUCH, 0 , FALSE );
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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;
|
break;
|
||||||
|
|
||||||
@@ -2381,9 +2395,12 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
|
|||||||
|
|
||||||
usItem = pSoldier->inv[ HANDPOS ].usItem;
|
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 )
|
if ( usSoundID != 0 )
|
||||||
{
|
{
|
||||||
@@ -3977,8 +3994,10 @@ BOOLEAN CheckForImproperFireGunEnd( SOLDIERTYPE *pSoldier )
|
|||||||
return( FALSE );
|
return( FALSE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OBJECTTYPE* pObjHand = pSoldier->GetUsedWeapon( &pSoldier->inv[ HANDPOS ] );
|
||||||
|
|
||||||
// Check single hand for jammed status, ( or ammo is out.. )
|
// 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 we have 2 pistols, donot go back!
|
||||||
if ( Item[ pSoldier->inv[ SECONDHANDPOS ].usItem ].usItemClass != IC_GUN )
|
if ( Item[ pSoldier->inv[ SECONDHANDPOS ].usItem ].usItemClass != IC_GUN )
|
||||||
|
|||||||
@@ -12911,7 +12911,7 @@ void SOLDIERTYPE::SoldierInventoryCoolDown(void)
|
|||||||
attachmentList::iterator iterend = (*pObj)[i]->attachments.end();
|
attachmentList::iterator iterend = (*pObj)[i]->attachments.end();
|
||||||
for (attachmentList::iterator iter = (*pObj)[i]->attachments.begin(); iter != iterend; ++iter)
|
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 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 SOLDIERTYPE::IsWeaponMounted( void )
|
||||||
{
|
{
|
||||||
BOOLEAN applybipod = FALSE;
|
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
|
// not possible if already prone
|
||||||
if ( gAnimControl[ this->usAnimState ].ubEndHeight == ANIM_PRONE )
|
if ( gAnimControl[ this->usAnimState ].ubEndHeight == ANIM_PRONE )
|
||||||
return( FALSE );
|
return( FALSE );
|
||||||
@@ -13022,6 +13030,33 @@ BOOLEAN SOLDIERTYPE::IsWeaponMounted( void )
|
|||||||
return( applybipod );
|
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 )
|
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
|
||||||
{
|
{
|
||||||
INT8 bBandaged; //,savedOurTurn;
|
INT8 bBandaged; //,savedOurTurn;
|
||||||
|
|||||||
@@ -1319,7 +1319,9 @@ public:
|
|||||||
BOOLEAN IsValidSecondHandShotForReloadingPurposes( void );
|
BOOLEAN IsValidSecondHandShotForReloadingPurposes( void );
|
||||||
BOOLEAN SoldierCarriesTwoHandedWeapon( void );
|
BOOLEAN SoldierCarriesTwoHandedWeapon( void );
|
||||||
void SoldierInventoryCoolDown( void ); // Flugente FTW 1: Cool down all items in inventory
|
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;
|
}; // SOLDIERTYPE;
|
||||||
|
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ void HandleTacticalEndTurn( )
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Flugente FTW 1: Cool down all items not in a soldier's inventory
|
// 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 ) )
|
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
|
//magazine is not full
|
||||||
if ( (*pGun)[0]->data.gun.ubGunShotsLeft < GetMagSize( pGun ) )
|
if ( (*pGun)[0]->data.gun.ubGunShotsLeft < GetMagSize( pGun ) )
|
||||||
|
|||||||
@@ -2574,8 +2574,7 @@ UINT8 GetActionModeCursor( SOLDIERTYPE *pSoldier )
|
|||||||
return ( TRAJECTORYCURS );
|
return ( TRAJECTORYCURS );
|
||||||
}
|
}
|
||||||
|
|
||||||
usInHand = pSoldier->inv[HANDPOS].usItem;
|
usInHand = pSoldier->GetUsedWeaponNumber( &pSoldier->inv[HANDPOS] );
|
||||||
|
|
||||||
// Start off with what is in our hand
|
// Start off with what is in our hand
|
||||||
ubCursor = Item[ usInHand ].ubCursor;
|
ubCursor = Item[ usInHand ].ubCursor;
|
||||||
|
|
||||||
|
|||||||
+253
-222
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,9 @@ enum WeaponMode
|
|||||||
WM_ATTACHED_GL,
|
WM_ATTACHED_GL,
|
||||||
WM_ATTACHED_GL_BURST,
|
WM_ATTACHED_GL_BURST,
|
||||||
WM_ATTACHED_GL_AUTO,
|
WM_ATTACHED_GL_AUTO,
|
||||||
|
WM_ATTACHED_UB,
|
||||||
|
WM_ATTACHED_UB_BURST,
|
||||||
|
WM_ATTACHED_UB_AUTO,
|
||||||
NUM_WEAPON_MODES
|
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)
|
// 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 ...
|
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 ...
|
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 ...
|
FLOAT cooldownfactor = GetItemCooldownFactor(pObj); // ... get item cooldown factor provided of attachments ...
|
||||||
cooldownfactor *= gGameExternalOptions.iCooldownModificatorLonelyBarrel;
|
|
||||||
|
|
||||||
FLOAT newguntemperatre = max(0.0, guntemperature - cooldownfactor); // ... calculate new temperature ...
|
if ( Item[gWorldItems[ uiCount ].object.usItem].barrel == TRUE ) // ... a barrel lying around cools down a bit faster ...
|
||||||
(*pObj)[i]->data.bTemperature = newguntemperatre; // ... set new temperature
|
cooldownfactor *= gGameExternalOptions.iCooldownModificatorLonelyBarrel;
|
||||||
|
|
||||||
|
newguntemperature = max(0.0, guntemperature - cooldownfactor); // ... calculate new temperature ...
|
||||||
|
}
|
||||||
|
|
||||||
|
(*pObj)[i]->data.bTemperature = newguntemperature; // ... set new temperature
|
||||||
|
|
||||||
#if 0//def JA2TESTVERSION
|
#if 0//def JA2TESTVERSION
|
||||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"World: Item temperature lowered from %4.2f to %4.2f", guntemperature, newguntemperatre );
|
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();
|
attachmentList::iterator iterend = (*pObj)[i]->attachments.end();
|
||||||
for (attachmentList::iterator iter = (*pObj)[i]->attachments.begin(); iter != iterend; ++iter)
|
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
|
(*iter)[i]->data.bTemperature = newtemperature; // ... set new temperature
|
||||||
|
|
||||||
#if 0//def JA2TESTVERSION
|
#if 0//def JA2TESTVERSION
|
||||||
|
|||||||
@@ -119,6 +119,6 @@ extern void FindPanicBombsAndTriggers( void );
|
|||||||
extern INT32 FindWorldItemForBombInGridNo( INT32 sGridNo, INT8 bLevel);
|
extern INT32 FindWorldItemForBombInGridNo( INT32 sGridNo, INT8 bLevel);
|
||||||
|
|
||||||
void RefreshWorldItemsIntoItemPools( WORLDITEM * pItemList, INT32 iNumberOfItems );
|
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
|
#endif
|
||||||
@@ -2060,6 +2060,9 @@ enum
|
|||||||
MSG113_GL,
|
MSG113_GL,
|
||||||
MSG113_GL_BRST,
|
MSG113_GL_BRST,
|
||||||
MSG113_GL_AUTO,
|
MSG113_GL_AUTO,
|
||||||
|
MSG113_UB,
|
||||||
|
MSG113_UB_BRST,
|
||||||
|
MSG113_UB_AUTO,
|
||||||
MSG113_SNIPER,
|
MSG113_SNIPER,
|
||||||
MSG113_UNABLETOSPLITMONEY,
|
MSG113_UNABLETOSPLITMONEY,
|
||||||
MSG113_ARRIVINGREROUTED,
|
MSG113_ARRIVINGREROUTED,
|
||||||
|
|||||||
@@ -6051,6 +6051,9 @@ STR16 New113Message[] =
|
|||||||
L"榴弹",
|
L"榴弹",
|
||||||
L"榴弹点射",
|
L"榴弹点射",
|
||||||
L"榴弹自动",
|
L"榴弹自动",
|
||||||
|
L"UB", // TODO.Translate, INFO: UB = Under Barrel
|
||||||
|
L"UBRST",
|
||||||
|
L"UAUTO",
|
||||||
L"狙击手!",
|
L"狙击手!",
|
||||||
L"已经点选物品,此时无法分钱。",
|
L"已经点选物品,此时无法分钱。",
|
||||||
L"新兵的会合地被挪至 %s, 因降落地点 %s 目前由敌人占据。",
|
L"新兵的会合地被挪至 %s, 因降落地点 %s 目前由敌人占据。",
|
||||||
|
|||||||
@@ -6053,6 +6053,9 @@ STR16 New113Message[] =
|
|||||||
L"GL",
|
L"GL",
|
||||||
L"GL BRST",
|
L"GL BRST",
|
||||||
L"GL AUTO",
|
L"GL AUTO",
|
||||||
|
L"UB",
|
||||||
|
L"UBRST",
|
||||||
|
L"UAUTO",
|
||||||
L"Sniper!",
|
L"Sniper!",
|
||||||
L"Unable to split money due to having an item on your cursor.",
|
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.",
|
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",
|
||||||
L"GL BRST",
|
L"GL BRST",
|
||||||
L"GL AUTO",
|
L"GL AUTO",
|
||||||
|
L"UB",
|
||||||
|
L"UBRST",
|
||||||
|
L"UAUTO",
|
||||||
L"Sniper!",
|
L"Sniper!",
|
||||||
L"Unable to split money due to having an item on your cursor.",
|
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.",
|
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"LG",
|
||||||
L"RAF. LG",
|
L"RAF. LG",
|
||||||
L"LG AUTO",
|
L"LG AUTO",
|
||||||
|
L"UB", // TODO.Translate
|
||||||
|
L"UBRST",
|
||||||
|
L"UAUTO",
|
||||||
L"Tireur embusqué !",
|
L"Tireur embusqué !",
|
||||||
L"Unable to split money due to having an item on your cursor.",
|
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.",
|
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",
|
||||||
L"GL BRST",
|
L"GL BRST",
|
||||||
L"GL AUTO",
|
L"GL AUTO",
|
||||||
|
L"UB",
|
||||||
|
L"UBRST",
|
||||||
|
L"UAUTO",
|
||||||
L"Scharfschütze!",
|
L"Scharfschütze!",
|
||||||
L"Geld kann nicht aufgeteilt werden, weil ein Gegenstand am Cursor ist.",
|
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.",
|
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",
|
||||||
L"GL BRST",
|
L"GL BRST",
|
||||||
L"GL AUTO",
|
L"GL AUTO",
|
||||||
|
L"UB",
|
||||||
|
L"UBRST",
|
||||||
|
L"UAUTO",
|
||||||
L"Sniper!",
|
L"Sniper!",
|
||||||
L"Unable to split money due to having an item on your cursor.",
|
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.",
|
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",
|
||||||
L"GL BRST",
|
L"GL BRST",
|
||||||
L"GL AUTO",
|
L"GL AUTO",
|
||||||
|
L"UB", // TODO.Translate
|
||||||
|
L"UBRST",
|
||||||
|
L"UAUTO",
|
||||||
L"Snajper!",
|
L"Snajper!",
|
||||||
L"Nie można podzielić pieniędzy z powodu przedmiotu na kursorze.",
|
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.",
|
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"ГР *",
|
||||||
L"ГР ***",
|
L"ГР ***",
|
||||||
|
L"UB", // TODO.Translate
|
||||||
|
L"UBRST",
|
||||||
|
L"UAUTO",
|
||||||
L"Снайпер!",
|
L"Снайпер!",
|
||||||
L"Невозможно разделить деньги из-за предмета на курсоре.",
|
L"Невозможно разделить деньги из-за предмета на курсоре.",
|
||||||
L"Точка высадки новых наемников перенесена в %s, так как предыдущая точка высадки %s захвачена противником.",
|
L"Точка высадки новых наемников перенесена в %s, так как предыдущая точка высадки %s захвачена противником.",
|
||||||
|
|||||||
@@ -6055,6 +6055,9 @@ STR16 New113Message[] =
|
|||||||
L"GL",
|
L"GL",
|
||||||
L"GL BRST",
|
L"GL BRST",
|
||||||
L"GL AUTO",
|
L"GL AUTO",
|
||||||
|
L"UB",
|
||||||
|
L"UBRST",
|
||||||
|
L"UAUTO",
|
||||||
L"Sniper!",
|
L"Sniper!",
|
||||||
L"Unable to split money due to having an item on your cursor.",
|
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.",
|
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