void CElementRPCs::SetElementDimension ( NetBitStreamInterface& bitStream ) { ElementID ID; unsigned short usDimension; if ( bitStream.Read ( ID ) && bitStream.Read ( usDimension ) ) { CClientEntity* pEntity = CElementIDs::GetElement ( ID ); if ( pEntity ) { if ( pEntity->GetType () == CCLIENTTEAM ) { CClientTeam* pTeam = static_cast < CClientTeam* > ( pEntity ); list < CClientPlayer* > ::const_iterator iter = pTeam->IterBegin (); for ( ; iter != pTeam->IterEnd () ; iter++ ) { CClientPlayer* pPlayer = *iter; if ( pPlayer->IsLocalPlayer () ) { // Update all of our streamers/managers to the local player's dimension m_pClientGame->SetAllDimensions ( usDimension ); } pPlayer->SetDimension ( usDimension ); } } else { if ( pEntity->GetType () == CCLIENTPLAYER ) { CClientPlayer* pPlayer = static_cast < CClientPlayer* > ( pEntity ); if ( pPlayer->IsLocalPlayer () ) { // Update all of our streamers/managers to the local player's dimension m_pClientGame->SetAllDimensions ( usDimension ); } } pEntity->SetDimension ( usDimension ); } } } }
void CClientMarker::Callback_OnLeave ( CClientColShape& Shape, CClientEntity& Entity ) { if ( IS_PLAYER ( &Entity ) ) { // Call the marker hit event CLuaArguments Arguments; Arguments.PushElement ( &Entity ); // player that hit it Arguments.PushBoolean ( ( Shape.GetDimension () == Entity.GetDimension () ) ); // matching dimension? CallEvent ( "onClientMarkerLeave", Arguments, true ); } }
void CElementRPCs::SetElementName ( NetBitStreamInterface& bitStream ) { ElementID ID; unsigned short usNameLength; if ( bitStream.Read ( ID ) && bitStream.Read ( usNameLength ) ) { char* szName = new char [ usNameLength + 1 ]; szName [ usNameLength ] = 0; if ( bitStream.Read ( szName, usNameLength ) ) { CClientEntity* pEntity = CElementIDs::GetElement ( ID ); if ( pEntity ) { pEntity->SetName ( szName ); } } delete [] szName; } }
int CLuaFunctionDefs::AddEventHandler ( lua_State* luaVM ) { // bool addEventHandler ( string eventName, element attachedTo, function handlerFunction, [bool getPropagated = true] ) SString strName; CClientEntity* pEntity; CLuaFunctionRef iLuaFunction; bool bPropagated; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strName ); argStream.ReadUserData ( pEntity ); argStream.ReadFunction ( iLuaFunction ); argStream.ReadBool ( bPropagated, true ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { // Grab our virtual machine CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { // Check if the handle is in use if ( pEntity->GetEventManager()->HandleExists ( pLuaMain, strName, iLuaFunction ) ) { m_pScriptDebugging->LogCustom ( luaVM, 255, 0, 0, "addEventHandler: '%s' with this function is already handled", *strName ); lua_pushboolean ( luaVM, false ); return 1; } // Do it if ( CStaticFunctionDefinitions::AddEventHandler ( *pLuaMain, strName, *pEntity, iLuaFunction, bPropagated ) ) { lua_pushboolean ( luaVM, true ); return 1; } } } else m_pScriptDebugging->LogCustom ( luaVM, SString ( "Bad argument @ '%s' [%s]", "addEventHandler", *argStream.GetErrorMessage () ) ); // Failed lua_pushboolean ( luaVM, false ); return 1; }
void CElementRPCs::AttachElements ( NetBitStreamInterface& bitStream ) { ElementID ID, usAttachedToID; CVector vecPosition, vecRotation; if ( bitStream.Read ( ID ) && bitStream.Read ( usAttachedToID ) && bitStream.Read ( vecPosition.fX ) && bitStream.Read ( vecPosition.fY ) && bitStream.Read ( vecPosition.fZ ) && bitStream.Read ( vecRotation.fX ) && bitStream.Read ( vecRotation.fY ) && bitStream.Read ( vecRotation.fZ ) ) { CClientEntity* pEntity = CElementIDs::GetElement ( ID ); CClientEntity* pAttachedToEntity = CElementIDs::GetElement ( usAttachedToID ); if ( pEntity && pAttachedToEntity ) { pEntity->SetAttachedOffsets ( vecPosition, vecRotation ); pEntity->AttachTo ( pAttachedToEntity ); } } }
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; } }
CClientEntity* lua_toelement ( lua_State* luaVM, int iArgument ) { if ( lua_type ( luaVM, iArgument ) == LUA_TLIGHTUSERDATA ) { ElementID ID = TO_ELEMENTID ( lua_touserdata ( luaVM, iArgument ) ); CClientEntity* pEntity = CElementIDs::GetElement ( ID ); if ( !pEntity || pEntity->IsBeingDeleted () ) return NULL; return pEntity; } else if ( lua_type ( luaVM, iArgument ) == LUA_TUSERDATA ) { ElementID ID = TO_ELEMENTID ( * ( ( void ** ) lua_touserdata ( luaVM, iArgument ) ) ); CClientEntity* pEntity = CElementIDs::GetElement ( ID ); if ( !pEntity || pEntity->IsBeingDeleted () ) return NULL; return pEntity; } return NULL; }
int CLuaTaskDefs::setPlayerTask ( lua_State* luaVM ) { // bool setPlayerTask ( ped thePed, taskinstance task ) // returns true on success or false on failure // Verify types if ( argtype ( 1, LUA_TLIGHTUSERDATA ) && argtype ( 2, LUA_TTABLE ) ) { // Grab the player // TODO: Support peds too CClientEntity* pEntity = lua_toelement ( luaVM, 1 ); if ( pEntity ) { // Player? if ( pEntity->GetType () == CCLIENTPLAYER ) { // Grab the player CClientPlayer* pPlayer = static_cast < CClientPlayer* > ( pEntity ); // Read out the task data CClientTask Task ( m_pManager ); if ( Task.Read ( luaVM, 2, true ) ) { // Apply it on the player bool bSuccess = Task.ApplyTask ( *pPlayer ); // Success lua_pushboolean ( luaVM, bSuccess ); return 1; } } } } // Failed lua_pushboolean ( luaVM, false ); return 1; }
void CElementRPCs::SetElementParent ( NetBitStreamInterface& bitStream ) { // Read out the entity id and parent id ElementID ID, ParentID; if ( bitStream.Read ( ID ) && bitStream.Read ( ParentID ) ) { CClientEntity* pEntity = CElementIDs::GetElement ( ID ); CClientEntity* pParent = CElementIDs::GetElement ( ParentID ); if ( pEntity && pParent ) { pEntity->SetParent ( pParent ); } else { // TODO: raise an error } } else { // TODO: raise an error } }
void CElementRPCs::DetachElements ( NetBitStreamInterface& bitStream ) { ElementID ID; unsigned char ucTimeContext; if ( bitStream.Read ( ID ) && bitStream.Read ( ucTimeContext ) ) { CClientEntity* pEntity = CElementIDs::GetElement ( ID ); if ( pEntity ) { pEntity->SetSyncTimeContext ( ucTimeContext ); pEntity->AttachTo ( NULL ); CVector vecPosition; if ( bitStream.Read ( vecPosition.fX ) && bitStream.Read ( vecPosition.fY ) && bitStream.Read ( vecPosition.fZ ) ) { pEntity->SetPosition ( vecPosition ); } } } }
CClientEntity* CClientEntity::FindChildIndex ( const char* szName, unsigned int uiIndex, unsigned int& uiCurrentIndex, bool bRecursive ) { assert ( szName ); // Look among our children list < CClientEntity* > ::const_iterator iter = m_Children.begin (); for ( ; iter != m_Children.end (); iter++ ) { CClientEntity* pChild = *iter; // Name matches? if ( strcmp ( pChild->GetName (), szName ) == 0 ) { // Does the index match? If it doesn't, increment it and keep searching if ( uiIndex == uiCurrentIndex ) { return pChild; } else { ++uiCurrentIndex; } } // Tell this child to search too if recursive if ( bRecursive ) { CClientEntity* pEntity = pChild->FindChildIndex ( szName, uiIndex, uiCurrentIndex, true ); if ( pEntity ) { return pEntity; } } } // Doesn't exist within us return NULL; }
/////////////////////////////////////////////////////////////// // // CClientSpatialDatabaseImpl::FlushUpdateQueue // // Process all entities that have changed since the last call // /////////////////////////////////////////////////////////////// void CClientSpatialDatabaseImpl::FlushUpdateQueue ( void ) { std::map < CClientEntity*, int > updateQueueCopy = m_UpdateQueue; m_UpdateQueue.clear (); for ( std::map < CClientEntity*, int >::iterator it = updateQueueCopy.begin (); it != updateQueueCopy.end (); ++it ) { CClientEntity* pEntity = it->first; // Get the new bounding box SEntityInfo newInfo; CSphere sphere = pEntity->GetWorldBoundingSphere (); newInfo.box = CBox ( sphere.vecPosition, fabsf ( sphere.fRadius ) ); // Make everything 2D for now newInfo.box.vecMin.fZ = SPATIAL_2D_Z; newInfo.box.vecMax.fZ = SPATIAL_2D_Z; // Get previous info if ( SEntityInfo* pOldInfo = MapFind ( m_InfoMap, pEntity ) ) { // Don't update if bounding box is the same if ( pOldInfo->box == newInfo.box ) continue; // Remove old bounding box from tree m_Tree.Remove ( &pOldInfo->box.vecMin.fX, &pOldInfo->box.vecMax.fX, pEntity ); } if ( !IsValidSphere ( sphere ) ) continue; // Add new bounding box m_Tree.Insert( &newInfo.box.vecMin.fX, &newInfo.box.vecMax.fX, pEntity ); // Update info map MapSet ( m_InfoMap, pEntity, newInfo ); } }
void CElementRPCs::SetElementModel ( NetBitStreamInterface& bitStream ) { ElementID ID; unsigned short usModel; if ( bitStream.Read ( ID ) && bitStream.Read ( usModel ) ) { CClientEntity * pEntity = CElementIDs::GetElement ( ID ); if ( pEntity ) { switch ( pEntity->GetType () ) { case CCLIENTPED: case CCLIENTPLAYER: { CClientPed* pPed = static_cast < CClientPed * > ( pEntity ); pPed->SetModel ( usModel ); break; } case CCLIENTVEHICLE: { CClientVehicle* pVehicle = static_cast < CClientVehicle * > ( pEntity ); pVehicle->SetModelBlocking ( usModel ); break; } case CCLIENTOBJECT: { CClientObject* pObject = static_cast < CClientObject * > ( pEntity ); pObject->SetModel ( usModel ); break; } } } } }
// // Make player 'orbit camera' rotate to face this point // void CClientCamera::SetOrbitTarget ( const CVector& vecPosition ) { if ( m_pCamera ) { CClientEntity* pCameraTarget = GetTargetEntity ( ); if ( pCameraTarget != nullptr ) { CVector vecTargetPosition; pCameraTarget->GetPosition ( vecTargetPosition ); if ( pCameraTarget->GetType () == CCLIENTPLAYER ) vecTargetPosition.fZ += 0.6f; CVector vecDirection = vecPosition - vecTargetPosition; vecDirection.Normalize (); float fAngleHorz = -atan2 ( vecDirection.fX, vecDirection.fY ) - PI / 2; float fAngleVert = asin ( vecDirection.fZ ); CCam* pCam = m_pCamera->GetCam ( m_pCamera->GetActiveCam () ); pCam->SetDirection ( fAngleHorz, fAngleVert ); } } }
void CElementRPCs::SetElementInterior ( NetBitStreamInterface& bitStream ) { ElementID ID; unsigned char ucInterior, ucSetPosition; if ( bitStream.Read ( ID ) && bitStream.Read ( ucInterior ) && bitStream.Read ( ucSetPosition ) ) { CClientEntity* pEntity = CElementIDs::GetElement ( ID ); if ( pEntity ) { pEntity->SetInterior ( ucInterior ); if ( ucSetPosition == 1 ) { CVector vecPosition; if ( bitStream.Read ( vecPosition.fX ) && bitStream.Read ( vecPosition.fY ) && bitStream.Read ( vecPosition.fZ ) ) { pEntity->SetPosition ( vecPosition ); } } } } }
json_object * CLuaArgument::WriteToJSONObject ( bool bSerialize, std::map < CLuaArguments*, unsigned long > * pKnownTables ) { switch ( GetType () ) { case LUA_TNIL: { return json_object_new_int(0); } case LUA_TBOOLEAN: { return json_object_new_boolean(GetBoolean ()); } case LUA_TTABLE: { if ( pKnownTables && pKnownTables->find ( m_pTableData ) != pKnownTables->end () ) { char szTableID[10]; snprintf ( szTableID, sizeof(szTableID), "^T^%lu", pKnownTables->find ( m_pTableData )->second ); return json_object_new_string ( szTableID ); } else { return m_pTableData->WriteTableToJSONObject ( bSerialize, pKnownTables ); } } case LUA_TNUMBER: { float fNum = static_cast < float > ( GetNumber () ); int iNum = static_cast < int > ( GetNumber () ); if ( iNum == fNum ) { return json_object_new_int(iNum); } else { return json_object_new_double(fNum); } break; } case LUA_TSTRING: { const char* szTemp = GetString (); unsigned short usLength = static_cast < unsigned short > ( strlen ( szTemp ) ); if ( strlen ( szTemp ) == usLength ) { return json_object_new_string_len ( (char *)szTemp, usLength ); } else { g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON. Invalid string specified, limit is 65535 characters." ); } break; } case LUA_TLIGHTUSERDATA: { CClientEntity* pElement = GetElement (); CResource* pResource = reinterpret_cast < CResource* > ( GetLightUserData() ); // Elements are dynamic, so storing them is potentially unsafe if ( pElement && bSerialize ) { char szElementID[10] = {0}; snprintf ( szElementID, 9, "^E^%d", (int)pElement->GetID().Value() ); return json_object_new_string ( szElementID ); } else if ( VERIFY_RESOURCE(pResource) ) { char szElementID[MAX_RESOURCE_NAME_LENGTH+4] = {0}; snprintf ( szElementID, MAX_RESOURCE_NAME_LENGTH+3, "^R^%s", pResource->GetName()/*.c_str ()*/ ); return json_object_new_string ( szElementID ); } else { g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON, only valid elements can be sent." ); return NULL; } break; } default: { g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON, unsupported data type. Use Table, Nil, String, Number, Boolean, Resource or Element." ); return NULL; } } return NULL; }
int CLuaFunctionDefs::CreateProjectile ( lua_State* luaVM ) { if ( ( lua_istype ( luaVM, 1, LUA_TLIGHTUSERDATA ) ) && ( lua_istype ( luaVM, 2, LUA_TNUMBER ) || lua_istype ( luaVM, 2, LUA_TSTRING ) ) ) { CClientEntity* pCreator = lua_toelement ( luaVM, 1 ); if ( pCreator ) { unsigned char ucWeaponType = static_cast < unsigned char > ( lua_tonumber ( luaVM, 2 ) ); CVector vecOrigin; pCreator->GetPosition ( vecOrigin ); float fForce = 1.0f; CClientEntity* pTarget = NULL; CVector *pvecRotation = NULL, *pvecMoveSpeed = NULL; unsigned short usModel = 0; if ( ( lua_istype ( luaVM, 3, LUA_TNUMBER ) || lua_istype ( luaVM, 3, LUA_TSTRING ) ) && ( lua_istype ( luaVM, 4, LUA_TNUMBER ) || lua_istype ( luaVM, 4, LUA_TSTRING ) ) && ( lua_istype ( luaVM, 5, LUA_TNUMBER ) || lua_istype ( luaVM, 5, LUA_TSTRING ) ) ) { vecOrigin = CVector ( static_cast < float > ( lua_tonumber ( luaVM, 3 ) ), static_cast < float > ( lua_tonumber ( luaVM, 4 ) ), static_cast < float > ( lua_tonumber ( luaVM, 5 ) ) ); if ( lua_istype ( luaVM, 6, LUA_TNUMBER ) || lua_istype ( luaVM, 6, LUA_TSTRING ) ) { fForce = static_cast < float > ( lua_tonumber ( luaVM, 6 ) ); if ( lua_istype ( luaVM, 7, LUA_TLIGHTUSERDATA ) ) { CClientEntity* pTemp = lua_toelement ( luaVM, 7 ); if ( pTemp ) { pTarget = pTemp; } else m_pScriptDebugging->LogBadPointer ( luaVM, "createProjectile", "element", 7 ); } int iArgument8 = lua_type ( luaVM, 8 ); int iArgument9 = lua_type ( luaVM, 9 ); int iArgument10 = lua_type ( luaVM, 10 ); if ( ( iArgument8 == LUA_TSTRING || iArgument8 == LUA_TNUMBER ) && ( iArgument9 == LUA_TSTRING || iArgument9 == LUA_TNUMBER ) && ( iArgument10 == LUA_TSTRING || iArgument10 == LUA_TNUMBER ) ) { pvecRotation = new CVector ( static_cast < float > ( lua_tonumber ( luaVM, 8 ) ), static_cast < float > ( lua_tonumber ( luaVM, 9 ) ), static_cast < float > ( lua_tonumber ( luaVM, 10 ) ) ); } int iArgument11 = lua_type ( luaVM, 11 ); int iArgument12 = lua_type ( luaVM, 12 ); int iArgument13 = lua_type ( luaVM, 13 ); if ( ( iArgument11 == LUA_TSTRING || iArgument11 == LUA_TNUMBER ) && ( iArgument12 == LUA_TSTRING || iArgument12 == LUA_TNUMBER ) && ( iArgument13 == LUA_TSTRING || iArgument13 == LUA_TNUMBER ) ) { pvecMoveSpeed = new CVector ( static_cast < float > ( lua_tonumber ( luaVM, 11 ) ), static_cast < float > ( lua_tonumber ( luaVM, 12 ) ), static_cast < float > ( lua_tonumber ( luaVM, 13 ) ) ); int iArgument14 = lua_type ( luaVM, 14 ); if ( iArgument14 == LUA_TSTRING || iArgument14 == LUA_TNUMBER ) { usModel = static_cast < unsigned short > ( lua_tonumber ( luaVM, 14 ) ); } } } } CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { CResource * pResource = pLuaMain->GetResource(); if ( pResource ) { CClientProjectile * pProjectile = CStaticFunctionDefinitions::CreateProjectile ( *pResource, *pCreator, ucWeaponType, vecOrigin, fForce, pTarget, pvecRotation, pvecMoveSpeed, usModel ); if ( pProjectile ) { CElementGroup * pGroup = pResource->GetElementGroup(); if ( pGroup ) { pGroup->Add ( ( CClientEntity* ) pProjectile ); } if ( pvecRotation ) { delete pvecRotation; pvecRotation = NULL; } if ( pvecMoveSpeed ) { delete pvecMoveSpeed; pvecMoveSpeed = NULL; } lua_pushelement ( luaVM, pProjectile ); return 1; } } } if ( pvecRotation ) { delete pvecRotation; pvecRotation = NULL; } if ( pvecMoveSpeed ) { delete pvecMoveSpeed; pvecMoveSpeed = NULL; } } else m_pScriptDebugging->LogBadPointer ( luaVM, "createProjectile", "element", 1 ); } else m_pScriptDebugging->LogBadType ( luaVM, "createProjectile" ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFunctionDefs::IsLineOfSightClear ( lua_State * luaVM ) { int iArgument1 = lua_type ( luaVM, 1 ); int iArgument2 = lua_type ( luaVM, 2 ); int iArgument3 = lua_type ( luaVM, 3 ); int iArgument4 = lua_type ( luaVM, 4 ); int iArgument5 = lua_type ( luaVM, 5 ); int iArgument6 = lua_type ( luaVM, 6 ); if ( ( iArgument1 == LUA_TNUMBER || iArgument1 == LUA_TSTRING ) && ( iArgument2 == LUA_TNUMBER || iArgument2 == LUA_TSTRING ) && ( iArgument3 == LUA_TNUMBER || iArgument3 == LUA_TSTRING ) && ( iArgument4 == LUA_TNUMBER || iArgument4 == LUA_TSTRING ) && ( iArgument5 == LUA_TNUMBER || iArgument5 == LUA_TSTRING ) && ( iArgument6 == LUA_TNUMBER || iArgument6 == LUA_TSTRING ) ) { CVector vecStart ( static_cast < float > ( lua_tonumber ( luaVM, 1 ) ), static_cast < float > ( lua_tonumber ( luaVM, 2 ) ), static_cast < float > ( lua_tonumber ( luaVM, 3 ) ) ); CVector vecEnd ( static_cast < float > ( lua_tonumber ( luaVM, 4 ) ), static_cast < float > ( lua_tonumber ( luaVM, 5 ) ), static_cast < float > ( lua_tonumber ( luaVM, 6 ) ) ); bool bCheckBuildings = true, bCheckVehicles = true, bCheckPeds = true, bCheckObjects = true, bCheckDummies = true, bSeeThroughStuff = false, bIgnoreSomeObjectsForCamera = false; CEntity* pIgnoredEntity = NULL; if ( lua_type ( luaVM, 7 ) == LUA_TBOOLEAN ) { bCheckBuildings = ( lua_toboolean ( luaVM, 7 ) ) ? true:false; if ( lua_type ( luaVM, 8 ) == LUA_TBOOLEAN ) { bCheckVehicles = ( lua_toboolean ( luaVM, 8 ) ) ? true:false; if ( lua_type ( luaVM, 9 ) == LUA_TBOOLEAN ) { bCheckPeds = ( lua_toboolean ( luaVM, 9 ) ) ? true:false; if ( lua_type ( luaVM, 10 ) == LUA_TBOOLEAN ) { bCheckObjects = ( lua_toboolean ( luaVM, 10 ) ) ? true:false; if ( lua_type ( luaVM, 11 ) == LUA_TBOOLEAN ) { bCheckDummies = ( lua_toboolean ( luaVM, 11 ) ) ? true:false; if ( lua_type ( luaVM, 12 ) == LUA_TBOOLEAN ) { bSeeThroughStuff = ( lua_toboolean ( luaVM, 12 ) ) ? true:false; if ( lua_type ( luaVM, 13 ) == LUA_TBOOLEAN ) { bIgnoreSomeObjectsForCamera = ( lua_toboolean ( luaVM, 13 ) ) ? true:false; if ( lua_type ( luaVM, 14 ) == LUA_TLIGHTUSERDATA ) { CClientEntity* pEntity = lua_toelement ( luaVM, 14 ); if ( pEntity ) { switch ( pEntity->GetType () ) { case CCLIENTPED: case CCLIENTPLAYER: pIgnoredEntity = static_cast < CClientPed* > ( pEntity )->GetGamePlayer (); break; case CCLIENTVEHICLE: pIgnoredEntity = static_cast < CClientVehicle* > ( pEntity )->GetGameVehicle (); break; case CCLIENTOBJECT: pIgnoredEntity = static_cast < CClientObject* > ( pEntity )->GetGameObject (); break; } } } } } } } } } } bool bIsClear; if ( CStaticFunctionDefinitions::IsLineOfSightClear ( vecStart, vecEnd, bIsClear, bCheckBuildings, bCheckVehicles, bCheckPeds, bCheckObjects, bCheckDummies, bSeeThroughStuff, bIgnoreSomeObjectsForCamera, pIgnoredEntity ) ) { lua_pushboolean ( luaVM, bIsClear ); return 1; } } else m_pScriptDebugging->LogBadType ( luaVM, "isLineOfSightClear" ); lua_pushboolean ( luaVM, false ); return 1; }
bool CLuaArgument::WriteToBitStream ( NetBitStreamInterface& bitStream, CFastHashMap < CLuaArguments*, unsigned long > * pKnownTables ) const { SLuaTypeSync type; switch ( GetType () ) { // Nil type case LUA_TNIL: { type.data.ucType = LUA_TNIL; bitStream.Write ( &type ); break; } // Boolean type case LUA_TBOOLEAN: { type.data.ucType = LUA_TBOOLEAN; bitStream.Write ( &type ); // Write the boolean to it bitStream.WriteBit ( GetBoolean () ); break; } // Table argument case LUA_TTABLE: { ulong* pTableId; if ( pKnownTables && ( pTableId = MapFind ( *pKnownTables, m_pTableData ) ) ) { // Self-referencing table type.data.ucType = LUA_TTABLEREF; bitStream.Write ( &type ); bitStream.WriteCompressed ( *pTableId ); } else { type.data.ucType = LUA_TTABLE; bitStream.Write ( &type ); // Write the subtable to the bitstream m_pTableData->WriteToBitStream ( bitStream, pKnownTables ); } break; } // Number argument? case LUA_TNUMBER: { type.data.ucType = LUA_TNUMBER; bitStream.Write ( &type ); if ( bitStream.Version() < 0x59 ) { // Old way int iNumber; if ( !ShouldUseInt( GetNumber(), &iNumber ) ) { bitStream.WriteBit ( true ); bitStream.Write ( static_cast < float > ( GetNumber() ) ); } else { bitStream.WriteBit ( false ); bitStream.WriteCompressed ( iNumber ); } } else { // New way - Maybe use double to better preserve > 32bit numbers int iNumber; float fNumber; double dNumber; EDataType dataType = GetDataTypeToUse( GetNumber(), &iNumber, &fNumber, &dNumber ); if ( dataType == DATA_TYPE_INT ) { bitStream.WriteBit ( false ); bitStream.WriteCompressed ( iNumber ); } else if ( dataType == DATA_TYPE_FLOAT ) { bitStream.WriteBit ( true ); bitStream.WriteBit ( false ); bitStream.Write ( fNumber ); } else { bitStream.WriteBit ( true ); bitStream.WriteBit ( true ); bitStream.Write ( dNumber ); } } break; } // String argument case LUA_TSTRING: { // Grab the string and its length. Is it short enough to be sendable? const char* szTemp = m_strString.c_str (); size_t sizeTemp = m_strString.length (); unsigned short usLength = static_cast < unsigned short > ( sizeTemp ); if ( sizeTemp == usLength ) { // This is a string argument type.data.ucType = LUA_TSTRING; bitStream.Write ( &type ); // Write its length bitStream.WriteCompressed ( usLength ); // Write the content too if it's not empty if ( usLength > 0 ) { bitStream.Write ( szTemp, usLength ); } } else { // This is a long string argument type.data.ucType = LUA_TSTRING_LONG; bitStream.Write ( &type ); // Write its length uint uiLength = sizeTemp; bitStream.WriteCompressed ( uiLength ); // Write the content too if it's not empty if ( uiLength > 0 ) { bitStream.AlignWriteToByteBoundary (); bitStream.Write ( szTemp, uiLength ); } } break; } // Element packet case LUA_TLIGHTUSERDATA: case LUA_TUSERDATA: { // Got a valid element to send? CClientEntity* pElement = GetElement (); if ( pElement ) { // Clientside element? if ( !pElement->IsLocalEntity () ) { type.data.ucType = LUA_TLIGHTUSERDATA; bitStream.Write ( &type ); bitStream.Write ( pElement->GetID () ); } else { // Write a nil though so other side won't get out of sync type.data.ucType = LUA_TNIL; bitStream.Write ( &type ); return false; } } else { // Write a nil though so other side won't get out of sync type.data.ucType = LUA_TNIL; bitStream.Write ( &type ); return false; } break; } // Unpacketizable type. default: { // Unpacketizable LogUnableToPacketize ( "Couldn't packetize argument list, unknown type specified." ); // Write a nil though so other side won't get out of sync type.data.ucType = LUA_TNIL; bitStream.Write ( &type ); return false; } } // Success return true; }
json_object * CLuaArgument::WriteToJSONObject ( bool bSerialize, CFastHashMap < CLuaArguments*, unsigned long > * pKnownTables ) { switch ( GetType () ) { case LUA_TNIL: { return json_object_new_int(0); } case LUA_TBOOLEAN: { return json_object_new_boolean(GetBoolean ()); } case LUA_TTABLE: { ulong* pTableId; if ( pKnownTables && ( pTableId = MapFind ( *pKnownTables, m_pTableData ) ) ) { // Self-referencing table char szTableID[10]; snprintf ( szTableID, sizeof(szTableID), "^T^%lu", *pTableId ); return json_object_new_string ( szTableID ); } else { return m_pTableData->WriteTableToJSONObject ( bSerialize, pKnownTables ); } } case LUA_TNUMBER: { int iNumber; if ( ShouldUseInt( GetNumber(), &iNumber ) ) { return json_object_new_int( iNumber ); } else { return json_object_new_double( static_cast < float > ( GetNumber() ) ); } break; } case LUA_TSTRING: { const char* szTemp = GetString (); unsigned short usLength = static_cast < unsigned short > ( strlen ( szTemp ) ); if ( strlen ( szTemp ) == usLength ) { return json_object_new_string_len ( (char *)szTemp, usLength ); } else { g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON. Invalid string specified, limit is 65535 characters." ); } break; } case LUA_TUSERDATA: case LUA_TLIGHTUSERDATA: { CClientEntity* pElement = GetElement (); CResource* pResource = g_pClientGame->GetResourceManager ()->GetResourceFromScriptID ( reinterpret_cast < unsigned long > ( GetUserData () ) ); // Elements are dynamic, so storing them is potentially unsafe if ( pElement && bSerialize ) { char szElementID[10] = {0}; snprintf ( szElementID, 9, "^E^%d", (int)pElement->GetID().Value() ); return json_object_new_string ( szElementID ); } else if ( VERIFY_RESOURCE(pResource) ) { char szElementID[MAX_RESOURCE_NAME_LENGTH+4] = {0}; snprintf ( szElementID, MAX_RESOURCE_NAME_LENGTH+3, "^R^%s", pResource->GetName()/*.c_str ()*/ ); return json_object_new_string ( szElementID ); } else { if ( pElement ) // eg toJSON() with valid element g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert userdata argument to JSON, elements not allowed for this function." ); else if ( !bSerialize ) // eg toJSON() with invalid element g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert userdata argument to JSON, only valid resources can be included for this function." ); else g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert userdata argument to JSON, only valid elements or resources can be included." ); return NULL; } break; } default: { g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON, unsupported data type. Use Table, Nil, String, Number, Boolean, Resource or Element." ); return NULL; } } return NULL; }
char * CLuaArgument::WriteToString ( char * szBuffer, int length ) { switch ( GetType () ) { case LUA_TNIL: { snprintf ( szBuffer, length, "0" ); return szBuffer; } case LUA_TBOOLEAN: { if ( GetBoolean () ) snprintf ( szBuffer, length, "true" ); else snprintf ( szBuffer, length, "false" ); return szBuffer; } case LUA_TTABLE: { g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Cannot convert table to string (do not use tables as keys in tables if you want to send them over http/JSON)." ); return NULL; } case LUA_TNUMBER: { int iNumber; if ( ShouldUseInt( GetNumber(), &iNumber ) ) { snprintf ( szBuffer, length, "%d", iNumber ); return szBuffer; } else { snprintf ( szBuffer, length, "%f", static_cast < float > ( GetNumber() ) ); return szBuffer; } break; } case LUA_TSTRING: { const char* szTemp = GetString (); unsigned short usLength = static_cast < unsigned short > ( strlen ( szTemp ) ); if ( strlen ( szTemp ) == usLength ) { snprintf ( szBuffer, length, "%s", szTemp ); return szBuffer; } else { g_pClientGame->GetScriptDebugging()->LogError ( NULL, "String is too long. Limit is 65535 characters." ); } break; } case LUA_TLIGHTUSERDATA: case LUA_TUSERDATA: { CClientEntity* pElement = GetElement (); CResource* pResource = reinterpret_cast < CResource* > ( GetUserData() ); if ( pElement ) { snprintf ( szBuffer, length, "#E#%d", (int)pElement->GetID().Value() ); return szBuffer; } else if ( VERIFY_RESOURCE(pResource) ) { snprintf ( szBuffer, length, "#R#%s", pResource->GetName()/*.c_str ()*/ ); return szBuffer; } else { g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert element to string, only valid elements can be sent." ); return NULL; } break; } default: { g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument to string, unsupported data type. Use String, Number, Boolean or Element." ); return NULL; } } return NULL; }
void CNametags::DrawDefault() { // Grab the resolution width and height static float fResWidth = static_cast<float>(g_pCore->GetGraphics()->GetViewportWidth()); static float fResHeight = static_cast<float>(g_pCore->GetGraphics()->GetViewportHeight()); // Got any players that are not local? if (m_pPlayerManager->Count() <= 1) return; list<CClientPlayer*> playerTags; // Grab the local player CClientPlayer* pLocalPlayer = m_pPlayerManager->GetLocalPlayer(); if (!pLocalPlayer) return; CClientVehicle* pSniperTargetedVehicle = NULL; CClientPlayer* pSniperTargetedPlayer = NULL; // Grab our current weapon slot. Use screen center if melee or none eWeaponSlot eSlot = pLocalPlayer->GetCurrentWeaponSlot(); if (eSlot >= WEAPONSLOT_TYPE_HANDGUN && eSlot <= WEAPONSLOT_TYPE_RIFLE) { CVector vecOrigin, vecTarget; pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); // Ignore the local player for this pLocalPlayer->WorldIgnore(true); // Do the raycast CColPoint* pColPoint = NULL; CEntity* pEntity = NULL; SLineOfSightFlags flags; flags.bCheckBuildings = true; flags.bCheckVehicles = true; flags.bCheckPeds = true; flags.bCheckObjects = true; flags.bCheckDummies = true; flags.bSeeThroughStuff = true; flags.bIgnoreSomeObjectsForCamera = false; flags.bShootThroughStuff = true; g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pEntity, flags); if (pColPoint) pColPoint->Destroy(); // Un-ignore the local player pLocalPlayer->WorldIgnore(false); // Did we find an entity? if (pEntity) { // Grab the CClientEntity belonging to this game_sa entity CClientEntity* pClientEntity = reinterpret_cast<CClientEntity*>(pEntity->GetStoredPointer()); if (pClientEntity) { // Is it a vehicle? Is it a ped? eClientEntityType EntityType = pClientEntity->GetType(); switch (EntityType) { case CCLIENTVEHICLE: { pSniperTargetedVehicle = static_cast<CClientVehicle*>(pClientEntity); break; } case CCLIENTPLAYER: { pSniperTargetedPlayer = static_cast<CClientPlayer*>(pClientEntity); break; } default: break; } } } } // Grab the local player vehicle CClientVehicle* pLocalVehicle = pLocalPlayer->GetOccupiedVehicle(); CVehicle* pLocalGameVehicle = NULL; if (pLocalVehicle) pLocalGameVehicle = pLocalVehicle->GetGameVehicle(); CMatrix CameraMatrix; g_pGame->GetCamera()->GetMatrix(&CameraMatrix); // Remove collision from our local vehicle (if we have one) if (pLocalVehicle) pLocalVehicle->WorldIgnore(true); // Draw the nametags we need to CVector vecPlayerPosition; CClientVehicle* pPlayerVehicle = NULL; float fDistanceExp; bool bCollision; CColPoint* pColPoint = NULL; CEntity* pGameEntity = NULL; CClientEntity* pEntity = NULL; CClientPlayer* pPlayer; CClientStreamElement* pElement; list<CClientStreamElement*>::const_iterator iter = m_pPlayerStreamer->ActiveElementsBegin(); for (; iter != m_pPlayerStreamer->ActiveElementsEnd(); ++iter) { pElement = *iter; if (!pElement->IsStreamedIn()) continue; if (pElement->GetType() != CCLIENTPLAYER) continue; pPlayer = static_cast<CClientPlayer*>(pElement); if (pPlayer->IsLocalPlayer()) continue; // Get the distance from the camera pPlayer->GetPosition(vecPlayerPosition); fDistanceExp = pPlayer->GetExpDistance(); pPlayerVehicle = pPlayer->GetOccupiedVehicle(); // Is he in the same vehicle as the local player? if ((pSniperTargetedPlayer == pPlayer) || (pSniperTargetedVehicle && pSniperTargetedVehicle == pPlayerVehicle) || (pLocalVehicle && pLocalVehicle == pPlayerVehicle) || (fDistanceExp < DEFAULT_VIEW_RANGE_EXP && pPlayer->IsOnScreen())) { SLineOfSightFlags flags; flags.bCheckBuildings = true; flags.bCheckVehicles = true; flags.bCheckPeds = false; flags.bCheckObjects = true; bCollision = g_pCore->GetGame()->GetWorld()->ProcessLineOfSight(&CameraMatrix.vPos, &vecPlayerPosition, &pColPoint, &pGameEntity, flags); if (!bCollision || (pGameEntity && pPlayerVehicle && pGameEntity == pPlayerVehicle->GetGameEntity())) { pPlayer->SetNametagDistance(sqrt(fDistanceExp)); playerTags.push_front(pPlayer); } // Destroy the colpoint if (pColPoint) pColPoint->Destroy(); } } // Readd collision from our local vehicle (if we have one) if (pLocalVehicle) pLocalVehicle->WorldIgnore(false); // Draw each player's nametag float fAlphaModifier; unsigned char ucAlpha; float fDistance; list<CClientPlayer*>::iterator iterTags = playerTags.begin(); for (; iterTags != playerTags.end(); ++iterTags) { pPlayer = *iterTags; fDistance = pPlayer->GetNametagDistance(); static float fFullAlphaDistance = 7.0f; if ((fDistance < fFullAlphaDistance) || (pSniperTargetedPlayer && pSniperTargetedPlayer == pPlayer) || (pSniperTargetedVehicle && pSniperTargetedVehicle == pPlayer->GetOccupiedVehicle())) { fAlphaModifier = 1.0f; } else { fAlphaModifier = 1.0f - ((fDistance - fFullAlphaDistance) / (DEFAULT_VIEW_RANGE - fFullAlphaDistance)); } // Calculate the alpha for the nametag ucAlpha = static_cast<unsigned char>(180.0f * fAlphaModifier); // Draw the tag DrawTagForPlayer(pPlayer, ucAlpha); } }
CClientEntity::~CClientEntity ( void ) { // Make sure we won't get deleted later by the element deleter if we've been requested so if ( m_bBeingDeleted ) { g_pClientGame->GetElementDeleter ()->Unreference ( this ); } // Remove from parent ClearChildren (); SetParent ( NULL ); // Reset our index in the element array if ( m_ID != INVALID_ELEMENT_ID ) { CElementIDs::SetElement ( m_ID, NULL ); // Got a clientside ID? Push it back on our stack so we don't run out of client id's if ( IsLocalEntity () ) { CElementIDs::PushClientID ( m_ID ); } } // Remove our custom data if ( m_pCustomData ) { delete m_pCustomData; } // Detach from everything AttachTo( NULL ); while( m_AttachedEntities.size() ) { CClientEntity* pAttachedEntity = m_AttachedEntities.back(); pAttachedEntity->AttachTo( NULL ); } m_bDisallowAttaching = true; assert( !m_pAttachedToEntity && m_AttachedEntities.empty() ); RemoveAllCollisions (); if ( m_pEventManager ) { delete m_pEventManager; m_pEventManager = NULL; } if ( m_pElementGroup ) { m_pElementGroup->Remove ( this ); } if ( m_OriginSourceUsers.size () > 0 ) { list < CClientPed* > ::iterator iterUsers = m_OriginSourceUsers.begin (); for ( ; iterUsers != m_OriginSourceUsers.end () ; iterUsers++ ) { CClientPed* pModel = *iterUsers; if ( pModel->m_interp.pTargetOriginSource == this ) { pModel->m_interp.pTargetOriginSource = NULL; pModel->m_interp.bHadOriginSource = true; } } m_OriginSourceUsers.clear (); } // Unlink our contacts list < CClientPed * > ::iterator iterContacts = m_Contacts.begin (); for ( ; iterContacts != m_Contacts.end () ; iterContacts++ ) { CClientPed * pModel = *iterContacts; if ( pModel->GetCurrentContactEntity () == this ) { pModel->SetCurrentContactEntity ( NULL ); } } m_Contacts.clear (); // Unlink disabled-collisions while ( !m_DisabledCollisions.empty () ) { CClientEntity * pEntity = m_DisabledCollisions.begin ()->first; SetCollidableWith ( pEntity, true ); } // Remove from spatial database if ( !g_pClientGame->IsBeingDeleted () ) GetClientSpatialDatabase ()->RemoveEntity ( this ); // Ensure not referenced in the disabled collisions list assert ( !MapContains ( g_pClientGame->m_AllDisabledCollisions, this ) ); // Ensure nothing has inadvertently set a parent assert ( m_pParent == NULL ); if ( !g_pClientGame->IsBeingDeleted () ) CClientEntityRefManager::OnEntityDelete ( this ); g_pClientGame->GetGameEntityXRefManager ()->OnClientEntityDelete ( this ); SAFE_RELEASE( m_pChildrenListSnapshot ); g_pCore->GetGraphics ()->GetRenderItemManager ()->RemoveClientEntityRefs ( this ); g_pCore->UpdateDummyProgress(); }
bool CClientExplosionManager::Hook_ExplosionCreation ( CEntity* pGameExplodingEntity, CEntity* pGameCreator, const CVector& vecPosition, eExplosionType explosionType ) { CClientPlayer * pLocalPlayer = m_pManager->GetPlayerManager ()->GetLocalPlayer (); // Grab the entity responsible CClientEntity * pResponsible = NULL; CEntity* pResponsibleGameEntity = ( pGameExplodingEntity ) ? pGameExplodingEntity : pGameCreator; if ( pResponsibleGameEntity ) pResponsible = m_pManager->FindEntity ( pResponsibleGameEntity, false ); unsigned short usModel; if ( pResponsible && ( pResponsible->IsLocalEntity () || ( CStaticFunctionDefinitions::GetElementModel ( *pResponsible, usModel ) && CClientObjectManager::IsBreakableModel ( usModel ) ) ) ) return true; // Handle this explosion client side only if entity is local or breakable (i.e. barrel) eWeaponType explosionWeaponType; switch ( explosionType ) { case EXP_TYPE_GRENADE: { // Grenade type explosions from vehicles should only be freefall bombs // TODO: need a way to check if its a freefall bomb if creator is a ped if ( pGameCreator && pGameCreator->GetEntityType () == ENTITY_TYPE_VEHICLE ) explosionWeaponType = WEAPONTYPE_FREEFALL_BOMB; else explosionWeaponType = WEAPONTYPE_GRENADE; break; } case EXP_TYPE_MOLOTOV: explosionWeaponType = WEAPONTYPE_MOLOTOV; break; case EXP_TYPE_ROCKET: case EXP_TYPE_ROCKET_WEAK: explosionWeaponType = WEAPONTYPE_ROCKET; break; case EXP_TYPE_TANK_GRENADE: explosionWeaponType = WEAPONTYPE_TANK_GRENADE; break; default: explosionWeaponType = WEAPONTYPE_EXPLOSION; break; } // Got a responsible entity? if ( pResponsible ) { // Is the local player responsible for this? bool bLocal = ( ( pResponsible == pLocalPlayer ) || ( pResponsible == pLocalPlayer->GetOccupiedVehicle () ) || ( g_pClientGame->GetUnoccupiedVehicleSync ()->Exists ( static_cast < CDeathmatchVehicle * > ( pResponsible ) ) ) ); if ( bLocal ) { CClientEntity * pOriginSource = NULL; // Is this an exploding vehicle? if ( pGameExplodingEntity && pGameExplodingEntity->GetEntityType () == ENTITY_TYPE_VEHICLE ) { // Set our origin-source to the vehicle pOriginSource = m_pManager->FindEntity ( pGameExplodingEntity, false ); } // If theres other players, sync it relative to the closest (lag compensation) else if ( m_pManager->GetPlayerManager ()->Count () > 1 ) { switch ( explosionWeaponType ) { case WEAPONTYPE_ROCKET: case WEAPONTYPE_ROCKET_HS: { CClientPlayer * pPlayer = g_pClientGame->GetClosestRemotePlayer ( vecPosition, 200.0f ); if ( pPlayer ) { pOriginSource = pPlayer; } break; } } } // Request a new explosion g_pClientGame->SendExplosionSync ( vecPosition, explosionType, pOriginSource ); } } // All explosions are handled server side return false; }
bool CLuaArgument::WriteToBitStream ( NetBitStreamInterface& bitStream, std::map < CLuaArguments*, unsigned long > * pKnownTables ) const { SLuaTypeSync type; switch ( GetType () ) { // Nil type case LUA_TNIL: { type.data.ucType = LUA_TNIL; bitStream.Write ( &type ); break; } // Boolean type case LUA_TBOOLEAN: { type.data.ucType = LUA_TBOOLEAN; bitStream.Write ( &type ); // Write the boolean to it bitStream.WriteBit ( GetBoolean () ); break; } // Table argument case LUA_TTABLE: { if ( pKnownTables && pKnownTables->find ( m_pTableData ) != pKnownTables->end () ) { // Self-referencing table type.data.ucType = LUA_TTABLEREF; bitStream.Write ( &type ); bitStream.WriteCompressed ( pKnownTables->find ( m_pTableData )->second ); } else { type.data.ucType = LUA_TTABLE; bitStream.Write ( &type ); // Write the subtable to the bitstream m_pTableData->WriteToBitStream ( bitStream, pKnownTables ); } break; } // Number argument? case LUA_TNUMBER: { type.data.ucType = LUA_TNUMBER; bitStream.Write ( &type ); float fNumber = static_cast < float > ( GetNumber () ); long lNumber = static_cast < long > ( fNumber ); float fNumberInteger = static_cast < float > ( lNumber ); // Check if the number is an integer and can fit a long datatype if ( fabs ( fNumber ) > fabs ( fNumberInteger + 1 ) || fabs ( fNumber - fNumberInteger ) >= FLOAT_EPSILON ) { bitStream.WriteBit ( true ); bitStream.Write ( fNumber ); } else { bitStream.WriteBit ( false ); bitStream.WriteCompressed ( lNumber ); } break; } // String argument case LUA_TSTRING: { // Grab the string and its length. Is it short enough to be sendable? const char* szTemp = m_strString.c_str (); size_t sizeTemp = strlen ( szTemp ); unsigned short usLength = static_cast < unsigned short > ( sizeTemp ); if ( sizeTemp == usLength ) { // This is a string argument type.data.ucType = LUA_TSTRING; bitStream.Write ( &type ); // Write its length bitStream.WriteCompressed ( usLength ); // Write the content too if it's not empty if ( usLength > 0 ) { bitStream.Write ( const_cast < char* > ( szTemp ), usLength ); } } else { // Too long string LogUnableToPacketize ( "Couldn't packetize argument list. Invalid string specified, limit is 65535 characters." ); // Write a nil though so other side won't get out of sync bitStream.Write ( (unsigned char) LUA_TNIL ); return false; } break; } // Element packet case LUA_TLIGHTUSERDATA: { // Got a valid element to send? CClientEntity* pElement = GetElement (); if ( pElement ) { // Clientside element? if ( !pElement->IsLocalEntity () ) { type.data.ucType = LUA_TLIGHTUSERDATA; bitStream.Write ( &type ); bitStream.WriteCompressed ( static_cast < ElementID > ( pElement->GetID () ) ); } else { // Write a nil though so other side won't get out of sync type.data.ucType = LUA_TNIL; bitStream.Write ( &type ); return false; } } else { // Write a nil though so other side won't get out of sync type.data.ucType = LUA_TNIL; bitStream.Write ( &type ); return false; } break; } // Unpacketizable type. default: { // Unpacketizable LogUnableToPacketize ( "Couldn't packetize argument list, unknown type specified." ); // Write a nil though so other side won't get out of sync type.data.ucType = LUA_TNIL; bitStream.Write ( &type ); return false; } } // Success return true; }
int CLuaFunctionDefs::ProcessLineOfSight ( lua_State * luaVM ) { int iArgument1 = lua_type ( luaVM, 1 ); int iArgument2 = lua_type ( luaVM, 2 ); int iArgument3 = lua_type ( luaVM, 3 ); int iArgument4 = lua_type ( luaVM, 4 ); int iArgument5 = lua_type ( luaVM, 5 ); int iArgument6 = lua_type ( luaVM, 6 ); if ( ( iArgument1 == LUA_TNUMBER || iArgument1 == LUA_TSTRING ) && ( iArgument2 == LUA_TNUMBER || iArgument2 == LUA_TSTRING ) && ( iArgument3 == LUA_TNUMBER || iArgument3 == LUA_TSTRING ) && ( iArgument4 == LUA_TNUMBER || iArgument4 == LUA_TSTRING ) && ( iArgument5 == LUA_TNUMBER || iArgument5 == LUA_TSTRING ) && ( iArgument6 == LUA_TNUMBER || iArgument6 == LUA_TSTRING ) ) { CVector vecStart ( static_cast < float > ( lua_tonumber ( luaVM, 1 ) ), static_cast < float > ( lua_tonumber ( luaVM, 2 ) ), static_cast < float > ( lua_tonumber ( luaVM, 3 ) ) ); CVector vecEnd ( static_cast < float > ( lua_tonumber ( luaVM, 4 ) ), static_cast < float > ( lua_tonumber ( luaVM, 5 ) ), static_cast < float > ( lua_tonumber ( luaVM, 6 ) ) ); CColPoint* pColPoint = NULL; CClientEntity* pColEntity = NULL; bool bCheckBuildings = true, bCheckVehicles = true, bCheckPeds = true, bCheckObjects = true, bCheckDummies = true, bSeeThroughStuff = false, bIgnoreSomeObjectsForCamera = false, bShootThroughStuff = false; CEntity* pIgnoredEntity = NULL; if ( lua_type ( luaVM, 7 ) == LUA_TBOOLEAN ) { bCheckBuildings = ( lua_toboolean ( luaVM, 7 ) ) ? true:false; if ( lua_type ( luaVM, 8 ) == LUA_TBOOLEAN ) { bCheckVehicles = ( lua_toboolean ( luaVM, 8 ) ) ? true:false; if ( lua_type ( luaVM, 9 ) == LUA_TBOOLEAN ) { bCheckPeds = ( lua_toboolean ( luaVM, 9 ) ) ? true:false; if ( lua_type ( luaVM, 10 ) == LUA_TBOOLEAN ) { bCheckObjects = ( lua_toboolean ( luaVM, 10 ) ) ? true:false; if ( lua_type ( luaVM, 11 ) == LUA_TBOOLEAN ) { bCheckDummies = ( lua_toboolean ( luaVM, 11 ) ) ? true:false; if ( lua_type ( luaVM, 12 ) == LUA_TBOOLEAN ) { bSeeThroughStuff = ( lua_toboolean ( luaVM, 12 ) ) ? true:false; if ( lua_type ( luaVM, 13 ) == LUA_TBOOLEAN ) { bIgnoreSomeObjectsForCamera = ( lua_toboolean ( luaVM, 13 ) ) ? true:false; if ( lua_type ( luaVM, 14 ) == LUA_TBOOLEAN ) { bShootThroughStuff = ( lua_toboolean ( luaVM, 14 ) ) ? true:false; if ( lua_type ( luaVM, 15 ) == LUA_TLIGHTUSERDATA ) { CClientEntity* pEntity = lua_toelement ( luaVM, 15 ); if ( pEntity ) { switch ( pEntity->GetType () ) { case CCLIENTPED: case CCLIENTPLAYER: pIgnoredEntity = static_cast < CClientPed* > ( pEntity )->GetGamePlayer (); break; case CCLIENTVEHICLE: pIgnoredEntity = static_cast < CClientVehicle* > ( pEntity )->GetGameVehicle (); break; case CCLIENTOBJECT: pIgnoredEntity = static_cast < CClientObject* > ( pEntity )->GetGameObject (); break; } } } } } } } } } } } bool bCollision; if ( CStaticFunctionDefinitions::ProcessLineOfSight ( vecStart, vecEnd, bCollision, &pColPoint, &pColEntity, bCheckBuildings, bCheckVehicles, bCheckPeds, bCheckObjects, bCheckDummies, bSeeThroughStuff, bIgnoreSomeObjectsForCamera, bShootThroughStuff, pIgnoredEntity ) ) { // Got a collision? CVector vecColPosition; if ( pColPoint ) { // Get the collision position vecColPosition = *pColPoint->GetPosition (); // Delete the colpoint pColPoint->Destroy (); } lua_pushboolean ( luaVM, bCollision ); if ( bCollision ) { lua_pushnumber ( luaVM, vecColPosition.fX ); lua_pushnumber ( luaVM, vecColPosition.fY ); lua_pushnumber ( luaVM, vecColPosition.fZ ); if ( pColEntity ) lua_pushelement ( luaVM, pColEntity ); else lua_pushnil ( luaVM ); return 5; } return 1; } } else m_pScriptDebugging->LogBadType ( luaVM, "processLineOfSight" ); lua_pushboolean ( luaVM, false ); return 1; }
void CNametags::DrawFromAim() { unsigned long ulCurrentTime = CClientTime::GetTime(); // Got any players that are not local? if (m_pPlayerManager->Count() > 1) { // Grab the local player CClientPlayer* pLocalPlayer = m_pPlayerManager->GetLocalPlayer(); if (pLocalPlayer) { // Grab the current time and the camera unsigned long ulCurrentTime = CClientTime::GetTime(); CCamera* pCamera = g_pGame->GetCamera(); // Grab our controller state CControllerState State; g_pGame->GetPad()->GetCurrentControllerState(&State); // Grab our current weapon slot. Use screen center if melee or none CVector vecStart; CVector vecTarget; eWeaponSlot eSlot = pLocalPlayer->GetCurrentWeaponSlot(); if (eSlot == WEAPONSLOT_TYPE_UNARMED || eSlot == WEAPONSLOT_TYPE_MELEE || eSlot == WEAPONSLOT_TYPE_RIFLE || eSlot == WEAPONSLOT_TYPE_THROWN || eSlot == WEAPONSLOT_TYPE_SPECIAL || eSlot == WEAPONSLOT_TYPE_GIFT || eSlot == WEAPONSLOT_TYPE_PARACHUTE || eSlot == WEAPONSLOT_TYPE_DETONATOR) { // Grab the active cam CCamera* pCamera = g_pGame->GetCamera(); CCam* pActive = pCamera->GetCam(pCamera->GetActiveCam()); // Grab the camera matrix CMatrix matCamera; pCamera->GetMatrix(&matCamera); vecStart = matCamera.vPos; // Range float fRange; eWeaponType eWeapon = pLocalPlayer->GetCurrentWeaponType(); float fSkill = pLocalPlayer->GetStat(g_pGame->GetStats()->GetSkillStatIndex(eWeapon)); CWeaponStat* pWeaponStat = g_pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(eWeapon, fSkill); if (pWeaponStat) { fRange = pWeaponStat->GetTargetRange(); } else { fRange = MELEE_VISIBLE_RANGE; } // Find the target position CVector vecFront = *pActive->GetFront(); vecFront.Normalize(); vecTarget = *pActive->GetSource() + vecFront * fRange; } else { // Grab the weapon and keysync state. If it exists and he holds Target down CWeapon* pPlayerWeapon = pLocalPlayer->GetWeapon(); if (pPlayerWeapon && State.RightShoulder1) { // Grab the gun muzzle position eWeaponType eWeapon = pLocalPlayer->GetCurrentWeaponType(); float fSkill = pLocalPlayer->GetStat(g_pGame->GetStats()->GetSkillStatIndex(eWeapon)); CWeaponStat* pWeaponStat = g_pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(eWeapon, fSkill); CVector vecGunMuzzle = *pWeaponStat->GetFireOffset(); pLocalPlayer->GetTransformedBonePosition(BONE_RIGHTWRIST, vecGunMuzzle); // Grab the target point pCamera->Find3rdPersonCamTargetVector(AIM_VISIBLE_RANGE, &vecGunMuzzle, &vecStart, &vecTarget); } else { // Grab the active cam CCam* pActive = pCamera->GetCam(pCamera->GetActiveCam()); // Grab the camera matrix CMatrix matCamera; pCamera->GetMatrix(&matCamera); vecStart = matCamera.vPos; // Find the target position CVector vecFront = *pActive->GetFront(); vecFront.Normalize(); vecTarget = *pActive->GetSource() + vecFront * MELEE_VISIBLE_RANGE; } } // Ignore the local player for this pLocalPlayer->WorldIgnore(true); // Do the raycast CColPoint* pColPoint = NULL; CEntity* pEntity = NULL; SLineOfSightFlags flags; flags.bCheckBuildings = true; flags.bCheckVehicles = true; flags.bCheckPeds = true; flags.bCheckObjects = true; flags.bCheckDummies = true; flags.bSeeThroughStuff = true; flags.bIgnoreSomeObjectsForCamera = false; flags.bShootThroughStuff = true; g_pGame->GetWorld()->ProcessLineOfSight(&vecStart, &vecTarget, &pColPoint, &pEntity, flags); if (pColPoint) pColPoint->Destroy(); // Un-ignore the local player pLocalPlayer->WorldIgnore(false); // Did we find an entity? if (pEntity) { // Grab the CClientEntity belonging to this game_sa entity CClientEntity* pClientEntity = reinterpret_cast<CClientEntity*>(pEntity->GetStoredPointer()); if (pClientEntity) { // Is it a vehicle? Is it a ped? eClientEntityType EntityType = pClientEntity->GetType(); if (EntityType == CCLIENTVEHICLE) { CClientVehicle* pClientVehicle = static_cast<CClientVehicle*>(pClientEntity); // Set the current time as the last draw time for all players inside CClientPed* pPed; int i; for (i = 0; i < 8; i++) { // Grab this seat's occupant and set its last nametag show time to now pPed = pClientVehicle->GetOccupant(i); if (pPed && pPed->GetType() == CCLIENTPLAYER) { static_cast<CClientPlayer*>(pPed)->SetLastNametagShow(ulCurrentTime); } } } else if (EntityType == CCLIENTPLAYER) { // Grab the player this entity is CClientPlayer* pClientPlayer = static_cast<CClientPlayer*>(pClientEntity); if (pClientPlayer) { // Set now as the last time we had the cursor above him pClientPlayer->SetLastNametagShow(ulCurrentTime); } } } } // Grab the local player vehicle CClientVehicle* pLocalVehicle = pLocalPlayer->GetOccupiedVehicle(); // Draw the nametags we need to CClientPlayer* pPlayer; CClientStreamElement* pElement; list<CClientStreamElement*>::const_iterator iter = m_pPlayerStreamer->ActiveElementsBegin(); for (; iter != m_pPlayerStreamer->ActiveElementsEnd(); ++iter) { pElement = *iter; if (!pElement->IsStreamedIn()) continue; if (pElement->GetType() != CCLIENTPLAYER) continue; pPlayer = static_cast<CClientPlayer*>(pElement); if (pPlayer->IsLocalPlayer()) continue; // Is he in the same vehicle as the local player? if (pLocalVehicle && pPlayer->GetOccupiedVehicle() == pLocalVehicle) { pPlayer->SetLastNametagShow(ulCurrentTime); } // Can we show this player's nametag unsigned long ulLastNametagShow = pPlayer->GetLastNametagShow(); if (ulLastNametagShow != 0 && ulCurrentTime <= ulLastNametagShow + NAMETAG_END_FADE_TIME) { unsigned long ulLastNametagShow = pPlayer->GetLastNametagShow(); // Calculate the alpha modifier float fAlphaTimeModifier; if (ulCurrentTime < ulLastNametagShow + NAMETAG_BEGIN_FADE_TIME) { fAlphaTimeModifier = 1.0f; } else { fAlphaTimeModifier = 1.0f - (ulCurrentTime - ulLastNametagShow - NAMETAG_BEGIN_FADE_TIME) / 1000.0f; } // Calculate the alpha for the nametag unsigned char ucAlpha = static_cast<unsigned char>(180.0f * fAlphaTimeModifier); // Draw it DrawTagForPlayer(pPlayer, ucAlpha); } } } } }