void SearchForOtherMembersWithinPitRadiusAndMakeThemFall( INT16 sGridNo, INT16 sRadius ) { INT16 x, y, sNewGridNo; UINT8 ubID; SOLDIERTYPE *pSoldier; PlayJA2Sample( CAVE_COLLAPSE, RATE_11025, SoundVolume( HIGHVOLUME, sGridNo ), 1, SoundDir( sGridNo ) ); for( y = -sRadius; y <= sRadius; y++ ) for( x = -sRadius; x <= sRadius; x++ ) { sNewGridNo = sGridNo + y * WORLD_COLS + x; //Validate gridno location, and check if there are any mercs here. If there are //any mercs, we want them to fall below. The exitgrid already exists at this location if( GridNoOnVisibleWorldTile( sNewGridNo ) ) { // Check if buddy exists here..... ubID = WhoIsThere2( sNewGridNo, 0 ); if ( ubID != NOBODY ) { // OK, make guy fall... // Set data to look for exit grid.... pSoldier = MercPtrs[ ubID ]; pSoldier->uiPendingActionData4 = sNewGridNo; EVENT_InitNewSoldierAnim( pSoldier, FALL_INTO_PIT, 0 , FALSE ); } } } }
// This function changes the graphic of the statue and adds the exit grid... void ChangeO3SectorStatue( BOOLEAN fFromExplosion ) { EXITGRID ExitGrid; UINT16 usTileIndex; INT16 sX, sY; // Remove old graphic ApplyMapChangesToMapTempFile( TRUE ); // Remove it! // Get index for it... GetTileIndexFromTypeSubIndex( EIGHTOSTRUCT, (INT8)( 5 ), &usTileIndex ); RemoveStruct( 13830, usTileIndex ); // Add new one... if ( fFromExplosion ) { // Use damaged peice GetTileIndexFromTypeSubIndex( EIGHTOSTRUCT, (INT8)( 7 ), &usTileIndex ); } else { GetTileIndexFromTypeSubIndex( EIGHTOSTRUCT, (INT8)( 8 ), &usTileIndex ); // Play sound... PlayJA2Sample( OPEN_STATUE, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); } AddStructToHead( 13830, usTileIndex ); // Add exit grid ExitGrid.ubGotoSectorX = 3; ExitGrid.ubGotoSectorY = MAP_ROW_O; ExitGrid.ubGotoSectorZ = 1; ExitGrid.usGridNo = 13037; AddExitGridToWorld( 13669, &ExitGrid ); gpWorldLevelData[ 13669 ].uiFlags |= MAPELEMENT_REVEALED; // Turn off permenant changes.... ApplyMapChangesToMapTempFile( FALSE ); // Re-render the world! gTacticalStatus.uiFlags |= NOHIDE_REDUNDENCY; // FOR THE NEXT RENDER LOOP, RE-EVALUATE REDUNDENT TILES InvalidateWorldRedundency( ); SetRenderFlags(RENDER_FLAG_FULL); // Redo movement costs.... ConvertGridNoToXY( 13830, &sX, &sY ); RecompileLocalMovementCostsFromRadius( 13830, 5 ); }
UINT32 PlaySoldierJA2Sample( UINT16 usID, UINT32 usNum, UINT32 usRate, UINT32 ubVolume, UINT32 ubLoops, UINT32 uiPan, BOOLEAN fCheck ) { if( !( gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) ) { // CHECK IF GUY IS ON SCREEN BEFORE PLAYING! if ( ( MercPtrs[ usID ]->bVisible != -1 ) || !fCheck ) { return( PlayJA2Sample( usNum, usRate, CalculateSoundEffectsVolume( ubVolume ), ubLoops, uiPan ) ); } } return( 0 ); }
UINT8 HandleActivatedTargetCursor( SOLDIERTYPE *pSoldier, UINT16 usMapPos, BOOLEAN fShowAPs, BOOLEAN fRecalc, UINT32 uiCursorFlags ) { UINT8 switchVal; BOOLEAN fEnoughPoints = TRUE; UINT8 bFutureAim; INT16 sAPCosts; UINT16 usCursor=0; BOOLEAN fMaxPointLimitHit = FALSE; UINT16 usInHand; usInHand = pSoldier->inv[ HANDPOS ].usItem; if ( Item[ usInHand ].usItemClass != IC_THROWING_KNIFE ) { // If we are in realtime, follow! if ( ( !( gTacticalStatus.uiFlags & INCOMBAT ) ) ) { if ( ( gAnimControl[ MercPtrs[ gusSelectedSoldier ]->usAnimState ].uiFlags & ANIM_STATIONARY ) ) { if ( gUITargetShotWaiting ) { guiPendingOverrideEvent = CA_MERC_SHOOT; } } //SoldierFollowGridNo( pSoldier, usMapPos ); } // Check if we are reloading if ( ( ( gTacticalStatus.uiFlags & REALTIME ) || !( gTacticalStatus.uiFlags & INCOMBAT ) ) ) { if ( pSoldier->fReloading || pSoldier->fPauseAim ) { return( ACTION_TARGET_RELOADING ); } } } // Determine where we are shooting / aiming //if ( fRecalc ) { DetermineCursorBodyLocation( (UINT8)gusSelectedSoldier, TRUE, TRUE ); } if ( gTacticalStatus.uiFlags & TURNBASED && ( gTacticalStatus.uiFlags & INCOMBAT ) ) { gsCurrentActionPoints = CalcTotalAPsToAttack( pSoldier, usMapPos, TRUE, (INT8)(pSoldier->bShownAimTime / 2) ); gfUIDisplayActionPoints = TRUE; gfUIDisplayActionPointsCenter = TRUE; // If we don't have any points and we are at the first refine, do nothing but warn! if ( !EnoughPoints( pSoldier, gsCurrentActionPoints, 0 , FALSE ) ) { gfUIDisplayActionPointsInvalid = TRUE; fMaxPointLimitHit = TRUE; } else { bFutureAim = (INT8)( pSoldier->bShownAimTime + 2 ); if ( bFutureAim <= REFINE_AIM_5 ) { sAPCosts = MinAPsToAttack( pSoldier, usMapPos, TRUE ) + ( bFutureAim / 2 ); // Determine if we can afford! if ( !EnoughPoints( pSoldier, (INT16)sAPCosts, 0 , FALSE ) ) { fEnoughPoints = FALSE; } } } } if ( ( ( gTacticalStatus.uiFlags & REALTIME ) || !( gTacticalStatus.uiFlags & INCOMBAT ) ) ) { if ( !pSoldier->fPauseAim ) { if ( COUNTERDONE( TARGETREFINE ) ) { // Reset counter RESETCOUNTER( TARGETREFINE ); if ( pSoldier->bDoBurst ) { pSoldier->bShownAimTime = REFINE_AIM_BURST; } else { pSoldier->bShownAimTime++; if ( pSoldier->bShownAimTime > REFINE_AIM_5 ) { pSoldier->bShownAimTime = REFINE_AIM_5; } else { if ( pSoldier->bShownAimTime % 2 ) { PlayJA2Sample( TARG_REFINE_BEEP, RATE_11025, MIDVOLUME, 1, MIDDLEPAN ); } } } } } } if ( fRecalc ) { if ( gusUIFullTargetID != NOBODY ) { if ( SoldierToSoldierBodyPartChanceToGetThrough( pSoldier, MercPtrs[ gusUIFullTargetID ], pSoldier->bAimShotLocation ) < OK_CHANCE_TO_GET_THROUGH ) { gfCannotGetThrough = TRUE; } else { gfCannotGetThrough = FALSE; } } else { if ( SoldierToLocationChanceToGetThrough( pSoldier, usMapPos, (INT8) gsInterfaceLevel, pSoldier->bTargetCubeLevel, NOBODY ) < OK_CHANCE_TO_GET_THROUGH ) { gfCannotGetThrough = TRUE; } else { gfCannotGetThrough = FALSE; } } } // OK, if we begin to move, reset the cursor... if ( uiCursorFlags & MOUSE_MOVING ) { //gfCannotGetThrough = FALSE; } if ( fMaxPointLimitHit ) { // Check if we're in burst mode! if ( pSoldier->bDoBurst ) { usCursor = ACTION_TARGETREDBURST_UICURSOR; } else if ( Item[ usInHand ].usItemClass == IC_THROWING_KNIFE ) { usCursor = RED_THROW_UICURSOR; } else { usCursor = ACTION_TARGETRED_UICURSOR; } } else if ( pSoldier->bDoBurst ) { if ( pSoldier->fDoSpread ) { usCursor = ACTION_TARGETREDBURST_UICURSOR; } else { usCursor = ACTION_TARGETCONFIRMBURST_UICURSOR; } } else { // IF we are in turnbased, half the shown time values if ( gTacticalStatus.uiFlags & TURNBASED && (gTacticalStatus.uiFlags & INCOMBAT) ) { switchVal = pSoldier->bShownAimTime; } else { switchVal = pSoldier->bShownAimTime; } switch( switchVal ) { case REFINE_AIM_1: if ( Item[ usInHand ].usItemClass == IC_THROWING_KNIFE ) { if ( gfDisplayFullCountRing ) { usCursor = ACTION_THROWAIMYELLOW1_UICURSOR; } else if ( fEnoughPoints ) { usCursor = ACTION_THROWAIM1_UICURSOR; } else { usCursor = ACTION_THROWAIMCANT1_UICURSOR; } } else { if ( gfDisplayFullCountRing ) { usCursor = ACTION_TARGETAIMYELLOW1_UICURSOR; } else if ( fEnoughPoints ) { usCursor = ACTION_TARGETAIM1_UICURSOR; } else { usCursor = ACTION_TARGETAIMCANT1_UICURSOR; } } break; case REFINE_AIM_2: if ( Item[ usInHand ].usItemClass == IC_THROWING_KNIFE ) { if ( gfDisplayFullCountRing ) { usCursor = ACTION_THROWAIMYELLOW2_UICURSOR; } else if ( fEnoughPoints ) { usCursor = ACTION_THROWAIM3_UICURSOR; } else { usCursor = ACTION_THROWAIMCANT2_UICURSOR; } } else { if ( gfDisplayFullCountRing ) { usCursor = ACTION_TARGETAIMYELLOW2_UICURSOR; } else if ( fEnoughPoints ) { usCursor = ACTION_TARGETAIM3_UICURSOR; } else { usCursor = ACTION_TARGETAIMCANT2_UICURSOR; } } break; case REFINE_AIM_3: if ( Item[ usInHand ].usItemClass == IC_THROWING_KNIFE ) { if ( gfDisplayFullCountRing ) { usCursor = ACTION_THROWAIMYELLOW3_UICURSOR; } else if ( fEnoughPoints ) { usCursor = ACTION_THROWAIM5_UICURSOR; } else { usCursor = ACTION_THROWAIMCANT3_UICURSOR; } } else { if ( gfDisplayFullCountRing ) { usCursor = ACTION_TARGETAIMYELLOW3_UICURSOR; } else if ( fEnoughPoints ) { usCursor = ACTION_TARGETAIM5_UICURSOR; } else { usCursor = ACTION_TARGETAIMCANT3_UICURSOR; } } break; case REFINE_AIM_4: if ( Item[ usInHand ].usItemClass == IC_THROWING_KNIFE ) { if ( gfDisplayFullCountRing ) { usCursor = ACTION_THROWAIMYELLOW4_UICURSOR; } else if ( fEnoughPoints ) { usCursor = ACTION_THROWAIM7_UICURSOR; } else { usCursor = ACTION_THROWAIMCANT4_UICURSOR; } } else { if ( gfDisplayFullCountRing ) { usCursor = ACTION_TARGETAIMYELLOW4_UICURSOR; } else if ( fEnoughPoints ) { usCursor = ACTION_TARGETAIM7_UICURSOR; } else { usCursor = ACTION_TARGETAIMCANT4_UICURSOR; } } break; case REFINE_AIM_5: if ( Item[ usInHand ].usItemClass == IC_THROWING_KNIFE ) { if ( gfDisplayFullCountRing ) { usCursor = ACTION_THROWAIMFULL_UICURSOR; } else if ( fEnoughPoints ) { usCursor = ACTION_THROWAIM9_UICURSOR; } else { usCursor = ACTION_THROWAIMCANT5_UICURSOR; } } else { if ( gfDisplayFullCountRing ) { usCursor = ACTION_TARGETAIMFULL_UICURSOR; } else if ( fEnoughPoints ) { usCursor = ACTION_TARGETAIM9_UICURSOR; } else { usCursor = ACTION_TARGETAIMCANT5_UICURSOR; } } break; case REFINE_AIM_MID1: usCursor = ACTION_TARGETAIM2_UICURSOR; break; case REFINE_AIM_MID2: usCursor = ACTION_TARGETAIM4_UICURSOR; break; case REFINE_AIM_MID3: usCursor = ACTION_TARGETAIM6_UICURSOR; break; case REFINE_AIM_MID4: usCursor = ACTION_TARGETAIM8_UICURSOR; break; } } if ( !fMaxPointLimitHit ) { // Remove flash flag! RemoveCursorFlags( gUICursors[ usCursor ].usFreeCursorName, CURSOR_TO_FLASH ); RemoveCursorFlags( gUICursors[ usCursor ].usFreeCursorName, CURSOR_TO_PLAY_SOUND ); if ( gfCannotGetThrough ) { SetCursorSpecialFrame( gUICursors[ usCursor ].usFreeCursorName, 1 ); } else { if ( !InRange( pSoldier, usMapPos ) ) { // OK, make buddy flash! SetCursorFlags( gUICursors[ usCursor ].usFreeCursorName, CURSOR_TO_FLASH ); SetCursorFlags( gUICursors[ usCursor ].usFreeCursorName, CURSOR_TO_PLAY_SOUND ); } else { SetCursorSpecialFrame( gUICursors[ usCursor ].usFreeCursorName, 0 ); } } } return( (UINT8)usCursor ); }
UINT8 HandlePunchCursor( SOLDIERTYPE *pSoldier, UINT16 sGridNo, BOOLEAN fActivated, UINT32 uiCursorFlags ) { INT16 sAPCosts; INT8 bFutureAim; BOOLEAN fEnoughPoints = TRUE; // DRAW PATH TO GUY HandleUIMovementCursor( pSoldier, uiCursorFlags, sGridNo, MOVEUI_TARGET_MERCS ); if ( fActivated ) { DetermineCursorBodyLocation( pSoldier->ubID, TRUE, TRUE ); if ( gfUIHandleShowMoveGrid ) { gfUIHandleShowMoveGrid = 2; } // Calculate action points if ( gTacticalStatus.uiFlags & TURNBASED ) { gsCurrentActionPoints = CalcTotalAPsToAttack( pSoldier, sGridNo, TRUE, (INT8)(pSoldier->bShownAimTime / 2) ); gfUIDisplayActionPoints = TRUE; gfUIDisplayActionPointsCenter = TRUE; // If we don't have any points and we are at the first refine, do nothing but warn! if ( !EnoughPoints( pSoldier, gsCurrentActionPoints, 0 , FALSE ) ) { gfUIDisplayActionPointsInvalid = TRUE; if ( pSoldier->bShownAimTime == REFINE_PUNCH_1 ) { return( ACTION_PUNCH_RED ); } } bFutureAim = (INT8)( REFINE_PUNCH_2 ); sAPCosts = CalcTotalAPsToAttack( pSoldier, sGridNo, TRUE, (INT8)(bFutureAim / 2) ); // Determine if we can afford! if ( !EnoughPoints( pSoldier, (INT16)sAPCosts, 0 , FALSE ) ) { fEnoughPoints = FALSE; } } if ( ( ( gTacticalStatus.uiFlags & REALTIME ) || !( gTacticalStatus.uiFlags & INCOMBAT ) ) ) { if ( !pSoldier->fPauseAim ) { if ( COUNTERDONE( NONGUNTARGETREFINE ) ) { // Reset counter RESETCOUNTER( NONGUNTARGETREFINE ); if ( pSoldier->bShownAimTime == REFINE_PUNCH_1 ) { PlayJA2Sample( TARG_REFINE_BEEP, RATE_11025, MIDVOLUME, 1, MIDDLEPAN ); } pSoldier->bShownAimTime = REFINE_PUNCH_2; } } } switch( pSoldier->bShownAimTime ) { case REFINE_PUNCH_1: if ( gfDisplayFullCountRing ) { return( ACTION_PUNCH_YELLOW_AIM1_UICURSOR ); } else if ( fEnoughPoints ) { return( ACTION_PUNCH_RED_AIM1_UICURSOR ); } else { return( ACTION_PUNCH_NOGO_AIM1_UICURSOR ); } break; case REFINE_PUNCH_2: if ( gfDisplayFullCountRing ) { return( ACTION_PUNCH_YELLOW_AIM2_UICURSOR ); } else if ( fEnoughPoints ) { return( ACTION_PUNCH_RED_AIM2_UICURSOR ); } else { return( ACTION_PUNCH_NOGO_AIM2_UICURSOR ); } break; default: Assert( FALSE ); // no return value! return(0); break; } } else { gfUIDisplayActionPointsCenter = TRUE; // CHECK IF WE ARE ON A GUY ( THAT'S NOT SELECTED )! if ( gfUIFullTargetFound && !( guiUIFullTargetFlags & SELECTED_MERC ) ) { DetermineCursorBodyLocation( pSoldier->ubID, TRUE, TRUE ); return( ACTION_PUNCH_RED ); } else { return( ACTION_PUNCH_GRAY ); } } }
void UpdateAniTiles( ) { ANITILE *pAniNode = NULL; ANITILE *pNode = NULL; UINT32 uiClock = GetJA2Clock( ); UINT16 usMaxFrames, usMinFrames; UINT8 ubTempDir; // LOOP THROUGH EACH NODE pAniNode = pAniTileHead; while( pAniNode != NULL ) { pNode = pAniNode; pAniNode = pAniNode->pNext; if ( (uiClock - pNode->uiTimeLastUpdate ) > (UINT32)pNode->sDelay && !( pNode->uiFlags & ANITILE_PAUSED ) ) { pNode->uiTimeLastUpdate = GetJA2Clock( ); if ( pNode->uiFlags & ( ANITILE_OPTIMIZEFORSLOWMOVING ) ) { pNode->pLevelNode->uiFlags |= (LEVELNODE_DYNAMIC ); pNode->pLevelNode->uiFlags &= (~LEVELNODE_LASTDYNAMIC); } else if ( pNode->uiFlags & ( ANITILE_OPTIMIZEFORSMOKEEFFECT ) ) { // pNode->pLevelNode->uiFlags |= LEVELNODE_DYNAMICZ; ResetSpecificLayerOptimizing( TILES_DYNAMIC_STRUCTURES ); pNode->pLevelNode->uiFlags &= (~LEVELNODE_LASTDYNAMIC); pNode->pLevelNode->uiFlags |= (LEVELNODE_DYNAMIC ); } if ( pNode->uiFlags & ANITILE_FORWARD ) { usMaxFrames = pNode->usNumFrames; if ( pNode->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME ) { ubTempDir = gOneCDirection[ pNode->uiUserData3 ]; usMaxFrames = (UINT16)usMaxFrames + ( pNode->usNumFrames * ubTempDir ); } if ( pNode->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME ) { ubTempDir = gb4DirectionsFrom8[ pNode->uiUserData3 ]; usMaxFrames = (UINT16)usMaxFrames + ( pNode->usNumFrames * ubTempDir ); } if ( ( pNode->sCurrentFrame + 1 ) < usMaxFrames ) { pNode->sCurrentFrame++; pNode->pLevelNode->sCurrentFrame = pNode->sCurrentFrame; if ( pNode->uiFlags & ANITILE_EXPLOSION ) { // Talk to the explosion data... UpdateExplosionFrame( pNode->uiUserData3, pNode->sCurrentFrame ); } // CHECK IF WE SHOULD BE DISPLAYING TRANSLUCENTLY! if ( pNode->sCurrentFrame == pNode->ubKeyFrame1 ) { switch( pNode->uiKeyFrame1Code ) { case ANI_KEYFRAME_BEGIN_TRANSLUCENCY: pNode->pLevelNode->uiFlags |= LEVELNODE_REVEAL; break; case ANI_KEYFRAME_CHAIN_WATER_EXPLOSION: IgniteExplosion( pNode->ubUserData2, pNode->pLevelNode->sRelativeX, pNode->pLevelNode->sRelativeY, 0, pNode->sGridNo, (UINT16)( pNode->uiUserData ), 0 ); break; case ANI_KEYFRAME_DO_SOUND: PlayJA2Sample( pNode->uiUserData, RATE_11025, SoundVolume( MIDVOLUME, (INT16)pNode->uiUserData3 ), 1, SoundDir( (INT16)pNode->uiUserData3 ) ); break; } } // CHECK IF WE SHOULD BE DISPLAYING TRANSLUCENTLY! if ( pNode->sCurrentFrame == pNode->ubKeyFrame2 ) { UINT8 ubExpType; switch( pNode->uiKeyFrame2Code ) { case ANI_KEYFRAME_BEGIN_DAMAGE: ubExpType = Explosive[ Item[ (UINT16)pNode->uiUserData ].ubClassIndex ].ubType; if ( ubExpType == EXPLOSV_TEARGAS || ubExpType == EXPLOSV_MUSTGAS || ubExpType == EXPLOSV_SMOKE ) { // Do sound.... // PlayJA2Sample( AIR_ESCAPING_1, RATE_11025, SoundVolume( HIGHVOLUME, pNode->sGridNo ), 1, SoundDir( pNode->sGridNo ) ); NewSmokeEffect( pNode->sGridNo, (UINT16)pNode->uiUserData, gExplosionData[ pNode->uiUserData3 ].Params.bLevel, (UINT8)pNode->ubUserData2 ); } else { SpreadEffect( pNode->sGridNo, Explosive[ Item[ (UINT16)pNode->uiUserData ].ubClassIndex ].ubRadius, (UINT16)pNode->uiUserData, (UINT8)pNode->ubUserData2, FALSE, gExplosionData[ pNode->uiUserData3 ].Params.bLevel, -1 ); } // Forfait any other animations this frame.... return; } } } else { // We are done! if ( pNode->uiFlags & ANITILE_LOOPING ) { pNode->sCurrentFrame = pNode->sStartFrame; if ( ( pNode->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME ) ) { // Our start frame is actually a direction indicator ubTempDir = gOneCDirection[ pNode->uiUserData3 ]; pNode->sCurrentFrame = (UINT16)( pNode->usNumFrames * ubTempDir ); } if ( ( pNode->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME ) ) { // Our start frame is actually a direction indicator ubTempDir = gb4DirectionsFrom8[ pNode->uiUserData3 ]; pNode->sCurrentFrame = (UINT16)( pNode->usNumFrames * ubTempDir ); } } else if ( pNode->uiFlags & ANITILE_REVERSE_LOOPING ) { // Turn off backwards flag pNode->uiFlags &= (~ANITILE_FORWARD ); // Turn onn forwards flag pNode->uiFlags |= ANITILE_BACKWARD; } else { // Delete from world! DeleteAniTile( pNode ); // Turn back on redunency checks! gTacticalStatus.uiFlags &= (~NOHIDE_REDUNDENCY); return; } } } if ( pNode->uiFlags & ANITILE_BACKWARD ) { if ( pNode->uiFlags & ANITILE_ERASEITEMFROMSAVEBUFFFER ) { // ATE: Check if bounding box is on the screen... if ( pNode->bFrameCountAfterStart == 0 ) { pNode->bFrameCountAfterStart = 1; pNode->pLevelNode->uiFlags |= (LEVELNODE_DYNAMIC ); // Dangerous here, since we may not even be on the screen... SetRenderFlags( RENDER_FLAG_FULL ); continue; } } usMinFrames = 0; if ( pNode->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME ) { ubTempDir = gOneCDirection[ pNode->uiUserData3 ]; usMinFrames = ( pNode->usNumFrames * ubTempDir ); } if ( pNode->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME ) { ubTempDir = gb4DirectionsFrom8[ pNode->uiUserData3 ]; usMinFrames = ( pNode->usNumFrames * ubTempDir ); } if ( ( pNode->sCurrentFrame - 1 ) >= usMinFrames ) { pNode->sCurrentFrame--; pNode->pLevelNode->sCurrentFrame = pNode->sCurrentFrame; if ( pNode->uiFlags & ANITILE_EXPLOSION ) { // Talk to the explosion data... UpdateExplosionFrame( pNode->uiUserData3, pNode->sCurrentFrame ); } } else { // We are done! if ( pNode->uiFlags & ANITILE_PAUSE_AFTER_LOOP ) { // Turn off backwards flag pNode->uiFlags &= (~ANITILE_BACKWARD ); // Pause pNode->uiFlags |= ANITILE_PAUSED; } else if ( pNode->uiFlags & ANITILE_LOOPING ) { pNode->sCurrentFrame = pNode->sStartFrame; if ( ( pNode->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME ) ) { // Our start frame is actually a direction indicator ubTempDir = gOneCDirection[ pNode->uiUserData3 ]; pNode->sCurrentFrame = (UINT16)( pNode->usNumFrames * ubTempDir ); } if ( ( pNode->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME ) ) { // Our start frame is actually a direction indicator ubTempDir = gb4DirectionsFrom8[ pNode->uiUserData3 ]; pNode->sCurrentFrame = (UINT16)( pNode->usNumFrames * ubTempDir ); } } else if ( pNode->uiFlags & ANITILE_REVERSE_LOOPING ) { // Turn off backwards flag pNode->uiFlags &= (~ANITILE_BACKWARD ); // Turn onn forwards flag pNode->uiFlags |= ANITILE_FORWARD; } else { // Delete from world! DeleteAniTile( pNode ); return; } if ( pNode->uiFlags & ANITILE_ERASEITEMFROMSAVEBUFFFER ) { // ATE: Check if bounding box is on the screen... pNode->bFrameCountAfterStart = 0; //pNode->pLevelNode->uiFlags |= LEVELNODE_UPDATESAVEBUFFERONCE; // Dangerous here, since we may not even be on the screen... SetRenderFlags( RENDER_FLAG_FULL ); } } } } else { if ( pNode->uiFlags & ( ANITILE_OPTIMIZEFORSLOWMOVING ) ) { // ONLY TURN OFF IF PAUSED... if ( ( pNode->uiFlags & ANITILE_ERASEITEMFROMSAVEBUFFFER ) ) { if ( pNode->uiFlags & ANITILE_PAUSED ) { if ( pNode->pLevelNode->uiFlags & LEVELNODE_DYNAMIC ) { pNode->pLevelNode->uiFlags &= (~LEVELNODE_DYNAMIC ); pNode->pLevelNode->uiFlags |= (LEVELNODE_LASTDYNAMIC); SetRenderFlags( RENDER_FLAG_FULL ); } } } else { pNode->pLevelNode->uiFlags &= (~LEVELNODE_DYNAMIC ); pNode->pLevelNode->uiFlags |= (LEVELNODE_LASTDYNAMIC); } } else if ( pNode->uiFlags & ( ANITILE_OPTIMIZEFORSMOKEEFFECT ) ) { pNode->pLevelNode->uiFlags |= (LEVELNODE_LASTDYNAMIC); pNode->pLevelNode->uiFlags &= (~LEVELNODE_DYNAMIC ); } } } }
BOOLEAN ExecuteGameEvent( EVENT *pEvent ) { SOLDIERTYPE *pSoldier; // Switch on event type switch( pEvent->uiEvent ) { case E_PLAYSOUND: memcpy( &EPlaySound, pEvent->pData, pEvent->uiDataSize ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Play Sound"); PlayJA2Sample( EPlaySound.usIndex, EPlaySound.usRate, EPlaySound.ubVolume, EPlaySound.ubLoops, EPlaySound.uiPan ); break; case S_CHANGESTATE: memcpy( &SChangeState, pEvent->pData, pEvent->uiDataSize ); // Get soldier pointer from ID if ( GetSoldier( &pSoldier, SChangeState.usSoldierID ) == FALSE ) { // Handle Error? DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Invalid Soldier ID"); break; } // check for error if( pSoldier->uiUniqueSoldierIdValue != SChangeState.uiUniqueId ) { break; } // Call soldier function // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Event Pump: ChangeState %S (%d)", gAnimControl[ SChangeState.ubNewState ].zAnimStr, SChangeState.usSoldierID ) ); pSoldier->EVENT_InitNewSoldierAnim( SChangeState.usNewState, SChangeState.usStartingAniCode, SChangeState.fForce ); break; case S_CHANGEDEST: memcpy( &SChangeDest, pEvent->pData, pEvent->uiDataSize ); // Get soldier pointer from ID if ( GetSoldier( &pSoldier, SChangeDest.usSoldierID ) == FALSE ) { // Handle Error? DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Event Pump: Invalid Soldier ID #%d", SChangeDest.usSoldierID) ); break; } // check for error if( pSoldier->uiUniqueSoldierIdValue != SChangeDest.uiUniqueId ) { break; } // Call soldier function DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Change Dest"); pSoldier->EVENT_SetSoldierDestination( (UINT8) SChangeDest.usNewDestination ); break; case S_SETPOSITION: memcpy( &SSetPosition, pEvent->pData, pEvent->uiDataSize ); // Get soldier pointer from ID if ( GetSoldier( &pSoldier, SSetPosition.usSoldierID ) == FALSE ) { // Handle Error? DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Invalid Soldier ID"); break; } // check for error if( pSoldier->uiUniqueSoldierIdValue != SSetPosition.uiUniqueId ) { break; } // Call soldier function // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Event Pump: SetPosition ( %f %f ) ( %d )", SSetPosition.dNewXPos, SSetPosition.dNewYPos, SSetPosition.usSoldierID ) ); pSoldier->EVENT_SetSoldierPosition( SSetPosition.dNewXPos, SSetPosition.dNewYPos ); break; case S_GETNEWPATH: memcpy( &SGetNewPath, pEvent->pData, pEvent->uiDataSize ); // Get soldier pointer from ID if ( GetSoldier( &pSoldier, SGetNewPath.usSoldierID ) == FALSE ) { // Handle Error? DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Invalid Soldier ID"); break; } // check for error if( pSoldier->uiUniqueSoldierIdValue != SGetNewPath.uiUniqueId ) { break; } // Call soldier function DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: GetNewPath"); pSoldier->EVENT_GetNewSoldierPath( SGetNewPath.sDestGridNo, SGetNewPath.usMovementAnim ); break; case S_BEGINTURN: memcpy( &SBeginTurn, pEvent->pData, pEvent->uiDataSize ); // Get soldier pointer from ID if ( GetSoldier( &pSoldier, SBeginTurn.usSoldierID ) == FALSE ) { // Handle Error? DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Invalid Soldier ID"); break; } // check for error if( pSoldier->uiUniqueSoldierIdValue != SBeginTurn.uiUniqueId ) { break; } // Call soldier function DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: BeginTurn"); pSoldier->EVENT_BeginMercTurn( FALSE, 0 ); break; case S_CHANGESTANCE: memcpy( &SChangeStance, pEvent->pData, pEvent->uiDataSize ); // Get soldier pointer from ID if ( GetSoldier( &pSoldier, SChangeStance.usSoldierID ) == FALSE ) { // Handle Error? DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Invalid Soldier ID"); break; } // check for error if( pSoldier->uiUniqueSoldierIdValue != SChangeStance.uiUniqueId ) { break; } // Call soldier function DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: ChangeStance"); pSoldier->ChangeSoldierStance( SChangeStance.ubNewStance ); break; case S_SETDIRECTION: memcpy( &SSetDirection, pEvent->pData, pEvent->uiDataSize ); // Get soldier pointer from ID if ( GetSoldier( &pSoldier, SSetDirection.usSoldierID ) == FALSE ) { // Handle Error? DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Invalid Soldier ID"); break; } // check for error if( pSoldier->uiUniqueSoldierIdValue != SSetDirection.uiUniqueId ) { break; } // Call soldier function DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Event Pump: SetDirection: Dir( %d )", SSetDirection.usNewDirection) ); pSoldier->EVENT_SetSoldierDirection( SSetDirection.usNewDirection ); break; case S_SETDESIREDDIRECTION: memcpy( &SSetDesiredDirection, pEvent->pData, pEvent->uiDataSize ); // Get soldier pointer from ID if ( GetSoldier( &pSoldier, SSetDesiredDirection.usSoldierID ) == FALSE ) { // Handle Error? DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Invalid Soldier ID"); break; } // check for error if( pSoldier->uiUniqueSoldierIdValue != SSetDesiredDirection.uiUniqueId ) { break; } // Call soldier function DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Event Pump: SetDesiredDirection: Dir( %d )", SSetDesiredDirection.usDesiredDirection) ); pSoldier->EVENT_SetSoldierDesiredDirection( (UINT8) SSetDesiredDirection.usDesiredDirection ); break; case S_BEGINFIREWEAPON: memcpy( &SBeginFireWeapon, pEvent->pData, pEvent->uiDataSize ); // Get soldier pointer from ID if ( GetSoldier( &pSoldier, SBeginFireWeapon.usSoldierID ) == FALSE ) { pSoldier = NULL; break; // Handle Error? // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Invalid Soldier ID"); } // check for error if( pSoldier->uiUniqueSoldierIdValue != SBeginFireWeapon.uiUniqueId ) { break; } // Call soldier function DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Begin Fire Weapon"); pSoldier->sTargetGridNo = SBeginFireWeapon.sTargetGridNo; pSoldier->bTargetLevel = SBeginFireWeapon.bTargetLevel; pSoldier->bTargetCubeLevel = SBeginFireWeapon.bTargetCubeLevel; pSoldier->EVENT_FireSoldierWeapon( SBeginFireWeapon.sTargetGridNo ); break; case S_FIREWEAPON: memcpy( &SFireWeapon, pEvent->pData, pEvent->uiDataSize ); // Get soldier pointer from ID if ( GetSoldier( &pSoldier, SFireWeapon.usSoldierID ) == FALSE ) { // Handle Error? DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Invalid Soldier ID"); break; } // check for error if( pSoldier->uiUniqueSoldierIdValue != SFireWeapon.uiUniqueId ) { break; } // Call soldier function DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: FireWeapon"); pSoldier->sTargetGridNo = SFireWeapon.sTargetGridNo; pSoldier->bTargetLevel = SFireWeapon.bTargetLevel; pSoldier->bTargetCubeLevel = SFireWeapon.bTargetCubeLevel; FireWeapon( pSoldier, SFireWeapon.sTargetGridNo ); break; case S_WEAPONHIT: memcpy( &SWeaponHit, pEvent->pData, pEvent->uiDataSize ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Event Pump: WeaponHit %d Damage", SWeaponHit.sDamage ) ); WeaponHit( SWeaponHit.usSoldierID, SWeaponHit.usWeaponIndex, SWeaponHit.sDamage, SWeaponHit.sBreathLoss, SWeaponHit.usDirection, SWeaponHit.sXPos, SWeaponHit.sYPos, SWeaponHit.sZPos, SWeaponHit.sRange, SWeaponHit.ubAttackerID, SWeaponHit.fHit, SWeaponHit.ubSpecial, SWeaponHit.ubLocation ); break; case S_STRUCTUREHIT: memcpy( &SStructureHit, pEvent->pData, pEvent->uiDataSize ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Event Pump: StructureHit" ) ); StructureHit( SStructureHit.iBullet, SStructureHit.usWeaponIndex, SStructureHit.bWeaponStatus, SStructureHit.ubAttackerID, SStructureHit.sXPos, SStructureHit.sYPos, SStructureHit.sZPos, SStructureHit.usStructureID, SStructureHit.iImpact, TRUE ); break; case S_WINDOWHIT: memcpy( &SWindowHit, pEvent->pData, pEvent->uiDataSize ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Event Pump: WindowHit" ) ); WindowHit( SWindowHit.sGridNo, SWindowHit.usStructureID, SWindowHit.fBlowWindowSouth, SWindowHit.fLargeForce ); break; case S_MISS: memcpy( &SMiss, pEvent->pData, pEvent->uiDataSize ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Event Pump: Shot Miss ( obsolete )" ) ); //ShotMiss( SMiss.ubAttackerID ); break; case S_NOISE: memcpy( &SNoise, pEvent->pData, pEvent->uiDataSize ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Event Pump: Noise from %d at %d/%d, type %d volume %d", SNoise.ubNoiseMaker, SNoise.sGridNo, SNoise.bLevel, SNoise.ubNoiseType, SNoise.ubVolume ) ); OurNoise( SNoise.ubNoiseMaker, SNoise.sGridNo, SNoise.bLevel, SNoise.ubTerrType, SNoise.ubVolume, SNoise.ubNoiseType, SNoise.zNoiseMessage ); break; case S_STOP_MERC: memcpy( &SStopMerc, pEvent->pData, pEvent->uiDataSize ); // Get soldier pointer from ID if ( GetSoldier( &pSoldier, SStopMerc.usSoldierID ) == FALSE ) { // Handle Error? DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Invalid Soldier ID"); break; } if( pSoldier->uiUniqueSoldierIdValue != SStopMerc.uiUniqueId ) { break; } // Call soldier function DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Event Pump: Stop Merc at Gridno %d", SStopMerc.sGridNo )); pSoldier->EVENT_StopMerc( SStopMerc.sGridNo, SStopMerc.ubDirection ); break; default: DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Event Pump: Invalid Event Received"); return( FALSE ); } return( TRUE ); }