bool ParticleSystem::UpdateParticle( particle *part, float frametime ) { if( frametime == 0 ) return true; part->age += frametime; edict_t *source = GetEntityByIndex( m_iEntIndex ); if( !source ) return false; // total paranoia :) // is this particle bound to an entity? if( part->m_iEntIndex ) { if ( enable ) { if( m_iEntAttachment ) { Vector pos = Vector( 0, 0, 0 ); GET_ATTACHMENT( source, m_iEntAttachment, pos, NULL ); if( pos == Vector( 0, 0, 0 )) pos = source->v.origin; // missed attachment part->velocity = (pos - part->origin ) / frametime; part->origin = pos; } else { part->velocity = ( source->v.origin - part->origin ) / frametime; part->origin = source->v.origin; } } else { // entity is switched off, die return false; } } else { // not tied to an entity, check whether it's time to die if( part->age_death >= 0 && part->age > part->age_death ) return false; // apply acceleration and velocity Vector vecOldPos = part->origin; if ( part->m_fDrag ) part->velocity = part->velocity + (-part->m_fDrag * frametime) * ( part->velocity - part->m_vecWind ); part->velocity = part->velocity + frametime * part->accel; part->origin = part->origin + frametime * part->velocity; if( part->pType->m_bBouncing ) { Vector vecTarget = part->origin + frametime * part->velocity; TraceResult tr; TRACE_LINE( part->origin, vecTarget, true, source, &tr ); if( tr.flFraction < 1.0f ) { part->origin = tr.vecEndPos; float bounceforce = DotProduct( tr.vecPlaneNormal, part->velocity ); float newspeed = (1.0f - part->pType->m_BounceFriction.GetInstance()); part->velocity = part->velocity * newspeed; part->velocity = part->velocity + (-bounceforce * ( newspeed + part->pType->m_Bounce.GetInstance())) * tr.vecPlaneNormal; } } } // spray children if ( part->age_spray && part->age > part->age_spray ) { part->age_spray = part->age + 1/part->pType->m_SprayRate.GetInstance(); // particle *pChild = ActivateParticle(); if (part->pType->m_pSprayType) { particle *pChild = part->pType->m_pSprayType->CreateParticle(this); if (pChild) { pChild->origin = part->origin; float fSprayForce = part->pType->m_SprayForce.GetInstance(); pChild->velocity = part->velocity; if (fSprayForce) { float fSprayPitch = part->pType->m_SprayPitch.GetInstance() - source->v.angles.x; float fSprayYaw = part->pType->m_SprayYaw.GetInstance() - source->v.angles.y; float fSprayRoll = source->v.angles.z; float fForceCosPitch = fSprayForce*CosLookup(fSprayPitch); pChild->velocity.x += CosLookup(fSprayYaw) * fForceCosPitch; pChild->velocity.y += SinLookup(fSprayYaw) * fForceCosPitch + SinLookup(fSprayYaw) * fSprayForce * SinLookup(fSprayRoll); pChild->velocity.z -= SinLookup(fSprayPitch) * fSprayForce * CosLookup(fSprayRoll); } } } } part->m_fSize += part->m_fSizeStep * frametime; part->m_fAlpha += part->m_fAlphaStep * frametime; part->m_fRed += part->m_fRedStep * frametime; part->m_fGreen += part->m_fGreenStep * frametime; part->m_fBlue += part->m_fBlueStep * frametime; part->frame += part->m_fFrameStep * frametime; if ( part->m_fAngleStep ) { part->m_fAngle += part->m_fAngleStep * frametime; while ( part->m_fAngle < 0 ) part->m_fAngle += 360; while ( part->m_fAngle > 360 ) part->m_fAngle -= 360; } return true; }
void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const entity_state_t *prev ) { float m_fLerp; if( state->ed_type == ED_CLIENT && state->ed_flags & ESF_NO_PREDICTION ) m_fLerp = 1.0f; else m_fLerp = GetLerpFrac(); if( state->flags & FL_PROJECTILE && state->ed_flags & ( ESF_NO_PREDICTION|ESF_NODELTA )) { // cut rocket trail, dont pass it from teleport // FIXME: don't work g_pViewRenderBeams->KillDeadBeams( ent ); } // copy state to progs ent->v.modelindex = state->modelindex; ent->v.weaponmodel = state->weaponmodel; ent->v.sequence = state->sequence; ent->v.gaitsequence = state->gaitsequence; ent->v.body = state->body; ent->v.skin = state->skin; ent->v.effects = state->effects; ent->v.velocity = state->velocity; ent->v.basevelocity = state->basevelocity; ent->v.oldorigin = ent->v.origin; // previous origin holds ent->v.mins = state->mins; ent->v.maxs = state->maxs; ent->v.framerate = state->framerate; ent->v.colormap = state->colormap; ent->v.rendermode = state->rendermode; ent->v.renderfx = state->renderfx; ent->v.fov = state->fov; ent->v.scale = state->scale; ent->v.weapons = state->weapons; ent->v.gravity = state->gravity; ent->v.health = state->health; ent->v.solid = state->solid; ent->v.movetype = state->movetype; ent->v.flags = state->flags; ent->v.ideal_pitch = state->idealpitch; ent->v.animtime = state->animtime; ent->v.ltime = state->localtime; if( state->groundent != -1 ) ent->v.groundentity = GetEntityByIndex( state->groundent ); else ent->v.groundentity = NULL; if( state->aiment != -1 ) ent->v.aiment = GetEntityByIndex( state->aiment ); else ent->v.aiment = NULL; switch( ent->v.movetype ) { case MOVETYPE_NONE: case MOVETYPE_STEP: // monster's steps will be interpolated on render-side ent->v.origin = state->origin; ent->v.angles = state->angles; ent->v.oldorigin = prev->origin; // used for lerp 'monster view' ent->v.oldangles = prev->angles; // used for lerp 'monster view' break; default: ent->v.angles = LerpAngle( prev->angles, state->angles, m_fLerp ); ent->v.origin = LerpPoint( prev->origin, state->origin, m_fLerp ); ent->v.basevelocity = LerpPoint( prev->basevelocity, state->basevelocity, m_fLerp ); break; } // interpolate scale, renderamount etc ent->v.scale = LerpPoint( prev->scale, state->scale, m_fLerp ); ent->v.rendercolor = LerpPoint( prev->rendercolor, state->rendercolor, m_fLerp ); ent->v.renderamt = LerpPoint( prev->renderamt, state->renderamt, m_fLerp ); if( ent->v.animtime ) { // use normal studio lerping ent->v.frame = state->frame; } else { // round sprite and brushmodel frames ent->v.frame = Q_rint( state->frame ); } switch( state->ed_type ) { case ED_CLIENT: ent->v.punchangle = LerpAngle( prev->punch_angles, state->punch_angles, m_fLerp ); ent->v.viewangles = LerpAngle( prev->viewangles, state->viewangles, m_fLerp ); ent->v.view_ofs = LerpPoint( prev->viewoffset, state->viewoffset, m_fLerp ); if( prev->fov != 90.0f && state->fov == 90.0f ) ent->v.fov = state->fov; // fov is reset, so don't lerping else ent->v.fov = LerpPoint( prev->fov, state->fov, m_fLerp ); ent->v.maxspeed = state->maxspeed; ent->v.iStepLeft = state->iStepLeft; ent->v.flFallVelocity = state->flFallVelocity; if( ent == GetLocalPlayer()) { edict_t *viewent = GetViewModel(); // if viewmodel has changed update sequence here if( viewent->v.modelindex != state->viewmodel ) { // ALERT( at_console, "Viewmodel changed\n" ); SendWeaponAnim( viewent->v.sequence, viewent->v.body, viewent->v.framerate ); } // setup player viewmodel (only for local player!) viewent->v.modelindex = state->viewmodel; gHUD.m_flFOV = ent->v.fov; // keep client fov an actual } break; case ED_PORTAL: case ED_MOVER: case ED_BSPBRUSH: ent->v.movedir = BitsToDir( state->body ); ent->v.oldorigin = state->oldorigin; break; case ED_SKYPORTAL: { skyportal_t *sky = &gpViewParams->skyportal; // setup sky portal sky->vieworg = ent->v.origin; sky->viewanglesOffset.x = sky->viewanglesOffset.z = 0.0f; sky->viewanglesOffset.y = gHUD.m_flTime * ent->v.angles[1]; sky->scale = (ent->v.scale ? 1.0f / ent->v.scale : 0.0f ); // critical stuff sky->fov = ent->v.fov; } break; case ED_BEAM: ent->v.oldorigin = state->oldorigin; // beam endpoint ent->v.frags = state->gaitsequence; if( state->owner != -1 ) ent->v.owner = GetEntityByIndex( state->owner ); else ent->v.owner = NULL; // add server beam now g_pViewRenderBeams->AddServerBeam( ent ); break; default: ent->v.movedir = Vector( 0, 0, 0 ); break; } int i; // copy blendings for( i = 0; i < MAXSTUDIOBLENDS; i++ ) ent->v.blending[i] = state->blending[i]; // copy controllers for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ ) ent->v.controller[i] = state->controller[i]; // g-cont. moved here because we may needs apply null scale to skyportal if( ent->v.scale == 0.0f && ent->v.skin >= 0 ) ent->v.scale = 1.0f; ent->v.pContainingEntity = ent; }
bool ParticleSystem::UpdateSystem( float frametime ) { // the entity emitting this system edict_t *source = GetEntityByIndex( m_iEntIndex ); if( !source ) return false; // Don't update if the system is outside the player's PVS. enable = (source->v.renderfx == kRenderFxAurora); // check for contents to remove if( POINT_CONTENTS( source->v.origin ) == m_iKillCondition ) { enable = 0; } if( m_pMainParticle == NULL ) { if ( enable ) { ParticleType *pType = m_pMainType; if ( pType ) { m_pMainParticle = pType->CreateParticle( this ); if ( m_pMainParticle ) { m_pMainParticle->m_iEntIndex = m_iEntIndex; m_pMainParticle->age_death = -1; // never die } } } } else if ( !enable ) { m_pMainParticle->age_death = 0; // die now m_pMainParticle = NULL; } particle* pParticle = m_pActiveParticle; particle* pLast = NULL; while( pParticle ) { if ( UpdateParticle( pParticle, frametime )) { pLast = pParticle; pParticle = pParticle->nextpart; } else // deactivate it { if ( pLast ) { pLast->nextpart = pParticle->nextpart; pParticle->nextpart = m_pFreeParticle; m_pFreeParticle = pParticle; pParticle = pLast->nextpart; } else // deactivate the first particle in the list { m_pActiveParticle = pParticle->nextpart; pParticle->nextpart = m_pFreeParticle; m_pFreeParticle = pParticle; pParticle = m_pActiveParticle; } } } return true; }
// ==================================================================================================== // IsEntity // ==================================================================================================== bool World::IsEntityRegistered(int iEntityIndex) { return GetEntityByIndex(iEntityIndex) != NULL; }