Пример #1
0
void CElementRPCs::RemoveElementData ( NetBitStreamInterface& bitStream )
{
    // Read out the entity id and name length
    ElementID ID;
    unsigned short usNameLength;
    bool bRecursive;
    if ( bitStream.ReadCompressed ( ID ) && bitStream.ReadCompressed ( usNameLength ) )
    {
        // Allocate a buffer for the name
        char* szName = new char [ usNameLength + 1 ];
        szName [ usNameLength ] = NULL;

        // Read it out plus whether it's recursive or not
        if ( bitStream.Read ( szName, usNameLength ) &&
             bitStream.ReadBit ( bRecursive ) )
        {
            // Grab the entity
            CClientEntity* pEntity = CElementIDs::GetElement ( ID );
            if ( pEntity )
            {
                // Remove that name
                pEntity->DeleteCustomData ( szName, bRecursive );
            }
        }

        // Delete the name buffer
        delete [] szName;
    }
}
Пример #2
0
bool CLuaArguments::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector<CLuaArguments*>* pKnownTables)
{
    bool bKnownTablesCreated = false;
    if (!pKnownTables)
    {
        pKnownTables = new std::vector<CLuaArguments*>();
        bKnownTablesCreated = true;
    }

    unsigned int uiNumArgs;
    bool         bResult;
#if MTA_DM_VERSION >= 0x150
    bResult = bitStream.ReadCompressed(uiNumArgs);
#else
    unsigned short usNumArgs;
    if (bitStream.Version() < 0x05B)
    {
        // We got the old version
        bResult = bitStream.ReadCompressed(usNumArgs);
        uiNumArgs = usNumArgs;
    }
    else
    {
        // Check if we got the new version
        if ((bResult = bitStream.ReadCompressed(usNumArgs)))
        {
            if (usNumArgs == 0xFFFF)
                // We got the new version
                bResult = bitStream.ReadCompressed(uiNumArgs);
            else
                // We got the old version
                uiNumArgs = usNumArgs;
        }
    }
#endif

    if (bResult)
    {
        pKnownTables->push_back(this);
        for (unsigned int ui = 0; ui < uiNumArgs; ++ui)
        {
            CLuaArgument* pArgument = new CLuaArgument(bitStream, pKnownTables);
            m_Arguments.push_back(pArgument);
        }
    }

    if (bKnownTablesCreated)
        delete pKnownTables;

    return true;
}
Пример #3
0
void CWeaponRPCs::TakeWeapon ( NetBitStreamInterface& bitStream )
{
    // Read out weapon id and ammo amount
    ElementID ID;
    SWeaponTypeSync weaponType;

    if ( bitStream.ReadCompressed ( ID ) &&
         bitStream.Read ( &weaponType )  )
    {
        unsigned char ucWeaponID = weaponType.data.ucWeaponType;

        CClientPed * pPed = m_pPedManager->Get ( ID, true );
        if ( pPed )
        {
            // Don't change remote players weapons (affects sync)
            if ( pPed->GetType () == CCLIENTPED || ( CClientPlayer * ) pPed == m_pPlayerManager->GetLocalPlayer () )
            {
                // Is the weapon id valid? (may not be neccessary, just being safe)
                if ( CClientPickupManager::IsValidWeaponID ( ucWeaponID ) )
                {
                    // Remove the weapon
                    pPed->RemoveWeapon ( static_cast < eWeaponType > ( ucWeaponID ) );
                }
            }
        }
    }
}
Пример #4
0
bool CLuaArguments::ReadFromBitStream ( NetBitStreamInterface& bitStream, std::vector < CLuaArguments* > * pKnownTables )
{
    bool bKnownTablesCreated = false;
    if ( !pKnownTables )
    {
        pKnownTables = new std::vector < CLuaArguments* > ();
        bKnownTablesCreated = true;
    }

    unsigned short usNumArgs;
    if ( bitStream.ReadCompressed ( usNumArgs ) )
    {
        pKnownTables->push_back ( this );
        for ( unsigned short us = 0 ; us < usNumArgs ; us++ )
        {
		    CLuaArgument* pArgument = new CLuaArgument ( bitStream, pKnownTables );
            m_Arguments.push_back ( pArgument );
        }
	}

    if ( bKnownTablesCreated )
        delete pKnownTables;

    return true;
}
Пример #5
0
void CElementRPCs::SetElementData ( NetBitStreamInterface& bitStream )
{
    ElementID ID;
    unsigned short usNameLength;
    if ( bitStream.ReadCompressed ( ID ) && bitStream.ReadCompressed ( usNameLength ) )
    {
        char* szName = new char [ usNameLength + 1 ];
        szName [ usNameLength ] = NULL;

        CLuaArgument Argument;
        if ( bitStream.Read ( szName, usNameLength ) && Argument.ReadFromBitStream ( bitStream ) )
        {
            CClientEntity* pEntity = CElementIDs::GetElement ( ID );
            if ( pEntity )
            {
                pEntity->SetCustomData ( szName, Argument, NULL );
            }
        }            
        delete [] szName;
    }
}
Пример #6
0
void CPedRPCs::SetPedMoveAnim ( CClientEntity* pSource, NetBitStreamInterface& bitStream )
{
    unsigned int uiMoveAnim;
    if ( bitStream.ReadCompressed ( uiMoveAnim ) )
    {
        CClientPed* pPed = m_pPedManager->Get ( pSource->GetID (), true );
        if ( pPed )
        {
            pPed->SetMoveAnim ( (eMoveAnim)uiMoveAnim );
        }
    }
}
Пример #7
0
void CWeaponRPCs::TakeAllWeapons ( NetBitStreamInterface& bitStream )
{
    ElementID ID;
    if ( bitStream.ReadCompressed ( ID ) )
    {
        CClientPed * pPed = m_pPedManager->Get ( ID, true );
        if ( pPed )
        {
            // Remove all our weapons
            pPed->RemoveAllWeapons ();
        }
    }
}
Пример #8
0
void CWeaponRPCs::SetWeaponSlot ( NetBitStreamInterface& bitStream )
{
    ElementID ID;
    SWeaponSlotSync slot;

    if ( bitStream.ReadCompressed ( ID ) &&
         bitStream.Read ( &slot ) )
    {
        CClientPed * pPed = m_pPedManager->Get ( ID, true );
        if ( pPed )
        {
            pPed->SetCurrentWeaponSlot ( (eWeaponSlot) slot.data.uiSlot );
        }
    }
}
Пример #9
0
bool CCustomDataPacket::Read(NetBitStreamInterface& BitStream)
{
    unsigned short usNameLength;
    if (BitStream.Read(m_ElementID) && BitStream.ReadCompressed(usNameLength) && usNameLength > 0 && usNameLength <= MAX_CUSTOMDATA_NAME_LENGTH)
    {
        m_szName = new char[usNameLength + 1];
        if (BitStream.Read(m_szName, usNameLength))
        {
            m_szName[usNameLength] = 0;
            if (m_Value.ReadFromBitStream(BitStream))
            {
                return true;
            }
        }
    }

    return false;
}
Пример #10
0
void CElementRPCs::RemoveElementData ( CClientEntity* pSource, NetBitStreamInterface& bitStream )
{
    // Read out the name length
    unsigned short usNameLength;
    bool bRecursive;
    if ( bitStream.ReadCompressed ( usNameLength ) )
    {
        SString strName;

        // Read out the name plus whether it's recursive or not
        if ( bitStream.ReadStringCharacters ( strName, usNameLength ) &&
             bitStream.ReadBit ( bRecursive ) )
        {
            // Remove that name
            pSource->DeleteCustomData ( strName, bRecursive );
        }
    }
}
Пример #11
0
void CWeaponRPCs::TakeWeaponAmmo ( NetBitStreamInterface& bitStream )
{
    ElementID ID;
    SWeaponTypeSync weaponType;
    if ( bitStream.ReadCompressed ( ID ) &&
         bitStream.Read ( &weaponType ) )
    {
        unsigned char ucWeaponID = weaponType.data.ucWeaponType;
        SWeaponAmmoSync ammo ( ucWeaponID, true, false );
        if ( bitStream.Read ( &ammo ) )
        {
            unsigned short usAmmo = ammo.data.usTotalAmmo;

            CClientPed * pPed = m_pPedManager->Get ( ID, true );
            if ( pPed )
            {
                // Valid weapon id?
                if ( !CClientPickupManager::IsValidWeaponID ( ucWeaponID ) ) return;

                // Do we have it?
                CWeapon* pPlayerWeapon = pPed->GetWeapon ( (eWeaponType) ucWeaponID );
                if ( pPlayerWeapon == NULL ) return;

                unsigned char ucAmmoInClip = static_cast < unsigned char > ( pPlayerWeapon->GetAmmoInClip () );
                pPlayerWeapon->SetAmmoInClip ( 0 );

                unsigned long ulWeaponAmmo = pPlayerWeapon->GetAmmoTotal ();
                if ( ulWeaponAmmo - usAmmo < 0 )
                    ulWeaponAmmo = 0;
                else
                    ulWeaponAmmo -= usAmmo;

                // Remove the weapon ammo
                pPlayerWeapon->SetAmmoTotal ( ulWeaponAmmo );

                if ( pPlayerWeapon->GetAmmoTotal () > ucAmmoInClip )
                    pPlayerWeapon->SetAmmoInClip ( ucAmmoInClip );
                else if ( pPlayerWeapon->GetAmmoTotal () <= ucAmmoInClip )
                    pPlayerWeapon->SetAmmoInClip ( pPlayerWeapon->GetAmmoTotal () );
            }
        }
    }
}
Пример #12
0
void CElementRPCs::SetElementData ( CClientEntity* pSource, NetBitStreamInterface& bitStream )
{
    unsigned short usNameLength;
    if ( bitStream.ReadCompressed ( usNameLength ) )
    {
        // We should never receive an illegal name length from the server
        if ( usNameLength > MAX_CUSTOMDATA_NAME_LENGTH )
        {
            CLogger::ErrorPrintf ( "RPC SetElementData name length > MAX_CUSTOMDATA_NAME_LENGTH" );
            return;
        }
        SString strName;
        CLuaArgument Argument;
        if ( bitStream.ReadStringCharacters ( strName, usNameLength ) && Argument.ReadFromBitStream ( bitStream ) )
        {
            pSource->SetCustomData ( strName, Argument, NULL );
        }
    }
}
Пример #13
0
void CRPCFunctions::PlayerTarget ( NetBitStreamInterface & bitStream )
{
    if ( m_pSourcePlayer->IsJoined () )
    {
        ElementID TargetID;
        bitStream.ReadCompressed ( TargetID );

        CElement* pTarget = NULL;
        if ( TargetID != INVALID_ELEMENT_ID ) pTarget = CElementIDs::GetElement ( TargetID );
        m_pSourcePlayer->SetTargetedElement ( pTarget );

        // Call our script event
        CLuaArguments Arguments;
        if ( pTarget ) Arguments.PushElement ( pTarget );
        else Arguments.PushBoolean ( false );

        m_pSourcePlayer->CallEvent ( "onPlayerTarget", Arguments );
    }
}
Пример #14
0
bool CLuaEventPacket::Read(NetBitStreamInterface& BitStream)
{
    unsigned short usNameLength;
    if (BitStream.ReadCompressed(usNameLength))
    {
        if (usNameLength < (MAX_EVENT_NAME_LENGTH - 1) && BitStream.ReadStringCharacters(m_strName, usNameLength) && BitStream.Read(m_ElementID))
        {
            // Faster than using a constructor
            m_ArgumentsStore.DeleteArguments();
            if(!m_ArgumentsStore.ReadFromBitStream(BitStream))
                return false;
            m_pArguments = &m_ArgumentsStore;

            return true;
        }
    }

    return false;
}
Пример #15
0
bool CPlayerJoinDataPacket::Read ( NetBitStreamInterface& BitStream )
{
    m_szNick [ MAX_NICK_LENGTH ] = 0;
    m_szSerialUser [MAX_SERIAL_LENGTH] = 0;

    // Read out the stuff
    if ( !BitStream.Read ( m_usNetVersion ) ||
         !BitStream.Read ( m_usMTAVersion ) )
        return false;

    if ( m_usMTAVersion < 0x0102 )
    {
        // Clients earlier than 1.0.2 do not have a bitstream version
        m_usBitStreamVersion = 0x01;
    }
    else
    {
        if ( !BitStream.Read ( m_usBitStreamVersion ) )
            return false;
    }

    if ( m_usBitStreamVersion >= 0x0b )
    {
        unsigned int uiLength;
        BitStream.ReadCompressed ( uiLength );
        if ( uiLength < 1 || uiLength > 100 )
            return false;

        m_strPlayerVersion.assign ( uiLength, 32 );
        BitStream.Read ( &m_strPlayerVersion.at ( 0 ), uiLength );
    }

    if ( m_usBitStreamVersion >= 0x0e )
        m_bOptionalUpdateInfoRequired = BitStream.ReadBit ();
    else
        m_bOptionalUpdateInfoRequired = false;

    return ( BitStream.Read ( m_ucGameVersion ) &&
             BitStream.Read ( m_szNick, MAX_NICK_LENGTH ) &&
             BitStream.Read ( reinterpret_cast < char* > ( &m_Password ), 16 ) &&
             BitStream.Read ( m_szSerialUser, MAX_SERIAL_LENGTH ) );
}
Пример #16
0
void CRPCFunctions::RequestStealthKill ( NetBitStreamInterface & bitStream )
{
    ElementID ID;
    bitStream.ReadCompressed ( ID );
    CElement * pElement = CElementIDs::GetElement ( ID );
    if ( pElement )
    {
        int elementType = pElement->GetType ();
        if ( elementType == CElement::PLAYER || elementType == CElement::PED )
        {
            CPed * pTarget = static_cast < CPed * > ( pElement );

            // Are they both alive?
            if ( !m_pSourcePlayer->IsDead () && !pTarget->IsDead () )
            {
                //Do we have any record of the killer currently having a knife?
                if ( m_pSourcePlayer->GetWeaponType( 1 ) == 4 )
                {
                    // Are they close enough?
                    if ( DistanceBetweenPoints3D ( m_pSourcePlayer->GetPosition (), pTarget->GetPosition () ) <= STEALTH_KILL_RANGE )
                    {
                        CLuaArguments Arguments;
                        Arguments.PushElement ( pTarget );
                        if ( m_pSourcePlayer->CallEvent ( "onPlayerStealthKill", Arguments, false ) )
                        {
                            // Start the stealth kill
                            CStaticFunctionDefinitions::KillPed ( pTarget, m_pSourcePlayer, 4 /*WEAPONTYPE_KNIFE*/, 9/*BODYPART_HEAD*/, true );
                        }
                    }
                }
                else
                {
                    //You shouldn't be able to get here without cheating to get a knife.
                    if ( !g_pGame->GetConfig ()->IsDisableAC ( "2" ) )
                    {
                        CStaticFunctionDefinitions::KickPlayer ( m_pSourcePlayer, NULL, "AC #2: You were kicked from the game" );
                    }
                }
            }
        }
    }
}
Пример #17
0
void CWeaponRPCs::GiveWeaponAmmo ( NetBitStreamInterface& bitStream )
{
    ElementID ID;
    SWeaponTypeSync weaponType;
    if ( bitStream.ReadCompressed ( ID ) &&
         bitStream.Read ( &weaponType ) )
    {
        unsigned char ucWeaponID = weaponType.data.ucWeaponType;
        SWeaponAmmoSync ammo ( ucWeaponID, true, false );
        if ( bitStream.Read ( &ammo ) )
        {
            unsigned short usAmmo = ammo.data.usTotalAmmo;
            CClientPed * pPed = m_pPedManager->Get ( ID, true );
            if ( pPed )
            {
                // Valid weapon id?
                if ( !CClientPickupManager::IsValidWeaponID ( ucWeaponID ) ) return;

                // Do we have it?
                CWeapon* pPlayerWeapon = pPed->GetWeapon ( (eWeaponType) ucWeaponID );
                if ( pPlayerWeapon == NULL ) return;

                unsigned long ulWeaponAmmo = pPlayerWeapon->GetAmmoTotal ();
                ulWeaponAmmo += usAmmo;
                // Adjust the ammo to 9999 if it's above
                if ( ulWeaponAmmo > 9999 )
                {
                    ulWeaponAmmo = 9999;
                }

                // Add the weapon ammo
                pPlayerWeapon->SetAmmoTotal ( ulWeaponAmmo );
            }
        }
    }
}
Пример #18
0
bool CLuaArgument::ReadFromBitStream ( NetBitStreamInterface& bitStream, std::vector < CLuaArguments* > * pKnownTables )
{
    DeleteTableData ();
    SLuaTypeSync type;

    // Read out the type
    if ( bitStream.Read ( &type ) )
    {
        // Depending on what type...
        switch ( type.data.ucType )
        {
            // Nil type
            case LUA_TNIL:
            {
                m_iType = LUA_TNIL;
                break;
            }

            // Boolean type
            case LUA_TBOOLEAN:
            {
                bool bValue;
                if ( bitStream.ReadBit ( bValue ) )
                    ReadBool ( bValue );
                break;
            }

            // Number type
            case LUA_TNUMBER:
            {
                bool bIsFloatingPoint;
                if ( bitStream.ReadBit ( bIsFloatingPoint ) && bIsFloatingPoint )
                {
                    float fNum;
                    if ( bitStream.Read ( fNum ) )
                        ReadNumber ( fNum );
                }
                else
                {
                    long lNum;
                    if ( bitStream.ReadCompressed ( lNum ) )
                        ReadNumber ( lNum );
                }
                break;
            }

            // Table type
            case LUA_TTABLE:
            {
                m_pTableData = new CLuaArguments ( bitStream, pKnownTables );
                m_bWeakTableRef = false;
                m_iType = LUA_TTABLE;
                m_pTableData->ValidateTableKeys ();
                break;
            }

            // Table reference
            case LUA_TTABLEREF:
            {
                unsigned long ulTableRef;
                if ( bitStream.ReadCompressed ( ulTableRef ) )
                {
                    if ( pKnownTables && ulTableRef < pKnownTables->size () )
                    {
                        m_pTableData = pKnownTables->at ( ulTableRef );
                        m_bWeakTableRef = true;
                        m_iType = LUA_TTABLE;
                    }
                }
                break;
            }

            // String type
            case LUA_TSTRING:
            {
                // Read out the string length
                unsigned short usLength;
                if ( bitStream.ReadCompressed ( usLength ) && usLength )
                {
                    // Allocate a buffer and read the string into it
                    char* szValue = new char [ usLength + 1 ];
                    if ( bitStream.Read ( szValue, usLength ) )
                    {
                        // Put it into us
                        ReadString ( std::string ( szValue, usLength ) );
                    }

                    // Delete the buffer
                    delete [] szValue;
                }
                else
                    ReadString ( "" );

                break;
            }

            // Long string type
            case LUA_TSTRING_LONG:
            {
                // Read out the string length
                uint uiLength;
                if ( bitStream.ReadCompressed ( uiLength ) && uiLength )
                {
                    bitStream.AlignReadToByteBoundary ();

                    // Allocate a buffer and read the string into it
                    char* szValue = new char [ uiLength + 1 ];
                    assert ( szValue );
                    if ( bitStream.Read ( szValue, uiLength ) )
                    {
                        // Put it into us
                        ReadString ( std::string ( szValue, uiLength ) );
                    }

                    // Delete the buffer
                    delete [] szValue;
                }
                else
                    ReadString ( "" );

                // Enforce min_mta_version version rule
                if ( uiLength > 65535 && g_pGame->CalculateMinClientRequirement () < LONG_STRING_MIN_VERSION )
                {
                    LogUnableToPacketize ( "#### Couldn't packetize argument list. Invalid string specified, limit is 65535 characters."
                                           " To use longer strings, set script <min_mta_version> to " LONG_STRING_MIN_VERSION " or higher." );
                    m_iType = LUA_TNIL;
                }

                break;
            }

            // Element type?
            case LUA_TLIGHTUSERDATA:
            {
                ElementID ElementID;
                if ( bitStream.Read ( ElementID ) )
                {
                    CElement * element = CElementIDs::GetElement ( ElementID );
                    ReadElement ( element );
                }
                break;
            }
        }
    }
    return true;
}
Пример #19
0
// Can't use bitStream.Version() here as it is sometimes not set
bool CLuaArgument::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector<CLuaArguments*>* pKnownTables)
{
    DeleteTableData();
    SLuaTypeSync type;

    // Read out the type
    if (bitStream.Read(&type))
    {
        // Depending on what type...
        switch (type.data.ucType)
        {
            // Nil type
            case LUA_TNIL:
            {
                m_iType = LUA_TNIL;
                break;
            }

            // Boolean type
            case LUA_TBOOLEAN:
            {
                bool bValue;
                if (bitStream.ReadBit(bValue))
                    ReadBool(bValue);
                break;
            }

            // Number type
            case LUA_TNUMBER:
            {
                if (bitStream.ReadBit())
                {
                    if (bitStream.ReadBit())
                    {
                        double dNum;
                        if (bitStream.Read(dNum))
                            ReadNumber(dNum);
                    }
                    else
                    {
                        float fNum;
                        if (bitStream.Read(fNum))
                            ReadNumber(RoundFromFloatSource(fNum));
                    }
                }
                else
                {
                    int iNum;
                    if (bitStream.ReadCompressed(iNum))
                        ReadNumber(iNum);
                }
                break;
            }

            // Table type
            case LUA_TTABLE:
            {
                m_pTableData = new CLuaArguments(bitStream, pKnownTables);
                m_bWeakTableRef = false;
                m_iType = LUA_TTABLE;
                m_pTableData->ValidateTableKeys();
                break;
            }

            // Table reference
            case LUA_TTABLEREF:
            {
                unsigned long ulTableRef;
                if (bitStream.ReadCompressed(ulTableRef))
                {
                    if (pKnownTables && ulTableRef < pKnownTables->size())
                    {
                        m_pTableData = pKnownTables->at(ulTableRef);
                        m_bWeakTableRef = true;
                        m_iType = LUA_TTABLE;
                    }
                }
                break;
            }

            // String type
            case LUA_TSTRING:
            {
                // Read out the string length
                unsigned short usLength;
                if (bitStream.ReadCompressed(usLength) && usLength)
                {
                    // Allocate a buffer and read the string into it
                    char* szValue = new char[usLength + 1];
                    if (bitStream.Read(szValue, usLength))
                    {
                        // Put it into us
                        ReadString(std::string(szValue, usLength));
                    }

                    // Delete the buffer
                    delete[] szValue;
                }
                else
                    ReadString("");

                break;
            }

            // Long string type
            case LUA_TSTRING_LONG:
            {
                // Read out the string length
                uint uiLength;
                if (bitStream.ReadCompressed(uiLength) && uiLength)
                {
                    bitStream.AlignReadToByteBoundary();

                    // Allocate a buffer and read the string into it
                    char* szValue = new char[uiLength + 1];
                    assert(szValue);
                    if (bitStream.Read(szValue, uiLength))
                    {
                        // Put it into us
                        ReadString(std::string(szValue, uiLength));
                    }

                    // Delete the buffer
                    delete[] szValue;
                }
                else
                    ReadString("");

                break;
            }

            // Element type?
            case LUA_TLIGHTUSERDATA:
            case LUA_TUSERDATA:
            {
                ElementID ElementID;
                if (bitStream.Read(ElementID))
                {
                    ReadElementID(ElementID);
                }
                break;
            }
        }
    }
    return true;
}
Пример #20
0
bool CProjectileSyncPacket::Read ( NetBitStreamInterface& BitStream )
{
    bool bHasOrigin;
    if ( !BitStream.ReadBit ( bHasOrigin ) )
        return false;

    m_OriginID = INVALID_ELEMENT_ID;
    if ( bHasOrigin && !BitStream.ReadCompressed ( m_OriginID ) )
        return false;

    SPositionSync origin ( false );
    if ( !BitStream.Read ( &origin ) )
        return false;
    m_vecOrigin = origin.data.vecPosition;

    SWeaponTypeSync weaponType;
    if ( !BitStream.Read ( &weaponType ) )
        return false;
    m_ucWeaponType = weaponType.data.ucWeaponType;

    switch ( m_ucWeaponType )
    {
        case 16: // WEAPONTYPE_GRENADE
        case 17: // WEAPONTYPE_TEARGAS            
        case 18: // WEAPONTYPE_MOLOTOV
        case 39: // WEAPONTYPE_REMOTE_SATCHEL_CHARGE
        {
            SFloatSync < 7, 17 > projectileForce;
            if ( !BitStream.Read ( &projectileForce ) )
                return false;
            m_fForce = projectileForce.data.fValue;

            SVelocitySync velocity;
            if ( !BitStream.Read ( &velocity ) )
                return false;
            m_vecMoveSpeed = velocity.data.vecVelocity;

            break;
        }
        case 19: // WEAPONTYPE_ROCKET
        case 20: // WEAPONTYPE_ROCKET_HS
        {
            bool bHasTarget;
            if ( !BitStream.ReadBit ( bHasTarget ) )
                return false;

            m_TargetID = INVALID_ELEMENT_ID;
            if ( bHasTarget && !BitStream.ReadCompressed ( m_TargetID ) )
                return false;

            SVelocitySync velocity;
            if ( !BitStream.Read ( &velocity ) )
                return false;
            m_vecMoveSpeed = velocity.data.vecVelocity;

            SRotationRadiansSync rotation ( true );
            if ( !BitStream.Read ( &rotation ) )
                return false;
            m_vecRotation = rotation.data.vecRotation;

            break;
        }
        case 58: // WEAPONTYPE_FLARE
        case 21: // WEAPONTYPE_FREEFALL_BOMB
            break;

        default:
            return false;
    }
    return true;
}
Пример #21
0
bool CLuaArgument::ReadFromBitStream ( NetBitStreamInterface& bitStream, std::vector < CLuaArguments* > * pKnownTables )
{
    DeleteTableData ();
    SLuaTypeSync type;

    // Read out the type
	if ( bitStream.Read ( &type ) )
	{
        // Depending on what type...
		switch ( type.data.ucType )
		{
            // Nil type
            case LUA_TNIL:
            {
                m_iType = LUA_TNIL;
                break;
            }

            // Boolean type
			case LUA_TBOOLEAN:
			{
				bool bValue;
				if ( bitStream.ReadBit ( bValue ) )
					Read(bValue);
				break;
			}

            // Number type
			case LUA_TNUMBER:
			{
                bool bIsFloatingPoint;
                if ( bitStream.ReadBit ( bIsFloatingPoint ) && bIsFloatingPoint )
                {
                    float fNum;
                    if ( bitStream.Read ( fNum ) )
                        Read ( (double) fNum );
                }
                else
                {
                    long lNum;
                    if ( bitStream.ReadCompressed ( lNum ) )
                        Read ( (double) lNum );
                }
				break;
			}

            // Table type
            case LUA_TTABLE:
            {
                m_pTableData = new CLuaArguments ( bitStream, pKnownTables );
                m_bWeakTableRef = false;
                m_iType = LUA_TTABLE;
                break;
            }

            // Table reference
            case LUA_TTABLEREF:
            {
                unsigned long ulTableRef;
                if ( bitStream.ReadCompressed ( ulTableRef ) )
                {
                    if ( pKnownTables && ulTableRef < pKnownTables->size () )
                    {
                        m_pTableData = pKnownTables->at ( ulTableRef );
                        m_bWeakTableRef = true;
                        m_iType = LUA_TTABLE;
                    }
                }
                break;
            }

            // String type
			case LUA_TSTRING:
			{
                // Read out the string length
				unsigned short usLength;
				if ( bitStream.ReadCompressed ( usLength ) && usLength )
				{
                    // Allocate a buffer and read the string into it
                    char* szValue = new char [ usLength + 1 ];
                    if ( bitStream.Read ( szValue, usLength ) )
                    {
                        // Put it into us
                        szValue [ usLength ] = 0;
						Read ( szValue );
                    }

                    // Delete the buffer
                    delete [] szValue;
				}
				else
					Read ( "" );

				break;
			}

            // Element type?
			case LUA_TLIGHTUSERDATA:
			{
				ElementID ElementID;
				if ( bitStream.ReadCompressed ( ElementID ) )
				{
					CElement * element = CElementIDs::GetElement ( ElementID );
					Read ( element );
				}
				break;
			}
		}
    }
    return true;
}
Пример #22
0
bool CVehiclePuresyncPacket::Read ( NetBitStreamInterface& BitStream )
{
    // Got a player to read?
    if ( m_pSourceElement )
    {
        CPlayer * pSourcePlayer = static_cast < CPlayer * > ( m_pSourceElement );

        // Player is in a vehicle?
        CVehicle* pVehicle = pSourcePlayer->GetOccupiedVehicle ();
        if ( pVehicle )
        {
            // Read out the time context
            unsigned char ucTimeContext = 0;
            if ( !BitStream.Read ( ucTimeContext ) )
                return false;

            // Only read this packet if it matches the current time context that
            // player is in.
            if ( !pSourcePlayer->CanUpdateSync ( ucTimeContext ) )
            {
                return false;
            }

            // Read out the keysync data
            CControllerState ControllerState;
            if ( !ReadFullKeysync ( ControllerState, BitStream ) )
                return false;

            // Read out its position
            SPositionSync position ( false );
            if ( !BitStream.Read ( &position ) )
                return false;
            pSourcePlayer->SetPosition ( position.data.vecPosition );

            // Jax: don't allow any outdated packets through
            unsigned char ucSeat;
            if ( !BitStream.Read ( ucSeat ) )
                return false;
            if ( ucSeat != pSourcePlayer->GetOccupiedVehicleSeat () )
            {
                // Mis-matching seats can happen when we warp into a different one,
                // which will screw up the whole packet
                return false;
            }

            // Read out the vehicle matrix only if he's the driver
            unsigned int uiSeat = pSourcePlayer->GetOccupiedVehicleSeat ();
            if ( uiSeat == 0 )
            {
                // Read out the vehicle rotation in degrees
                SRotationDegreesSync rotation;
                if( !BitStream.Read ( &rotation ) )
                    return false;

                // Set it
                pVehicle->SetPosition ( position.data.vecPosition );
                pVehicle->SetRotationDegrees ( rotation.data.vecRotation );

                // Move speed vector
                SVelocitySync velocity;
                if ( !BitStream.Read ( &velocity ) )
                    return false;

                pVehicle->SetVelocity ( velocity.data.vecVelocity );
                pSourcePlayer->SetVelocity ( velocity.data.vecVelocity );

                // Turn speed vector
                SVelocitySync turnSpeed;
                if ( !BitStream.Read ( &turnSpeed ) )
                    return false;

                pVehicle->SetTurnSpeed ( turnSpeed.data.vecVelocity );

                // Health
                SVehicleHealthSync health;
                if ( !BitStream.Read ( &health ) )
                    return false;
                float fPreviousHealth = pVehicle->GetHealth ();                
                float fHealth = health.data.fValue;

                // Less than last time?
                if ( fHealth < fPreviousHealth )
                {                 
                    // Grab the delta health
                    float fDeltaHealth = fPreviousHealth - fHealth;

					if ( fDeltaHealth > 0.0f )
					{
						// Call the onVehicleDamage event
						CLuaArguments Arguments;
						Arguments.PushNumber ( fDeltaHealth );
						pVehicle->CallEvent ( "onVehicleDamage", Arguments );
					}
                }
                pVehicle->SetHealth ( fHealth );

                // Trailer chain
                CVehicle* pTowedByVehicle = pVehicle;
                CVehicle* pTrailer = NULL;
                ElementID TrailerID;
                bool bHasTrailer;
                if ( !BitStream.ReadBit ( bHasTrailer ) )
                    return false;

                while ( bHasTrailer )
                {
                    BitStream.ReadCompressed ( TrailerID );
                    CElement* pElement = CElementIDs::GetElement ( TrailerID );
                    if ( pElement )
                        pTrailer = static_cast < CVehicle* > ( pElement );
                    
                    // Read out the trailer position and rotation
                    SPositionSync trailerPosition ( false );
                    if ( !BitStream.Read ( &trailerPosition ) )
                        return false;

                    SRotationDegreesSync trailerRotation;
                    if ( !BitStream.Read ( &trailerRotation ) )
                        return false;

                    // If we found the trailer
                    if ( pTrailer )
                    {
                        // Set its position and rotation
                        pTrailer->SetPosition ( trailerPosition.data.vecPosition );
                        pTrailer->SetRotationDegrees ( trailerRotation.data.vecRotation );
    
                        // Is this a new trailer, attached?
                        CVehicle* pCurrentTrailer = pTowedByVehicle->GetTowedVehicle ();
                        if ( pCurrentTrailer != pTrailer )
                        {
                            // If theres a trailer already attached
                            if ( pCurrentTrailer )
                            {
                                pTowedByVehicle->SetTowedVehicle ( NULL );
                                pCurrentTrailer->SetTowedByVehicle ( NULL );

                                // Tell everyone to detach them
                                CVehicleTrailerPacket AttachPacket ( pTowedByVehicle, pCurrentTrailer, false );
                                g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( AttachPacket );

                                // Execute the attach trailer script function
                                CLuaArguments Arguments;
                                Arguments.PushElement ( pTowedByVehicle );
                                pCurrentTrailer->CallEvent ( "onTrailerDetach", Arguments );
                            }

                            // If something else is towing this trailer
                            CVehicle* pCurrentVehicle = pTrailer->GetTowedByVehicle ();
                            if ( pCurrentVehicle )
                            {
                                pCurrentVehicle->SetTowedVehicle ( NULL );
                                pTrailer->SetTowedByVehicle ( NULL );

                                // Tell everyone to detach them
                                CVehicleTrailerPacket AttachPacket ( pCurrentVehicle, pTrailer, false );
                                g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( AttachPacket );

                                // Execute the attach trailer script function
                                CLuaArguments Arguments;
                                Arguments.PushElement ( pCurrentVehicle );
                                pTrailer->CallEvent ( "onTrailerDetach", Arguments );
                            }

                            pTowedByVehicle->SetTowedVehicle ( pTrailer );
                            pTrailer->SetTowedByVehicle ( pTowedByVehicle );

                            // Execute the attach trailer script function
                            CLuaArguments Arguments;
                            Arguments.PushElement ( pTowedByVehicle );
                            bool bContinue = pTrailer->CallEvent ( "onTrailerAttach", Arguments );

                            // Attach or detach trailers depending on the event outcome
                            CVehicleTrailerPacket TrailerPacket ( pTowedByVehicle, pTrailer, bContinue );
                            g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( TrailerPacket );
                        }
                    }
                    else
                        break;

                    pTowedByVehicle = pTrailer;

                    if ( BitStream.ReadBit ( bHasTrailer ) == false )
                        return false;
                }

                // If there was a trailer before
                CVehicle* pCurrentTrailer = pTowedByVehicle->GetTowedVehicle ();
                if ( pCurrentTrailer )
                {
                    pTowedByVehicle->SetTowedVehicle ( NULL );
                    pCurrentTrailer->SetTowedByVehicle ( NULL );

                    // Tell everyone else to detach them
                    CVehicleTrailerPacket AttachPacket ( pTowedByVehicle, pCurrentTrailer, false );
                    g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( AttachPacket );

                    // Execute the detach trailer script function
                    CLuaArguments Arguments;
                    Arguments.PushElement ( pTowedByVehicle );
                    pCurrentTrailer->CallEvent ( "onTrailerDetach", Arguments );                    
                }
            }

            // Player health
            SPlayerHealthSync health;
            if ( !BitStream.Read ( &health ) )
                return false;
            float fHealth = health.data.fValue;

            float fOldHealth = pSourcePlayer->GetHealth ();
			float fHealthLoss = fOldHealth - fHealth;

            // Less than last packet's frame?
            if ( fHealth < fOldHealth && fHealthLoss > 0 )
            {
                // Call the onPlayerDamage event
                CLuaArguments Arguments;
                Arguments.PushNil ();
                Arguments.PushNumber ( false );
                Arguments.PushNumber ( false );
                Arguments.PushNumber ( fHealthLoss );
                pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments );
            }
            pSourcePlayer->SetHealth ( fHealth );

			// Armor
            SPlayerArmorSync armor;
            if ( !BitStream.Read ( &armor ) )
                return false;
            float fArmor = armor.data.fValue;

			float fOldArmor = pSourcePlayer->GetArmor ();
			float fArmorLoss = fOldArmor - fArmor;

			// Less than last packet's frame?
			if ( fArmor < fOldArmor && fArmorLoss > 0 )
			{
				// Call the onPlayerDamage event
				CLuaArguments Arguments;
                Arguments.PushNil ();
                Arguments.PushNumber ( false );
                Arguments.PushNumber ( false );
				Arguments.PushNumber ( fArmorLoss );

				pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments );					
			}
            pSourcePlayer->SetArmor ( fArmor );

            // Flags
            SVehiclePuresyncFlags flags;
            if ( !BitStream.Read ( &flags ) )
                return false;

            pSourcePlayer->SetWearingGoggles ( flags.data.bIsWearingGoggles );
            pSourcePlayer->SetDoingGangDriveby ( flags.data.bIsDoingGangDriveby );            

            // Weapon sync
            if ( flags.data.bHasAWeapon )
            {
                SWeaponSlotSync slot;
                if ( !BitStream.Read ( &slot ) )
                    return false;

                pSourcePlayer->SetWeaponSlot ( slot.data.uiSlot );

                if ( flags.data.bIsDoingGangDriveby && CWeaponNames::DoesSlotHaveAmmo ( slot.data.uiSlot ) )
                {
                    // Read the ammo states
                    SWeaponAmmoSync ammo ( pSourcePlayer->GetWeaponType (), false, true );
                    if ( !BitStream.Read ( &ammo ) )
                        return false;
                    pSourcePlayer->SetWeaponAmmoInClip ( ammo.data.usAmmoInClip );

                    // Read aim data
                    SWeaponAimSync aim ( pSourcePlayer->GetWeaponRange (), true );
                    if ( !BitStream.Read ( &aim ) )
                        return false;
                    pSourcePlayer->SetAimDirection ( aim.data.fArm );
                    pSourcePlayer->SetSniperSourceVector ( aim.data.vecOrigin );
                    pSourcePlayer->SetTargettingVector ( aim.data.vecTarget );

                    // Read the driveby direction
                    SDrivebyDirectionSync driveby;
                    if ( !BitStream.Read ( &driveby ) )
                        return false;
                    pSourcePlayer->SetDriveByDirection ( driveby.data.ucDirection );
                }
            }
            else
                pSourcePlayer->SetWeaponSlot ( 0 );


            // Vehicle specific data if he's the driver
            if ( uiSeat == 0 )
            {
                ReadVehicleSpecific ( pVehicle, BitStream );

                // Set vehicle specific stuff if he's the driver
                pVehicle->SetSirenActive ( flags.data.bIsSirenOrAlarmActive );
                pVehicle->SetSmokeTrailEnabled ( flags.data.bIsSmokeTrailEnabled );
                pVehicle->SetLandingGearDown ( flags.data.bIsLandingGearDown );
                pVehicle->SetOnGround ( flags.data.bIsOnGround );
                pVehicle->SetInWater ( flags.data.bIsInWater );
                pVehicle->SetDerailed ( flags.data.bIsDerailed );
                pVehicle->SetHeliSearchLightVisible ( flags.data.bIsHeliSearchLightVisible );
            }

            // Read the vehicle_look_left and vehicle_look_right control states
            // if it's an aircraft.
            if ( flags.data.bIsAircraft )
            {
                ControllerState.LeftShoulder2 = BitStream.ReadBit () * 255;
                ControllerState.RightShoulder2 = BitStream.ReadBit () * 255;
            }

            pSourcePlayer->GetPad ()->NewControllerState ( ControllerState );

            // Success
            return true;
        }
    }

    return false;
}
Пример #23
0
bool CPlayerPuresyncPacket::Read ( NetBitStreamInterface& BitStream )
{
    if ( m_pSourceElement )
    {
        CPlayer * pSourcePlayer = static_cast < CPlayer * > ( m_pSourceElement );

        // Read out the time context
        unsigned char ucTimeContext = 0;
        if ( !BitStream.Read ( ucTimeContext ) )
            return false;

        // Only read this packet if it matches the current time context that
        // player is in.
        if ( !pSourcePlayer->CanUpdateSync ( ucTimeContext ) )
        {
            return false;
        }

        // Read out keys
        CControllerState ControllerState;
        ReadFullKeysync ( ControllerState, BitStream );
        pSourcePlayer->GetPad ()->NewControllerState ( ControllerState );

        // Read the flags
        SPlayerPuresyncFlags flags;
        if ( !BitStream.Read ( &flags ) )
            return false;

        pSourcePlayer->SetInWater ( flags.data.bIsInWater );
        pSourcePlayer->SetOnGround ( flags.data.bIsOnGround );
        pSourcePlayer->SetHasJetPack ( flags.data.bHasJetPack );
        pSourcePlayer->SetDucked ( flags.data.bIsDucked );
        pSourcePlayer->SetWearingGoggles ( flags.data.bWearsGoogles );
        pSourcePlayer->SetChoking ( flags.data.bIsChoking );
        pSourcePlayer->SetAkimboArmUp ( flags.data.bAkimboTargetUp );
        pSourcePlayer->SetOnFire ( flags.data.bIsOnFire );
        pSourcePlayer->SetStealthAiming ( flags.data.bStealthAiming );

        // Contact element
        CElement* pContactElement = NULL;
        if ( flags.data.bHasContact )
        {
            ElementID Temp;
            if ( !BitStream.ReadCompressed ( Temp ) )
                return false;
            pContactElement = CElementIDs::GetElement ( Temp );
        }
        CElement * pPreviousContactElement = pSourcePlayer->GetContactElement ();
        pSourcePlayer->SetContactElement ( pContactElement );

        if ( pPreviousContactElement != pContactElement )
        {
            // Call our onPlayerContact event
            CLuaArguments Arguments;
            if ( pPreviousContactElement )
                Arguments.PushElement ( pPreviousContactElement );
            else
                Arguments.PushNil ();
            if ( pContactElement )
                Arguments.PushElement ( pContactElement );
            else
                Arguments.PushNil ();

            pSourcePlayer->CallEvent ( "onPlayerContact", Arguments );
        }

        // Player position
        SPositionSync position ( false );
        if ( !BitStream.Read ( &position ) )
            return false;

        if ( pContactElement )
        {
            pSourcePlayer->SetContactPosition ( position.data.vecPosition );

            // Get the true position
            CVector vecTempPos = pContactElement->GetPosition ();
            position.data.vecPosition += vecTempPos;
        }
        pSourcePlayer->SetPosition ( position.data.vecPosition );

        // Player rotation
        SPedRotationSync rotation;
        if ( !BitStream.Read ( &rotation ) )
            return false;
        pSourcePlayer->SetRotation ( rotation.data.fRotation );

        // Move speed vector
        if ( flags.data.bSyncingVelocity )
        {
            SVelocitySync velocity;
            if ( !BitStream.Read ( &velocity ) )
                return false;
            pSourcePlayer->SetVelocity ( velocity.data.vecVelocity );
        }

        // Health ( stored with damage )
        SPlayerHealthSync health;
        if ( !BitStream.Read ( &health ) )
            return false;
        float fHealth = health.data.fValue;

        // Armor
        SPlayerArmorSync armor;
        if ( !BitStream.Read ( &armor ) )
            return false;

        float fArmor = armor.data.fValue;
        float fOldArmor = pSourcePlayer->GetArmor ();
        float fArmorLoss = fOldArmor - fArmor;

        pSourcePlayer->SetArmor ( fArmor );

        // Read out and set the camera rotation
        float fCameraRotation;
        if ( !BitStream.Read ( fCameraRotation ) )
            return false;
        pSourcePlayer->SetCameraRotation ( fCameraRotation );

        if ( flags.data.bHasAWeapon )
        {
            if ( BitStream.Version () >= 0x0d )
            {
                // Check client has the weapon we think he has
                unsigned char ucWeaponType;
                if ( !BitStream.Read ( ucWeaponType ) )
                    return false;

                if ( pSourcePlayer->GetWeaponType () != ucWeaponType )
                    return false;
            }

            // Current weapon slot
            SWeaponSlotSync slot;
            if ( !BitStream.Read ( &slot ) )
                return false;
            unsigned int uiSlot = slot.data.uiSlot;

            pSourcePlayer->SetWeaponSlot ( uiSlot );

            if ( CWeaponNames::DoesSlotHaveAmmo ( uiSlot ) )
            {
                // Read out the ammo states
                SWeaponAmmoSync ammo ( pSourcePlayer->GetWeaponType (), true, true );
                if ( !BitStream.Read ( &ammo ) )
                    return false;
                pSourcePlayer->SetWeaponAmmoInClip ( ammo.data.usAmmoInClip );
                pSourcePlayer->SetWeaponTotalAmmo ( ammo.data.usTotalAmmo );

                // Read out the aim data
                SWeaponAimSync sync ( pSourcePlayer->GetWeaponRange (), ( ControllerState.RightShoulder1 || ControllerState.ButtonCircle ) );
                if ( !BitStream.Read ( &sync ) )
                    return false;

                // Set the arm directions and whether or not arms are up
                pSourcePlayer->SetAimDirection ( sync.data.fArm );

                // Read the aim data only if he's shooting or aiming
                if ( sync.isFull() )
                {
                    pSourcePlayer->SetSniperSourceVector ( sync.data.vecOrigin );
                    pSourcePlayer->SetTargettingVector ( sync.data.vecTarget );
                }
            }
            else
            {
                pSourcePlayer->SetWeaponAmmoInClip ( 1 );
                pSourcePlayer->SetWeaponTotalAmmo ( 1 );
            }
        }
        else
        {
            pSourcePlayer->SetWeaponSlot ( 0 );
            pSourcePlayer->SetWeaponAmmoInClip ( 1 );
            pSourcePlayer->SetWeaponTotalAmmo ( 1 );
        }

        // Read out damage info if changed
        if ( BitStream.ReadBit () == true )
        {
            ElementID DamagerID;
            if ( !BitStream.ReadCompressed ( DamagerID ) )
                return false;

            SWeaponTypeSync weaponType;
            if ( !BitStream.Read ( &weaponType ) )
                return false;

            SBodypartSync bodyPart;
            if ( !BitStream.Read ( &bodyPart ) )
                return false;

            pSourcePlayer->SetDamageInfo ( DamagerID, weaponType.data.ucWeaponType, bodyPart.data.uiBodypart );
        }

        // If we know the player's dead, make sure the health we send on is 0
        if ( pSourcePlayer->IsDead () )
            fHealth = 0.0f;

        float fOldHealth = pSourcePlayer->GetHealth ();
        float fHealthLoss = fOldHealth - fHealth;
        pSourcePlayer->SetHealth ( fHealth );

        // Less than last packet's frame?
        if ( fHealthLoss > 0 || fArmorLoss > 0 )
        {
            float fDamage = 0.0f;
            if ( fHealthLoss > 0 ) fDamage += fHealthLoss;
            if ( fArmorLoss > 0 ) fDamage += fArmorLoss;

            // Call the onPlayerDamage event
            CLuaArguments Arguments;
            CElement* pKillerElement = CElementIDs::GetElement ( pSourcePlayer->GetPlayerAttacker () );
            if ( pKillerElement ) Arguments.PushElement ( pKillerElement );
            else Arguments.PushNil ();
            Arguments.PushNumber ( pSourcePlayer->GetAttackWeapon () );
            Arguments.PushNumber ( pSourcePlayer->GetAttackBodyPart () );
            Arguments.PushNumber ( fDamage );

            pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments );
        }

        // Success
        return true;
    }

    return false;
}
Пример #24
0
void CWeaponRPCs::GiveWeapon ( NetBitStreamInterface& bitStream )
{
    // Read out weapon id and ammo amount
    ElementID ID;
    SWeaponTypeSync weaponType;

    if ( bitStream.ReadCompressed ( ID ) &&
         bitStream.Read ( &weaponType ) )
    {
        SWeaponAmmoSync ammo ( weaponType.data.ucWeaponType, true, false );
        if ( bitStream.Read ( &ammo ) )
        {
            bool bGiveWeapon = bitStream.ReadBit ();
            unsigned char ucWeaponID = weaponType.data.ucWeaponType;
            unsigned short usAmmo = ammo.data.usTotalAmmo;

            CClientPed * pPed = m_pPedManager->Get ( ID, true );
            if ( pPed )
            {
                // Don't change remote players weapons (affects sync)
                if ( pPed->GetType () == CCLIENTPED || pPed->GetType () == CCLIENTPLAYER )
                {
                    // Valid weapon id?
                    if ( ucWeaponID == 0 || CClientPickupManager::IsValidWeaponID ( ucWeaponID ) )
                    {
                        // Adjust the ammo to 9999 if it's above
                        if ( usAmmo > 9999 ) usAmmo = 9999;

                        // Give the local player the weapon
                        CWeapon* pPlayerWeapon = NULL;
                        if ( ucWeaponID != 0 )
                        {
                            pPlayerWeapon = pPed->GiveWeapon ( static_cast < eWeaponType > ( ucWeaponID ), usAmmo );
                            if ( pPlayerWeapon && bGiveWeapon )
                                pPlayerWeapon->SetAsCurrentWeapon ();
                        }
                        else
                        {
                            // This could be entered into a hack of the year competition. Its about as hacky as it gets.
                            // For some stupid reason, going from brassknuckles to unarmed causes the knuckles to remain 
                            // on display but unusable. So, what we do is switch to a MELEE weapon (creating one if necessary)
                            // then switch back to unarmed from there, which works fine.
                            CWeapon* oldWeapon = pPed->GetWeapon (WEAPONSLOT_TYPE_UNARMED);
                            if ( oldWeapon )
                            {
                                eWeaponType unarmedWeapon = oldWeapon->GetType();
                                pPed->RemoveWeapon ( unarmedWeapon );
                                if ( bGiveWeapon || pPed->GetCurrentWeaponSlot() == WEAPONSLOT_TYPE_UNARMED )
                                {
                                    oldWeapon = NULL;
                                    if ( unarmedWeapon == WEAPONTYPE_BRASSKNUCKLE )
                                    {
                                        oldWeapon = pPed->GetWeapon(WEAPONSLOT_TYPE_MELEE);
                                        if ( oldWeapon && oldWeapon->GetType() == WEAPONTYPE_UNARMED )
                                        {
                                            oldWeapon = pPed->GiveWeapon(WEAPONTYPE_GOLFCLUB, 100);
                                        }
                                        else
                                        {
                                            oldWeapon = NULL;
                                        }
                                        pPed->SetCurrentWeaponSlot ( WEAPONSLOT_TYPE_MELEE );
                                    }

                                    // switch to the unarmed slot
                                    pPed->SetCurrentWeaponSlot ( WEAPONSLOT_TYPE_UNARMED );

                                    // if we created a special MELEE weapon just for this, remove it now
                                    if ( oldWeapon )
                                    {
                                        oldWeapon->Remove();
                                    }
                                }
                            }
                            else
                            {
                                // Probably the ped is streamed out
                                pPed->GiveWeapon ( WEAPONTYPE_UNARMED, 1 );
                                if ( bGiveWeapon )
                                    pPed->SetCurrentWeaponSlot ( WEAPONSLOT_TYPE_UNARMED );
                            }
                        }
                    }
                }
            }
        }
    }
}
Пример #25
0
void CRPCFunctions::CursorEvent ( NetBitStreamInterface & bitStream )
{
    SMouseButtonSync button;
    unsigned char ucButton;

    CVector2D vecCursorPosition;
    unsigned short usX;
    unsigned short usY;

    SPositionSync position ( false );
    CVector vecPosition;

    bool bHasCollisionElement;
    ElementID elementID;

    if ( bitStream.Read ( &button ) &&
            bitStream.ReadCompressed ( usX ) &&
            bitStream.ReadCompressed ( usY ) &&
            bitStream.Read ( &position ) &&
            bitStream.ReadBit ( bHasCollisionElement ) &&
            ( !bHasCollisionElement || bitStream.ReadCompressed ( elementID ) ) )
    {
        ucButton = button.data.ucButton;
        vecCursorPosition.fX = static_cast < float > ( usX );
        vecCursorPosition.fY = static_cast < float > ( usY );
        vecPosition = position.data.vecPosition;
        if ( !bHasCollisionElement )
            elementID = INVALID_ELEMENT_ID;
    }
    else
        return;

    if ( m_pSourcePlayer->IsJoined () )
    {
        // Get the button and state
        const char* szButton = NULL;
        const char* szState = NULL;
        switch ( ucButton )
        {
        case 0:
            szButton = "left";
            szState = "down";
            break;
        case 1:
            szButton = "left";
            szState = "up";
            break;
        case 2:
            szButton = "middle";
            szState = "down";
            break;
        case 3:
            szButton = "middle";
            szState = "up";
            break;
        case 4:
            szButton = "right";
            szState = "down";
            break;
        case 5:
            szButton = "right";
            szState = "up";
            break;
        }
        if ( szButton && szState )
        {
            CElement* pElement = CElementIDs::GetElement ( elementID );
            if ( pElement )
            {
                // Call the onElementClicked event
                CLuaArguments Arguments;
                Arguments.PushString ( szButton );
                Arguments.PushString ( szState );
                Arguments.PushElement ( m_pSourcePlayer );
                Arguments.PushNumber ( vecPosition.fX );
                Arguments.PushNumber ( vecPosition.fY );
                Arguments.PushNumber ( vecPosition.fZ );
                pElement->CallEvent ( "onElementClicked", Arguments );
            }
            // Call the onPlayerClick event
            CLuaArguments Arguments;
            Arguments.PushString ( szButton );
            Arguments.PushString ( szState );
            if ( pElement )
                Arguments.PushElement ( pElement );
            else
                Arguments.PushNil ();
            Arguments.PushNumber ( vecPosition.fX );
            Arguments.PushNumber ( vecPosition.fY );
            Arguments.PushNumber ( vecPosition.fZ );
            Arguments.PushNumber ( vecCursorPosition.fX );
            Arguments.PushNumber ( vecCursorPosition.fY );
            m_pSourcePlayer->CallEvent ( "onPlayerClick", Arguments );

            // TODO: iterate server-side element managers for the click events, eg: colshapes
        }
    }
}