Simulated Bullets: Difference between revisions
Jump to navigation
Jump to search
Note:This code is a work in progress. Feel free to make helpful changes.
m (→Preface) |
mNo edit summary |
||
Line 1: | Line 1: | ||
[[Category:Programming]] | |||
==Preface== | ==Preface== | ||
Basically, with simulated bullets, the aspects of physics are going to tried to be captured by simulating them in batch simulation code. So far the code is all server-side and is later expected to be client-side simulated with similar code. | Basically, with simulated bullets, the aspects of physics are going to tried to be captured by simulating them in batch simulation code. So far the code is all server-side and is later expected to be client-side simulated with similar code. |
Revision as of 20:03, 20 November 2005
Preface
Basically, with simulated bullets, the aspects of physics are going to tried to be captured by simulating them in batch simulation code. So far the code is all server-side and is later expected to be client-side simulated with similar code.

Body
This code is WIP by ts2do
bullet_manager.h
#define MAX_BULLETS 256 #define BULLET_SPEED 30//inches per hundredths of a second class CBulletManager; extern CBulletManager *g_pBulletManager; inline CBulletManager *BulletManager() { return g_pBulletManager; } extern ConVar g_debug_bullets; struct SimulatedBullet_t { SimulatedBullet_t() { m_Bullet = FireBulletsInfo_t(); m_vOrigin = vec3_origin; m_flInitialBulletSpeed = m_flBulletSpeed = BULLET_SPEED; m_flCreationTime = gpGlobals->curtime; } SimulatedBullet_t( FireBulletsInfo_t &bullet ) { m_Bullet = bullet; m_vOrigin = bullet.m_vecSrc; m_flInitialBulletSpeed = m_flBulletSpeed = BULLET_SPEED; m_flCreationTime = gpGlobals->curtime; } FireBulletsInfo_t m_Bullet; Vector m_vOrigin; float m_flBulletSpeed; float m_flInitialBulletSpeed; float m_flCreationTime; CUtlVector<CBaseEntity *> m_pHit; float m_flLastDensity; }; class CBulletManager : public CBaseEntity { DECLARE_CLASS( CBulletManager, CBaseEntity ); public: SimulatedBullet_t m_rgBullets[MAX_BULLETS]; int m_iLastBullet; CBulletManager(); void Spawn(void); void Think(void); void AddBullet(FireBulletsInfo_t &bullet); void RemoveBullet(int index); };
bullet_manager.cpp
#include "cbase.h" #include "movevars_shared.h" #include "util_shared.h" #include "bullet_manager.h" ConVar g_debug_bullets( "g_debug_bullets", "0", FCVAR_CHEAT ); CBulletManager *g_pBulletManager; LINK_ENTITY_TO_CLASS( bullet_manager, CBulletManager ); CBulletManager::CBulletManager() { Q_memset( m_rgBullets, 0, MAX_BULLETS ); m_iLastBullet = -1; } CON_COMMAND_F(createbullet,NULL,FCVAR_CHEAT) { Assert(BulletManager()); if(!BulletManager()) return; CBasePlayer *pPlayer = UTIL_GetCommandClient(); Vector dir; pPlayer->EyeVectors(&dir); FireBulletsInfo_t info(1,pPlayer->EyePosition(),dir,vec3_origin,0,0); info.m_pAttacker = pPlayer; BulletManager()->AddBullet(info); } void CBulletManager::Spawn(void) { SetNextThink( gpGlobals->curtime + 0.01f ); } void CBulletManager::Think(void) { for(int x=0;x<=m_iLastBullet;x++) { Vector m_vOldOrigin = m_rgBullets[x].m_vOrigin; DevMsg("BulletSpeed %f LastDensity %f\n",m_rgBullets[x].m_flBulletSpeed, m_rgBullets[x].m_flLastDensity); m_rgBullets[x].m_vOrigin += m_rgBullets[x].m_Bullet.m_vecDirShooting * m_rgBullets[x].m_flBulletSpeed; float T = gpGlobals->curtime - m_rgBullets[x].m_flCreationTime; m_rgBullets[x].m_vOrigin.z -= sv_gravity.GetFloat() * 0.01f * T * T * m_rgBullets[x].m_flBulletSpeed/m_rgBullets[x].m_flInitialBulletSpeed; CTraceFilterSkipTwoEntities traceFilter( m_rgBullets[x].m_Bullet.m_pAttacker, m_rgBullets[x].m_Bullet.m_pAdditionalIgnoreEnt, COLLISION_GROUP_NONE ); trace_t ptr; UTIL_TraceLine( m_vOldOrigin, m_rgBullets[x].m_vOrigin, MASK_SHOT, &traceFilter, &ptr ); if(ptr.m_pEnt) { if(!(m_rgBullets[x].m_pHit).Find(ptr.m_pEnt)) { } } if(ptr.allsolid) { m_rgBullets[x].m_flBulletSpeed -= m_rgBullets[x].m_flLastDensity / 3000.0f; } else if(ptr.startsolid) { m_rgBullets[x].m_flBulletSpeed -= ptr.fractionleftsolid * m_rgBullets[x].m_flLastDensity / 3000.0f; } if( ptr.fraction != 1.0f ) { DevMsg(" Hit %s\n",physprops->GetPropName(ptr.surface.surfaceProps)); m_rgBullets[x].m_flLastDensity = physprops->GetSurfaceData(ptr.surface.surfaceProps)->physics.density; } #ifndef _DEBUG if(g_debug_bullets.GetBool()) #endif { NDebugOverlay::Line(m_vOldOrigin,m_rgBullets[x].m_vOrigin, 255, 255, 255, true, 10 ); } if(m_rgBullets[x].m_flBulletSpeed<=0.0f) RemoveBullet(x); } SetNextThink( gpGlobals->curtime + 0.01f ); } void CBulletManager::AddBullet(FireBulletsInfo_t &bullet) { if(m_iLastBullet==MAX_BULLETS) { Assert(m_iLastBullet!=MAX_BULLETS); Warning("Bullet queue filled\n"); return; } m_iLastBullet++; DevMsg("Bullet Created (%i)\n",m_iLastBullet); m_rgBullets[m_iLastBullet] = SimulatedBullet_t(bullet); } void CBulletManager::RemoveBullet(int index) { DevMsg("Bullet Destroyed (%i)\n",index); m_rgBullets[index] = m_rgBullets[m_iLastBullet]; m_rgBullets[m_iLastBullet] = SimulatedBullet_t(); m_iLastBullet--; }
Implementation
bullet_manager entity
g_pPlayerResource = (CPlayerResource*)CBaseEntity::Create( "player_manager", vec3_origin, vec3_angle );
goes
g_pBulletManager = (CBulletManager*)CBaseEntity::Create( "bullet_manager", vec3_origin, vec3_angle );