Fixed appearance of save game corruption when a game with different inventory set is loaded. Note that such games can still cause odd behavior and CTD's

Fixed old-style behavior when creating a soldier struct (caused memory corruption and leaks)
Fixed soldiers unable to fire if an error happened while firing the off-hand weapon
Fix animation system problems with soldiers interrupted while changing stance, such as twitching and not being able to navigate around obstacles
Prevent splitting money while an item is in the hand, which would result in losing the original item
Fix reverse of X,Y when checking visibility through a roof, which could make soldiers falsely visible/invisible
Prevent militia from simply waiting on the border when enemies are known to be in the sector
Fix stack overflow for soldier inventory debug display
Optimized A* pathing and cleaned up VS2K5 specific code
AI can now use all climb points for climbable buildings, not just a random few
Fix to not allow flat roof butted against slanted roof to be identified as a climb point
Prevent soldiers who cause an interrupt from a special action from continuing on their path after being interrupted
Prevent soldiers who enter or leave deep water from moving a space too far and turning back
Prevent soldiers from trying to crouch while in shallow water
Make soldier turn in the closest direction when he must get up from prone and turn then fall back to prone
Allow a soldier to swat for a tile before returning to prone if unable to return to prone immediately after a turn
Fix civilians that should show up in a sector, missing because of others that aren't
Fix a memset on a C++ class
Place Skyrider in a sector near his helecopter once available and the helicopter is present
Fix soldier corruption if too many shots burst-spread into too few tiles
Include both first and last tile in spread when some locations must be skipped
Fix to shoot at last location in burst
Fix to remove other previous spread locations when calculating a new spread
Fix to reload or rechamber off-hand when necessary, such as having a pistol shotgun in that hand


