void CTaskSimpleChokingSA::UpdateChoke ( CPed* pPed, CPed* pAttacker, bool bIsTearGas )
{
    // Get game interfaces
    CPedSA* pPedSA = dynamic_cast < CPedSA* > ( pPed );
	if ( !pPedSA ) return;

    CPedSAInterface* pPedInterface = pPedSA->GetPedInterface ();

    CPedSAInterface* pAttackerInterface = NULL;
    if ( pAttacker )
    {
        CPedSA* pAttackerSA = dynamic_cast < CPedSA* > ( pAttacker );
		if ( pAttackerSA )
			pAttackerInterface = pAttackerSA->GetPedInterface ();
    }

    // Call the func
    DWORD dwThisInterface = (DWORD)this->GetInterface();
    DWORD dwFunc = FUNC_CTaskSimpleChoking__UpdateChoke;
    _asm
    {
        mov         ecx, dwThisInterface
        push        bIsTearGas
        push        pAttackerInterface
        push        pPedInterface
        call        dwFunc
    }
}
示例#2
0
/**
 * \todo Handle pEvent correctly to convert it
 */
bool CTaskSA::MakeAbortable(CPed* pPed, const int iPriority, const CEvent* pEvent)
{
    DEBUG_TRACE("bool CTaskSA::MakeAbortable(CPed* pPed, const int iPriority, const CEvent* pEvent)");

    CPedSA* pPedSA = dynamic_cast<CPedSA*>(pPed);
    if (!pPedSA)
        return false;

    DWORD dwPedInterface = (DWORD)pPedSA->GetInterface();
    DWORD dwThisInterface = (DWORD)this->GetInterface();
    DWORD dwFunc = this->GetInterface()->VTBL->MakeAbortable;
    bool  bReturn = 0;
    if (dwFunc != 0x82263A && dwFunc)            // 82263A = purecall
    {
        _asm
        {
            mov     ecx, dwThisInterface
            push    pEvent
            push    iPriority
            push    dwPedInterface
            call    dwFunc
            mov     bReturn, al
        }
    }
    return bReturn;
}
示例#3
0
VOID ReturnContextToLocalPlayer()
{   
    if ( bNotInLocalContext )
    {
        // Grab the remote data storage for the player we context switched to
        CPlayerPed* pContextSwitchedPlayerPed = dynamic_cast < CPlayerPed* > ( pContextSwitchedPed );
        if ( pContextSwitchedPlayerPed )
        {
            CRemoteDataStorageSA * data = CRemoteDataSA::GetRemoteDataStorage ( pContextSwitchedPlayerPed );
            if ( data )
            {
                // Store any changes the game has made to the pad
                CPad* pLocalPad = pGameInterface->GetPad ();
                CPadSAInterface* pLocalPadInterface = ( (CPadSA*) pLocalPad )->GetInterface ();
                memcpy ( &data->m_pad, pLocalPadInterface, sizeof ( CPadSAInterface ) );            
            }
        }

        pGameInterface->GetPad()->Restore();
        
        *(float *)VAR_CameraRotation = fLocalPlayerCameraRotation;

        bNotInLocalContext = false;

        CPed* pLocalPlayerPed = pGameInterface->GetPools ()->GetPedFromRef ( (DWORD)1 ); // the player
        CPedSA* pLocalPlayerPedSA = dynamic_cast < CPedSA* > ( pLocalPlayerPed );
        if ( pLocalPlayerPedSA )
        {
            CEntitySAInterface * ped = pLocalPlayerPedSA->GetInterface();
            *(DWORD *)0xB7CD98 = (DWORD)ped;
        }


        PostContextSwitch();

        if ( m_pPostContextSwitchHandler )
        {
            m_pPostContextSwitchHandler ();
        }        
    }
    else
    {
        // Store any changes to the local-players stats?
        if ( !bLocalStatsStatic )
        {
            memcpy ( &localStatsData.StatTypesFloat, (void *)0xb79380, sizeof(float) * MAX_FLOAT_STATS );
            memcpy ( &localStatsData.StatTypesInt, (void *)0xb79000, sizeof(int) * MAX_INT_STATS );
            memcpy ( &localStatsData.StatReactionValue, (void *)0xb78f10, sizeof(float) * MAX_REACTION_STATS );
        }
    }

    // radio change on startup hack
    //0050237C   90               NOP
    memset((void *)0x50237C, 0x90, 5);
    memset((void *)0x5023A3, 0x90, 5);

    // We need to set this back, even if its the local player
    pGameInterface->SetGravity ( fGlobalGravity );
}
示例#4
0
void CPoolsSA::RemovePed ( CPed* pPed, bool bDelete )
{
    DEBUG_TRACE("void CPoolsSA::RemovePed ( CPed* pPed, bool bDelete )");

    assert ( NULL != pPed );

    CPedSA* pPedSA = dynamic_cast < CPedSA* > ( pPed );
    if ( pPedSA )
    {
        RemovePed ( pPedSA->GetArrayID (), bDelete );
    }
}
示例#5
0
DWORD CPoolsSA::GetPedRef ( CPed* pPed )
{
    DEBUG_TRACE("DWORD CPoolsSA::GetPedRef ( CPed* pPed )");

    DWORD dwRef = 0;
    CPedSA* pPedSA = dynamic_cast < CPedSA * > ( pPed );
    if ( pPedSA )
    {
        CPedSAInterface* pInterface = pPedSA->GetPedInterface ();
        DWORD dwFunc = FUNC_GetPedRef;
        _asm
        {
            push    pInterface
            call    dwFunc
            add	    esp, 0x4
            mov	    dwRef, eax
        }
    }

    return dwRef;
}
bool CCarEnterExitSA::GetNearestCarDoor ( CPed * pPed, CVehicle * pVehicle, CVector * pVector, int * pDoor )
{
    DWORD dwFunc = FUNC_GetNearestCarDoor;
    bool bReturn = false;

    CPedSA* pPedSA = dynamic_cast < CPedSA* > ( pPed );
    CVehicleSA* pVehicleSA = dynamic_cast < CVehicleSA* > ( pVehicle );

    if ( pPedSA && pVehicleSA )
    {
        CPedSAInterface * pPedInterface = pPedSA->GetPedInterface ();
        CVehicleSAInterface * pVehicleInterface = pVehicleSA->GetVehicleInterface ();
        _asm
        {
            push    pDoor
            push    pVector
            push    pVehicleInterface
            push    pPedInterface
            call    dwFunc
            add     esp, 0x10
            mov     bReturn, al
        }
    }
CTaskSimpleChokingSA::CTaskSimpleChokingSA ( CPed* pAttacker, bool bIsTearGas )
{
    CPedSA* pAttackerSA = dynamic_cast < CPedSA* > ( pAttacker );

    DWORD dwFunc = FUNC_CTaskSimpleChoking__Constructor;
    DWORD dwIsTearGas = bIsTearGas;

    // Grab the GTA class for the attacker if any
    CPedSAInterface* pAttackerInterface = NULL;
    if ( pAttackerSA ) pAttackerInterface = pAttackerSA->GetPedInterface ();

    this->CreateTaskInterface ( sizeof ( CTaskSimpleChokingSAInterface ) );
    DWORD dwThisInterface = (DWORD)this->GetInterface();
    _asm
    {
        mov		ecx, dwThisInterface
        push    ebx
        push    bIsTearGas
        push    pAttackerInterface
        call    dwFunc
        pop     ebx
    }
}
示例#8
0
CTask* CTaskComplexSA::ControlSubTask(CPed* pPed)
{
    DEBUG_TRACE("CTask * CTaskComplexSA::ControlSubTask(CPed* pPed)");

    CPedSA* pPedSA = dynamic_cast<CPedSA*>(pPed);
    if (!pPedSA)
        return NULL;

    DWORD dwPedInterface = (DWORD)pPedSA->GetInterface();
    DWORD dwThisInterface = (DWORD)this->GetInterface();
    DWORD dwFunc = ((TaskComplexVTBL*)this->GetInterface()->VTBL)->ControlSubTask;
    DWORD dwReturn = 0;
    if (dwFunc != 0x82263A && dwFunc)
    {
        _asm
        {
            mov     ecx, dwThisInterface
            push    dwPedInterface
            call    dwFunc
            mov     dwReturn, eax
        }
    }
    return ((CTaskManagementSystemSA*)pGame->GetTaskManagementSystem())->GetTask((CTaskSAInterface*)dwReturn);
}
示例#9
0
bool CTaskSimpleSA::SetPedPosition(CPed* pPed)
{
    DEBUG_TRACE("bool CTaskSimpleSA::SetPedPosition(CPed* pPed)");

    CPedSA* pPedSA = dynamic_cast<CPedSA*>(pPed);
    if (!pPedSA)
        return false;

    DWORD dwPedInterface = (DWORD)pPedSA->GetInterface();
    DWORD dwThisInterface = (DWORD)this->GetInterface();
    DWORD dwFunc = ((TaskSimpleVTBL*)this->GetInterface()->VTBL)->SetPedPosition;
    bool  bReturn = 0;
    if (dwFunc != 0x82263A && dwFunc)
    {
        _asm
        {
            mov     ecx, dwThisInterface
            push    dwPedInterface
            call    dwFunc
            mov     bReturn, al
        }
    }
    return bReturn;
}
示例#10
0
void SwitchContext ( CPed* thePed )
{
    if ( thePed == NULL ) return;

    pContextSwitchedPed = thePed;
    // Are we not already in another context?
    if ( !bNotInLocalContext )
    {
        // Grab the local ped and the local pad
        CPed* pLocalPlayerPed = pGameInterface->GetPools ()->GetPedFromRef ( (DWORD)1 ); // the player
        CPad* pLocalPad = pGameInterface->GetPad ();
        CPadSAInterface* pLocalPadInterface = ( (CPadSA*) pLocalPad )->GetInterface ();

        // We're not switching to local player
        if ( thePed != pLocalPlayerPed )
        {
            // Store the local pad
            pLocalPad->Store (); // store a copy of the local pad internally

            // Grab the remote data storage for the player we're context switching to
            CPlayerPed* thePlayerPed = dynamic_cast < CPlayerPed* > ( thePed );
            if ( thePlayerPed )
            {
                CRemoteDataStorageSA * data = CRemoteDataSA::GetRemoteDataStorage ( thePlayerPed );
                if ( data )
                {
                    // We want the player to be seen as in targeting mode if they are right clicking and with weapons 
                    eWeaponType currentWeapon = thePed->GetWeapon(thePed->GetCurrentWeaponSlot())->GetType();
                    CControllerState * cs = data->CurrentControllerState();
                    
                    if ( cs->RightShoulder1 != 0 
                        && ( currentWeapon == WEAPONTYPE_SNIPERRIFLE || currentWeapon == WEAPONTYPE_ROCKETLAUNCHER
                        || currentWeapon == WEAPONTYPE_ROCKETLAUNCHER_HS || currentWeapon == WEAPONTYPE_CAMERA ) )
                    {
                        b1stPersonWeaponModeHackInPlace = true;
                        
                        // make the CCamera::Using1stPersonWeaponMode function return true
                        *(BYTE *)0x50BFF0 = 0xB0; // MOV AL, 1
                        *(BYTE *)0x50BFF1 = 0x01;
                        *(BYTE *)0x50BFF2 = 0xC3; // RETN
                    }

                    // Change the local player's pad to the remote player's
                    memcpy ( pLocalPadInterface, &data->m_pad, sizeof ( CPadSAInterface ) );

                    // this is to fix the horn/siren
                    pLocalPad->SetHornHistoryValue ( ( cs->ShockButtonL == 255 ) );
                    // disables the impatient actions on remote players (which cause desync)
                    pLocalPad->SetLastTimeTouched ( pGameInterface->GetSystemTime () );

                    // this is to make movement work correctly
                    fLocalPlayerCameraRotation = *(float *)VAR_CameraRotation;
                    *(float *)VAR_CameraRotation = data->m_fCameraRotation;

                    // Change the gravity to the remote player's
                    pGameInterface->SetGravity ( data->m_fGravity );

                    // Disable mouselook for remote players (so the mouse doesn't affect them)
                    // Only disable mouselook if they're not holding a 1st-person weapon
                    // And if they're not under-water
                    bool bDisableMouseLook = true;
                    CWeapon* pWeapon = thePed->GetWeapon ( thePed->GetCurrentWeaponSlot () );
                    if ( pWeapon )
                    {
                        eWeaponType weaponType = pWeapon->GetType ();
                        switch ( weaponType )
                        {
                            case WEAPONTYPE_SNIPERRIFLE:
                            case WEAPONTYPE_ROCKETLAUNCHER:
                            case WEAPONTYPE_ROCKETLAUNCHER_HS:
                                bDisableMouseLook = false;
                        }
                    }
                    bMouseLookEnabled = *(bool *)0xB6EC2E;
                    if ( bDisableMouseLook ) *(bool *)0xB6EC2E = false;

                    // Disable the goggles
                    bInfraredVisionEnabled = *(bool *)0xC402B9;
                    *(bool *)0xC402B9 = false;
                    bNightVisionEnabled = *(bool *)0xC402B8;
                    *(bool *)0xC402B8 = false;

                    // Remove the code making players cough on fire extinguisher and teargas
                    memset ( (void*) 0x4C03F0, 0x90, 3 );
                    memset ( (void*) 0x4C03F8, 0x90, 7 );

                    // Prevent it calling ClearWeaponTarget for remote players
                    *(BYTE *)0x609C80 = 0xC3;

                    // Prevent rockets firing oddly
                    //*(BYTE *)0x73811C = 0x90;
                    //*(BYTE *)0x73811D = 0xE9;

                    
                    // This is so weapon clicks and similar don't play for us when done remotly
                    *(BYTE *)0x60F273 = 0xEB; 
                    *(BYTE *)0x60F260 = 0x90;
                    *(BYTE *)0x60F261 = 0x90;
                    

                    // Prevent CCamera::SetNewPlayerWeaponMode being called
                    *(BYTE *)0x50BFB0 = 0xC2; // RETN 0xC
                    *(BYTE *)0x50BFB1 = 0x0C; 
                    *(BYTE *)0x50BFB2 = 0x00;

                    // Prevent it calling CCamera::ClearPlayerWeaponMode for remote players
                    *(BYTE *)0x50AB10 = 0xC3;

                    // Prevent it marking targets of remote players
                    *(BYTE *)0x742BF0 = 0xC3;

                    // this is to prevent shooting players following the local camera
                    *(BYTE *)0x687099 = 0xEB;

                    // Prevent the game making remote player's weapons get switched by the local player's
                    *(BYTE *)0x60D850 = 0xC2;
                    *(BYTE *)0x60D851 = 0x04;
                    *(BYTE *)0x60D852 = 0x00;

                    // Change the local player's stats to the remote player's
                    if ( data )
                    {
                        memcpy ( (void *)0xb79380, data->m_stats.StatTypesFloat, sizeof(float) * MAX_FLOAT_STATS );
                        memcpy ( (void *)0xb79000, data->m_stats.StatTypesInt, sizeof(int) * MAX_INT_STATS );
                        memcpy ( (void *)0xb78f10, data->m_stats.StatReactionValue, sizeof(float) * MAX_REACTION_STATS );
                    }                 

                    /*
                    // ChrML: Force as high stats as we can go before screwing up. Players can't have different
                    //        stats or guns don't work. We can't have dual guns either due to some screwups.
                    //        Dual gun screwup: Sync code needs update and the gun pointing up needs to.
                    float* pfStats = (float*) 0xb79380;
                    pfStats [ 69 ] = 500.0f;
                    pfStats [ 70 ] = 999.0f;
                    pfStats [ 71 ] = 999.0f;
                    pfStats [ 72 ] = 999.0f;
                    pfStats [ 73 ] = 500.0f;
                    pfStats [ 74 ] = 999.0f;
                    pfStats [ 75 ] = 500.0f;
                    pfStats [ 76 ] = 999.0f;
                    pfStats [ 77 ] = 999.0f;
                    pfStats [ 78 ] = 999.0f;
                    pfStats [ 79 ] = 999.0f;
                    */

                    CPedSA* thePedSA = dynamic_cast < CPedSA* > ( thePed );
                    if ( thePedSA )
                    {
                        CEntitySAInterface * ped = thePedSA->GetInterface();
                        *(DWORD *)0xB7CD98 = (DWORD)ped;
                    }

                    // Remember that we're not in the local player's context any more (for switching back)
                    bNotInLocalContext = true;

                    // Call the pre-context switch handler we might have
                    if ( m_pPreContextSwitchHandler )
                    {
                        CPlayerPed* pPlayerPed = dynamic_cast < CPlayerPed* > ( thePed );
                        if ( pPlayerPed )
                            m_pPreContextSwitchHandler ( pPlayerPed );
                    }
                }
            }
        }
        else
        {
            // Set the local players gravity
            pGameInterface->SetGravity ( fLocalPlayerGravity );

            if ( bCustomCameraRotation )
                *(float *)VAR_CameraRotation = fLocalPlayerCameraRotation;    
        }
    }
}
示例#11
0
void CPoolsSA::RemovePed ( unsigned long ulID, bool bDelete )
{
	DEBUG_TRACE("void CPoolsSA::RemovePed ( unsigned long ulID, bool bDelete )");

    static bool bIsDeletingPedAlready = false; // to prevent delete being called twice
    if ( !bIsDeletingPedAlready ) 
    {
        bIsDeletingPedAlready = true;

        CPedSA* pPedSA = m_pedPool.array [ ulID ];
        assert ( NULL != pPedSA );

        // Pop the element to remove from the pool array
        if ( ulID != m_pedPool.ulCount - 1 )
        {
            // We are removing an intermediate position of
            // the array. Move the last element to the just
            // deleted element position to not allow empty
            // spaces on it.
            m_pedPool.array [ ulID ] = m_pedPool.array [ m_pedPool.ulCount - 1 ];
            m_pedPool.array [ ulID ]->SetArrayID ( ulID );
        }
        m_pedPool.array [ m_pedPool.ulCount - 1 ] = NULL;

        // Unlink the element to remove from the pool map
        pedPool_t::mapType::iterator iter = m_pedPool.map.find ( pPedSA->GetPedInterface () );
        if ( iter != m_pedPool.map.end () )
        {
            m_pedPool.map.erase ( iter );
        }


        // Delete the element from memory
        switch ( pPedSA->GetType () )
        {
            case PLAYER_PED:
            {
                CPlayerPedSA* pPlayerPed = dynamic_cast < CPlayerPedSA* > ( pPedSA );
                if ( pPlayerPed )
                {
                    if ( ! bDelete )
                        pPlayerPed->SetDoNotRemoveFromGameWhenDeleted ( true );
                }

                delete pPlayerPed;

                break;
            }

            default:
            {
                CCivilianPedSA* pCivPed = dynamic_cast < CCivilianPedSA* > ( pPedSA );
                if ( pCivPed )
                {
                    if ( ! bDelete )
                        pCivPed->SetDoNotRemoveFromGameWhenDeleted ( true );
                }

                delete pCivPed;
            }
        }

        // Decrease the count of elements in the pool
        --m_pedPool.ulCount;

        bIsDeletingPedAlready = false;
    }
}