mirror of
https://github.com/1dot13/source.git
synced 2026-07-29 13:52:17 +02:00
Vehicle Update: Roadkill with vehicles and ramming (by anv)
- new feature: ramming people - set with Tactical Gameplay Settings > ALLOW_CARS_DRIVING_OVER_PEOPLE and Tactical Gameplay Settings > ALLOW_TANKS_DRIVING_OVER_PEOPLE - when shift is pressed planned vehicle route will go through people. Those who will stay on its path will be hit, causing wounds and knock-outs. - new feature: ramming structures - when shift is pressed planned vehicle route will go through obstacles. When vehicle hits the structure on its path it will be destroyed, causing small damage to vehicle too (with exception of tank). Tactical Gameplay Settings > CARS_RAMMING_MAX_STRUCTURE_ARMOUR and Tactical Gameplay Settings > TANKS_RAMMING_MAX_STRUCTURE_ARMOUR settings control how well armoured structure can be driven through and amount of potential damage for vehicle. - see: http://www.ja-galaxy-forum.com/ubbthreads.php/topics/333829/Drivable_Vehicles#Post333829 git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7284 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+128
-9
@@ -41,6 +41,13 @@
|
||||
|
||||
#include "Tile Animation.h"
|
||||
#include "Explosion Control.h" // added by Flugente
|
||||
|
||||
// anv: for ramming people with vehicles
|
||||
#include "Soldier macros.h"
|
||||
#include "Overhead.h"
|
||||
#include "Soldier Functions.h"
|
||||
#include "Animation Control.h"
|
||||
#include "Soldier Ani.h"
|
||||
#endif
|
||||
|
||||
#ifdef COUNT_PATHS
|
||||
@@ -625,7 +632,7 @@ STRUCTURE * CreateStructureFromDB( DB_STRUCTURE_REF * pDBStructureRef, UINT8 ubT
|
||||
return( pStructure );
|
||||
}
|
||||
|
||||
BOOLEAN OkayToAddStructureToTile( INT32 sBaseGridNo, INT16 sCubeOffset, DB_STRUCTURE_REF * pDBStructureRef, UINT8 ubTileIndex, INT16 sExclusionID, BOOLEAN fIgnorePeople )
|
||||
BOOLEAN OkayToAddStructureToTile( INT32 sBaseGridNo, INT16 sCubeOffset, DB_STRUCTURE_REF * pDBStructureRef, UINT8 ubTileIndex, INT16 sExclusionID, BOOLEAN fAddingForReal = FALSE, INT16 sSoldierID = NOBODY )
|
||||
{
|
||||
// Verifies whether a structure is blocked from being added to the map at a particular point
|
||||
DB_STRUCTURE * pDBStructure;
|
||||
@@ -636,6 +643,18 @@ BOOLEAN OkayToAddStructureToTile( INT32 sBaseGridNo, INT16 sCubeOffset, DB_STRUC
|
||||
INT32 sGridNo;
|
||||
INT32 sOtherGridNo;
|
||||
|
||||
BOOLEAN fIgnorePeople = (BOOLEAN)(sExclusionID == IGNORE_PEOPLE_STRUCTURE_ID);
|
||||
|
||||
BOOLEAN fVehicleIgnoreObstacles = (BOOLEAN)(sExclusionID == VEHICLE_IGNORE_OBSTACLES_STRUCTURE_ID);
|
||||
if( gGameExternalOptions.ubCarsRammingMaxStructureArmour && sSoldierID != NOBODY && MercPtrs[ sSoldierID ]->usSoldierFlagMask2 & SOLDIER_RAM_THROUGH_OBSTACLES )
|
||||
{
|
||||
fVehicleIgnoreObstacles = TRUE;
|
||||
}
|
||||
else if( gGameExternalOptions.ubTanksRammingMaxStructureArmour && sSoldierID != NOBODY && TANK( MercPtrs[ sSoldierID ] ) )
|
||||
{
|
||||
fVehicleIgnoreObstacles = TRUE;
|
||||
}
|
||||
|
||||
ppTile = pDBStructureRef->ppTile;
|
||||
#if 0//dnl ch83 080114
|
||||
sGridNo = sBaseGridNo + ppTile[ubTileIndex]->sPosRelToBase;
|
||||
@@ -666,7 +685,7 @@ BOOLEAN OkayToAddStructureToTile( INT32 sBaseGridNo, INT16 sCubeOffset, DB_STRUC
|
||||
|
||||
while (pExistingStructure != NULL)
|
||||
{
|
||||
if (sCubeOffset == pExistingStructure->sCubeOffset)
|
||||
if (pExistingStructure != NULL && sCubeOffset == pExistingStructure->sCubeOffset)
|
||||
{
|
||||
|
||||
// CJC:
|
||||
@@ -708,6 +727,70 @@ BOOLEAN OkayToAddStructureToTile( INT32 sBaseGridNo, INT16 sCubeOffset, DB_STRUC
|
||||
}
|
||||
}
|
||||
|
||||
if ( fVehicleIgnoreObstacles && !(pExistingStructure->fFlags & STRUCTURE_PASSABLE) && !(ppTile[ubTileIndex]->fFlags & TILE_PASSABLE) )
|
||||
{
|
||||
// anv: drive through people
|
||||
if ( pExistingStructure->usStructureID < TOTAL_SOLDIERS )
|
||||
{
|
||||
SOLDIERTYPE *pSoldier = MercPtrs[ pExistingStructure->usStructureID ];
|
||||
// but not monsters and such (they can't fall down due to lack of animations)
|
||||
// also make sure AI won't flatten their allies
|
||||
if( !( pSoldier->flags.uiStatusFlags & ( SOLDIER_VEHICLE | SOLDIER_ROBOT | SOLDIER_MONSTER ) ) &&
|
||||
( ( !TANK(MercPtrs[ sSoldierID ]) && gGameExternalOptions.fAllowCarsDrivingOverPeople ) ||
|
||||
( TANK(MercPtrs[ sSoldierID ]) && gGameExternalOptions.fAllowTanksDrivingOverPeople ) ) &&
|
||||
( MercPtrs[ sSoldierID ]->bTeam == gbPlayerNum || MercPtrs[ sSoldierID ]->bTeam != pSoldier->bTeam ) )
|
||||
{
|
||||
pExistingStructure = pExistingStructure->pNext;
|
||||
// damage people when driving on them
|
||||
if( fAddingForReal && ( MercPtrs[ sSoldierID ]->flags.fPastXDest || MercPtrs[ sSoldierID ]->flags.fPastYDest ) )
|
||||
{
|
||||
if( TANK( MercPtrs[ sSoldierID ] ) )
|
||||
{
|
||||
pSoldier->EVENT_SoldierGotHit( 0, Random(10)+5, Random(200)+Random(200), MercPtrs[ sSoldierID ]->ubDirection, 0, sSoldierID, FIRE_WEAPON_VEHICLE_TRAUMA, 0, 0, pSoldier->sGridNo );
|
||||
}
|
||||
else if( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE && MercPtrs[ sSoldierID ]->flags.fUIMovementFast )
|
||||
{
|
||||
pSoldier->EVENT_SoldierGotHit( 0, Random(5), Random(100)+Random(100), MercPtrs[ sSoldierID ]->ubDirection, 0, sSoldierID, FIRE_WEAPON_VEHICLE_TRAUMA, 0, 0, pSoldier->sGridNo );
|
||||
}
|
||||
else
|
||||
{
|
||||
pSoldier->EVENT_SoldierGotHit( 0, Random(10)+5, Random(200)+Random(200), MercPtrs[ sSoldierID ]->ubDirection, 0, sSoldierID, FIRE_WEAPON_VEHICLE_TRAUMA, 0, 0, pSoldier->sGridNo );
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// skip if it's part of the same vehicle
|
||||
else if( pExistingStructure->usStructureID == sSoldierID )
|
||||
{
|
||||
pExistingStructure = pExistingStructure->pNext;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// anv: ram and destroy structures
|
||||
else
|
||||
{
|
||||
// only if structure is weak enough
|
||||
if( ( !TANK(MercPtrs[ sSoldierID ]) && gubMaterialArmour[ pExistingStructure->pDBStructureRef->pDBStructure->ubArmour ] < gGameExternalOptions.ubCarsRammingMaxStructureArmour ) ||
|
||||
( TANK(MercPtrs[ sSoldierID ]) && gubMaterialArmour[ pExistingStructure->pDBStructureRef->pDBStructure->ubArmour ] < gGameExternalOptions.ubTanksRammingMaxStructureArmour ) )
|
||||
{
|
||||
// when not just plotting path, really destroy structure
|
||||
if( fAddingForReal )
|
||||
{
|
||||
INT16 sXPos, sYPos = 0;
|
||||
ConvertGridNoToXY(pExistingStructure->sGridNo, &sXPos, &sYPos);
|
||||
DamageStructure( pExistingStructure, 255, STRUCTURE_DAMAGE_VEHICLE_TRAUMA, pExistingStructure->sGridNo, sXPos, sYPos, sSoldierID, 0 );
|
||||
return( TRUE );
|
||||
}
|
||||
// else just skip
|
||||
else
|
||||
{
|
||||
pExistingStructure = pExistingStructure->pNext;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// two obstacle structures aren't allowed in the same tile at the same height
|
||||
// ATE: There is more sophisticated logic for mobiles, so postpone this check if mobile....
|
||||
if ( ( pExistingStructure->fFlags & STRUCTURE_OBSTACLE ) && !( pDBStructure->fFlags & STRUCTURE_MOBILE ) )
|
||||
@@ -830,6 +913,18 @@ BOOLEAN OkayToAddStructureToTile( INT32 sBaseGridNo, INT16 sCubeOffset, DB_STRUC
|
||||
// ATE: Added check here - UNLESS the part we are trying to add is PASSABLE!
|
||||
if ( pExistingStructure->fFlags & STRUCTURE_MOBILE && !(pExistingStructure->fFlags & STRUCTURE_PASSABLE) && !(ppTile[ubTileIndex]->fFlags & TILE_PASSABLE) )
|
||||
{
|
||||
// anv: check if we try to add soldier hit by a vehicle under vehicle
|
||||
if( sSoldierID != NOBODY && pExistingStructure->usStructureID < TOTAL_SOLDIERS )
|
||||
{
|
||||
if( MercPtrs[ pExistingStructure->usStructureID ] != NULL && MercPtrs[ pExistingStructure->usStructureID ]->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||
{
|
||||
if( MercPtrs[ sSoldierID ]->flags.fInNonintAnim == TRUE || gAnimControl[ MercPtrs[ sSoldierID ]->usAnimState ].ubEndHeight == ANIM_PRONE )
|
||||
{
|
||||
pExistingStructure = pExistingStructure->pNext;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// don't allow 2 people in the same tile
|
||||
return( FALSE );
|
||||
}
|
||||
@@ -840,7 +935,7 @@ BOOLEAN OkayToAddStructureToTile( INT32 sBaseGridNo, INT16 sCubeOffset, DB_STRUC
|
||||
// Skip!
|
||||
pExistingStructure = pExistingStructure->pNext;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// ATE: Added here - UNLESS this part is PASSABLE....
|
||||
// two obstacle structures aren't allowed in the same tile at the same height
|
||||
@@ -868,7 +963,7 @@ BOOLEAN OkayToAddStructureToTile( INT32 sBaseGridNo, INT16 sCubeOffset, DB_STRUC
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
BOOLEAN InternalOkayToAddStructureToWorld( INT32 sBaseGridNo, INT8 bLevel, DB_STRUCTURE_REF * pDBStructureRef, INT16 sExclusionID, BOOLEAN fIgnorePeople )
|
||||
BOOLEAN InternalOkayToAddStructureToWorld( INT32 sBaseGridNo, INT8 bLevel, DB_STRUCTURE_REF * pDBStructureRef, INT16 sExclusionID, BOOLEAN fAddingForReal, INT16 sSoldierID )
|
||||
{
|
||||
UINT8 ubLoop;
|
||||
INT16 sCubeOffset;
|
||||
@@ -903,7 +998,7 @@ BOOLEAN InternalOkayToAddStructureToWorld( INT32 sBaseGridNo, INT8 bLevel, DB_ST
|
||||
{
|
||||
sCubeOffset = bLevel * PROFILE_Z_SIZE;
|
||||
}
|
||||
if (!OkayToAddStructureToTile( sBaseGridNo, sCubeOffset, pDBStructureRef, ubLoop, sExclusionID, fIgnorePeople ))
|
||||
if (!OkayToAddStructureToTile( sBaseGridNo, sCubeOffset, pDBStructureRef, ubLoop, sExclusionID, fAddingForReal, sSoldierID ))
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
@@ -911,9 +1006,9 @@ BOOLEAN InternalOkayToAddStructureToWorld( INT32 sBaseGridNo, INT8 bLevel, DB_ST
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
BOOLEAN OkayToAddStructureToWorld( INT32 sBaseGridNo, INT8 bLevel, DB_STRUCTURE_REF * pDBStructureRef, INT16 sExclusionID )
|
||||
BOOLEAN OkayToAddStructureToWorld( INT32 sBaseGridNo, INT8 bLevel, DB_STRUCTURE_REF * pDBStructureRef, INT16 sExclusionID, BOOLEAN fAddingForReal, INT16 sSoldierID )
|
||||
{
|
||||
return( InternalOkayToAddStructureToWorld( sBaseGridNo, bLevel, pDBStructureRef, sExclusionID, (BOOLEAN)(sExclusionID == IGNORE_PEOPLE_STRUCTURE_ID) ) );
|
||||
return( InternalOkayToAddStructureToWorld( sBaseGridNo, bLevel, pDBStructureRef, sExclusionID, fAddingForReal, sSoldierID ) );
|
||||
}
|
||||
|
||||
BOOLEAN AddStructureToTile( MAP_ELEMENT * pMapElement, STRUCTURE * pStructure, UINT16 usStructureID )
|
||||
@@ -968,7 +1063,14 @@ STRUCTURE * InternalAddStructureToWorld( INT32 sBaseGridNo, INT8 bLevel, DB_STRU
|
||||
CHECKF( pDBStructure->ubNumberOfTiles > 0 );
|
||||
|
||||
// first check to see if the structure will be blocked
|
||||
if (!OkayToAddStructureToWorld( sBaseGridNo, bLevel, pDBStructureRef, INVALID_STRUCTURE_ID ) )
|
||||
if ( ( pLevelNode->uiFlags & LEVELNODE_SOLDIER ) && pLevelNode->pSoldier )
|
||||
{
|
||||
if ( !OkayToAddStructureToWorld( sBaseGridNo, bLevel, pDBStructureRef, INVALID_STRUCTURE_ID, TRUE, pLevelNode->pSoldier->ubID ) )
|
||||
{
|
||||
return( NULL );
|
||||
}
|
||||
}
|
||||
else if ( !OkayToAddStructureToWorld( sBaseGridNo, bLevel, pDBStructureRef, INVALID_STRUCTURE_ID ) )
|
||||
{
|
||||
return( NULL );
|
||||
}
|
||||
@@ -1724,7 +1826,7 @@ BOOLEAN DamageStructure( STRUCTURE * pStructure, UINT8 ubDamage, UINT8 ubReason,
|
||||
}
|
||||
|
||||
// OK, Let's check our reason
|
||||
if ( ubReason == STRUCTURE_DAMAGE_GUNFIRE )
|
||||
if ( ubReason == STRUCTURE_DAMAGE_GUNFIRE || ubReason == STRUCTURE_DAMAGE_VEHICLE_TRAUMA )
|
||||
{
|
||||
// If here, we have penetrated, check flags
|
||||
// Are we an explodable structure?
|
||||
@@ -1783,6 +1885,23 @@ BOOLEAN DamageStructure( STRUCTURE * pStructure, UINT8 ubDamage, UINT8 ubReason,
|
||||
gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_STRUCTURE_DAMAGED;
|
||||
}
|
||||
|
||||
// anv: if we ram something with vehicle we have to destroy it, or else vehicle and structure will be drawn at the same tile
|
||||
// max armour will be set by Player in .ini and checked before DamageStructure is called
|
||||
if ( ubReason == STRUCTURE_DAMAGE_VEHICLE_TRAUMA )
|
||||
{
|
||||
BOOLEAN recompile = FALSE;
|
||||
ExplosiveDamageGridNo( sGridNo, 255, 10, &recompile, FALSE, -1, FALSE, ubOwner, 0 );
|
||||
|
||||
//Since the structure is being damaged, set the map element that a structure is damaged
|
||||
gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_STRUCTURE_DAMAGED;
|
||||
|
||||
// handle structure revenge - damage to vehicle
|
||||
if( ubOwner != NOBODY )
|
||||
{
|
||||
MercPtrs[ ubOwner ]->SoldierTakeDamage( 0, Random(max(0,(ubBaseArmour-10)/5))+max(0,(ubBaseArmour-10)/5), 0, 0, TAKE_DAMAGE_STRUCTURE_EXPLOSION, NOBODY, MercPtrs[ ubOwner ]->sGridNo, 0, TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
// Don't update damage HPs....
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
// 100 == MAX_CORPSES
|
||||
#define INVALID_STRUCTURE_ID ( TOTAL_SOLDIERS + 100 )
|
||||
#define IGNORE_PEOPLE_STRUCTURE_ID (TOTAL_SOLDIERS+101)
|
||||
#define VEHICLE_IGNORE_OBSTACLES_STRUCTURE_ID (TOTAL_SOLDIERS+102)
|
||||
|
||||
#define STRUCTURE_DAMAGE_EXPLOSION 1
|
||||
#define STRUCTURE_DAMAGE_GUNFIRE 2
|
||||
#define STRUCTURE_DAMAGE_VEHICLE_TRAUMA 3
|
||||
|
||||
|
||||
// functions at the structure database level
|
||||
@@ -35,7 +37,7 @@ BOOLEAN FreeStructureFile( STRUCTURE_FILE_REF * pStructureFile );
|
||||
//
|
||||
// functions at the structure instance level
|
||||
//
|
||||
BOOLEAN OkayToAddStructureToWorld( INT32 sBaseGridNo, INT8 bLevel, DB_STRUCTURE_REF * pDBStructureRef, INT16 sExclusionID );
|
||||
BOOLEAN OkayToAddStructureToWorld( INT32 sBaseGridNo, INT8 bLevel, DB_STRUCTURE_REF * pDBStructureRef, INT16 sExclusionID, BOOLEAN fAddingForReal = FALSE, INT16 sSoldierID = NOBODY );
|
||||
|
||||
// for the PTR argument of AddStructureToWorld, pass in a LEVELNODE * please!
|
||||
BOOLEAN AddStructureToWorld( INT32 sBaseGridNo, INT8 bLevel, DB_STRUCTURE_REF * pDBStructureRef, PTR pLevelN );
|
||||
|
||||
@@ -428,6 +428,9 @@ BOOLEAN RemoveAllObjectsOfTypeRange( INT32 iMapIndex, UINT32 fStartType, UINT32
|
||||
UINT32 fTileType;
|
||||
BOOLEAN fRetVal = FALSE;
|
||||
|
||||
if( iMapIndex < 0 )
|
||||
return fRetVal;
|
||||
|
||||
pObject = gpWorldLevelData[ iMapIndex ].pObjectHead;
|
||||
|
||||
// Look through all objects and Search for type
|
||||
@@ -2996,6 +2999,9 @@ BOOLEAN RemoveAllOnRoofsOfTypeRange( INT32 iMapIndex, UINT32 fStartType, UINT32
|
||||
UINT32 fTileType;
|
||||
BOOLEAN fRetVal = FALSE;
|
||||
|
||||
if( iMapIndex < 0 )
|
||||
return fRetVal;
|
||||
|
||||
pOnRoof = gpWorldLevelData[ iMapIndex ].pOnRoofHead;
|
||||
|
||||
// Look through all OnRoofs and Search for type
|
||||
|
||||
Reference in New Issue
Block a user