git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@1532 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Overhaul
2007-10-20 08:09:03 +00:00
parent eeb82168b5
commit dd0d6ea66d
35 changed files with 1322 additions and 863 deletions
+12
View File
@@ -2663,6 +2663,8 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ FATCIV ][ GENERIC_HIT_DEATHTWITCHNB ] = FATMANDIE; gubAnimSurfaceIndex[ FATCIV ][ GENERIC_HIT_DEATHTWITCHNB ] = FATMANDIE;
gubAnimSurfaceIndex[ FATCIV ][ GENERIC_HIT_DEATHTWITCHB ] = FATMANDIE; gubAnimSurfaceIndex[ FATCIV ][ GENERIC_HIT_DEATHTWITCHB ] = FATMANDIE;
gubAnimSurfaceIndex[ FATCIV ][ FALLFORWARD_FROMHIT_STAND ] = FATMANDIE; gubAnimSurfaceIndex[ FATCIV ][ FALLFORWARD_FROMHIT_STAND ] = FATMANDIE;
gubAnimSurfaceIndex[ FATCIV ][ FALLFORWARD_FROMHIT_CROUCH ] = FATMANDIE;
gubAnimSurfaceIndex[ FATCIV ][ ENDFALLFORWARD_FROMHIT_CROUCH ] = FATMANDIE;
gubAnimSurfaceIndex[ FATCIV ][ FALLFORWARD_HITDEATH_STOP ] = FATMANDIE; gubAnimSurfaceIndex[ FATCIV ][ FALLFORWARD_HITDEATH_STOP ] = FATMANDIE;
gubAnimSurfaceIndex[ FATCIV ][ STAND_FALLFORWARD_STOP ] = FATMANDIE; gubAnimSurfaceIndex[ FATCIV ][ STAND_FALLFORWARD_STOP ] = FATMANDIE;
gubAnimSurfaceIndex[ FATCIV ][ GENERIC_HIT_DEATH ] = FATMANDIE; gubAnimSurfaceIndex[ FATCIV ][ GENERIC_HIT_DEATH ] = FATMANDIE;
@@ -2699,6 +2701,8 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ MANCIV ][ GENERIC_HIT_DEATHTWITCHNB ] = MANCIVDIE; gubAnimSurfaceIndex[ MANCIV ][ GENERIC_HIT_DEATHTWITCHNB ] = MANCIVDIE;
gubAnimSurfaceIndex[ MANCIV ][ GENERIC_HIT_DEATHTWITCHB ] = MANCIVDIE; gubAnimSurfaceIndex[ MANCIV ][ GENERIC_HIT_DEATHTWITCHB ] = MANCIVDIE;
gubAnimSurfaceIndex[ MANCIV ][ FALLFORWARD_FROMHIT_STAND ] = MANCIVDIE; gubAnimSurfaceIndex[ MANCIV ][ FALLFORWARD_FROMHIT_STAND ] = MANCIVDIE;
gubAnimSurfaceIndex[ MANCIV ][ FALLFORWARD_FROMHIT_CROUCH ] = MANCIVDIE;
gubAnimSurfaceIndex[ MANCIV ][ ENDFALLFORWARD_FROMHIT_CROUCH ] = MANCIVDIE;
gubAnimSurfaceIndex[ MANCIV ][ FALLFORWARD_HITDEATH_STOP ] = MANCIVDIE; gubAnimSurfaceIndex[ MANCIV ][ FALLFORWARD_HITDEATH_STOP ] = MANCIVDIE;
gubAnimSurfaceIndex[ MANCIV ][ STAND_FALLFORWARD_STOP ] = MANCIVDIE; gubAnimSurfaceIndex[ MANCIV ][ STAND_FALLFORWARD_STOP ] = MANCIVDIE;
gubAnimSurfaceIndex[ MANCIV ][ GENERIC_HIT_DEATH ] = MANCIVDIE; gubAnimSurfaceIndex[ MANCIV ][ GENERIC_HIT_DEATH ] = MANCIVDIE;
@@ -2734,6 +2738,8 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ MINICIV ][ GENERIC_HIT_DEATHTWITCHNB ] = MINICIVDIE; gubAnimSurfaceIndex[ MINICIV ][ GENERIC_HIT_DEATHTWITCHNB ] = MINICIVDIE;
gubAnimSurfaceIndex[ MINICIV ][ GENERIC_HIT_DEATHTWITCHB ] = MINICIVDIE; gubAnimSurfaceIndex[ MINICIV ][ GENERIC_HIT_DEATHTWITCHB ] = MINICIVDIE;
gubAnimSurfaceIndex[ MINICIV ][ FALLFORWARD_FROMHIT_STAND ] = MINICIVDIE; gubAnimSurfaceIndex[ MINICIV ][ FALLFORWARD_FROMHIT_STAND ] = MINICIVDIE;
gubAnimSurfaceIndex[ MINICIV ][ FALLFORWARD_FROMHIT_CROUCH ] = MINICIVDIE;
gubAnimSurfaceIndex[ MINICIV ][ ENDFALLFORWARD_FROMHIT_CROUCH ] = MINICIVDIE;
gubAnimSurfaceIndex[ MINICIV ][ FALLFORWARD_HITDEATH_STOP ] = MINICIVDIE; gubAnimSurfaceIndex[ MINICIV ][ FALLFORWARD_HITDEATH_STOP ] = MINICIVDIE;
gubAnimSurfaceIndex[ MINICIV ][ STAND_FALLFORWARD_STOP ] = MINICIVDIE; gubAnimSurfaceIndex[ MINICIV ][ STAND_FALLFORWARD_STOP ] = MINICIVDIE;
gubAnimSurfaceIndex[ MINICIV ][ GENERIC_HIT_DEATH ] = MINICIVDIE; gubAnimSurfaceIndex[ MINICIV ][ GENERIC_HIT_DEATH ] = MINICIVDIE;
@@ -2771,6 +2777,8 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ DRESSCIV ][ GENERIC_HIT_DEATHTWITCHNB ] = DRESSCIVDIE; gubAnimSurfaceIndex[ DRESSCIV ][ GENERIC_HIT_DEATHTWITCHNB ] = DRESSCIVDIE;
gubAnimSurfaceIndex[ DRESSCIV ][ GENERIC_HIT_DEATHTWITCHB ] = DRESSCIVDIE; gubAnimSurfaceIndex[ DRESSCIV ][ GENERIC_HIT_DEATHTWITCHB ] = DRESSCIVDIE;
gubAnimSurfaceIndex[ DRESSCIV ][ FALLFORWARD_FROMHIT_STAND ] = DRESSCIVDIE; gubAnimSurfaceIndex[ DRESSCIV ][ FALLFORWARD_FROMHIT_STAND ] = DRESSCIVDIE;
gubAnimSurfaceIndex[ DRESSCIV ][ FALLFORWARD_FROMHIT_CROUCH ] = DRESSCIVDIE;
gubAnimSurfaceIndex[ DRESSCIV ][ ENDFALLFORWARD_FROMHIT_CROUCH ] = DRESSCIVDIE;
gubAnimSurfaceIndex[ DRESSCIV ][ FALLFORWARD_HITDEATH_STOP ] = DRESSCIVDIE; gubAnimSurfaceIndex[ DRESSCIV ][ FALLFORWARD_HITDEATH_STOP ] = DRESSCIVDIE;
gubAnimSurfaceIndex[ DRESSCIV ][ STAND_FALLFORWARD_STOP ] = DRESSCIVDIE; gubAnimSurfaceIndex[ DRESSCIV ][ STAND_FALLFORWARD_STOP ] = DRESSCIVDIE;
gubAnimSurfaceIndex[ DRESSCIV ][ GENERIC_HIT_DEATH ] = DRESSCIVDIE; gubAnimSurfaceIndex[ DRESSCIV ][ GENERIC_HIT_DEATH ] = DRESSCIVDIE;
@@ -2798,6 +2806,8 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ HATKIDCIV ][ GENERIC_HIT_DEATHTWITCHNB ] = HATKIDCIVDIE; gubAnimSurfaceIndex[ HATKIDCIV ][ GENERIC_HIT_DEATHTWITCHNB ] = HATKIDCIVDIE;
gubAnimSurfaceIndex[ HATKIDCIV ][ GENERIC_HIT_DEATHTWITCHB ] = HATKIDCIVDIE; gubAnimSurfaceIndex[ HATKIDCIV ][ GENERIC_HIT_DEATHTWITCHB ] = HATKIDCIVDIE;
gubAnimSurfaceIndex[ HATKIDCIV ][ FALLFORWARD_FROMHIT_STAND ] = HATKIDCIVDIE; gubAnimSurfaceIndex[ HATKIDCIV ][ FALLFORWARD_FROMHIT_STAND ] = HATKIDCIVDIE;
gubAnimSurfaceIndex[ HATKIDCIV ][ FALLFORWARD_FROMHIT_CROUCH ] = HATKIDCIVDIE;
gubAnimSurfaceIndex[ HATKIDCIV ][ ENDFALLFORWARD_FROMHIT_CROUCH ] = HATKIDCIVDIE;
gubAnimSurfaceIndex[ HATKIDCIV ][ FALLFORWARD_HITDEATH_STOP ] = HATKIDCIVDIE; gubAnimSurfaceIndex[ HATKIDCIV ][ FALLFORWARD_HITDEATH_STOP ] = HATKIDCIVDIE;
gubAnimSurfaceIndex[ HATKIDCIV ][ STAND_FALLFORWARD_STOP ] = HATKIDCIVDIE; gubAnimSurfaceIndex[ HATKIDCIV ][ STAND_FALLFORWARD_STOP ] = HATKIDCIVDIE;
gubAnimSurfaceIndex[ HATKIDCIV ][ GENERIC_HIT_DEATH ] = HATKIDCIVDIE; gubAnimSurfaceIndex[ HATKIDCIV ][ GENERIC_HIT_DEATH ] = HATKIDCIVDIE;
@@ -2839,6 +2849,8 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ KIDCIV ][ GENERIC_HIT_DEATHTWITCHNB ] = KIDCIVDIE; gubAnimSurfaceIndex[ KIDCIV ][ GENERIC_HIT_DEATHTWITCHNB ] = KIDCIVDIE;
gubAnimSurfaceIndex[ KIDCIV ][ GENERIC_HIT_DEATHTWITCHB ] = KIDCIVDIE; gubAnimSurfaceIndex[ KIDCIV ][ GENERIC_HIT_DEATHTWITCHB ] = KIDCIVDIE;
gubAnimSurfaceIndex[ KIDCIV ][ FALLFORWARD_FROMHIT_STAND ] = KIDCIVDIE; gubAnimSurfaceIndex[ KIDCIV ][ FALLFORWARD_FROMHIT_STAND ] = KIDCIVDIE;
gubAnimSurfaceIndex[ KIDCIV ][ FALLFORWARD_FROMHIT_CROUCH ] = KIDCIVDIE;
gubAnimSurfaceIndex[ KIDCIV ][ ENDFALLFORWARD_FROMHIT_CROUCH ] = KIDCIVDIE;
gubAnimSurfaceIndex[ KIDCIV ][ FALLFORWARD_HITDEATH_STOP ] = KIDCIVDIE; gubAnimSurfaceIndex[ KIDCIV ][ FALLFORWARD_HITDEATH_STOP ] = KIDCIVDIE;
gubAnimSurfaceIndex[ KIDCIV ][ STAND_FALLFORWARD_STOP ] = KIDCIVDIE; gubAnimSurfaceIndex[ KIDCIV ][ STAND_FALLFORWARD_STOP ] = KIDCIVDIE;
gubAnimSurfaceIndex[ KIDCIV ][ GENERIC_HIT_DEATH ] = KIDCIVDIE; gubAnimSurfaceIndex[ KIDCIV ][ GENERIC_HIT_DEATH ] = KIDCIVDIE;
+3 -3
View File
@@ -778,7 +778,7 @@ BOOLEAN DeInitAnimationSystem( )
STRUCTURE_FILE_REF *InternalGetAnimationStructureRef( UINT16 usSoldierID, UINT16 usSurfaceIndex, UINT16 usAnimState, BOOLEAN fUseAbsolute ) STRUCTURE_FILE_REF *InternalGetAnimationStructureRef( UINT8 usSoldierID, UINT16 usSurfaceIndex, UINT16 usAnimState, BOOLEAN fUseAbsolute )
{ {
INT8 bStructDataType; INT8 bStructDataType;
@@ -807,13 +807,13 @@ STRUCTURE_FILE_REF *InternalGetAnimationStructureRef( UINT16 usSoldierID, UINT16
} }
STRUCTURE_FILE_REF *GetAnimationStructureRef( UINT16 usSoldierID, UINT16 usSurfaceIndex, UINT16 usAnimState ) STRUCTURE_FILE_REF *GetAnimationStructureRef( UINT8 usSoldierID, UINT16 usSurfaceIndex, UINT16 usAnimState )
{ {
return( InternalGetAnimationStructureRef( usSoldierID, usSurfaceIndex, usAnimState, FALSE ) ); return( InternalGetAnimationStructureRef( usSoldierID, usSurfaceIndex, usAnimState, FALSE ) );
} }
STRUCTURE_FILE_REF *GetDefaultStructureRef( UINT16 usSoldierID ) STRUCTURE_FILE_REF *GetDefaultStructureRef( UINT8 usSoldierID )
{ {
return( gAnimStructureDatabase[ MercPtrs[ usSoldierID ]->ubBodyType ][ DEFAULT_STRUCT ].pStructureFileRef ); return( gAnimStructureDatabase[ MercPtrs[ usSoldierID ]->ubBodyType ][ DEFAULT_STRUCT ].pStructureFileRef );
} }
+2 -2
View File
@@ -565,8 +565,8 @@ void ClearAnimationSurfacesUsageHistory( UINT16 usSoldierID );
void DeleteAnimationProfiles( ); void DeleteAnimationProfiles( );
BOOLEAN LoadAnimationProfiles( ); BOOLEAN LoadAnimationProfiles( );
STRUCTURE_FILE_REF *GetAnimationStructureRef( UINT16 usSoldierID, UINT16 usSurfaceIndex, UINT16 usAnimState ); STRUCTURE_FILE_REF *GetAnimationStructureRef( UINT8 usSoldierID, UINT16 usSurfaceIndex, UINT16 usAnimState );
STRUCTURE_FILE_REF *GetDefaultStructureRef( UINT16 usSoldierID ); STRUCTURE_FILE_REF *GetDefaultStructureRef( UINT8 usSoldierID );
// Profile data // Profile data
extern ANIM_PROF *gpAnimProfiles; extern ANIM_PROF *gpAnimProfiles;
+4 -4
View File
@@ -198,8 +198,8 @@ void ShutDownArmsDealers()
//loop through all the item types //loop through all the item types
for( usItemIndex = 1; usItemIndex < MAXITEMS; usItemIndex++ ) for( usItemIndex = 1; usItemIndex < MAXITEMS; usItemIndex++ )
{ {
if ( Item[usItemIndex].usItemClass == 0 ) //if ( Item[usItemIndex].usItemClass == 0 )
break; // break;
if( gArmsDealersInventory[ ubArmsDealer ][ usItemIndex ].ubElementsAlloced > 0 ) if( gArmsDealersInventory[ ubArmsDealer ][ usItemIndex ].ubElementsAlloced > 0 )
{ {
FreeSpecialItemArray( &gArmsDealersInventory[ ubArmsDealer ][ usItemIndex ] ); FreeSpecialItemArray( &gArmsDealersInventory[ ubArmsDealer ][ usItemIndex ] );
@@ -294,8 +294,8 @@ BOOLEAN LoadArmsDealerInventoryFromSavedGameFile( HWFILE hFile, BOOLEAN fInclude
//loop through this dealer's individual items //loop through this dealer's individual items
for(usItemIndex = 1; usItemIndex < MAXITEMS; usItemIndex++ ) for(usItemIndex = 1; usItemIndex < MAXITEMS; usItemIndex++ )
{ {
if ( Item[usItemIndex].usItemClass == 0 ) //if ( Item[usItemIndex].usItemClass == 0 )
break; // break;
//if there are any elements allocated for this item, load them //if there are any elements allocated for this item, load them
if( gArmsDealersInventory[ubArmsDealer][usItemIndex].ubElementsAlloced > 0 ) if( gArmsDealersInventory[ubArmsDealer][usItemIndex].ubElementsAlloced > 0 )
{ {
+2 -2
View File
@@ -463,10 +463,10 @@ void AutoBandage( BOOLEAN fStart )
if ( pSoldier->bSlotItemTakenFrom != NO_SLOT ) if ( pSoldier->bSlotItemTakenFrom != NO_SLOT )
{ {
// swap our old hand item back to the main hand // swap our old hand item back to the main hand
SwapObjs( &( pSoldier->inv[ HANDPOS ] ), &( pSoldier->inv[ pSoldier->bSlotItemTakenFrom ] ) ); SwapObjs( pSoldier, HANDPOS, pSoldier->bSlotItemTakenFrom );
} }
// ATE: Mkae everyone stand up! // ATE: Make everyone stand up!
if ( pSoldier->bLife >= OKLIFE && !pSoldier->bCollapsed ) if ( pSoldier->bLife >= OKLIFE && !pSoldier->bCollapsed )
{ {
if ( gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_STAND ) if ( gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_STAND )
+11 -19
View File
@@ -14,8 +14,7 @@ public:
HEAP<KEY, T>(T data, int key) {HEAP::data = data; HEAP::key = key; return;}; HEAP<KEY, T>(T data, int key) {HEAP::data = data; HEAP::key = key; return;};
bool operator==(HEAP<KEY, T> &compare) { bool operator==(HEAP<KEY, T> &compare) {
if (this->key == compare.key && this->data == compare.data) return true; return (this->key == compare.key && this->data == compare.data);
else return false;
} }
}; };
@@ -54,13 +53,15 @@ private:
public: public:
typedef HEAP<KEY, T> CBinaryHeap_t;
void clear () void clear ()
{ {
heapCount = 1; heapCount = 1;
return; return;
} }
CBinaryHeap(int size) CBinaryHeap(int size=WORLD_MAX)
{ {
if (size <= 0) { if (size <= 0) {
size = WORLD_MAX; size = WORLD_MAX;
@@ -72,21 +73,12 @@ public:
return; return;
} }
CBinaryHeap()
{
//size must be maxSize + 1, because 1 element is unused.
BinaryHeap = new HEAP<KEY, T>[WORLD_MAX+1];
maxSize = WORLD_MAX;
heapCount = 1;
return;
}
~CBinaryHeap() ~CBinaryHeap()
{ {
delete BinaryHeap; delete BinaryHeap;
} }
HEAP<KEY, T> removeElement(const T data) CBinaryHeap_t removeElement(const T data)
{ {
HEAP<KEY, T> returnHeap; HEAP<KEY, T> returnHeap;
int index = findData(data); int index = findData(data);
@@ -98,7 +90,7 @@ public:
return (returnHeap); return (returnHeap);
} }
HEAP<KEY, T> removeElement(const T data, const KEY key) CBinaryHeap_t removeElement(const T data, const KEY key)
{ {
HEAP<KEY, T> returnHeap; HEAP<KEY, T> returnHeap;
int index = findData(data, key); int index = findData(data, key);
@@ -250,7 +242,7 @@ insert:
}*/ }*/
} }
HEAP<KEY, T> popTopHeap(int& returnSize) CBinaryHeap_t popTopHeap(int& returnSize)
{ {
returnSize = heapCount-1; returnSize = heapCount-1;
if (heapCount != 1) { if (heapCount != 1) {
@@ -259,7 +251,7 @@ insert:
return (BinaryHeap[0]); return (BinaryHeap[0]);
} }
HEAP<KEY, T> popTopHeap() CBinaryHeap_t popTopHeap()
{ {
HEAP<KEY, T> returnHeap; HEAP<KEY, T> returnHeap;
if (heapCount != 1) { if (heapCount != 1) {
@@ -295,12 +287,12 @@ insert:
return (returnHeap); return (returnHeap);
} }
HEAP<KEY, T> peekTopHeap() const CBinaryHeap_t peekTopHeap() const
{ {
return (BinaryHeap[(heapCount != 1)]); return (BinaryHeap[(heapCount != 1)]);
} }
HEAP<KEY, T> peekElement(int index) const CBinaryHeap_t peekElement(int index) const
{ {
if (index < heapCount) { if (index < heapCount) {
return (BinaryHeap[index]); return (BinaryHeap[index]);
@@ -352,7 +344,7 @@ insert:
private: private:
int heapCount; int heapCount;
int maxSize; int maxSize;
HEAP<KEY, T>* BinaryHeap; CBinaryHeap_t* BinaryHeap;
}; };
#endif #endif
+2 -2
View File
@@ -1369,7 +1369,7 @@ BOOLEAN NewWayOfLoadingCiviliansFromTempFile()
if( !curr->pDetailedPlacement ) if( !curr->pDetailedPlacement )
{ {
//need to upgrade the placement to detailed placement //need to upgrade the placement to detailed placement
curr->pDetailedPlacement = new (MemAlloc( SIZEOF_SOLDIERCREATE_STRUCT )) SOLDIERCREATE_STRUCT; curr->pDetailedPlacement = new SOLDIERCREATE_STRUCT;
} }
//now replace the map pristine placement info with the temp map file version.. //now replace the map pristine placement info with the temp map file version..
//memcpy( curr->pDetailedPlacement, &tempDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT ); //memcpy( curr->pDetailedPlacement, &tempDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT );
@@ -1558,7 +1558,7 @@ BOOLEAN NewWayOfSavingEnemyAndCivliansToTempFile( INT16 sSectorX, INT16 sSectorY
//STEP ONE: Prep the soldiers for saving... //STEP ONE: Prep the soldiers for saving...
//modify the map's soldier init list to reflect the changes to the member's still alive... //modify the map's soldier init list to reflect the changes to the members still alive...
for( i = gTacticalStatus.Team[ ubStartID ].bFirstID; i <= gTacticalStatus.Team[ ubEndID ].bLastID; i++ ) for( i = gTacticalStatus.Team[ ubStartID ].bFirstID; i <= gTacticalStatus.Team[ ubEndID ].bLastID; i++ )
{ {
pSoldier = MercPtrs[ i ]; pSoldier = MercPtrs[ i ];
+8 -1
View File
@@ -284,6 +284,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bLevel, UINT16 usHa
// Check HAND ITEM // Check HAND ITEM
if ( Item[ usHandItem ].usItemClass == IC_GUN || Item[ usHandItem ].usItemClass == IC_THROWING_KNIFE ) if ( Item[ usHandItem ].usItemClass == IC_GUN || Item[ usHandItem ].usItemClass == IC_THROWING_KNIFE )
{ {
// WEAPONS // WEAPONS
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("HandleItem: checking for fingerprintID, item id = %d,id required = %d, imprint id = %d, soldier id = %d",usHandItem,Item[usHandItem].fingerprintid,pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID,pSoldier->ubProfile)); DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("HandleItem: checking for fingerprintID, item id = %d,id required = %d, imprint id = %d, soldier id = %d",usHandItem,Item[usHandItem].fingerprintid,pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID,pSoldier->ubProfile));
if ( Item[usHandItem].fingerprintid ) if ( Item[usHandItem].fingerprintid )
@@ -545,6 +546,8 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bLevel, UINT16 usHa
if ( Item[ usHandItem ].usItemClass != IC_THROWING_KNIFE ) if ( Item[ usHandItem ].usItemClass != IC_THROWING_KNIFE )
{ {
pSoldier->ubAttackingHand = HANDPOS;
pSoldier->usAttackingWeapon = usHandItem;
// If doing spread, set down the first gridno..... // If doing spread, set down the first gridno.....
if ( pSoldier->fDoSpread ) if ( pSoldier->fDoSpread )
{ {
@@ -2144,7 +2147,11 @@ OBJECTTYPE* InternalAddItemToPool( INT16 *psGridNo, OBJECTTYPE *pObject, INT8 bV
(*psGridNo) = sNewGridNo = gMapInformation.sCenterGridNo; (*psGridNo) = sNewGridNo = gMapInformation.sCenterGridNo;
//return( NULL ); // If no center grid number exists, shrug it off
if (sNewGridNo == -1)
{
return( NULL );
}
} }
// CHECK IF THIS ITEM IS IN DEEP WATER.... // CHECK IF THIS ITEM IS IN DEEP WATER....
+2 -2
View File
@@ -102,7 +102,7 @@ BOOLEAN AddUIPlan( UINT16 sGridNo, UINT8 ubPlanID )
ConvertGridNoToCenterCellXY( sGridNo, &sXPos, &sYPos ); ConvertGridNoToCenterCellXY( sGridNo, &sXPos, &sYPos );
EVENT_SetSoldierPosition( pPlanSoldier, sXPos, sYPos ); EVENT_SetSoldierPosition( pPlanSoldier, sXPos, sYPos );
EVENT_SetSoldierDestination( pPlanSoldier, sGridNo ); EVENT_SetSoldierDestination( pPlanSoldier, (UINT8) sGridNo ); // Hopefully this code is never used anymore because the second param is now direction, not grid
pPlanSoldier->bVisible = 1; pPlanSoldier->bVisible = 1;
pPlanSoldier->usUIMovementMode = gpUIPlannedSoldier->usUIMovementMode; pPlanSoldier->usUIMovementMode = gpUIPlannedSoldier->usUIMovementMode;
@@ -181,7 +181,7 @@ BOOLEAN AddUIPlan( UINT16 sGridNo, UINT8 ubPlanID )
} }
EVENT_SetSoldierPosition( pPlanSoldier, gpUIPlannedSoldier->dXPos, gpUIPlannedSoldier->dYPos ); EVENT_SetSoldierPosition( pPlanSoldier, gpUIPlannedSoldier->dXPos, gpUIPlannedSoldier->dYPos );
EVENT_SetSoldierDestination( pPlanSoldier, gpUIPlannedSoldier->sGridNo ); EVENT_SetSoldierDestination( pPlanSoldier, (UINT8) gpUIPlannedSoldier->sGridNo );
pPlanSoldier->bVisible = 1; pPlanSoldier->bVisible = 1;
pPlanSoldier->usUIMovementMode = gpUIPlannedSoldier->usUIMovementMode; pPlanSoldier->usUIMovementMode = gpUIPlannedSoldier->usUIMovementMode;
+5 -2
View File
@@ -3386,7 +3386,7 @@ void UIHandleSoldierStanceChange( UINT8 ubSoldierID, INT8 bNewStance )
// IF turn-based - adjust stance now! // IF turn-based - adjust stance now!
if ( gTacticalStatus.uiFlags & TURNBASED && ( gTacticalStatus.uiFlags & INCOMBAT ) ) if ( gTacticalStatus.uiFlags & TURNBASED && ( gTacticalStatus.uiFlags & INCOMBAT ) )
{ {
pSoldier->fTurningFromPronePosition = FALSE; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
// Check if we have enough APS // Check if we have enough APS
if ( SoldierCanAffordNewStance( pSoldier, bNewStance ) ) if ( SoldierCanAffordNewStance( pSoldier, bNewStance ) )
@@ -3420,13 +3420,16 @@ void UIHandleSoldierStanceChange( UINT8 ubSoldierID, INT8 bNewStance )
// LOCK VARIBLE FOR NO UPDATE INDEX... // LOCK VARIBLE FOR NO UPDATE INDEX...
pSoldier->usUIMovementMode = GetMoveStateBasedOnStance( pSoldier, bNewStance ); pSoldier->usUIMovementMode = GetMoveStateBasedOnStance( pSoldier, bNewStance );
pSoldier->ubDesiredHeight = NO_DESIRED_HEIGHT;
#if 0
if ( pSoldier->usUIMovementMode == CRAWLING && gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_PRONE ) if ( pSoldier->usUIMovementMode == CRAWLING && gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_PRONE )
{ {
pSoldier->usDontUpdateNewGridNoOnMoveAnimChange = LOCKED_NO_NEWGRIDNO; pSoldier->usDontUpdateNewGridNoOnMoveAnimChange = LOCKED_NO_NEWGRIDNO;
pSoldier->bPathStored = FALSE; pSoldier->bPathStored = FALSE;
} }
else else
#endif
{ {
pSoldier->usDontUpdateNewGridNoOnMoveAnimChange = 1; pSoldier->usDontUpdateNewGridNoOnMoveAnimChange = 1;
} }
@@ -6319,7 +6322,7 @@ BOOLEAN ValidQuickExchangePosition( )
BOOLEAN IsValidJumpLocation( SOLDIERTYPE *pSoldier, INT16 sGridNo, BOOLEAN fCheckForPath ) BOOLEAN IsValidJumpLocation( SOLDIERTYPE *pSoldier, INT16 sGridNo, BOOLEAN fCheckForPath )
{ {
INT16 sFourGrids[4], sDistance=0, sSpot, sIntSpot; INT16 sFourGrids[4], sDistance=0, sSpot, sIntSpot;
INT8 sDirs[4] = { NORTH, EAST, SOUTH, WEST }; static const UINT8 sDirs[4] = { NORTH, EAST, SOUTH, WEST };
//INT32 cnt; //INT32 cnt;
UINT8 ubGuyThere; UINT8 ubGuyThere;
UINT8 ubMovementCost; UINT8 ubMovementCost;
+3 -3
View File
@@ -1166,7 +1166,7 @@ BOOLEAN HandleTalkingMenuEscape( BOOLEAN fCanDelete , BOOLEAN fFromEscKey )
{ {
ShutupaYoFace( gTalkPanel.iFaceIndex ); ShutupaYoFace( gTalkPanel.iFaceIndex );
} }
// Else if our queue is empty, delete emnu // Else if our queue is empty, delete menu
else else
{ {
if ( DialogueQueueIsEmpty( ) && fCanDelete ) if ( DialogueQueueIsEmpty( ) && fCanDelete )
@@ -2225,7 +2225,7 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
bItemIn = FindAIUsableObjClass( pSoldier, IC_GUN ); bItemIn = FindAIUsableObjClass( pSoldier, IC_GUN );
if (bItemIn != NO_SLOT && bItemIn != HANDPOS) if (bItemIn != NO_SLOT && bItemIn != HANDPOS)
{ {
SwapObjs( &(pSoldier->inv[HANDPOS]), &(pSoldier->inv[bItemIn]) ); SwapObjs( pSoldier, HANDPOS, bItemIn );
sGridNo = pSoldier->sGridNo + DirectionInc( pSoldier->ubDirection ); sGridNo = pSoldier->sGridNo + DirectionInc( pSoldier->ubDirection );
SoldierReadyWeapon( pSoldier, (INT16) (sGridNo % WORLD_COLS), (INT16) (sGridNo / WORLD_COLS), FALSE ); SoldierReadyWeapon( pSoldier, (INT16) (sGridNo % WORLD_COLS), (INT16) (sGridNo / WORLD_COLS), FALSE );
} }
@@ -3114,7 +3114,7 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
if (bMoneySlot < bEmptySlot) if (bMoneySlot < bEmptySlot)
{ {
// move main stash to later in inventory! // move main stash to later in inventory!
SwapObjs( &(pSoldier->inv[ bEmptySlot ] ), &(pSoldier->inv[ bMoneySlot ] ) ); SwapObjs( pSoldier, bEmptySlot, bMoneySlot );
SoldierGiveItem( pSoldier, pSoldier2, &(pSoldier->inv[ bMoneySlot ] ), bMoneySlot ); SoldierGiveItem( pSoldier, pSoldier2, &(pSoldier->inv[ bMoneySlot ] ), bMoneySlot );
} }
else else
+11 -3
View File
@@ -610,7 +610,7 @@ void GenerateProsString( STR16 zItemPros, OBJECTTYPE * pObject, UINT32 uiPixLimi
ubWeight = Item[ usItem ].ubWeight; ubWeight = Item[ usItem ].ubWeight;
if (Item[ usItem ].usItemClass == IC_GUN) if (Item[ usItem ].usItemClass == IC_GUN)
{ {
ubWeight += Item[ pObject->ItemData.Gun.usGunAmmoItem ].ubWeight; ubWeight = ubWeight + Item[ pObject->ItemData.Gun.usGunAmmoItem ].ubWeight;
} }
if (Weapon[usItem].bAccuracy >= EXCEPTIONAL_ACCURACY ) if (Weapon[usItem].bAccuracy >= EXCEPTIONAL_ACCURACY )
@@ -753,7 +753,7 @@ void GenerateConsString( STR16 zItemCons, OBJECTTYPE * pObject, UINT32 uiPixLimi
ubWeight = Item[ usItem ].ubWeight; ubWeight = Item[ usItem ].ubWeight;
if (Item[ usItem ].usItemClass == IC_GUN) if (Item[ usItem ].usItemClass == IC_GUN)
{ {
ubWeight += Item[ pObject->ItemData.Gun.usGunAmmoItem ].ubWeight; ubWeight = ubWeight + Item[ pObject->ItemData.Gun.usGunAmmoItem ].ubWeight;
} }
if (ubWeight >= BAD_WEIGHT) if (ubWeight >= BAD_WEIGHT)
@@ -2390,6 +2390,14 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
INT16 sForeColour; INT16 sForeColour;
INT16 sProsConsIndent; INT16 sProsConsIndent;
// ADB: Make sure the current object isn't money if there's something in hand
if (Item[ pObject->usItem].usItemClass & IC_MONEY && gpItemPointer != NULL && gpItemPointer->usItem != 0) {
//ADB oops, money splits and puts a new item on the cursor, which would replace what's already on the cursor!
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Unable to split money due to having an item on your cursor." );
return FALSE;
}
//Set the current screen //Set the current screen
guiCurrentItemDescriptionScreen = guiCurrentScreen; guiCurrentItemDescriptionScreen = guiCurrentScreen;
@@ -5539,7 +5547,7 @@ BOOLEAN InitKeyRingPopup( SOLDIERTYPE *pSoldier, INT16 sInvX, INT16 sInvY, INT16
HVOBJECT hVObject; HVOBJECT hVObject;
INT32 cnt; INT32 cnt;
UINT16 usPopupWidth, usPopupHeight; UINT16 usPopupWidth, usPopupHeight;
UINT8 ubSlotSimilarToKeySlot = 10; //UINT8 ubSlotSimilarToKeySlot = 10;
INT16 sKeyRingItemWidth = 0; INT16 sKeyRingItemWidth = 0;
INT16 sOffSetY = 0, sOffSetX = 0; INT16 sOffSetY = 0, sOffSetX = 0;
+29 -8
View File
@@ -2378,6 +2378,26 @@ void SwapObjs( OBJECTTYPE * pObj1, OBJECTTYPE * pObj2 )
*/ */
} }
//ADB these 2 functions were created because the code calls SwapObjs all over the place
//but never handles the effects of that swap!
void SwapObjs(SOLDIERTYPE* pSoldier, int leftSlot, int rightSlot)
{
PERFORMANCE_MARKER
SwapObjs(&pSoldier->inv[ leftSlot ], &pSoldier->inv[ rightSlot ]);
//old usItem for the left slot is now stored in the right slot, and vice versa
HandleTacticalEffectsOfEquipmentChange(pSoldier, leftSlot, pSoldier->inv[ rightSlot ].usItem, pSoldier->inv[ leftSlot ].usItem);
HandleTacticalEffectsOfEquipmentChange(pSoldier, rightSlot, pSoldier->inv[ leftSlot ].usItem, pSoldier->inv[ rightSlot ].usItem);
}
void SwapObjs(SOLDIERTYPE* pSoldier, int slot, OBJECTTYPE* pObject)
{
PERFORMANCE_MARKER
SwapObjs(&pSoldier->inv[ slot ], pObject);
HandleTacticalEffectsOfEquipmentChange(pSoldier, slot, pObject->usItem, pSoldier->inv[ slot ].usItem);
}
void RemoveObjFrom( OBJECTTYPE * pObj, UINT8 ubRemoveIndex ) void RemoveObjFrom( OBJECTTYPE * pObj, UINT8 ubRemoveIndex )
{ {
// remove 1 object from an OBJECTTYPE, starting at index bRemoveIndex // remove 1 object from an OBJECTTYPE, starting at index bRemoveIndex
@@ -3922,7 +3942,7 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
if (pSoldier->inv[SECONDHANDPOS].usItem != 0) if (pSoldier->inv[SECONDHANDPOS].usItem != 0)
{ {
// swap what WAS in the second hand into the cursor // swap what WAS in the second hand into the cursor
SwapObjs( pObj, &(pSoldier->inv[SECONDHANDPOS])); SwapObjs( pSoldier, SECONDHANDPOS, pObj);
} }
} }
} }
@@ -3932,7 +3952,8 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
{ {
// replacement/reloading/merging/stacking // replacement/reloading/merging/stacking
// keys have an additional check for key ID being the same // keys have an additional check for key ID being the same
if ( (pObj->usItem == pInSlot->usItem) && ( Item[ pObj->usItem ].usItemClass != IC_KEY || pObj->ItemData.Key.ubKeyID == pInSlot->ItemData.Key.ubKeyID ) ) if ( (pObj->usItem == pInSlot->usItem) &&
( Item[ pObj->usItem ].usItemClass != IC_KEY || pObj->ItemData.Key.ubKeyID == pInSlot->ItemData.Key.ubKeyID ) )
{ {
if (Item[ pObj->usItem ].usItemClass == IC_MONEY) if (Item[ pObj->usItem ].usItemClass == IC_MONEY)
{ {
@@ -3967,7 +3988,7 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
if (pObj->ubNumberOfObjects <= 1) if (pObj->ubNumberOfObjects <= 1)
{ {
// swapping // swapping
SwapObjs( pObj, pInSlot ); SwapObjs( pSoldier, bPos, pObj );
} }
else else
{ {
@@ -4031,13 +4052,13 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
} }
else else
{ {
SwapObjs( pObj, pInSlot ); SwapObjs( pSoldier, bPos, pObj );
} }
} }
else if (pObj->ubNumberOfObjects <= __max( ubSlotLimit, 1 ) ) else if (pObj->ubNumberOfObjects <= __max( ubSlotLimit, 1 ) )
{ {
// swapping // swapping
SwapObjs( pObj, pInSlot ); SwapObjs( pSoldier, bPos, pObj );
} }
else else
{ {
@@ -5647,7 +5668,7 @@ void SwapHandItems( SOLDIERTYPE * pSoldier )
if (pSoldier->inv[HANDPOS].usItem == NOTHING || pSoldier->inv[SECONDHANDPOS].usItem == NOTHING) if (pSoldier->inv[HANDPOS].usItem == NOTHING || pSoldier->inv[SECONDHANDPOS].usItem == NOTHING)
{ {
// whatever is in the second hand can be swapped to the main hand! // whatever is in the second hand can be swapped to the main hand!
SwapObjs( &(pSoldier->inv[HANDPOS]), &(pSoldier->inv[SECONDHANDPOS]) ); SwapObjs( pSoldier, HANDPOS, SECONDHANDPOS );
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
} }
else else
@@ -5662,7 +5683,7 @@ void SwapHandItems( SOLDIERTYPE * pSoldier )
} }
// the main hand is now empty so a swap is going to work... // the main hand is now empty so a swap is going to work...
} }
SwapObjs( &(pSoldier->inv[HANDPOS]), &(pSoldier->inv[SECONDHANDPOS]) ); SwapObjs( pSoldier, HANDPOS, SECONDHANDPOS );
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
} }
} }
@@ -5679,7 +5700,7 @@ void SwapOutHandItem( SOLDIERTYPE * pSoldier )
if (pSoldier->inv[SECONDHANDPOS].usItem == NOTHING) if (pSoldier->inv[SECONDHANDPOS].usItem == NOTHING)
{ {
// just swap the hand item to the second hand // just swap the hand item to the second hand
SwapObjs( &(pSoldier->inv[HANDPOS]), &(pSoldier->inv[SECONDHANDPOS]) ); SwapObjs( pSoldier, HANDPOS, SECONDHANDPOS );
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
return; return;
} }
+2
View File
@@ -35,6 +35,8 @@ extern INT8 FindUsableObj( SOLDIERTYPE * pSoldier, UINT16 usItem );
extern void DeleteObj(OBJECTTYPE * pObj ); extern void DeleteObj(OBJECTTYPE * pObj );
extern void CopyObj( OBJECTTYPE * pSourceObj, OBJECTTYPE * pTargetObj ); extern void CopyObj( OBJECTTYPE * pSourceObj, OBJECTTYPE * pTargetObj );
extern void SwapObjs( OBJECTTYPE * pObj1, OBJECTTYPE * pObj2 ); extern void SwapObjs( OBJECTTYPE * pObj1, OBJECTTYPE * pObj2 );
extern void SwapObjs(SOLDIERTYPE* pSoldier, int leftSlot, int rightSlot);
extern void SwapObjs(SOLDIERTYPE* pSoldier, int slot, OBJECTTYPE* pObject);
extern void SwapWithinObj( OBJECTTYPE * pObj, UINT8 ubIndex1, UINT8 ubIndex2 ); extern void SwapWithinObj( OBJECTTYPE * pObj, UINT8 ubIndex1, UINT8 ubIndex2 );
extern void RemoveObjFrom( OBJECTTYPE * pObj, UINT8 ubRemoveIndex ); extern void RemoveObjFrom( OBJECTTYPE * pObj, UINT8 ubRemoveIndex );
+2 -2
View File
@@ -799,7 +799,7 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX,
fCheckForRoof = FALSE; fCheckForRoof = FALSE;
// figure out starting and ending cubes // figure out starting and ending cubes
iGridNo = GETWORLDINDEXFROMWORLDCOORDS( (INT32)dStartX, (INT32)dStartY ); iGridNo = GETWORLDINDEXFROMWORLDCOORDS( (INT32)dStartY, (INT32)dStartX );
qCurrZ = FloatToFixed( dStartZ ); qCurrZ = FloatToFixed( dStartZ );
qLandHeight = INT32_TO_FIXEDPT( CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ iGridNo ].sHeight ) ); qLandHeight = INT32_TO_FIXEDPT( CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ iGridNo ].sHeight ) );
iCurrAboveLevelZ = FIXEDPT_TO_INT32( qCurrZ - qLandHeight ); iCurrAboveLevelZ = FIXEDPT_TO_INT32( qCurrZ - qLandHeight );
@@ -835,7 +835,7 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX,
} }
} }
iGridNo = GETWORLDINDEXFROMWORLDCOORDS( (INT32)dEndX, (INT32)dEndY ); iGridNo = GETWORLDINDEXFROMWORLDCOORDS( (INT32)dEndY, (INT32)dEndX );
qCurrZ = FloatToFixed( dEndZ ); qCurrZ = FloatToFixed( dEndZ );
qLandHeight = INT32_TO_FIXEDPT( CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ iGridNo ].sHeight ) ); qLandHeight = INT32_TO_FIXEDPT( CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ iGridNo ].sHeight ) );
iCurrAboveLevelZ = FIXEDPT_TO_INT32( qCurrZ - qLandHeight ); iCurrAboveLevelZ = FIXEDPT_TO_INT32( qCurrZ - qLandHeight );
+3
View File
@@ -232,6 +232,9 @@ void PrepareMilitiaForTactical( BOOLEAN fPrepareAll)
ubRegs = pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ]; ubRegs = pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ];
ubElites = pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ]; ubElites = pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ];
// Prevent militia from just waiting on the border
gTacticalStatus.Team[MILITIA_TEAM].bAwareOfOpposition = (pSector->uiFlags & SF_PLAYER_KNOWS_ENEMIES_ARE_HERE) != 0;
if(guiDirNumber) if(guiDirNumber)
{ {
if (fPrepareAll) if (fPrepareAll)
+14 -9
View File
@@ -110,6 +110,7 @@
#include "Strategic Status.h" #include "Strategic Status.h"
#include "PreBattle Interface.h" #include "PreBattle Interface.h"
#include "Militia Control.h" #include "Militia Control.h"
#include "Lua Interpreter.h"
#endif #endif
extern void HandleBestSightingPositionInRealtime(); extern void HandleBestSightingPositionInRealtime();
@@ -707,6 +708,8 @@ BOOLEAN InitOverhead( )
ZeroAnimSurfaceCounts( ); ZeroAnimSurfaceCounts( );
InitializeLua();
return( TRUE ); return( TRUE );
} }
@@ -714,6 +717,8 @@ BOOLEAN ShutdownOverhead( )
{ {
UINT32 cnt; UINT32 cnt;
ShutdownLua( );
// Delete any soldiers which have been created! // Delete any soldiers which have been created!
for( cnt = 0; cnt < TOTAL_SOLDIERS; cnt++ ) for( cnt = 0; cnt < TOTAL_SOLDIERS; cnt++ )
{ {
@@ -1575,7 +1580,7 @@ BOOLEAN ExecuteOverhead( )
{ {
// Change desired direction // Change desired direction
// Just change direction // Just change direction
EVENT_InternalSetSoldierDestination( pSoldier, pSoldier->usPathingData[ pSoldier->usPathIndex ], FALSE, pSoldier->usAnimState ); EVENT_InternalSetSoldierDestination( pSoldier, (UINT8) pSoldier->usPathingData[ pSoldier->usPathIndex ], FALSE, pSoldier->usAnimState );
} }
if ( gTacticalStatus.bBoxingState != NOT_BOXING && (gTacticalStatus.bBoxingState == BOXING_WAITING_FOR_PLAYER || gTacticalStatus.bBoxingState == PRE_BOXING || gTacticalStatus.bBoxingState == BOXING) ) if ( gTacticalStatus.bBoxingState != NOT_BOXING && (gTacticalStatus.bBoxingState == BOXING_WAITING_FOR_PLAYER || gTacticalStatus.bBoxingState == PRE_BOXING || gTacticalStatus.bBoxingState == BOXING) )
@@ -2273,7 +2278,7 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE
if ( !fDontContinue ) if ( !fDontContinue )
{ {
// Don't apply the first deduction in points... // Don't apply the first deduction in points...
if ( usAnimState == CRAWLING && pSoldier->fTurningFromPronePosition > 1 ) if ( usAnimState == CRAWLING && pSoldier->bTurningFromPronePosition > TURNING_FROM_PRONE_ON )
{ {
} }
else else
@@ -2325,7 +2330,7 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE
} }
// Change desired direction // Change desired direction
EVENT_InternalSetSoldierDestination( pSoldier, pSoldier->usPathingData[ pSoldier->usPathIndex ], fInitialMove, usAnimState ); EVENT_InternalSetSoldierDestination( pSoldier, (UINT8) pSoldier->usPathingData[ pSoldier->usPathIndex ], fInitialMove, usAnimState );
// CONTINUE // CONTINUE
// IT'S SAVE TO GO AGAIN, REFRESH flag // IT'S SAVE TO GO AGAIN, REFRESH flag
@@ -4586,7 +4591,7 @@ INT16 FindAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pubDirect
// fDoor determines whether special door-handling code should be used (for interacting with doors) // fDoor determines whether special door-handling code should be used (for interacting with doors)
INT16 sFourGrids[4], sDistance=0; INT16 sFourGrids[4], sDistance=0;
INT8 sDirs[4] = { NORTH, EAST, SOUTH, WEST }; static const UINT8 sDirs[4] = { NORTH, EAST, SOUTH, WEST };
//INT32 cnt; //INT32 cnt;
INT16 sClosest=NOWHERE, sSpot, sOkTest; INT16 sClosest=NOWHERE, sSpot, sOkTest;
INT16 sCloseGridNo=NOWHERE; INT16 sCloseGridNo=NOWHERE;
@@ -4730,7 +4735,7 @@ INT16 FindAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pubDirect
// MOVE OUT TWO DIRECTIONS // MOVE OUT TWO DIRECTIONS
sFourGrids[cnt] = sSpot = NewGridNo( sGridNo, DirectionInc( sDirs[ cnt ] ) ); sFourGrids[cnt] = sSpot = NewGridNo( sGridNo, DirectionInc( sDirs[ cnt ] ) );
ubTestDirection = (UINT8)sDirs[ cnt ]; ubTestDirection = sDirs[ cnt ];
// For switches, ALLOW them to walk through walls to reach it.... // For switches, ALLOW them to walk through walls to reach it....
if ( pDoor && pDoor->fFlags & STRUCTURE_SWITCH ) if ( pDoor && pDoor->fFlags & STRUCTURE_SWITCH )
@@ -4874,7 +4879,7 @@ INT16 FindNextToAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pub
// fDoor determines whether special door-handling code should be used (for interacting with doors) // fDoor determines whether special door-handling code should be used (for interacting with doors)
INT16 sFourGrids[4], sDistance=0; INT16 sFourGrids[4], sDistance=0;
INT8 sDirs[4] = { NORTH, EAST, SOUTH, WEST }; static const UINT8 sDirs[4] = { NORTH, EAST, SOUTH, WEST };
//INT32 cnt; //INT32 cnt;
INT16 sClosest=WORLD_MAX, sSpot, sSpot2, sOkTest; INT16 sClosest=WORLD_MAX, sSpot, sSpot2, sOkTest;
INT16 sCloseGridNo=NOWHERE; INT16 sCloseGridNo=NOWHERE;
@@ -4957,7 +4962,7 @@ INT16 FindNextToAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pub
// MOVE OUT TWO DIRECTIONS // MOVE OUT TWO DIRECTIONS
sFourGrids[cnt] = sSpot = NewGridNo( sGridNo, DirectionInc( sDirs[ cnt ] ) ); sFourGrids[cnt] = sSpot = NewGridNo( sGridNo, DirectionInc( sDirs[ cnt ] ) );
ubTestDirection = (UINT8)sDirs[ cnt ]; ubTestDirection = sDirs[ cnt ];
if ( pDoor && pDoor->fFlags & STRUCTURE_SWITCH ) if ( pDoor && pDoor->fFlags & STRUCTURE_SWITCH )
{ {
@@ -5274,7 +5279,7 @@ void HandleTeamServices( UINT8 ubTeamNum )
} }
if ( bSlot != NO_SLOT ) if ( bSlot != NO_SLOT )
{ {
SwapObjs( &(pTeamSoldier->inv[HANDPOS]), &(pTeamSoldier->inv[bSlot] ) ); SwapObjs( pTeamSoldier, HANDPOS, bSlot );
} }
else else
{ {
@@ -5361,7 +5366,7 @@ void HandlePlayerServices( SOLDIERTYPE *pTeamSoldier )
if ( bSlot != NO_SLOT ) if ( bSlot != NO_SLOT )
{ {
SwapObjs( &(pTeamSoldier->inv[HANDPOS]), &(pTeamSoldier->inv[bSlot] ) ); SwapObjs( pTeamSoldier, HANDPOS, bSlot );
} }
else else
{ {
+69 -63
View File
@@ -10,6 +10,7 @@
#define _PATHAI_H #define _PATHAI_H
#include "isometric utils.h" #include "isometric utils.h"
#define USE_ASTAR_PATHS #define USE_ASTAR_PATHS
#ifdef USE_ASTAR_PATHS #ifdef USE_ASTAR_PATHS
@@ -30,30 +31,25 @@ class AStar_Data
public: public:
AStar_Data() AStar_Data()
{ {
cost = f = APCost = direction = prevCost = 0; cost = directionFromPrev = 0;
#ifdef ASTAR_USING_EXTRACOVER
extraGCoverCost = -1;//-1 means we have not stopped at this node extraGCoverCost = -1;//-1 means we have not stopped at this node
#endif
wasBackwards = false; wasBackwards = false;
status = AStar_Init; status = AStar_Init;
parent = GridNode(-1,-1); parent = -1;
}; };
//no H // h is calculated on the fly
int cost;//G INT16 cost;//G
int f;//F //int f;//F is also calculated on the fly
int APCost;//the APs spent to get here //int APCost;//the APs spent to get here // Isn't this the same as "cost"?
#ifdef ASTAR_USING_EXTRACOVER
int extraGCoverCost;//an extra cost that makes stopping in midpath at a node with little cover worse int extraGCoverCost;//an extra cost that makes stopping in midpath at a node with little cover worse
#endif INT16 parent;
GridNode parent;
eAStar status; eAStar status;
int prevCost; //int prevCost;
bool wasBackwards; bool wasBackwards;
int direction; UINT8 directionFromPrev;
int numSteps;
}; };
typedef HEAP<int, GridNode> AStarHeap;
class AStarPathfinder class AStarPathfinder
{ {
public: public:
@@ -68,13 +64,19 @@ public:
private: private:
static AStarPathfinder* pThis; static AStarPathfinder* pThis;
std::vector<GridNode> ClosedList; CBinaryHeap<int, INT16> OpenHeap;
CBinaryHeap<int, GridNode> OpenHeap;
int direction;//current direction // The "closed list" is the AStarData array below which is also the path backtrace when a path is found.
int startDir;
int endDir; // For PythSpacesAway, we do not really need the distance, but rather something to compare against.
int lastDir; // So I will eliminate the sqrt function from the result for the sake of speed. This means that when comparing against
// input distances, we should square them. This is one of the variables that needs to hold the squared value.
int gubNPCDistLimitSq;
UINT8 direction;//current direction
UINT8 startDir;
UINT8 endDir;
UINT8 lastDir;
bool startingLoop; bool startingLoop;
SOLDIERTYPE* pSoldier; SOLDIERTYPE* pSoldier;
@@ -84,7 +86,7 @@ private:
bool fPathingForPlayer; bool fPathingForPlayer;
bool fPathAroundPeople; bool fPathAroundPeople;
bool fGoingThroughDoor; bool fGoingThroughDoor;
int bOKToAddStructID; INT16 bOKToAddStructID;
int bLoopState; int bLoopState;
bool bWaterToWater; bool bWaterToWater;
bool fVisitSpotsOnlyOnce; bool fVisitSpotsOnlyOnce;
@@ -95,13 +97,16 @@ private:
bool fConsiderPersonAtDestAsObstacle; bool fConsiderPersonAtDestAsObstacle;
bool fCopyReachable; bool fCopyReachable;
bool fCopyPathCosts; bool fCopyPathCosts;
bool fFindClimbPoints;
int maxAPBudget;//the gubNPCAPBudget int maxAPBudget;//the gubNPCAPBudget
int mercsMaxAPs;//the merc only has so many points to move with int mercsMaxAPs;//the merc only has so many points to move with
int movementMode; UINT16 movementMode;
int sClosePathLimit; int sClosePathLimitSq;
int PATHAI_VISIBLE_DEBUG_Counter; int travelcostDiag;
int travelcostOrth;
INT16 PATHAI_VISIBLE_DEBUG_Counter;
//vehicle defined in cpp //vehicle defined in cpp
//#ifdef VEHICLE //#ifdef VEHICLE
@@ -110,20 +115,18 @@ private:
//#endif //#endif
// member variables to prevent passing them around // member variables to prevent passing them around
GridNode StartNode; INT16 StartNode;
GridNode DestNode; INT16 DestNode;
GridNode CurrentNode; INT16 CurrentNode;
GridNode ParentNode; INT16 ParentNode;
INT16 ParentNodeIndex;
INT16 CurrentNodeIndex;
AStar_Data AStarData[WORLD_COLS][WORLD_ROWS]; AStar_Data AStarData[WORLD_MAX];
AStarHeap AStar (); INT16 AStar ();
void ExecuteAStarLogic(); void ExecuteAStarLogic();
@@ -131,49 +134,49 @@ private:
int TerrainCostToAStarG(int const terrainCost); int TerrainCostToAStarG(int const terrainCost);
int CalcG (int* pPrevCost); int CalcG (int* pPrevCost);
int CalcAP (int const terrainCost); INT16 CalcAP (int const terrainCost, UINT8 const direction);
int CalcH (); int CalcH ();
int CalcGCover (int const NodeIndex, int CalcGCover (int const NodeIndex,
int const APCost); int const APCost);
int CalcStartingAP (); INT16 CalcStartingAP ();
//including THREATTYPE was a pain, so pass by value //including THREATTYPE was a pain, so pass by value
int CalcCoverValue (INT16 sMyGridNo, INT32 iMyThreat, INT32 iMyAPsLeft, int CalcCoverValue (INT16 sMyGridNo, INT32 iMyThreat, INT32 iMyAPsLeft,
INT32 myThreatsiOrigRange, INT16 myThreatssGridNo, SOLDIERTYPE* myThreatspOpponent, INT32 myThreatsiOrigRange, INT16 myThreatssGridNo, SOLDIERTYPE* myThreatspOpponent,
INT32 myThreatsiValue, INT32 myThreatsiAPs, INT32 myThreatsiCertainty); INT32 myThreatsiValue, INT32 myThreatsiAPs, INT32 myThreatsiCertainty);
eAStar GetAStarStatus (const GridNode node) const {return AStarData[node.x][node.y].status;}; eAStar GetAStarStatus (const INT16 node) const {return AStarData[node].status;};
GridNode GetAStarParent (const GridNode node) const {return AStarData[node.x][node.y].parent;}; INT16 GetAStarParent (const INT16 node) const {return AStarData[node].parent;};
int GetAStarG (const GridNode node) const {return AStarData[node.x][node.y].cost;}; INT16 GetAStarG (INT16 node) const {return AStarData[node].cost;};
int GetAStarF (const GridNode node) const {return AStarData[node.x][node.y].f;}; int GetExtraGCover (const INT16 node) const {return AStarData[node].extraGCoverCost;};
int GetActionPoints (const GridNode node) const {return AStarData[node.x][node.y].APCost;}; //int GetAStarF (const INT16 node) const {return AStarData[node].f;};
bool GetLoopState (const GridNode node) const {return AStarData[node.x][node.y].wasBackwards;}; //int GetActionPoints (const INT16 node) const {return AStarData[node].APCost;};
int GetPrevCost (const GridNode node) const {return AStarData[node.x][node.y].prevCost;}; bool GetLoopState (const INT16 node) const {return AStarData[node].wasBackwards;};
int GetDirection (const GridNode node) const {return AStarData[node.x][node.y].direction;}; //int GetPrevCost (const INT16 node) const {return AStarData[node].prevCost;};
#ifdef ASTAR_USING_EXTRACOVER UINT8 GetDirection (const INT16 node) const {return AStarData[node].directionFromPrev;};
int GetExtraGCover (const GridNode node) const {return AStarData[node.x][node.y].extraGCoverCost;}; int GetNumSteps (const INT16 node) const {return AStarData[node].numSteps;};
void SetExtraGCover (const GridNode node, const int extraGCoverCost) {AStarData[node.x][node.y].extraGCoverCost = extraGCoverCost;}; void SetAStarStatus (const INT16 node, const eAStar status) {AStarData[node].status = status;};
#endif void SetAStarParent (const INT16 node, const INT16 parent) {AStarData[node].parent = parent;};
void SetAStarStatus (const GridNode node, const eAStar status) {AStarData[node.x][node.y].status = status;}; void SetAStarG (const INT16 node, const INT16 cost) {AStarData[node].cost = cost;};
void SetAStarParent (const GridNode node, const GridNode parent) {AStarData[node.x][node.y].parent = parent;}; void SetExtraGCover (const INT16 node, const int extraGCoverCost) {AStarData[node].extraGCoverCost = extraGCoverCost;};
void SetAStarG (const GridNode node, const int cost) {AStarData[node.x][node.y].cost = cost;}; //void SetAStarF (const INT16 node, const int f) {AStarData[node].f = f;};
void SetAStarF (const GridNode node, const int f) {AStarData[node.x][node.y].f = f;}; //void SetActionPoints (const INT16 node, const int APCost) {AStarData[node].APCost = APCost;};
void SetActionPoints (const GridNode node, const int APCost) {AStarData[node.x][node.y].APCost = APCost;}; void SetLoopState (const INT16 node, const int loopState);
void SetLoopState (const GridNode node, const int loopState); //void SetPrevCost (const INT16 node, const int prevCost) {AStarData[node].prevCost = prevCost;};
void SetPrevCost (const GridNode node, const int prevCost) {AStarData[node.x][node.y].prevCost = prevCost;}; void SetDirection (const INT16 node, const UINT8 direction) {AStarData[node].directionFromPrev = direction;};
void SetDirection (const GridNode node, const int direction) {AStarData[node.x][node.y].direction = direction;}; void SetNumSteps (const INT16 node, const int steps) {AStarData[node].numSteps = steps;};
INT16 PythSpacesAway (GridNode const node1, int PythSpacesAway (const INT16 node1,
GridNode const node2); const INT16 node2);
INT16 SpacesAway (GridNode const node1, INT16 SpacesAway (const INT16 node1,
GridNode const node2); const INT16 node2);
//bool IsDiagonal (GridNode const node1, //bool IsDiagonal (const INT16 node1,
// GridNode const node2) {return (abs(node1.x - node2.x) && abs(node1.y - node2.y));}; // const INT16 node2) {return (abs(node1.x - node2.x) && abs(node1.y - node2.y));};
bool IsDiagonal (int const direction) {return (direction & 1);}; bool IsDiagonal (int const direction) {return (direction & 1);};
void InitVehicle (); void InitVehicle ();
int VehicleObstacleCheck(); int VehicleObstacleCheck();
bool CanTraverse (); bool WantToTraverse (); // Renamed this because it doesn't mean "can we traverse" but rather, if it is profitable to.
bool IsSomeoneInTheWay(); bool IsSomeoneInTheWay();
void IncrementLoop (); void IncrementLoop ();
void InitLoop (); void InitLoop ();
@@ -182,7 +185,7 @@ private:
};//end namespace ASTAR };//end namespace ASTAR
#endif//end #ifdef USE_ASTAR_PATHS #endif// USE_ASTAR_PATHS
BOOLEAN InitPathAI( void ); BOOLEAN InitPathAI( void );
@@ -289,12 +292,15 @@ extern UINT8 gubGlobalPathFlags;
#define COPYROUTE 1 #define COPYROUTE 1
#define COPYREACHABLE 2 #define COPYREACHABLE 2
#define COPYREACHABLE_AND_APS 3 #define COPYREACHABLE_AND_APS 3
#define FINDCLIMBPOINTS 4
#define PATH_THROUGH_PEOPLE 0x01 #define PATH_THROUGH_PEOPLE 0x01
#define PATH_IGNORE_PERSON_AT_DEST 0x02 #define PATH_IGNORE_PERSON_AT_DEST 0x02
#define PATH_CLOSE_GOOD_ENOUGH 0x04 #define PATH_CLOSE_GOOD_ENOUGH 0x04
#define PATH_CLOSE_RADIUS 5 #define PATH_CLOSE_RADIUS 5
#define PATH_CLOSE_RADIUS_SQ 25
// ------------------------------------------ // ------------------------------------------
+678 -375
View File
File diff suppressed because it is too large Load Diff
+25 -8
View File
@@ -83,12 +83,21 @@ INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT16 sGridno, INT8 bDir, INT8
} }
else if (IS_TRAVELCOST_DOOR( sSwitchValue )) else if (IS_TRAVELCOST_DOOR( sSwitchValue ))
{ {
// Can't travel diagonally through a door
if (bDir & 1)
{
return -1;
}
sSwitchValue = DoorTravelCost( pSoldier, sGridno, (UINT8) sSwitchValue, (BOOLEAN) (pSoldier->bTeam == gbPlayerNum), NULL ); sSwitchValue = DoorTravelCost( pSoldier, sGridno, (UINT8) sSwitchValue, (BOOLEAN) (pSoldier->bTeam == gbPlayerNum), NULL );
} }
else if (gfPlotPathToExitGrid && sSwitchValue == TRAVELCOST_EXITGRID)
if (sSwitchValue >= TRAVELCOST_BLOCKED && sSwitchValue != TRAVELCOST_DOOR )
{ {
return(100); // Cost too much to be considered! sSwitchValue = gTileTypeMovementCost[ gpWorldLevelData[ sGridno ].ubTerrainID ];
}
if (sSwitchValue >= TRAVELCOST_BLOCKED && sSwitchValue != TRAVELCOST_DOOR)
{
return(-1); // Cost too much to be considered!
} }
switch( sSwitchValue ) switch( sSwitchValue )
@@ -115,7 +124,7 @@ INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT16 sGridno, INT8 bDir, INT8
case TRAVELCOST_VEINMID : sAPCost += AP_MOVEMENT_FLAT; case TRAVELCOST_VEINMID : sAPCost += AP_MOVEMENT_FLAT;
break; break;
*/ */
case TRAVELCOST_DOOR : sAPCost += AP_MOVEMENT_FLAT; case TRAVELCOST_DOOR : sAPCost += AP_MOVEMENT_FLAT + AP_OPEN_DOOR + AP_OPEN_DOOR; // Include open and close costs!
break; break;
// cost for jumping a fence REPLACES all other AP costs! // cost for jumping a fence REPLACES all other AP costs!
@@ -265,6 +274,10 @@ INT16 ActionPointCost( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bDir, UINT16 u
// get the tile cost for that tile based on WALKING // get the tile cost for that tile based on WALKING
sTileCost = TerrainActionPoints( pSoldier, sGridNo, bDir, pSoldier->bLevel ); sTileCost = TerrainActionPoints( pSoldier, sGridNo, bDir, pSoldier->bLevel );
if (sTileCost == -1)
{
return 100;
}
// Get switch value... // Get switch value...
sSwitchValue = gubWorldMovementCosts[ sGridNo ][ bDir ][ pSoldier->bLevel ]; sSwitchValue = gubWorldMovementCosts[ sGridNo ][ bDir ][ pSoldier->bLevel ];
@@ -343,6 +356,10 @@ INT16 EstimateActionPointCost( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bDir,
// get the tile cost for that tile based on WALKING // get the tile cost for that tile based on WALKING
sTileCost = TerrainActionPoints( pSoldier, sGridNo, bDir, pSoldier->bLevel ); sTileCost = TerrainActionPoints( pSoldier, sGridNo, bDir, pSoldier->bLevel );
if (sTileCost == -1)
{
return 100;
}
// so, then we must modify it for other movement styles and accumulate // so, then we must modify it for other movement styles and accumulate
if (sTileCost > 0) if (sTileCost > 0)
@@ -1484,7 +1501,7 @@ UINT8 MinAPsToPunch(SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubAddTurningCost
INT8 MinPtsToMove(SOLDIERTYPE *pSoldier) INT8 MinPtsToMove(SOLDIERTYPE *pSoldier)
{ {
// look around all 8 directions and return lowest terrain cost // look around all 8 directions and return lowest terrain cost
INT8 cnt; UINT8 cnt;
INT16 sLowest=127; INT16 sLowest=127;
INT16 sGridno,sCost; INT16 sGridno,sCost;
@@ -1493,9 +1510,9 @@ INT8 MinPtsToMove(SOLDIERTYPE *pSoldier)
return( (INT8)sLowest); return( (INT8)sLowest);
} }
for (cnt=0; cnt <= 7; cnt++) for (cnt=0; cnt < 8; cnt++)
{ {
sGridno = NewGridNo(pSoldier->sGridNo, DirectionInc( cnt )); sGridno = NewGridNo(pSoldier->sGridNo,DirectionInc(cnt));
if (sGridno != pSoldier->sGridNo) if (sGridno != pSoldier->sGridNo)
{ {
if ( (sCost=ActionPointCost( pSoldier, sGridno, cnt , pSoldier->usUIMovementMode ) ) < sLowest ) if ( (sCost=ActionPointCost( pSoldier, sGridno, cnt , pSoldier->usUIMovementMode ) ) < sLowest )
@@ -1513,7 +1530,7 @@ INT8 PtsToMoveDirection(SOLDIERTYPE *pSoldier, INT8 bDirection )
INT8 bOverTerrainType; INT8 bOverTerrainType;
UINT16 usMoveModeToUse; UINT16 usMoveModeToUse;
sGridno = NewGridNo( pSoldier->sGridNo, DirectionInc( bDirection ) ); sGridno = NewGridNo( pSoldier->sGridNo, DirectionInc(bDirection ) );
usMoveModeToUse = pSoldier->usUIMovementMode; usMoveModeToUse = pSoldier->usUIMovementMode;
+1
View File
@@ -3,5 +3,6 @@
BOOLEAN IsItAllowedToRenderRain(); BOOLEAN IsItAllowedToRenderRain();
void RenderRain(); void RenderRain();
void ResetRain();
#endif #endif
+2 -2
View File
@@ -1817,7 +1817,7 @@ void GetBloodFromCorpse( SOLDIERTYPE *pSoldier )
{ {
ROTTING_CORPSE *pCorpse; ROTTING_CORPSE *pCorpse;
INT8 bObjSlot; INT8 bObjSlot;
OBJECTTYPE Object; OBJECTTYPE Object = {};
// OK, get corpse // OK, get corpse
pCorpse = &( gRottingCorpse[ pSoldier->uiPendingActionData4 ] ); pCorpse = &( gRottingCorpse[ pSoldier->uiPendingActionData4 ] );
@@ -1847,7 +1847,7 @@ void GetBloodFromCorpse( SOLDIERTYPE *pSoldier )
if ( bObjSlot != NO_SLOT ) if ( bObjSlot != NO_SLOT )
{ {
SwapObjs( &(pSoldier->inv[ bObjSlot ] ), &Object ); SwapObjs( pSoldier, bObjSlot, &Object );
} }
} }
+14 -4
View File
@@ -2020,7 +2020,9 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
// ReduceAttackBusyCount( pSoldier->ubSuppressorID, FALSE ); // ReduceAttackBusyCount( pSoldier->ubSuppressorID, FALSE );
// } // }
if ( pSoldier->usPendingAnimation == NO_PENDING_ANIMATION && ( pSoldier->fTurningFromPronePosition != 3 ) && ( pSoldier->fTurningFromPronePosition != 1 ) ) if ( pSoldier->usPendingAnimation == NO_PENDING_ANIMATION &&
( pSoldier->bTurningFromPronePosition != TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE ) &&
( pSoldier->bTurningFromPronePosition != TURNING_FROM_PRONE_ON ) )
{ {
if ( gTacticalStatus.ubAttackBusyCount == 0 ) if ( gTacticalStatus.ubAttackBusyCount == 0 )
{ {
@@ -2033,7 +2035,10 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
// Check to see if we have changed stance and need to update visibility // Check to see if we have changed stance and need to update visibility
if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_STANCECHANGEANIM) if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_STANCECHANGEANIM)
{ {
if ( pSoldier->usPendingAnimation == NO_PENDING_ANIMATION && gTacticalStatus.ubAttackBusyCount == 0 && pSoldier->fTurningFromPronePosition != 3 && pSoldier->fTurningFromPronePosition != 1 ) if ( pSoldier->usPendingAnimation == NO_PENDING_ANIMATION &&
gTacticalStatus.ubAttackBusyCount == 0 &&
pSoldier->bTurningFromPronePosition != TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE &&
pSoldier->bTurningFromPronePosition != TURNING_FROM_PRONE_ON )
{ {
HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO | SIGHT_INTERRUPT ); HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO | SIGHT_INTERRUPT );
} }
@@ -2057,7 +2062,12 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
} }
// Have we finished opening doors? // Have we finished opening doors?
if ( pSoldier->usAnimState == END_OPEN_DOOR || pSoldier->usAnimState == END_OPEN_DOOR_CROUCHED || pSoldier->usAnimState == CRIPPLE_CLOSE_DOOR || pSoldier->usAnimState == CRIPPLE_END_OPEN_DOOR ) // 0verhaul: Added additional check: Are we told to stop at this point, maybe due to being interrupted?
if ( !pSoldier->fNoAPToFinishMove &&
(pSoldier->usAnimState == END_OPEN_DOOR ||
pSoldier->usAnimState == END_OPEN_DOOR_CROUCHED ||
pSoldier->usAnimState == CRIPPLE_CLOSE_DOOR ||
pSoldier->usAnimState == CRIPPLE_END_OPEN_DOOR ) )
{ {
// Are we told to continue movement...? // Are we told to continue movement...?
if ( pSoldier->bEndDoorOpenCode == 1 ) if ( pSoldier->bEndDoorOpenCode == 1 )
@@ -3565,7 +3575,7 @@ void CheckForAndHandleSoldierIncompacitated( SOLDIERTYPE *pSoldier )
return; return;
} }
} }
else if ( pSoldier->usAnimState == GENERIC_HIT_CROUCH ) else if ( pSoldier->usAnimState == GENERIC_HIT_CROUCH || pSoldier->usAnimState == CIV_COWER_HIT)
{ {
ChangeSoldierState( pSoldier, FALLFORWARD_FROMHIT_CROUCH, 0 , FALSE); ChangeSoldierState( pSoldier, FALLFORWARD_FROMHIT_CROUCH, 0 , FALSE);
BeginTyingToFall( pSoldier ); BeginTyingToFall( pSoldier );
+89 -49
View File
@@ -94,6 +94,7 @@
#include "Campaign Types.h" #include "Campaign Types.h"
#include "Strategic Status.h" #include "Strategic Status.h"
#include "civ quotes.h" #include "civ quotes.h"
#include "Strategic Pathing.h"
#endif #endif
//turnspeed //turnspeed
@@ -113,11 +114,6 @@ extern INT16 DirIncrementer[8];
#define LOW_MORALE_BATTLE_SND_THREASHOLD 35 #define LOW_MORALE_BATTLE_SND_THREASHOLD 35
#define TURNING_FROM_PRONE_OFF 0
#define TURNING_FROM_PRONE_ON 1
#define TURNING_FROM_PRONE_START_UP_FROM_MOVE 2
#define TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE 3
#define MIN_SUBSEQUENT_SNDS_DELAY 2000 #define MIN_SUBSEQUENT_SNDS_DELAY 2000
// Enumerate extended directions // Enumerate extended directions
@@ -1756,7 +1752,7 @@ BOOLEAN ReevaluateEnemyStance( SOLDIERTYPE *pSoldier, UINT16 usAnimState )
// make the chosen one not turn to face us // make the chosen one not turn to face us
if ( OK_ENEMY_MERC( pSoldier ) && pSoldier->ubID != gTacticalStatus.ubTheChosenOne && gAnimControl[ usAnimState ].ubEndHeight == ANIM_STAND && !( pSoldier->uiStatusFlags & SOLDIER_UNDERAICONTROL) ) if ( OK_ENEMY_MERC( pSoldier ) && pSoldier->ubID != gTacticalStatus.ubTheChosenOne && gAnimControl[ usAnimState ].ubEndHeight == ANIM_STAND && !( pSoldier->uiStatusFlags & SOLDIER_UNDERAICONTROL) )
{ {
if ( pSoldier->fTurningFromPronePosition == TURNING_FROM_PRONE_OFF ) if ( pSoldier->bTurningFromPronePosition == TURNING_FROM_PRONE_OFF )
{ {
// If we are a queen and see enemies, goto ready // If we are a queen and see enemies, goto ready
if ( pSoldier->ubBodyType == QUEENMONSTER ) if ( pSoldier->ubBodyType == QUEENMONSTER )
@@ -2000,7 +1996,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT
EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->ubPendingDirection ); EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->ubPendingDirection );
pSoldier->ubPendingDirection = NO_PENDING_DIRECTION; pSoldier->ubPendingDirection = NO_PENDING_DIRECTION;
pSoldier->usPendingAnimation = CLIMBDOWNROOF; pSoldier->usPendingAnimation = CLIMBDOWNROOF;
pSoldier->fTurningFromPronePosition = FALSE; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
pSoldier->fTurningUntilDone = TRUE; pSoldier->fTurningUntilDone = TRUE;
SoldierGotoStationaryStance( pSoldier ); SoldierGotoStationaryStance( pSoldier );
return( TRUE ); return( TRUE );
@@ -2236,20 +2232,29 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT
// Unset paused for no APs..... // Unset paused for no APs.....
AdjustNoAPToFinishMove( pSoldier, FALSE ); AdjustNoAPToFinishMove( pSoldier, FALSE );
#if 0
// 0verhaul: This is a test. The only time I have been able to make this code hit is when
// the player goes prone while moving. And that is not what this part is intended for. I
// have seen the soldier in the middle of crawling, get up, turn, and then go prone again to
// continue along his path. But this code was not hit for that part. And this code seems
// to be made for that part. So apparently they found another way to deal with it. So
// I disabled the "locked" code for usDontUpdateNewGridNoOnMoveAnimChange since it can cause
// problems of its own. Now we see if we can do without this part too.
if ( usNewState == CRAWLING && pSoldier->usDontUpdateNewGridNoOnMoveAnimChange == 1 ) if ( usNewState == CRAWLING && pSoldier->usDontUpdateNewGridNoOnMoveAnimChange == 1 )
{ {
if ( pSoldier->fTurningFromPronePosition != TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE ) if ( pSoldier->bTurningFromPronePosition != TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE )
{ {
pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_START_UP_FROM_MOVE; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_START_UP_FROM_MOVE;
} }
// ATE: IF we are starting to crawl, but have to getup to turn first...... // ATE: IF we are starting to crawl, but have to getup to turn first......
if ( pSoldier->fTurningFromPronePosition == TURNING_FROM_PRONE_START_UP_FROM_MOVE ) if ( pSoldier->bTurningFromPronePosition == TURNING_FROM_PRONE_START_UP_FROM_MOVE )
{ {
usNewState = PRONE_UP; usNewState = PRONE_UP;
pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE;
} }
} }
#endif
// We are about to start moving // We are about to start moving
// Handle buddy beginning to move... // Handle buddy beginning to move...
@@ -2303,7 +2308,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT
{ {
// Change desired direction // Change desired direction
// Just change direction // Just change direction
EVENT_InternalSetSoldierDestination( pSoldier, pSoldier->usPathingData[ pSoldier->usPathIndex ], FALSE, pSoldier->usAnimState ); EVENT_InternalSetSoldierDestination( pSoldier, (UINT8) pSoldier->usPathingData[ pSoldier->usPathIndex ], FALSE, pSoldier->usAnimState );
} }
//check for services //check for services
@@ -2336,7 +2341,14 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT
// ( Unless locked ) // ( Unless locked )
if ( gAnimControl[ usNewState ].uiFlags & ANIM_MOVING ) if ( gAnimControl[ usNewState ].uiFlags & ANIM_MOVING )
{ {
if ( pSoldier->usDontUpdateNewGridNoOnMoveAnimChange != LOCKED_NO_NEWGRIDNO ) // 0verhaul: **** Special hack!!!!
// If a merc begins to go prone while moving, the LOCKED_NO_NEWGRIDNO is set. If the merc never finishes
// going prone, either due to interrupting the stance change with a different stance change, or other possible
// factors such as maybe getting shot (this is realtime so an enemy could see him), it stays on locked. Once
// it stays on locked, the soldier will be unable to navigate around obstacles but will simply stay put
// twitching. Since the LOCKED is only set when going prone, this unsets it.
if ( pSoldier->usDontUpdateNewGridNoOnMoveAnimChange != LOCKED_NO_NEWGRIDNO ||
(pSoldier->usDontUpdateNewGridNoOnMoveAnimChange == LOCKED_NO_NEWGRIDNO && pSoldier->usAnimState != PRONE_DOWN))
{ {
pSoldier->usDontUpdateNewGridNoOnMoveAnimChange = FALSE; pSoldier->usDontUpdateNewGridNoOnMoveAnimChange = FALSE;
} }
@@ -2367,7 +2379,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT
uiOldAnimFlags = gAnimControl[ pSoldier->usAnimState ].uiFlags; uiOldAnimFlags = gAnimControl[ pSoldier->usAnimState ].uiFlags;
uiNewAnimFlags = gAnimControl[ usNewState ].uiFlags; uiNewAnimFlags = gAnimControl[ usNewState ].uiFlags;
usNewGridNo = NewGridNo( pSoldier->sGridNo, DirectionInc( pSoldier->usPathingData[ pSoldier->usPathIndex ] ) ); usNewGridNo = NewGridNo( pSoldier->sGridNo, DirectionInc( (UINT8) pSoldier->usPathingData[ pSoldier->usPathIndex ] ) );
// CHECKING IF WE HAVE A HIT FINISH BUT NO DEATH IS DONE WITH A SPECIAL ANI CODE // CHECKING IF WE HAVE A HIT FINISH BUT NO DEATH IS DONE WITH A SPECIAL ANI CODE
@@ -2479,7 +2491,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT
case CRAWLING: case CRAWLING:
// Turn off flag... // Turn off flag...
pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_OFF; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
pSoldier->ubPendingActionAnimCount = 0; pSoldier->ubPendingActionAnimCount = 0;
pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; pSoldier->usPendingAnimation = NO_PENDING_ANIMATION;
break; break;
@@ -2521,7 +2533,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT
case PRONE_DOWN: case PRONE_DOWN:
// ATE: If we are NOT waiting for prone down... // ATE: If we are NOT waiting for prone down...
if ( pSoldier->fTurningFromPronePosition < TURNING_FROM_PRONE_START_UP_FROM_MOVE && !pSoldier->fDontChargeAPsForStanceChange ) if ( pSoldier->bTurningFromPronePosition < TURNING_FROM_PRONE_START_UP_FROM_MOVE && !pSoldier->fDontChargeAPsForStanceChange )
{ {
// ATE: Don't do this if we are still 'moving'.... // ATE: Don't do this if we are still 'moving'....
if ( pSoldier->sGridNo == pSoldier->sFinalDestination || pSoldier->usPathIndex == 0 ) if ( pSoldier->sGridNo == pSoldier->sFinalDestination || pSoldier->usPathIndex == 0 )
@@ -2649,7 +2661,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT
pSoldier->usPathDataSize++; pSoldier->usPathDataSize++;
pSoldier->sFinalDestination = usNewGridNo; pSoldier->sFinalDestination = usNewGridNo;
// Set direction // Set direction
EVENT_InternalSetSoldierDestination( pSoldier, pSoldier->usPathingData[ pSoldier->usPathIndex ], FALSE, JUMP_OVER_BLOCKING_PERSON ); EVENT_InternalSetSoldierDestination( pSoldier, (UINT8) pSoldier->usPathingData[ pSoldier->usPathIndex ], FALSE, JUMP_OVER_BLOCKING_PERSON );
} }
break; break;
@@ -3256,7 +3268,7 @@ void SetSoldierGridNo( SOLDIERTYPE *pSoldier, INT16 sNewGridNo, BOOLEAN fForceRe
// Make transition from low to deep // Make transition from low to deep
EVENT_InitNewSoldierAnim( pSoldier, LOW_TO_DEEP_WATER, 0 , FALSE ); EVENT_InitNewSoldierAnim( pSoldier, LOW_TO_DEEP_WATER, 0 , FALSE );
pSoldier->usPendingAnimation = DEEP_WATER_SWIM; pSoldier->usPendingAnimation = DEEP_WATER_SWIM;
pSoldier->usDontUpdateNewGridNoOnMoveAnimChange = 1;
PlayJA2Sample( ENTER_DEEP_WATER_1, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); PlayJA2Sample( ENTER_DEEP_WATER_1, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
} }
@@ -3273,6 +3285,7 @@ void SetSoldierGridNo( SOLDIERTYPE *pSoldier, INT16 sNewGridNo, BOOLEAN fForceRe
{ {
// Make transition from low to deep // Make transition from low to deep
EVENT_InitNewSoldierAnim( pSoldier, DEEP_TO_LOW_WATER, 0 , FALSE ); EVENT_InitNewSoldierAnim( pSoldier, DEEP_TO_LOW_WATER, 0 , FALSE );
pSoldier->usDontUpdateNewGridNoOnMoveAnimChange = 1;
pSoldier->usPendingAnimation = pSoldier->usUIMovementMode; pSoldier->usPendingAnimation = pSoldier->usUIMovementMode;
} }
} }
@@ -3494,7 +3507,7 @@ void EVENT_FireSoldierWeapon( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo )
pSoldier->fDontUnsetLastTargetFromTurn = TRUE; pSoldier->fDontUnsetLastTargetFromTurn = TRUE;
// Make sure we don't try and do fancy prone turning..... // Make sure we don't try and do fancy prone turning.....
pSoldier->fTurningFromPronePosition = FALSE; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
// Force our direction! // Force our direction!
EVENT_SetSoldierDirection( pSoldier, pSoldier->bDesiredDirection ); EVENT_SetSoldierDirection( pSoldier, pSoldier->bDesiredDirection );
@@ -5032,7 +5045,7 @@ BOOLEAN EVENT_InternalGetNewSoldierPath( SOLDIERTYPE *pSoldier, UINT16 sDestGrid
pSoldier->sGridNo = pSoldier->sDestination; pSoldier->sGridNo = pSoldier->sDestination;
// Check if path is good before copying it into guy's path... // Check if path is good before copying it into guy's path...
if ( FindBestPath( pSoldier, sDestGridNo, pSoldier->bLevel, pSoldier->usUIMovementMode, NO_COPYROUTE, fFlags ) == 0 ) if ( !(uiDist = FindBestPath( pSoldier, sDestGridNo, pSoldier->bLevel, pSoldier->usUIMovementMode, COPYROUTE, fFlags ) ) )
{ {
// Set to old.... // Set to old....
pSoldier->sGridNo = sMercGridNo; pSoldier->sGridNo = sMercGridNo;
@@ -5040,7 +5053,7 @@ BOOLEAN EVENT_InternalGetNewSoldierPath( SOLDIERTYPE *pSoldier, UINT16 sDestGrid
return( FALSE ); return( FALSE );
} }
uiDist = FindBestPath( pSoldier, sDestGridNo, pSoldier->bLevel, pSoldier->usUIMovementMode, COPYROUTE, fFlags ); //uiDist = FindBestPath( pSoldier, sDestGridNo, pSoldier->bLevel, pSoldier->usUIMovementMode, COPYROUTE, fFlags );
pSoldier->sGridNo = sMercGridNo; pSoldier->sGridNo = sMercGridNo;
pSoldier->sFinalDestination = sDestGridNo; pSoldier->sFinalDestination = sDestGridNo;
@@ -5124,6 +5137,11 @@ BOOLEAN EVENT_InternalGetNewSoldierPath( SOLDIERTYPE *pSoldier, UINT16 sDestGrid
{ {
usMoveAnimState = DEEP_WATER_SWIM; usMoveAnimState = DEEP_WATER_SWIM;
} }
// Can't forget shallow water! AI will sometimes attempt to swat through it, which is not legal either
else if ( MercInWater( pSoldier) )
{
usMoveAnimState = WALKING;
}
// If we were aiming, end aim! // If we were aiming, end aim!
usAnimState = PickSoldierReadyAnimation( pSoldier, TRUE ); usAnimState = PickSoldierReadyAnimation( pSoldier, TRUE );
@@ -5330,9 +5348,9 @@ void EVENT_InternalSetSoldierDestination( SOLDIERTYPE *pSoldier, UINT8 ubNewDire
} }
} }
void EVENT_SetSoldierDestination( SOLDIERTYPE *pSoldier, UINT16 usNewDirection ) void EVENT_SetSoldierDestination( SOLDIERTYPE *pSoldier, UINT8 ubNewDirection )
{ {
EVENT_InternalSetSoldierDestination( pSoldier, usNewDirection, FALSE, pSoldier->usAnimState ); EVENT_InternalSetSoldierDestination( pSoldier, ubNewDirection, FALSE, pSoldier->usAnimState );
} }
@@ -5402,7 +5420,7 @@ INT8 MultiTiledTurnDirection( SOLDIERTYPE * pSoldier, INT8 bStartDirection, INT8
} }
bLoop++; bLoop++;
if ( bLoop < 2 ) //if ( bLoop < 2 )
{ {
// change direction of loop etc // change direction of loop etc
bCurrentDirection = bStartDirection; bCurrentDirection = bStartDirection;
@@ -5469,9 +5487,9 @@ void EVENT_InternalSetSoldierDesiredDirection( SOLDIERTYPE *pSoldier, UINT8 ubNe
{ {
if ( gAnimControl[ usAnimState ].ubHeight == ANIM_PRONE ) if ( gAnimControl[ usAnimState ].ubHeight == ANIM_PRONE )
{ {
if ( pSoldier->fTurningFromPronePosition != TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE ) if ( pSoldier->bTurningFromPronePosition != TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE )
{ {
pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_START_UP_FROM_MOVE; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_START_UP_FROM_MOVE;
} }
} }
} }
@@ -5485,7 +5503,7 @@ void EVENT_InternalSetSoldierDesiredDirection( SOLDIERTYPE *pSoldier, UINT8 ubNe
//if ( pSoldier->sDestination == pSoldier->sGridNo ) //if ( pSoldier->sDestination == pSoldier->sGridNo )
if ( !fInitalMove ) if ( !fInitalMove )
{ {
pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_ON; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_ON;
// Set a pending animation to change stance first... // Set a pending animation to change stance first...
SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH ); SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH );
@@ -5922,7 +5940,11 @@ void TurnSoldier( SOLDIERTYPE *pSoldier)
{ {
if ( pSoldier->ubDirection == pSoldier->bDesiredDirection ) if ( pSoldier->ubDirection == pSoldier->bDesiredDirection )
{ {
if ( ( (gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIREREADY ) && !pSoldier->fTurningFromPronePosition ) || pSoldier->ubBodyType == ROBOTNOWEAPON || pSoldier->ubBodyType == TANK_NW || pSoldier->ubBodyType == TANK_NE ) if ( ( (gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIREREADY ) &&
pSoldier->bTurningFromPronePosition == TURNING_FROM_PRONE_OFF) ||
pSoldier->ubBodyType == ROBOTNOWEAPON ||
pSoldier->ubBodyType == TANK_NW ||
pSoldier->ubBodyType == TANK_NE )
{ {
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("TurnSoldier: EVENT_InitNewSoldierAnim") ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("TurnSoldier: EVENT_InitNewSoldierAnim") );
EVENT_InitNewSoldierAnim( pSoldier, SelectFireAnimation( pSoldier, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ), 0, FALSE ); EVENT_InitNewSoldierAnim( pSoldier, SelectFireAnimation( pSoldier, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ), 0, FALSE );
@@ -5933,7 +5955,7 @@ void TurnSoldier( SOLDIERTYPE *pSoldier)
} }
// Else check if we are trying to shoot and once was prone, but am now crouched because we needed to turn... // Else check if we are trying to shoot and once was prone, but am now crouched because we needed to turn...
else if ( pSoldier->fTurningFromPronePosition ) else if ( pSoldier->bTurningFromPronePosition != TURNING_FROM_PRONE_OFF )
{ {
if ( IsValidStance( pSoldier, ANIM_PRONE ) ) if ( IsValidStance( pSoldier, ANIM_PRONE ) )
{ {
@@ -5945,7 +5967,7 @@ void TurnSoldier( SOLDIERTYPE *pSoldier)
EVENT_InitNewSoldierAnim( pSoldier, SelectFireAnimation( pSoldier, ANIM_CROUCH ), 0, FALSE ); EVENT_InitNewSoldierAnim( pSoldier, SelectFireAnimation( pSoldier, ANIM_CROUCH ), 0, FALSE );
} }
pSoldier->fTurningToShoot = FALSE; pSoldier->fTurningToShoot = FALSE;
pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_OFF; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
} }
} }
} }
@@ -6002,7 +6024,9 @@ void TurnSoldier( SOLDIERTYPE *pSoldier)
pSoldier->fDontUnsetLastTargetFromTurn = FALSE; pSoldier->fDontUnsetLastTargetFromTurn = FALSE;
// Unset ui busy if from ui // Unset ui busy if from ui
if ( pSoldier->bTurningFromUI && ( pSoldier->fTurningFromPronePosition != 3 ) && ( pSoldier->fTurningFromPronePosition != 1 ) ) if ( pSoldier->bTurningFromUI &&
( pSoldier->bTurningFromPronePosition != TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE ) &&
( pSoldier->bTurningFromPronePosition != TURNING_FROM_PRONE_ON ) )
{ {
UnSetUIBusy( pSoldier->ubID ); UnSetUIBusy( pSoldier->ubID );
pSoldier->bTurningFromUI = FALSE; pSoldier->bTurningFromUI = FALSE;
@@ -6017,23 +6041,30 @@ void TurnSoldier( SOLDIERTYPE *pSoldier)
// Undo our flag for prone turning... // Undo our flag for prone turning...
// Else check if we are trying to shoot and once was prone, but am now crouched because we needed to turn... // Else check if we are trying to shoot and once was prone, but am now crouched because we needed to turn...
if ( pSoldier->fTurningFromPronePosition == TURNING_FROM_PRONE_ON ) if ( pSoldier->bTurningFromPronePosition == TURNING_FROM_PRONE_ON )
{ {
// ATE: Don't do this if we have something in our hands we are going to throw! // ATE: Don't do this if we have something in our hands we are going to throw!
if ( IsValidStance( pSoldier, ANIM_PRONE ) && pSoldier->pTempObject == NULL ) if ( IsValidStance( pSoldier, ANIM_PRONE ) && pSoldier->pTempObject == NULL )
{ {
SendChangeSoldierStanceEvent( pSoldier, ANIM_PRONE ); SendChangeSoldierStanceEvent( pSoldier, ANIM_PRONE );
} }
pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_OFF; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
} }
// If a special code, make guy crawl after stance change! // If a special code, make guy crawl after stance change!
if ( pSoldier->fTurningFromPronePosition == TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE && pSoldier->usAnimState != PRONE_UP && pSoldier->usAnimState != PRONE_DOWN ) if ( pSoldier->bTurningFromPronePosition == TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE &&
pSoldier->usAnimState != PRONE_UP &&
pSoldier->usAnimState != PRONE_DOWN )
{ {
if ( IsValidStance( pSoldier, ANIM_PRONE ) ) if ( IsValidStance( pSoldier, ANIM_PRONE ) )
{ {
EVENT_InitNewSoldierAnim( pSoldier, CRAWLING, 0, FALSE ); EVENT_InitNewSoldierAnim( pSoldier, CRAWLING, 0, FALSE );
} }
// Else swat for a tile so that there's room to resume prone
else
{
EVENT_InitNewSoldierAnim( pSoldier, pSoldier->usUIMovementMode, 0 , FALSE );
}
} }
if ( pSoldier->uiStatusFlags & SOLDIER_TURNINGFROMHIT ) if ( pSoldier->uiStatusFlags & SOLDIER_TURNINGFROMHIT )
@@ -6181,7 +6212,7 @@ void TurnSoldier( SOLDIERTYPE *pSoldier)
{ {
// OK, we want to getup, turn and go prone again.... // OK, we want to getup, turn and go prone again....
SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH ); SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH );
pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE;
} }
// If we are a creature, or multi-tiled, cancel AI action.....? // If we are a creature, or multi-tiled, cancel AI action.....?
else if ( pSoldier->uiStatusFlags & SOLDIER_MULTITILE ) else if ( pSoldier->uiStatusFlags & SOLDIER_MULTITILE )
@@ -7090,7 +7121,7 @@ void BeginSoldierClimbFence( SOLDIERTYPE *pSoldier )
EVENT_InternalSetSoldierDesiredDirection( pSoldier, bDirection, FALSE, pSoldier->usAnimState ); EVENT_InternalSetSoldierDesiredDirection( pSoldier, bDirection, FALSE, pSoldier->usAnimState );
pSoldier->fTurningUntilDone = TRUE; pSoldier->fTurningUntilDone = TRUE;
// ATE: Reset flag to go back to prone... // ATE: Reset flag to go back to prone...
pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_OFF; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
pSoldier->usPendingAnimation = HOPFENCE; pSoldier->usPendingAnimation = HOPFENCE;
} }
@@ -9603,7 +9634,7 @@ void EVENT_SoldierBeginKnifeThrowAttack( SOLDIERTYPE *pSoldier, INT16 sGridNo, U
// SET TARGET GRIDNO // SET TARGET GRIDNO
pSoldier->sTargetGridNo = sGridNo; pSoldier->sTargetGridNo = sGridNo;
pSoldier->sLastTarget = sGridNo; pSoldier->sLastTarget = sGridNo;
pSoldier->fTurningFromPronePosition = 0; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
// NB target level must be set by functions outside of here... but I think it // NB target level must be set by functions outside of here... but I think it
// is already set in HandleItem or in the AI code - CJC // is already set in HandleItem or in the AI code - CJC
pSoldier->ubTargetID = WhoIsThere2( sGridNo, pSoldier->bTargetLevel ); pSoldier->ubTargetID = WhoIsThere2( sGridNo, pSoldier->bTargetLevel );
@@ -10158,7 +10189,7 @@ void HaultSoldierFromSighting( SOLDIERTYPE *pSoldier, BOOLEAN fFromSightingEnemy
if ( !pSoldier->fTurningToShoot ) if ( !pSoldier->fTurningToShoot )
{ {
pSoldier->fTurningFromPronePosition = FALSE; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
} }
} }
@@ -10195,7 +10226,7 @@ void EVENT_StopMerc( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bDirection )
} }
pSoldier->bEndDoorOpenCode = 0; pSoldier->bEndDoorOpenCode = 0;
pSoldier->fTurningFromPronePosition = 0; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
// Cancel path data! // Cancel path data!
pSoldier->usPathIndex = pSoldier->usPathDataSize = 0; pSoldier->usPathIndex = pSoldier->usPathDataSize = 0;
@@ -10982,15 +11013,17 @@ void SoldierCollapse( SOLDIERTYPE *pSoldier )
// Crouched or prone, only for mercs! // Crouched or prone, only for mercs!
BeginTyingToFall( pSoldier ); BeginTyingToFall( pSoldier );
if ( fMerc ) // 0verhaul: No special case here! First the FALLFORWARD_FROMHIT_CROUCH can be filled in to use the FALLFORWARD_FROMHIT_STAND anim
{ // then when real anims come, use them instead.
//if ( fMerc )
//{
EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_CROUCH, 0 , FALSE); EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_CROUCH, 0 , FALSE);
} //}
else //else
{ //{
// For civs... use fall from stand... // // For civs... use fall from stand...
EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0 , FALSE); // EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0 , FALSE);
} //}
break; break;
case ANIM_PRONE: case ANIM_PRONE:
@@ -11572,7 +11605,7 @@ void ChangeToFlybackAnimation( SOLDIERTYPE *pSoldier, UINT8 ubDirection )
pSoldier->usPathingData[ pSoldier->usPathDataSize ] = ubOppositeDir; pSoldier->usPathingData[ pSoldier->usPathDataSize ] = ubOppositeDir;
pSoldier->usPathDataSize++; pSoldier->usPathDataSize++;
pSoldier->sFinalDestination = sNewGridNo; pSoldier->sFinalDestination = sNewGridNo;
EVENT_InternalSetSoldierDestination( pSoldier, pSoldier->usPathingData[ pSoldier->usPathIndex ], FALSE, FLYBACK_HIT ); EVENT_InternalSetSoldierDestination( pSoldier, (UINT8) pSoldier->usPathingData[ pSoldier->usPathIndex ], FALSE, FLYBACK_HIT );
// Get a new direction based on direction // Get a new direction based on direction
EVENT_InitNewSoldierAnim( pSoldier, FLYBACK_HIT, 0 , FALSE ); EVENT_InitNewSoldierAnim( pSoldier, FLYBACK_HIT, 0 , FALSE );
@@ -12047,14 +12080,21 @@ void HandleSoldierTakeDamageFeedback( SOLDIERTYPE *pSoldier )
void HandleSystemNewAISituation( SOLDIERTYPE *pSoldier, BOOLEAN fResetABC ) void HandleSystemNewAISituation( SOLDIERTYPE *pSoldier, BOOLEAN fResetABC )
{ {
// Are we an AI guy? // Are we an AI guy?
// 0verhaul:
// This code will only stop a soldier if it is not the player's turn. The problem here is that the soldier's
// actions may have triggered an interrupt. This code is called in order to cancel the soldier's movement
// after the interrupt is triggered, so if the AI causes an interrupt and it's the player's turn, he will
// continue doing what he was going to do. We need this function to work even when it's the player's turn,
// at least in this case.
if ( gTacticalStatus.ubCurrentTeam != gbPlayerNum && pSoldier->bTeam != gbPlayerNum ) if ( gTacticalStatus.ubCurrentTeam != gbPlayerNum && pSoldier->bTeam != gbPlayerNum )
//if ( pSoldier->bTeam != gbPlayerNum )
{ {
if ( pSoldier->bNewSituation == IS_NEW_SITUATION ) if ( pSoldier->bNewSituation == IS_NEW_SITUATION )
{ {
// Cancel what they were doing.... // Cancel what they were doing....
pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; pSoldier->usPendingAnimation = NO_PENDING_ANIMATION;
pSoldier->usPendingAnimation2 = NO_PENDING_ANIMATION; pSoldier->usPendingAnimation2 = NO_PENDING_ANIMATION;
pSoldier->fTurningFromPronePosition = FALSE; pSoldier->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
pSoldier->ubPendingDirection = NO_PENDING_DIRECTION; pSoldier->ubPendingDirection = NO_PENDING_DIRECTION;
pSoldier->ubPendingAction = NO_PENDING_ACTION; pSoldier->ubPendingAction = NO_PENDING_ACTION;
pSoldier->bEndDoorOpenCode = 0; pSoldier->bEndDoorOpenCode = 0;
+7 -2
View File
@@ -172,6 +172,11 @@ extern UINT16 CivLastNames[MAXCIVLASTNAMES][10];
//so that we can increase it if we can stand breaking the saves //so that we can increase it if we can stand breaking the saves
#define MAX_BURST_SPREAD_TARGETS 6 #define MAX_BURST_SPREAD_TARGETS 6
#define TURNING_FROM_PRONE_OFF 0
#define TURNING_FROM_PRONE_ON 1
#define TURNING_FROM_PRONE_START_UP_FROM_MOVE 2
#define TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE 3
//ENUMERATIONS FOR ACTIONS //ENUMERATIONS FOR ACTIONS
enum enum
{ {
@@ -633,7 +638,7 @@ public:
INT8 bMarksmanship; INT8 bMarksmanship;
INT8 bExplosive; INT8 bExplosive;
THROW_PARAMS *pThrowParams; THROW_PARAMS *pThrowParams;
BOOLEAN fTurningFromPronePosition; INT8 bTurningFromPronePosition;
INT8 bReverse; INT8 bReverse;
LEVELNODE *pLevelNode; LEVELNODE *pLevelNode;
LEVELNODE *pExternShadowLevelNode; LEVELNODE *pExternShadowLevelNode;
@@ -1153,7 +1158,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT
BOOLEAN ChangeSoldierState( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT16 usStartingAniCode, BOOLEAN fForce ); BOOLEAN ChangeSoldierState( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT16 usStartingAniCode, BOOLEAN fForce );
void EVENT_SetSoldierPosition( SOLDIERTYPE *pSoldier, FLOAT dNewXPos, FLOAT dNewYPos ); void EVENT_SetSoldierPosition( SOLDIERTYPE *pSoldier, FLOAT dNewXPos, FLOAT dNewYPos );
void EVENT_SetSoldierDestination( SOLDIERTYPE *pSoldier, UINT16 usNewDirection ); void EVENT_SetSoldierDestination( SOLDIERTYPE *pSoldier, UINT8 ubNewDirection );
void EVENT_GetNewSoldierPath( SOLDIERTYPE *pSoldier, UINT16 sDestGridNo, UINT16 usMovementAnim ); void EVENT_GetNewSoldierPath( SOLDIERTYPE *pSoldier, UINT16 sDestGridNo, UINT16 usMovementAnim );
BOOLEAN EVENT_InternalGetNewSoldierPath( SOLDIERTYPE *pSoldier, UINT16 sDestGridNo, UINT16 usMovementAnim, BOOLEAN fFromUI, BOOLEAN fForceRestart ); BOOLEAN EVENT_InternalGetNewSoldierPath( SOLDIERTYPE *pSoldier, UINT16 sDestGridNo, UINT16 usMovementAnim, BOOLEAN fFromUI, BOOLEAN fForceRestart );
+259 -249
View File
@@ -1,51 +1,51 @@
#ifdef PRECOMPILEDHEADERS #ifdef PRECOMPILEDHEADERS
#include "Tactical All.h" #include "Tactical All.h"
#else #else
#include "builddefines.h" #include "builddefines.h"
#include <stdio.h> #include <stdio.h>
#include <memory.h> #include <memory.h>
#include "types.h" #include "types.h"
#include "strategicmap.h" #include "strategicmap.h"
#include "overhead.h" #include "overhead.h"
#include "isometric utils.h" #include "isometric utils.h"
#include "soldier add.h" #include "soldier add.h"
#include "soldier create.h" #include "soldier create.h"
#include "Soldier Init List.h" #include "Soldier Init List.h"
#include "debug.h" #include "debug.h"
#include "Random.h" #include "Random.h"
#include "items.h" #include "items.h"
#include "cursors.h" #include "cursors.h"
#include "Map Information.h" #include "Map Information.h"
#include "soldier profile.h" #include "soldier profile.h"
#include "Sys Globals.h" #include "Sys Globals.h"
#include "EditorMercs.h" #include "EditorMercs.h"
#include "Animation Data.h" #include "Animation Data.h"
#include "message.h" #include "message.h"
#include "Font Control.h" #include "Font Control.h"
#include "Sound Control.h" #include "Sound Control.h"
#include "Quests.h" #include "Quests.h"
#include "Render Fun.h" #include "Render Fun.h"
#include "meanwhile.h" #include "meanwhile.h"
#include "Map Screen Interface Map.h" #include "Map Screen Interface Map.h"
#include "mapscreen.h" #include "mapscreen.h"
#include "Debug Control.h" #include "Debug Control.h"
#include "Inventory Choosing.h" #include "Inventory Choosing.h"
#include "Strategic AI.h" #include "Strategic AI.h"
#include "strategic.h" #include "strategic.h"
#include "Campaign Types.h" #include "Campaign Types.h"
#include "ai.h" #include "ai.h"
#include "NPC.h" #include "NPC.h"
#include "Scheduling.h" #include "Scheduling.h"
#include "opplist.h" #include "opplist.h"
#include "MessageBoxScreen.h" #include "MessageBoxScreen.h"
#include "screenids.h" #include "screenids.h"
#include "SaveLoadScreen.h" #include "SaveLoadScreen.h"
#include "Rotting Corpses.h" #include "Rotting Corpses.h"
#endif #endif
#include "Map Edgepoints.h" #include "Map Edgepoints.h"
@@ -58,8 +58,8 @@ SOLDIERINITNODE *gOriginalSoldierInitListHead = NULL;
SOLDIERINITNODE *gAlternateSoldierInitListHead = NULL; SOLDIERINITNODE *gAlternateSoldierInitListHead = NULL;
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
BOOLEAN ValidateSoldierInitLinks( UINT8 ubCode ); BOOLEAN ValidateSoldierInitLinks( UINT8 ubCode );
BOOLEAN gfDoDialogOnceGameScreenFadesIn = FALSE; BOOLEAN gfDoDialogOnceGameScreenFadesIn = FALSE;
#endif #endif
UINT32 CountNumberOfNodesWithSoldiers() UINT32 CountNumberOfNodesWithSoldiers()
@@ -83,14 +83,14 @@ void SortSoldierInitList();
void InitSoldierInitList() void InitSoldierInitList()
{ {
if( gSoldierInitHead ) if( gSoldierInitHead )
KillSoldierInitList(); KillSoldierInitList();
gSoldierInitHead = NULL; gSoldierInitHead = NULL;
gSoldierInitTail = NULL; gSoldierInitTail = NULL;
} }
void KillSoldierInitList() void KillSoldierInitList()
{ {
while( gSoldierInitHead ) while( gSoldierInitHead )
RemoveSoldierNodeFromInitList( gSoldierInitTail ); RemoveSoldierNodeFromInitList( gSoldierInitTail );
if( gfOriginalList ) if( gfOriginalList )
gOriginalSoldierInitListHead = NULL; gOriginalSoldierInitListHead = NULL;
@@ -220,10 +220,10 @@ BOOLEAN SaveSoldiersToMap( HWFILE fp )
//mode, and kill them all, while replacing them with the proper ones. Not only that, the alternate //mode, and kill them all, while replacing them with the proper ones. Not only that, the alternate
//editing mode is turned off, and if intentions are to play the game, the user will be facing many //editing mode is turned off, and if intentions are to play the game, the user will be facing many
//enemies! //enemies!
#ifdef JA2EDITOR #ifdef JA2EDITOR
if( !gfOriginalList ) if( !gfOriginalList )
ResetAllMercPositions(); ResetAllMercPositions();
#endif #endif
curr = gSoldierInitHead; curr = gSoldierInitHead;
for( i=0; i < gMapInformation.ubNumIndividuals; i++ ) for( i=0; i < gMapInformation.ubNumIndividuals; i++ )
@@ -237,7 +237,7 @@ BOOLEAN SaveSoldiersToMap( HWFILE fp )
{ {
if( !curr->pDetailedPlacement ) if( !curr->pDetailedPlacement )
return FALSE; return FALSE;
// WDS - Clean up inventory handling // WDS - Clean up inventory handling
curr->pDetailedPlacement->CopyNewInventoryToOld(); curr->pDetailedPlacement->CopyNewInventoryToOld();
FileWrite( fp, curr->pDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT_POD /*SIZEOF_SOLDIERCREATE_STRUCT*/, &uiBytesWritten ); FileWrite( fp, curr->pDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT_POD /*SIZEOF_SOLDIERCREATE_STRUCT*/, &uiBytesWritten );
} }
@@ -295,7 +295,7 @@ BOOLEAN LoadSoldiersFromMap( INT8 **hBuffer )
} }
if( tempBasicPlacement.fDetailedPlacement ) if( tempBasicPlacement.fDetailedPlacement )
{ //Add the static detailed placement information in the same newly created node as the basic placement. { //Add the static detailed placement information in the same newly created node as the basic placement.
// WDS - Clean up inventory handling // WDS - Clean up inventory handling
tempDetailedPlacement.initialize(); tempDetailedPlacement.initialize();
//read static detailed placement from file //read static detailed placement from file
LOADDATA( &tempDetailedPlacement, *hBuffer, SIZEOF_SOLDIERCREATE_STRUCT_POD ); LOADDATA( &tempDetailedPlacement, *hBuffer, SIZEOF_SOLDIERCREATE_STRUCT_POD );
@@ -553,7 +553,7 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL )
} }
//else //else
//{ //{
//break; //break;
//} //}
} while (pCorpse); } while (pCorpse);
} }
@@ -567,13 +567,13 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL )
if( ubProfile != NO_PROFILE && !gfEditMode ) if( ubProfile != NO_PROFILE && !gfEditMode )
{ {
if( gMercProfiles[ ubProfile ].sSectorX != gWorldSectorX || if( gMercProfiles[ ubProfile ].sSectorX != gWorldSectorX ||
gMercProfiles[ ubProfile ].sSectorY != gWorldSectorY || gMercProfiles[ ubProfile ].sSectorY != gWorldSectorY ||
gMercProfiles[ ubProfile ].bSectorZ != gbWorldSectorZ || gMercProfiles[ ubProfile ].bSectorZ != gbWorldSectorZ ||
gMercProfiles[ ubProfile ].ubMiscFlags & (PROFILE_MISC_FLAG_RECRUITED | PROFILE_MISC_FLAG_EPCACTIVE) || gMercProfiles[ ubProfile ].ubMiscFlags & (PROFILE_MISC_FLAG_RECRUITED | PROFILE_MISC_FLAG_EPCACTIVE) ||
// gMercProfiles[ ubProfile ].ubMiscFlags2 & PROFILE_MISC_FLAG2_DONT_ADD_TO_SECTOR || // gMercProfiles[ ubProfile ].ubMiscFlags2 & PROFILE_MISC_FLAG2_DONT_ADD_TO_SECTOR ||
!gMercProfiles[ ubProfile ].bLife || !gMercProfiles[ ubProfile ].bLife ||
gMercProfiles[ ubProfile ].fUseProfileInsertionInfo gMercProfiles[ ubProfile ].fUseProfileInsertionInfo
) )
{ {
return FALSE; return FALSE;
} }
@@ -587,8 +587,8 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL )
if( curr->pDetailedPlacement->bBodyType == ICECREAMTRUCK ) if( curr->pDetailedPlacement->bBodyType == ICECREAMTRUCK )
{ //Check to see if Hamous is here and not recruited. If so, add truck { //Check to see if Hamous is here and not recruited. If so, add truck
if( gMercProfiles[ HAMOUS ].sSectorX != gWorldSectorX || if( gMercProfiles[ HAMOUS ].sSectorX != gWorldSectorX ||
gMercProfiles[ HAMOUS ].sSectorY != gWorldSectorY || gMercProfiles[ HAMOUS ].sSectorY != gWorldSectorY ||
gMercProfiles[ HAMOUS ].bSectorZ ) gMercProfiles[ HAMOUS ].bSectorZ )
{ //not here, so don't add { //not here, so don't add
return TRUE; return TRUE;
} }
@@ -632,15 +632,15 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL )
switch( PreRandom( 3 ) ) switch( PreRandom( 3 ) )
{ {
case 0: case 0:
tempDetailedPlacement.bOrders = ONGUARD; tempDetailedPlacement.bOrders = ONGUARD;
break; break;
case 1: case 1:
tempDetailedPlacement.bOrders = CLOSEPATROL; tempDetailedPlacement.bOrders = CLOSEPATROL;
break; break;
case 2: case 2:
tempDetailedPlacement.bOrders = ONCALL; tempDetailedPlacement.bOrders = ONCALL;
break; break;
} }
} }
@@ -857,6 +857,7 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum )
if( AddPlacementToWorld( curr ) ) if( AddPlacementToWorld( curr ) )
{ {
ubNumAdded++; ubNumAdded++;
ubSlotsToFill--;
} }
else else
{ {
@@ -864,9 +865,17 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum )
//engine are already full. Besides, the strategic AI shouldn't be trying to fill a map with //engine are already full. Besides, the strategic AI shouldn't be trying to fill a map with
//more than the maximum allowable soldiers of team. All teams can have a max of 32 individuals, //more than the maximum allowable soldiers of team. All teams can have a max of 32 individuals,
//except for the player which is 20. Players aren't processed in this list anyway. //except for the player which is 20. Players aren't processed in this list anyway.
return ubNumAdded; // 0verhaul: Bzzzzzzzttttt.... Wrong! Other reasons for a false return:
// Profiled merc not in sector
// Profiled merc is recruited
// Profiled merc is escorted
// Profiled merc is dead
// Profiled merc needs to use profile insertion data instead of placement
// None of these instances is a reason to give up on the rest of the placements.
//return ubNumAdded;
} }
ubSlotsToFill--; // 0verhaul: However, move this to the point of successful insertion!
//ubSlotsToFill--;
} }
ubSlotsAvailable--; ubSlotsAvailable--;
//With the decrementing of the slot vars in this manner, the chances increase so that all slots //With the decrementing of the slot vars in this manner, the chances increase so that all slots
@@ -884,7 +893,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
INT32 iRandom; INT32 iRandom;
UINT8 ubMaxNum; UINT8 ubMaxNum;
INT8 bTeam = ENEMY_TEAM; INT8 bTeam = ENEMY_TEAM;
UINT8 ubElitePDSlots = 0, ubEliteDSlots = 0, ubElitePSlots = 0, ubEliteBSlots = 0; UINT8 ubElitePDSlots = 0, ubEliteDSlots = 0, ubElitePSlots = 0, ubEliteBSlots = 0;
UINT8 ubTroopPDSlots = 0, ubTroopDSlots = 0, ubTroopPSlots = 0, ubTroopBSlots = 0; UINT8 ubTroopPDSlots = 0, ubTroopDSlots = 0, ubTroopPSlots = 0, ubTroopBSlots = 0;
UINT8 ubAdminPDSlots = 0, ubAdminDSlots = 0, ubAdminPSlots = 0, ubAdminBSlots = 0; UINT8 ubAdminPDSlots = 0, ubAdminDSlots = 0, ubAdminPSlots = 0, ubAdminBSlots = 0;
UINT8 ubFreeSlots; UINT8 ubFreeSlots;
@@ -921,36 +930,36 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
{ {
switch( curr->pBasicPlacement->ubSoldierClass ) switch( curr->pBasicPlacement->ubSoldierClass )
{ {
case SOLDIER_CLASS_ELITE: case SOLDIER_CLASS_ELITE:
if( curr->pBasicPlacement->fPriorityExistance && curr->pDetailedPlacement ) if( curr->pBasicPlacement->fPriorityExistance && curr->pDetailedPlacement )
ubElitePDSlots++; ubElitePDSlots++;
else if( curr->pBasicPlacement->fPriorityExistance ) else if( curr->pBasicPlacement->fPriorityExistance )
ubElitePSlots++; ubElitePSlots++;
else if( curr->pDetailedPlacement ) else if( curr->pDetailedPlacement )
ubEliteDSlots++; ubEliteDSlots++;
else else
ubEliteBSlots++; ubEliteBSlots++;
break; break;
case SOLDIER_CLASS_ADMINISTRATOR: case SOLDIER_CLASS_ADMINISTRATOR:
if( curr->pBasicPlacement->fPriorityExistance && curr->pDetailedPlacement ) if( curr->pBasicPlacement->fPriorityExistance && curr->pDetailedPlacement )
ubAdminPDSlots++; ubAdminPDSlots++;
else if( curr->pBasicPlacement->fPriorityExistance ) else if( curr->pBasicPlacement->fPriorityExistance )
ubAdminPSlots++; ubAdminPSlots++;
else if( curr->pDetailedPlacement ) else if( curr->pDetailedPlacement )
ubAdminDSlots++; ubAdminDSlots++;
else else
ubAdminBSlots++; ubAdminBSlots++;
break; break;
case SOLDIER_CLASS_ARMY: case SOLDIER_CLASS_ARMY:
if( curr->pBasicPlacement->fPriorityExistance && curr->pDetailedPlacement ) if( curr->pBasicPlacement->fPriorityExistance && curr->pDetailedPlacement )
ubTroopPDSlots++; ubTroopPDSlots++;
else if( curr->pBasicPlacement->fPriorityExistance ) else if( curr->pBasicPlacement->fPriorityExistance )
ubTroopPSlots++; ubTroopPSlots++;
else if( curr->pDetailedPlacement ) else if( curr->pDetailedPlacement )
ubTroopDSlots++; ubTroopDSlots++;
else else
ubTroopBSlots++; ubTroopBSlots++;
break; break;
} }
} }
curr = curr->next; curr = curr->next;
@@ -964,23 +973,23 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
//First, prepare the counters. //First, prepare the counters.
switch( ubCurrClass ) switch( ubCurrClass )
{ {
case SOLDIER_CLASS_ADMINISTRATOR: case SOLDIER_CLASS_ADMINISTRATOR:
pCurrSlots = &ubAdminPDSlots; pCurrSlots = &ubAdminPDSlots;
pCurrTotal = &ubTotalAdmin; pCurrTotal = &ubTotalAdmin;
break; break;
case SOLDIER_CLASS_ELITE: case SOLDIER_CLASS_ELITE:
pCurrSlots = &ubElitePDSlots; pCurrSlots = &ubElitePDSlots;
pCurrTotal = &ubTotalElite; pCurrTotal = &ubTotalElite;
break; break;
case SOLDIER_CLASS_ARMY: case SOLDIER_CLASS_ARMY:
pCurrSlots = &ubTroopPDSlots; pCurrSlots = &ubTroopPDSlots;
pCurrTotal = &ubTotalTroops; pCurrTotal = &ubTotalTroops;
break; break;
} }
//Now, loop through the priority existance and detailed placement section of the list. //Now, loop through the priority existance and detailed placement section of the list.
curr = gSoldierInitHead; curr = gSoldierInitHead;
while( curr && ubMaxNum && *pCurrTotal && *pCurrSlots && while( curr && ubMaxNum && *pCurrTotal && *pCurrSlots &&
curr->pDetailedPlacement && curr->pBasicPlacement->fPriorityExistance ) curr->pDetailedPlacement && curr->pBasicPlacement->fPriorityExistance )
{ {
if( !curr->pSoldier && curr->pBasicPlacement->bTeam == ENEMY_TEAM ) if( !curr->pSoldier && curr->pBasicPlacement->bTeam == ENEMY_TEAM )
{ {
@@ -1020,23 +1029,23 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
//First, prepare the counters. //First, prepare the counters.
switch( ubCurrClass ) switch( ubCurrClass )
{ {
case SOLDIER_CLASS_ADMINISTRATOR: case SOLDIER_CLASS_ADMINISTRATOR:
pCurrSlots = &ubAdminPSlots; pCurrSlots = &ubAdminPSlots;
pCurrTotal = &ubTotalAdmin; pCurrTotal = &ubTotalAdmin;
break; break;
case SOLDIER_CLASS_ELITE: case SOLDIER_CLASS_ELITE:
pCurrSlots = &ubElitePSlots; pCurrSlots = &ubElitePSlots;
pCurrTotal = &ubTotalElite; pCurrTotal = &ubTotalElite;
break; break;
case SOLDIER_CLASS_ARMY: case SOLDIER_CLASS_ARMY:
pCurrSlots = &ubTroopPSlots; pCurrSlots = &ubTroopPSlots;
pCurrTotal = &ubTotalTroops; pCurrTotal = &ubTotalTroops;
break; break;
} }
//Now, loop through the priority existance and non detailed placement section of the list. //Now, loop through the priority existance and non detailed placement section of the list.
curr = mark; curr = mark;
while( curr && ubMaxNum && *pCurrTotal && *pCurrSlots && while( curr && ubMaxNum && *pCurrTotal && *pCurrSlots &&
!curr->pDetailedPlacement && curr->pBasicPlacement->fPriorityExistance ) !curr->pDetailedPlacement && curr->pBasicPlacement->fPriorityExistance )
{ {
if( !curr->pSoldier && curr->pBasicPlacement->bTeam == ENEMY_TEAM ) if( !curr->pSoldier && curr->pBasicPlacement->bTeam == ENEMY_TEAM )
{ {
@@ -1076,23 +1085,23 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
//First, prepare the counters. //First, prepare the counters.
switch( ubCurrClass ) switch( ubCurrClass )
{ {
case SOLDIER_CLASS_ADMINISTRATOR: case SOLDIER_CLASS_ADMINISTRATOR:
pCurrSlots = &ubAdminDSlots; pCurrSlots = &ubAdminDSlots;
pCurrTotal = &ubTotalAdmin; pCurrTotal = &ubTotalAdmin;
break; break;
case SOLDIER_CLASS_ELITE: case SOLDIER_CLASS_ELITE:
pCurrSlots = &ubEliteDSlots; pCurrSlots = &ubEliteDSlots;
pCurrTotal = &ubTotalElite; pCurrTotal = &ubTotalElite;
break; break;
case SOLDIER_CLASS_ARMY: case SOLDIER_CLASS_ARMY:
pCurrSlots = &ubTroopDSlots; pCurrSlots = &ubTroopDSlots;
pCurrTotal = &ubTotalTroops; pCurrTotal = &ubTotalTroops;
break; break;
} }
//Now, loop through the priority existance and detailed placement section of the list. //Now, loop through the priority existance and detailed placement section of the list.
curr = mark; curr = mark;
while( curr && ubMaxNum && *pCurrTotal && *pCurrSlots && while( curr && ubMaxNum && *pCurrTotal && *pCurrSlots &&
curr->pDetailedPlacement && !curr->pBasicPlacement->fPriorityExistance ) curr->pDetailedPlacement && !curr->pBasicPlacement->fPriorityExistance )
{ {
if( !curr->pSoldier && curr->pBasicPlacement->bTeam == ENEMY_TEAM ) if( !curr->pSoldier && curr->pBasicPlacement->bTeam == ENEMY_TEAM )
{ {
@@ -1174,18 +1183,18 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
//First, prepare the counters. //First, prepare the counters.
switch( ubCurrClass ) switch( ubCurrClass )
{ {
case SOLDIER_CLASS_ADMINISTRATOR: case SOLDIER_CLASS_ADMINISTRATOR:
pCurrSlots = &ubAdminBSlots; pCurrSlots = &ubAdminBSlots;
pCurrTotal = &ubTotalAdmin; pCurrTotal = &ubTotalAdmin;
break; break;
case SOLDIER_CLASS_ELITE: case SOLDIER_CLASS_ELITE:
pCurrSlots = &ubEliteBSlots; pCurrSlots = &ubEliteBSlots;
pCurrTotal = &ubTotalElite; pCurrTotal = &ubTotalElite;
break; break;
case SOLDIER_CLASS_ARMY: case SOLDIER_CLASS_ARMY:
pCurrSlots = &ubTroopBSlots; pCurrSlots = &ubTroopBSlots;
pCurrTotal = &ubTotalTroops; pCurrTotal = &ubTotalTroops;
break; break;
} }
//Now, loop through the regular basic placements section of the list. //Now, loop through the regular basic placements section of the list.
curr = mark; curr = mark;
@@ -1266,9 +1275,9 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
/* DISABLE THE OVERRIDE FOR NOW... /* DISABLE THE OVERRIDE FOR NOW...
if( curr->pDetailedPlacement ) if( curr->pDetailedPlacement )
{ //delete the detailed placement information. { //delete the detailed placement information.
MemFree( curr->pDetailedPlacement ); MemFree( curr->pDetailedPlacement );
curr->pDetailedPlacement = NULL; curr->pDetailedPlacement = NULL;
curr->pBasicPlacement->fDetailedPlacement = FALSE; curr->pBasicPlacement->fDetailedPlacement = FALSE;
} }
*/ */
if( AddPlacementToWorld( curr ) ) if( AddPlacementToWorld( curr ) )
@@ -1299,7 +1308,7 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
UINT8 ubMaxNum; UINT8 ubMaxNum;
BOOLEAN fDoPlacement; BOOLEAN fDoPlacement;
INT8 bTeam = ENEMY_TEAM; INT8 bTeam = ENEMY_TEAM;
UINT8 ubEliteSlots = 0; UINT8 ubEliteSlots = 0;
UINT8 ubRegSlots = 0; UINT8 ubRegSlots = 0;
UINT8 ubGreenSlots = 0; UINT8 ubGreenSlots = 0;
UINT8 ubFreeSlots; UINT8 ubFreeSlots;
@@ -1380,9 +1389,9 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
{ {
switch( curr->pBasicPlacement->ubSoldierClass ) switch( curr->pBasicPlacement->ubSoldierClass )
{ {
case SOLDIER_CLASS_ELITE: ubEliteSlots++; break; case SOLDIER_CLASS_ELITE: ubEliteSlots++; break;
case SOLDIER_CLASS_ADMINISTRATOR: ubGreenSlots++; break; case SOLDIER_CLASS_ADMINISTRATOR: ubGreenSlots++; break;
case SOLDIER_CLASS_ARMY: ubRegSlots++; break; case SOLDIER_CLASS_ARMY: ubRegSlots++; break;
} }
} }
curr = curr->next; curr = curr->next;
@@ -1395,18 +1404,18 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
//First, prepare the counters. //First, prepare the counters.
switch( ubCurrClass ) switch( ubCurrClass )
{ {
case SOLDIER_CLASS_ADMINISTRATOR: case SOLDIER_CLASS_ADMINISTRATOR:
pCurrSlots = &ubGreenSlots; pCurrSlots = &ubGreenSlots;
pCurrTotal = &ubNumGreen; pCurrTotal = &ubNumGreen;
break; break;
case SOLDIER_CLASS_ELITE: case SOLDIER_CLASS_ELITE:
pCurrSlots = &ubEliteSlots; pCurrSlots = &ubEliteSlots;
pCurrTotal = &ubNumElites; pCurrTotal = &ubNumElites;
break; break;
case SOLDIER_CLASS_ARMY: case SOLDIER_CLASS_ARMY:
pCurrSlots = &ubRegSlots; pCurrSlots = &ubRegSlots;
pCurrTotal = &ubNumRegs; pCurrTotal = &ubNumRegs;
break; break;
} }
//Now, loop through the basic placement of the list. //Now, loop through the basic placement of the list.
curr = mark; //mark is the marker where the basic placements start. curr = mark; //mark is the marker where the basic placements start.
@@ -1422,15 +1431,15 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
curr->pBasicPlacement->bOrders = STATIONARY; curr->pBasicPlacement->bOrders = STATIONARY;
switch( ubCurrClass ) switch( ubCurrClass )
{ {
case SOLDIER_CLASS_ADMINISTRATOR: case SOLDIER_CLASS_ADMINISTRATOR:
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_GREEN_MILITIA; curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_GREEN_MILITIA;
break; break;
case SOLDIER_CLASS_ARMY: case SOLDIER_CLASS_ARMY:
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_REG_MILITIA; curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_REG_MILITIA;
break; break;
case SOLDIER_CLASS_ELITE: case SOLDIER_CLASS_ELITE:
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_ELITE_MILITIA; curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_ELITE_MILITIA;
break; break;
} }
//found matching team, so add this soldier to the game. //found matching team, so add this soldier to the game.
if( AddPlacementToWorld( curr ) ) if( AddPlacementToWorld( curr ) )
@@ -1524,8 +1533,8 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
} }
void AddSoldierInitListCreatures( BOOLEAN fQueen, UINT8 ubNumLarvae, UINT8 ubNumInfants, void AddSoldierInitListCreatures( BOOLEAN fQueen, UINT8 ubNumLarvae, UINT8 ubNumInfants,
UINT8 ubNumYoungMales, UINT8 ubNumYoungFemales, UINT8 ubNumAdultMales, UINT8 ubNumYoungMales, UINT8 ubNumYoungFemales, UINT8 ubNumAdultMales,
UINT8 ubNumAdultFemales ) UINT8 ubNumAdultFemales )
{ {
SOLDIERINITNODE *curr; SOLDIERINITNODE *curr;
INT32 iRandom; INT32 iRandom;
@@ -1556,9 +1565,9 @@ void AddSoldierInitListCreatures( BOOLEAN fQueen, UINT8 ubNumLarvae, UINT8 ubNum
} }
if( !fQueen ) if( !fQueen )
{ {
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
ScreenMsg( FONT_RED, MSG_ERROR, L"Couldn't place the queen." ); ScreenMsg( FONT_RED, MSG_ERROR, L"Couldn't place the queen." );
#endif #endif
} }
} }
@@ -1867,9 +1876,9 @@ BOOLEAN LoadSoldierInitListLinks( HWFILE hfile )
{ {
curr->ubSoldierID = ubSoldierID; curr->ubSoldierID = ubSoldierID;
if( ubSoldierID >= gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID && if( ubSoldierID >= gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID &&
ubSoldierID <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID || ubSoldierID <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID ||
ubSoldierID >= gTacticalStatus.Team[ CIV_TEAM ].bFirstID && ubSoldierID >= gTacticalStatus.Team[ CIV_TEAM ].bFirstID &&
ubSoldierID <= gTacticalStatus.Team[ CIV_TEAM ].bLastID ) ubSoldierID <= gTacticalStatus.Team[ CIV_TEAM ].bLastID )
{ //only enemies and creatures. { //only enemies and creatures.
curr->pSoldier = MercPtrs[ ubSoldierID ]; curr->pSoldier = MercPtrs[ ubSoldierID ];
} }
@@ -1915,14 +1924,14 @@ void AddSoldierInitListBloodcats()
curr = curr->next; curr = curr->next;
} }
if( bBloodCatPlacements != pSector->bBloodCatPlacements && if( bBloodCatPlacements != pSector->bBloodCatPlacements &&
ubSectorID != SEC_I16 && ubSectorID != SEC_N5 ) ubSectorID != SEC_I16 && ubSectorID != SEC_N5 )
{ {
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
CHAR16 str[200]; CHAR16 str[200];
swprintf( str, L"Table specifies that there are %d bloodcat placements in sector %c%d, but the map actually has %d bloodcat placements. Map value takes precedence. KM,LC:1", swprintf( str, L"Table specifies that there are %d bloodcat placements in sector %c%d, but the map actually has %d bloodcat placements. Map value takes precedence. KM,LC:1",
pSector->bBloodCatPlacements, gWorldSectorY + 'A' - 1, gWorldSectorX, bBloodCatPlacements ); pSector->bBloodCatPlacements, gWorldSectorY + 'A' - 1, gWorldSectorX, bBloodCatPlacements );
DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL ); DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL );
#endif #endif
pSector->bBloodCatPlacements = bBloodCatPlacements; pSector->bBloodCatPlacements = bBloodCatPlacements;
pSector->bBloodCats = -1; pSector->bBloodCats = -1;
if( !bBloodCatPlacements ) if( !bBloodCatPlacements )
@@ -2057,13 +2066,13 @@ void AddProfilesUsingProfileInsertionData()
//Perform various checks to make sure the soldier is actually in the same sector, alive, and so on. //Perform various checks to make sure the soldier is actually in the same sector, alive, and so on.
//More importantly, the flag to use profile insertion data must be set. //More importantly, the flag to use profile insertion data must be set.
if( gMercProfiles[ i ].sSectorX != gWorldSectorX || if( gMercProfiles[ i ].sSectorX != gWorldSectorX ||
gMercProfiles[ i ].sSectorY != gWorldSectorY || gMercProfiles[ i ].sSectorY != gWorldSectorY ||
gMercProfiles[ i ].bSectorZ != gbWorldSectorZ || gMercProfiles[ i ].bSectorZ != gbWorldSectorZ ||
gMercProfiles[ i ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED || gMercProfiles[ i ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED ||
gMercProfiles[ i ].ubMiscFlags & PROFILE_MISC_FLAG_EPCACTIVE || gMercProfiles[ i ].ubMiscFlags & PROFILE_MISC_FLAG_EPCACTIVE ||
// gMercProfiles[ i ].ubMiscFlags2 & PROFILE_MISC_FLAG2_DONT_ADD_TO_SECTOR || // gMercProfiles[ i ].ubMiscFlags2 & PROFILE_MISC_FLAG2_DONT_ADD_TO_SECTOR ||
!gMercProfiles[ i ].bLife || !gMercProfiles[ i ].bLife ||
!gMercProfiles[ i ].fUseProfileInsertionInfo !gMercProfiles[ i ].fUseProfileInsertionInfo
) )
{ //Don't add, so skip to the next soldier. { //Don't add, so skip to the next soldier.
continue; continue;
@@ -2075,7 +2084,8 @@ void AddProfilesUsingProfileInsertionData()
UINT8 ubID; UINT8 ubID;
//Set up the create struct so that we can properly create the profile soldier. //Set up the create struct so that we can properly create the profile soldier.
memset( &MercCreateStruct, 0, sizeof( MercCreateStruct ) ); // It's been C++'d, so don't do this!
//memset( &MercCreateStruct, 0, sizeof( MercCreateStruct ) );
MercCreateStruct.bTeam = CIV_TEAM; MercCreateStruct.bTeam = CIV_TEAM;
MercCreateStruct.ubProfile = (UINT8)i; MercCreateStruct.ubProfile = (UINT8)i;
MercCreateStruct.sSectorX = gWorldSectorX; MercCreateStruct.sSectorX = gWorldSectorX;
@@ -2135,11 +2145,11 @@ void AddProfilesNotUsingProfileInsertionData()
while( curr ) while( curr )
{ {
if( !curr->pSoldier && if( !curr->pSoldier &&
curr->pBasicPlacement->bTeam == CIV_TEAM && curr->pBasicPlacement->bTeam == CIV_TEAM &&
curr->pDetailedPlacement && curr->pDetailedPlacement &&
curr->pDetailedPlacement->ubProfile != NO_PROFILE && curr->pDetailedPlacement->ubProfile != NO_PROFILE &&
!gMercProfiles[ curr->pDetailedPlacement->ubProfile ].fUseProfileInsertionInfo && !gMercProfiles[ curr->pDetailedPlacement->ubProfile ].fUseProfileInsertionInfo &&
gMercProfiles[ curr->pDetailedPlacement->ubProfile ].bLife ) gMercProfiles[ curr->pDetailedPlacement->ubProfile ].bLife )
{ {
AddPlacementToWorld( curr ); AddPlacementToWorld( curr );
} }
@@ -2171,31 +2181,31 @@ BOOLEAN ValidateSoldierInitLinks( UINT8 ubCode )
{ {
switch( ubCode ) switch( ubCode )
{ {
case 1: //loading save case 1: //loading save
swprintf( str, L"Error detected in save file WHILE LOADING. Please send save and text files associated with save to Kris and Dave." swprintf( str, L"Error detected in save file WHILE LOADING. Please send save and text files associated with save to Kris and Dave."
L" After doing so, go back into the game and immediately resave the game which will fix the problem." L" After doing so, go back into the game and immediately resave the game which will fix the problem."
L" This is the bug responsible for mercs disappearing. Be prepared to answer lots of questions..." ); L" This is the bug responsible for mercs disappearing. Be prepared to answer lots of questions..." );
DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, str, SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, ErrorDetectedInSaveCallback ); DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, str, SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, ErrorDetectedInSaveCallback );
break; break;
case 2: //saving game case 2: //saving game
//swprintf( str, L"Error detected WHILE SAVING file. Please send save and text files associated with save to Kris and Dave." //swprintf( str, L"Error detected WHILE SAVING file. Please send save and text files associated with save to Kris and Dave."
// L" After doing so, go back into the game and try reloading the new save and saving it again which *could* fix the problem." // L" After doing so, go back into the game and try reloading the new save and saving it again which *could* fix the problem."
// L" This is the bug responsible for mercs disappearing. Be prepared to answer lots of questions..." ); // L" This is the bug responsible for mercs disappearing. Be prepared to answer lots of questions..." );
//if( guiPreviousOptionScreen == MAP_SCREEN ) //if( guiPreviousOptionScreen == MAP_SCREEN )
// DoMapMessageBox( MSG_BOX_BASIC_STYLE, str, MAP_SCREEN, MSG_BOX_FLAG_OK, NULL ); // DoMapMessageBox( MSG_BOX_BASIC_STYLE, str, MAP_SCREEN, MSG_BOX_FLAG_OK, NULL );
//else //else
// DoMessageBox( MSG_BOX_BASIC_STYLE, str, GAME_SCREEN, MSG_BOX_FLAG_OK, NULL, NULL ); // DoMessageBox( MSG_BOX_BASIC_STYLE, str, GAME_SCREEN, MSG_BOX_FLAG_OK, NULL, NULL );
break; break;
case 3: //entering sector using temp files (before fade in) case 3: //entering sector using temp files (before fade in)
gfDoDialogOnceGameScreenFadesIn = TRUE; gfDoDialogOnceGameScreenFadesIn = TRUE;
break; break;
case 4: //after fade in case 4: //after fade in
gfDoDialogOnceGameScreenFadesIn = FALSE; gfDoDialogOnceGameScreenFadesIn = FALSE;
swprintf( str, L"Error detected while entering sector USING TEMP FILES. Please send previous save and text files associated with save to Kris and Dave." swprintf( str, L"Error detected while entering sector USING TEMP FILES. Please send previous save and text files associated with save to Kris and Dave."
L" After doing so, go back into the game and saving the game, reloading it, and saving it again *could* fix it." L" After doing so, go back into the game and saving the game, reloading it, and saving it again *could* fix it."
L" This is the bug responsible for mercs disappearing. Be prepared to answer lots of questions..." ); L" This is the bug responsible for mercs disappearing. Be prepared to answer lots of questions..." );
DoMessageBox( MSG_BOX_BASIC_STYLE, str, GAME_SCREEN, MSG_BOX_FLAG_OK, NULL, NULL ); DoMessageBox( MSG_BOX_BASIC_STYLE, str, GAME_SCREEN, MSG_BOX_FLAG_OK, NULL, NULL );
break; break;
} }
return FALSE; return FALSE;
} }
@@ -2237,7 +2247,7 @@ BOOLEAN NewWayOfLoadingEnemySoldierInitListLinks( HWFILE hfile )
{ {
curr->ubSoldierID = ubSoldierID; curr->ubSoldierID = ubSoldierID;
if( ubSoldierID >= gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID && if( ubSoldierID >= gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID &&
ubSoldierID <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID ) ubSoldierID <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID )
{ //only enemies and creatures. { //only enemies and creatures.
curr->pSoldier = MercPtrs[ ubSoldierID ]; curr->pSoldier = MercPtrs[ ubSoldierID ];
} }
@@ -2283,7 +2293,7 @@ BOOLEAN NewWayOfLoadingCivilianInitListLinks( HWFILE hfile )
{ {
curr->ubSoldierID = ubSoldierID; curr->ubSoldierID = ubSoldierID;
if( ubSoldierID >= gTacticalStatus.Team[ CIV_TEAM ].bFirstID && if( ubSoldierID >= gTacticalStatus.Team[ CIV_TEAM ].bFirstID &&
ubSoldierID <= gTacticalStatus.Team[ CIV_TEAM ].bLastID ) ubSoldierID <= gTacticalStatus.Team[ CIV_TEAM ].bLastID )
{ //only enemies and creatures. { //only enemies and creatures.
curr->pSoldier = MercPtrs[ ubSoldierID ]; curr->pSoldier = MercPtrs[ ubSoldierID ];
} }
@@ -2329,7 +2339,7 @@ BOOLEAN LookAtButDontProcessEnemySoldierInitListLinks( HWFILE hfile )
{ {
curr->ubSoldierID = ubSoldierID; curr->ubSoldierID = ubSoldierID;
if( ubSoldierID >= gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID && if( ubSoldierID >= gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID &&
ubSoldierID <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID ) ubSoldierID <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID )
{ //only enemies and creatures. { //only enemies and creatures.
curr->pSoldier = MercPtrs[ ubSoldierID ]; curr->pSoldier = MercPtrs[ ubSoldierID ];
} }
@@ -2407,15 +2417,15 @@ void AddSoldierInitListMilitiaOnEdge( UINT8 ubStrategicInsertionCode, UINT8 ubNu
switch( ubStrategicInsertionCode ) switch( ubStrategicInsertionCode )
{ {
case INSERTION_CODE_NORTH: bDesiredDirection = SOUTHEAST; break; case INSERTION_CODE_NORTH: bDesiredDirection = SOUTHEAST; break;
case INSERTION_CODE_EAST: bDesiredDirection = SOUTHWEST; break; case INSERTION_CODE_EAST: bDesiredDirection = SOUTHWEST; break;
case INSERTION_CODE_SOUTH: bDesiredDirection = NORTHWEST; break; case INSERTION_CODE_SOUTH: bDesiredDirection = NORTHWEST; break;
case INSERTION_CODE_WEST: bDesiredDirection = NORTHEAST; break; case INSERTION_CODE_WEST: bDesiredDirection = NORTHEAST; break;
default: AssertMsg( 0, "Illegal direction passed to AddSoldierInitListMilitiaOnEdge()" ); break; default: AssertMsg( 0, "Illegal direction passed to AddSoldierInitListMilitiaOnEdge()" ); break;
} }
#ifdef JA2TESTVERSION #ifdef JA2TESTVERSION
ScreenMsg( FONT_RED, MSG_INTERFACE, L"Militia reinforcements have arrived! (%d admins, %d troops, %d elite)", ubNumGreen, ubNumReg, ubNumElites ); ScreenMsg( FONT_RED, MSG_INTERFACE, L"Militia reinforcements have arrived! (%d admins, %d troops, %d elite)", ubNumGreen, ubNumReg, ubNumElites );
#endif #endif
ChooseMapEdgepoints( &MapEdgepointInfo, ubStrategicInsertionCode, (UINT8)(ubNumGreen + ubNumReg + ubNumElites) ); ChooseMapEdgepoints( &MapEdgepointInfo, ubStrategicInsertionCode, (UINT8)(ubNumGreen + ubNumReg + ubNumElites) );
ubCurrSlot = 0; ubCurrSlot = 0;
@@ -2529,9 +2539,9 @@ void AddSoldierInitListMilitiaOnEdge( UINT8 ubStrategicInsertionCode, UINT8 ubNu
pSoldier->ubNoiseVolume = MAX_MISC_NOISE_DURATION; pSoldier->ubNoiseVolume = MAX_MISC_NOISE_DURATION;
} }
// if ( GetTimeOfDayAmbientLightLevel() < NORMAL_LIGHTLEVEL_DAY + 2 ) // if ( GetTimeOfDayAmbientLightLevel() < NORMAL_LIGHTLEVEL_DAY + 2 )
// gTacticalStatus.Team[ ENEMY_TEAM ].bAwareOfOpposition = TRUE; // gTacticalStatus.Team[ ENEMY_TEAM ].bAwareOfOpposition = TRUE;
// gTacticalStatus.Team[ MILITIA_TEAM ].bAwareOfOpposition = TRUE; // gTacticalStatus.Team[ MILITIA_TEAM ].bAwareOfOpposition = TRUE;
//Setup the position //Setup the position
if( ubCurrSlot < MapEdgepointInfo.ubNumPoints ) if( ubCurrSlot < MapEdgepointInfo.ubNumPoints )
+5 -2
View File
@@ -53,6 +53,7 @@
#include "personnel.h" #include "personnel.h"
#include "environment.h" #include "environment.h"
#include "Player Command.h" #include "Player Command.h"
#include "strategic.h"
#endif #endif
#ifdef JA2EDITOR #ifdef JA2EDITOR
@@ -1083,7 +1084,7 @@ BOOLEAN RecruitRPC( UINT8 ubCharNum )
} }
} }
// swap item to hand // swap item to hand
SwapObjs( &(pNewSoldier->inv[ bSlot ]), &(pNewSoldier->inv[ HANDPOS ]) ); SwapObjs( pNewSoldier, bSlot, HANDPOS );
} }
} }
@@ -1211,8 +1212,10 @@ BOOLEAN UnRecruitEPC( UINT8 ubCharNum )
} }
// how do we decide whether or not to set this? // how do we decide whether or not to set this?
gMercProfiles[ ubCharNum ].fUseProfileInsertionInfo = TRUE;
gMercProfiles[ ubCharNum ].ubMiscFlags3 |= PROFILE_MISC_FLAG3_PERMANENT_INSERTION_CODE; gMercProfiles[ ubCharNum ].ubMiscFlags3 |= PROFILE_MISC_FLAG3_PERMANENT_INSERTION_CODE;
gMercProfiles[ ubCharNum ].usStrategicInsertionData = pSoldier->sGridNo;
gMercProfiles[ ubCharNum ].fUseProfileInsertionInfo = TRUE;
gMercProfiles[ ubCharNum ].ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
// Add this guy to CIV team! // Add this guy to CIV team!
pNewSoldier = ChangeSoldierTeam( pSoldier, CIV_TEAM ); pNewSoldier = ChangeSoldierTeam( pSoldier, CIV_TEAM );
+9 -2
View File
@@ -150,7 +150,7 @@ void PickBurstLocations( SOLDIERTYPE *pSoldier )
ubShotsPerBurst = pSoldier->bDoAutofire; ubShotsPerBurst = pSoldier->bDoAutofire;
} }
else if ( gbNumBurstLocations > 0 ) else if ( gbNumBurstLocations > 0 )
ubShotsPerBurst = pSoldier->bDoAutofire / gbNumBurstLocations; ubShotsPerBurst = pSoldier->bDoAutofire; // / gbNumBurstLocations;
} }
else else
@@ -163,8 +163,15 @@ void PickBurstLocations( SOLDIERTYPE *pSoldier )
ubShotsPerBurst = __min( ubShotsPerBurst, MAX_BURST_SPREAD_TARGETS); ubShotsPerBurst = __min( ubShotsPerBurst, MAX_BURST_SPREAD_TARGETS);
if (ubShotsPerBurst == 1)
{
pSoldier->fDoSpread = FALSE;
return;
}
// Use # gridnos accululated and # burst shots to determine accululator // Use # gridnos accululated and # burst shots to determine accululator
dStep = gbNumBurstLocations / (FLOAT)ubShotsPerBurst; // Calculate it so that the actual last chosen shot location is the last spread point
dStep = (gbNumBurstLocations-1) / (FLOAT)(ubShotsPerBurst-1);
//Loop through our shots! //Loop through our shots!
for ( cnt = 0; cnt < ubShotsPerBurst; cnt++ ) for ( cnt = 0; cnt < ubShotsPerBurst; cnt++ )
+1 -1
View File
@@ -1198,7 +1198,7 @@ BOOLEAN LoadCurrentSectorsInformationFromTempItemsFile()
} }
//if the save is an older version, use theold way of oading it up //if the save is an older version, use the old way of loading it up
if( guiSavedGameVersion < 57 ) if( guiSavedGameVersion < 57 )
{ {
if( DoesTempFileExistsForMap( SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) ) if( DoesTempFileExistsForMap( SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
+4 -4
View File
@@ -556,7 +556,7 @@ void DisplayHiddenInterrupt( SOLDIERTYPE * pSoldier )
// Stop our guy.... // Stop our guy....
AdjustNoAPToFinishMove( MercPtrs[ LATEST_INTERRUPT_GUY ], TRUE ); AdjustNoAPToFinishMove( MercPtrs[ LATEST_INTERRUPT_GUY ], TRUE );
// Stop him from going to prone position if doing a turn while prone // Stop him from going to prone position if doing a turn while prone
MercPtrs[ LATEST_INTERRUPT_GUY ]->fTurningFromPronePosition = FALSE; MercPtrs[ LATEST_INTERRUPT_GUY ]->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"about to call AddTopMessage"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"about to call AddTopMessage");
// get rid of any old overlay message // get rid of any old overlay message
@@ -862,7 +862,7 @@ void StartInterrupt( void )
{ {
// Stop this guy.... // Stop this guy....
AdjustNoAPToFinishMove( MercPtrs[ LATEST_INTERRUPT_GUY ], TRUE ); AdjustNoAPToFinishMove( MercPtrs[ LATEST_INTERRUPT_GUY ], TRUE );
MercPtrs[ LATEST_INTERRUPT_GUY ]->fTurningFromPronePosition = FALSE; MercPtrs[ LATEST_INTERRUPT_GUY ]->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
} }
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"StartInterrupt done"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"StartInterrupt done");
@@ -1770,7 +1770,7 @@ void VerifyOutOfTurnOrderArray()
AdjustNoAPToFinishMove( MercPtrs[ gubOutOfTurnOrder[ ubNextIndex ] ], TRUE ); AdjustNoAPToFinishMove( MercPtrs[ gubOutOfTurnOrder[ ubNextIndex ] ], TRUE );
// If they were turning from prone, stop them // If they were turning from prone, stop them
MercPtrs[ gubOutOfTurnOrder[ ubNextIndex ] ]->fTurningFromPronePosition = FALSE; MercPtrs[ gubOutOfTurnOrder[ ubNextIndex ] ]->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
DeleteFromIntList( ubNextIndex, FALSE ); DeleteFromIntList( ubNextIndex, FALSE );
} }
@@ -1826,7 +1826,7 @@ void VerifyOutOfTurnOrderArray()
AdjustNoAPToFinishMove( MercPtrs[ gubOutOfTurnOrder[ ubLoop ] ], TRUE ); AdjustNoAPToFinishMove( MercPtrs[ gubOutOfTurnOrder[ ubLoop ] ], TRUE );
// If they were turning from prone, stop them // If they were turning from prone, stop them
MercPtrs[ gubOutOfTurnOrder[ ubLoop ] ]->fTurningFromPronePosition = FALSE; MercPtrs[ gubOutOfTurnOrder[ ubLoop ] ]->bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
DeleteFromIntList( ubLoop, FALSE ); DeleteFromIntList( ubLoop, FALSE );
+2 -2
View File
@@ -3110,7 +3110,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
} }
else if ( bSlot2 != ITEM_NOT_FOUND ) else if ( bSlot2 != ITEM_NOT_FOUND )
{ {
SwapObjs( &(pTeamSoldier->inv[bSlot1]), &(pTeamSoldier->inv[bSlot2] ) ); SwapObjs( pTeamSoldier, bSlot1, bSlot2 );
} }
break; break;
} }
@@ -3153,7 +3153,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
} }
else if ( bSlot2 != ITEM_NOT_FOUND ) else if ( bSlot2 != ITEM_NOT_FOUND )
{ {
SwapObjs( &(pTeamSoldier->inv[bSlot1]), &(pTeamSoldier->inv[bSlot2] ) ); SwapObjs( pTeamSoldier, bSlot1, bSlot2 );
} }
break; break;
} }
+3 -2
View File
@@ -201,7 +201,8 @@ UINT8 GetProperItemCursor( UINT8 ubSoldierID, UINT16 ubItemIndex, UINT16 usMapPo
if ( fRecalc && gfUIFullTargetFound ) if ( fRecalc && gfUIFullTargetFound )
{ {
// ATE: Check for ammo // ATE: Check for ammo
if ( IsValidTargetMerc( (UINT8)gusUIFullTargetID ) && EnoughAmmo( pSoldier, FALSE, HANDPOS ) ) if ( IsValidTargetMerc( (UINT8)gusUIFullTargetID ) && EnoughAmmo( pSoldier, FALSE, HANDPOS ) &&
(!IsValidSecondHandShotForReloadingPurposes( pSoldier) || EnoughAmmo( pSoldier, FALSE, SECONDHANDPOS) ) )
{ {
// IF it's an ememy, goto confirm action mode // IF it's an ememy, goto confirm action mode
if ( ( guiUIFullTargetFlags & ENEMY_MERC ) && ( guiUIFullTargetFlags & VISIBLE_MERC ) && !( guiUIFullTargetFlags & DEAD_MERC ) && !gfCannotGetThrough ) if ( ( guiUIFullTargetFlags & ENEMY_MERC ) && ( guiUIFullTargetFlags & VISIBLE_MERC ) && !( guiUIFullTargetFlags & DEAD_MERC ) && !gfCannotGetThrough )
@@ -972,7 +973,7 @@ UINT8 HandleNonActivatedTargetCursor( SOLDIERTYPE *pSoldier, UINT16 usMapPos , B
} }
// Check for enough ammo... // Check for enough ammo...
if ( !EnoughAmmo( pSoldier, FALSE, HANDPOS ) ) if ( !EnoughAmmo( pSoldier, FALSE, HANDPOS ) || (IsValidSecondHandShotForReloadingPurposes( pSoldier) && !EnoughAmmo( pSoldier, FALSE, SECONDHANDPOS) ) )
{ {
// Check if ANY ammo exists..... // Check if ANY ammo exists.....
if ( FindAmmoToReload( pSoldier, HANDPOS, NO_SLOT ) == NO_SLOT ) if ( FindAmmoToReload( pSoldier, HANDPOS, NO_SLOT ) == NO_SLOT )
+11 -7
View File
@@ -1300,7 +1300,7 @@ BOOLEAN FireWeapon( SOLDIERTYPE *pSoldier , INT16 sTargetGridNo )
// SET ATTACKER TO NOBODY, WILL GET SET EVENTUALLY // SET ATTACKER TO NOBODY, WILL GET SET EVENTUALLY
pSoldier->ubOppNum = NOBODY ; pSoldier->ubOppNum = NOBODY ;
UINT16 usItemClass = Item[ pSoldier->usAttackingWeapon ].usItemClass; UINT32 usItemClass = Item[ pSoldier->usAttackingWeapon ].usItemClass;
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 )
usItemClass = IC_LAUNCHER; usItemClass = IC_LAUNCHER;
@@ -1316,15 +1316,19 @@ BOOLEAN FireWeapon( SOLDIERTYPE *pSoldier , INT16 sTargetGridNo )
// ATE: PAtch up - bookkeeping for spreading done out of whak // ATE: PAtch up - bookkeeping for spreading done out of whak
if ( pSoldier->fDoSpread) if ( pSoldier->fDoSpread)
{ {
if (pSoldier->bDoBurst )
{ // 0verhaul: This check does not work! All auto-fire has bDoBurst turned on. And only allowing a spread
pSoldier->fDoSpread = FALSE; // for a single-shot mode is useless.
} //if (pSoldier->bDoBurst )
//{
// pSoldier->fDoSpread = FALSE;
//}
//else
// 0verhaul: The original code seemed brain damaged: If the current spread target was 0 it would shoot at the // 0verhaul: The original code seemed brain damaged: If the current spread target was 0 it would shoot at the
// non-spread target grid # instead. Also fDoSpread is used as a counter from 1 to MAX_BURST_SPREAD_TARGETS, // non-spread target grid # instead. Also fDoSpread is used as a counter from 1 to MAX_BURST_SPREAD_TARGETS,
// but was actually reset before it got there. So the final spread target would never be shot at. Hopefully this // but was actually reset before it got there. So the final spread target would never be shot at. Hopefully this
// will work better. // will work better.
else if (pSoldier->fDoSpread > MAX_BURST_SPREAD_TARGETS || if (pSoldier->fDoSpread > MAX_BURST_SPREAD_TARGETS ||
pSoldier->sSpreadLocations[ pSoldier->fDoSpread - 1 ] == 0) pSoldier->sSpreadLocations[ pSoldier->fDoSpread - 1 ] == 0)
{ {
if (pSoldier->fDoSpread == 1) if (pSoldier->fDoSpread == 1)
@@ -1574,7 +1578,7 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT16 sTargetGridNo )
sprintf( zBurstString, gzBurstSndStrings[ Weapon[ usItemNum ].sBurstSound ], bShotsToFire ); sprintf( zBurstString, gzBurstSndStrings[ Weapon[ usItemNum ].sBurstSound ], bShotsToFire );
INT8 volume = HIGHVOLUME; INT8 volume = HIGHVOLUME;
if ( noisefactor < 100 ) volume = (volume * noisefactor) / 100; if ( noisefactor < 100 ) volume = (INT8) ((volume * noisefactor) / 100);
// Try playing sound... // Try playing sound...
pSoldier->iBurstSoundID = PlayJA2SampleFromFile( zBurstString, RATE_11025, SoundVolume( (INT8) volume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); pSoldier->iBurstSoundID = PlayJA2SampleFromFile( zBurstString, RATE_11025, SoundVolume( (INT8) volume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
} }
+3 -4
View File
@@ -288,7 +288,8 @@ void ExamineSlantRoofFOVSlots( )
void RevealRoofsAndItems(SOLDIERTYPE *pSoldier, UINT32 itemsToo, BOOLEAN fShowLocators, UINT8 ubLevel, BOOLEAN fForce ) void RevealRoofsAndItems(SOLDIERTYPE *pSoldier, UINT32 itemsToo, BOOLEAN fShowLocators, UINT8 ubLevel, BOOLEAN fForce )
{ {
UINT32 maincnt,markercnt,marker,tilesLeftToSee,cnt,prevmarker; UINT32 maincnt,markercnt,marker,tilesLeftToSee,prevmarker;
UINT8 cnt;
INT32 Inc[6],Dir[6]; INT32 Inc[6],Dir[6];
INT8 itemVisible = FALSE; INT8 itemVisible = FALSE;
INT8 Blocking,twoMoreTiles,markerDir; INT8 Blocking,twoMoreTiles,markerDir;
@@ -371,9 +372,7 @@ void RevealRoofsAndItems(SOLDIERTYPE *pSoldier, UINT32 itemsToo, BOOLEAN fShowLo
BuildSightDir(dir,(UINT32 *)&Dir[0],(UINT32 *)&Dir[1],(UINT32 *)&Dir[2],(UINT32 *)&Dir[3],(UINT32 *)&Dir[4]); BuildSightDir(dir,(UINT32 *)&Dir[0],(UINT32 *)&Dir[1],(UINT32 *)&Dir[2],(UINT32 *)&Dir[3],(UINT32 *)&Dir[4]);
for (cnt = 0; cnt < 5; cnt++) for (cnt = 0; cnt < 5; cnt++)
{ Inc[cnt] = DirectionInc( (UINT8) Dir[cnt]);
Inc[cnt] = DirectionInc( Dir[cnt] );
}
// create gridno increment for NOVIEW - in other words, no increment! // create gridno increment for NOVIEW - in other words, no increment!
Inc[5] = 0; Inc[5] = 0;
+2 -2
View File
@@ -4409,8 +4409,8 @@ void WriteQuantityAndAttachments( OBJECTTYPE *pObject, INT32 yp )
{ //ammo { //ammo
if( pObject->ubNumberOfObjects > 1 ) if( pObject->ubNumberOfObjects > 1 )
{ {
CHAR16 str[50]; CHAR16 str[100];
CHAR16 temp[5]; CHAR16 temp[10];
UINT8 i; UINT8 i;
swprintf( str, L"Clips: %d (%d", pObject->ubNumberOfObjects, pObject->ItemData.Generic.bStatus[0] ); swprintf( str, L"Clips: %d (%d", pObject->ubNumberOfObjects, pObject->ItemData.Generic.bStatus[0] );
for( i = 1; i < pObject->ubNumberOfObjects; i++ ) for( i = 1; i < pObject->ubNumberOfObjects; i++ )