int CheckBaseHandle(CBaseHandle &hndl) { if (!hndl.IsValid()) { return -1; } int index = hndl.GetEntryIndex(); edict_t *pStoredEdict; pStoredEdict = engine->PEntityOfEntIndex(index); if (pStoredEdict == NULL) { return -1; } IServerEntity *pSE = pStoredEdict->GetIServerEntity(); if (pSE == NULL) { return -1; } if (pSE->GetRefEHandle() != hndl) { return -1; } return index; }
//----------------------------------------------------------------------------- // After we built the touch list, deal with all the impacts... //----------------------------------------------------------------------------- void CMoveHelperServer::ProcessImpacts( void ) { Assert( m_pHostPlayer ); // Relink in order to build absorigin and absmin/max to reflect any changes // from prediction. Relink will early out on SOLID_NOT engine->RelinkEntity( m_pHostPlayer->pev, true ); // Don't bother if the player ain't solid if ( m_pHostPlayer->IsSolidFlagSet( FSOLID_NOT_SOLID ) ) { return; } // Save off the velocity, cause we need to temporarily reset it Vector vel = m_pHostPlayer->GetAbsVelocity(); // Touch other objects that were intersected during the movement. for (int i = 0 ; i < m_TouchList.Size(); i++) { CBaseHandle entindex = m_TouchList[i].trace.m_pEnt->GetRefEHandle(); // We should have culled negative indices by now Assert( entindex.IsValid() ); edict_t* ent = GetEdict( entindex ); if (!ent) continue; // Run the impact function as if we had run it during movement. CBaseEntity *entity = GetContainingEntity( ent ); if ( !entity ) continue; Assert( entity != m_pHostPlayer ); // Don't ever collide with self!!!! if ( entity == m_pHostPlayer ) continue; // Reconstruct trace results. m_TouchList[i].trace.m_pEnt = CBaseEntity::Instance( ent ); // Use the velocity we had when we collided, so boxes will move, etc. m_pHostPlayer->SetAbsVelocity( m_TouchList[i].deltavelocity ); entity->PhysicsImpact( m_pHostPlayer, m_TouchList[i].trace ); } // Restore the velocity m_pHostPlayer->SetAbsVelocity( vel ); // So no stuff is ever left over, sigh... ResetTouchList(); }
//----------------------------------------------------------------------------- // Returns an index from the given BaseHandle instance. //----------------------------------------------------------------------------- bool IndexFromBaseHandle( CBaseHandle hBaseHandle, unsigned int& output ) { if (!hBaseHandle.IsValid() || !hBaseHandle.ToInt()) return false; int iEntityIndex = hBaseHandle.GetEntryIndex(); if (iEntityIndex == INVALID_ENTITY_INDEX) return false; output = iEntityIndex; return true; }
//----------------------------------------------------------------------------- // Returns an IntHandle from the given BaseHandle instance. //----------------------------------------------------------------------------- bool IntHandleFromBaseHandle( CBaseHandle hBaseHandle, unsigned int& output ) { if (!hBaseHandle.IsValid()) return false; unsigned int iEntityHandle = hBaseHandle.ToInt(); if (!iEntityHandle) return false; output = iEntityHandle; return true; }
//----------------------------------------------------------------------------- // Returns an index from the given IntHandle. //----------------------------------------------------------------------------- bool IndexFromIntHandle( unsigned int iEntityHandle, unsigned int& output ) { if (iEntityHandle == (int) INVALID_EHANDLE_INDEX) return false; CBaseHandle hBaseHandle(iEntityHandle); unsigned int iEntityIndex; if (!IndexFromBaseHandle(hBaseHandle, iEntityIndex)) return false; edict_t* pEdict; if (!EdictFromIndex(iEntityIndex, pEdict)) return false; CBaseHandle hTestHandle; if (!BaseHandleFromEdict(pEdict, hTestHandle)) return false; if (!hTestHandle.IsValid() || hBaseHandle.GetSerialNumber() != hTestHandle.GetSerialNumber()) return false; output = iEntityIndex; return true; }
IServerEntity *CServerTools::GetIServerEntity( IClientEntity *pClientEntity ) { if ( pClientEntity == NULL ) return NULL; CBaseHandle ehandle = pClientEntity->GetRefEHandle(); if ( ehandle.GetEntryIndex() >= MAX_EDICTS ) return NULL; // the first MAX_EDICTS entities are networked, the rest are client or server only #if 0 // this fails, since the server entities have extra bits in their serial numbers, // since 20 bits are reserved for serial numbers, except for networked entities, which are restricted to 10 // Brian believes that everything should just restrict itself to 10 to make things simpler, // so if/when he changes NUM_SERIAL_NUM_BITS to 10, we can switch back to this simpler code IServerNetworkable *pNet = gEntList.GetServerNetworkable( ehandle ); if ( pNet == NULL ) return NULL; CBaseEntity *pServerEnt = pNet->GetBaseEntity(); return pServerEnt; #else IHandleEntity *pEnt = gEntList.LookupEntityByNetworkIndex( ehandle.GetEntryIndex() ); if ( pEnt == NULL ) return NULL; CBaseHandle h = gEntList.GetNetworkableHandle( ehandle.GetEntryIndex() ); const int mask = ( 1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS ) - 1; if ( !h.IsValid() || ( ( h.GetSerialNumber() & mask ) != ( ehandle.GetSerialNumber() & mask ) ) ) return NULL; IServerUnknown *pUnk = static_cast< IServerUnknown* >( pEnt ); return pUnk->GetBaseEntity(); #endif }