diff --git a/client/client.dsp b/client/client.dsp index 27e7f8f1..4dca7abd 100644 --- a/client/client.dsp +++ b/client/client.dsp @@ -121,6 +121,10 @@ SOURCE=.\global\aurora.cpp # End Source File # Begin Source File +SOURCE=.\global\cl_tent.cpp +# End Source File +# Begin Source File + SOURCE=.\global\dll_int.cpp # End Source File # Begin Source File @@ -245,10 +249,6 @@ SOURCE=.\global\studio.cpp # End Source File # Begin Source File -SOURCE=.\global\sv_tent.cpp -# End Source File -# Begin Source File - SOURCE=.\global\triapi.cpp # End Source File # Begin Source File diff --git a/client/global/sv_tent.cpp b/client/global/cl_tent.cpp similarity index 87% rename from client/global/sv_tent.cpp rename to client/global/cl_tent.cpp index d5ba2446..16342661 100644 --- a/client/global/sv_tent.cpp +++ b/client/global/cl_tent.cpp @@ -715,6 +715,7 @@ see env_funnel description for details */ void TE_ParseFunnel( void ) { + // FIXME: implement } /* @@ -779,6 +780,14 @@ Create alpha sprites inside of entity, float upwards */ void TE_ParseFizzEffect( void ) { + int modelIndex, density; + edict_t *pEnt; + + pEnt = GetEntityByIndex( READ_SHORT()); + modelIndex = READ_SHORT(); + density = READ_BYTE(); + + g_pTempEnts->FizzEffect( pEnt, modelIndex, density ); } /* @@ -881,10 +890,11 @@ TE_ParseSpriteSpray spray of alpha sprites --------------- */ -void TE_ParseSpriteSpray( void ) +void TE_ParseSpriteSpray( int type ) { Vector pos, vel; int spriteIndex, count, speed, noise; + int renderMode; pos.x = READ_COORD(); pos.y = READ_COORD(); @@ -897,7 +907,15 @@ void TE_ParseSpriteSpray( void ) speed = READ_BYTE(); noise = READ_BYTE(); - g_pTempEnts->Sprite_Spray( pos, vel, spriteIndex, count, speed, noise ); + if( type == TE_SPRAY ) + { + renderMode = READ_BYTE(); + g_pTempEnts->Sprite_Spray( pos, vel, spriteIndex, count, speed, noise, renderMode ); + } + else + { + g_pTempEnts->Sprite_Spray( pos, vel, spriteIndex, count, speed, noise ); + } } /* @@ -918,6 +936,8 @@ void TE_ParseArmorRicochet( void ) pos.z = READ_COORD(); radius = (float)(READ_BYTE() * 0.1f); + int modelIndex = g_engfuncs.pEventAPI->EV_FindModelIndex( "sprites/richo1.spr" ); + g_pTempEnts->RicochetSprite( pos, modelIndex, radius ); g_pParticles->RicochetSparks( pos, radius ); sprintf( soundpath, "weapons/ric%i.wav", RANDOM_LONG( 1, 5 )); @@ -928,11 +948,53 @@ void TE_ParseArmorRicochet( void ) --------------- TE_ParseBubblesEffect +Create a colored decal, get settings from client +--------------- +*/ +void TE_ParsePlayerDecal( void ) +{ + int clientIndex, decalIndex, entityIndex; + Vector pos; + + clientIndex = READ_BYTE(); + pos.x = READ_COORD(); + pos.y = READ_COORD(); + pos.z = READ_COORD(); + entityIndex = READ_SHORT(); + decalIndex = READ_BYTE(); + + // FIXME: get decal settings from the client + int iColor = 134; + + HSPRITE hDecal = g_engfuncs.pEfxAPI->CL_DecalIndex( decalIndex ); + g_engfuncs.pEfxAPI->R_ShootDecal( hDecal, NULL, pos, iColor, 90.0f, 5.0f ); +} + +/* +--------------- +TE_ParseBubblesEffect + Create alpha sprites inside of box, float upwards --------------- */ void TE_ParseBubblesEffect( void ) { + Vector mins, maxs; + int modelIndex, count; + float height, speed; + + maxs.x = READ_COORD(); + maxs.y = READ_COORD(); + maxs.z = READ_COORD(); + maxs.x = READ_COORD(); + maxs.y = READ_COORD(); + maxs.z = READ_COORD(); + height = READ_COORD(); + modelIndex = READ_SHORT(); + count = READ_BYTE(); + speed = READ_COORD(); + + g_pTempEnts->Bubbles( mins, maxs, height, modelIndex, count, speed ); } /* @@ -944,6 +1006,22 @@ Create alpha sprites along a line, float upwards */ void TE_ParseBubbleTrail( void ) { + Vector start, end; + int modelIndex, count; + float height, speed; + + start.x = READ_COORD(); + start.y = READ_COORD(); + start.z = READ_COORD(); + end.x = READ_COORD(); + end.y = READ_COORD(); + end.z = READ_COORD(); + height = READ_COORD(); + modelIndex = READ_SHORT(); + count = READ_BYTE(); + speed = READ_COORD(); + + g_pTempEnts->BubbleTrail( start, end, height, modelIndex, count, speed ); } /* @@ -989,7 +1067,7 @@ void TE_ParseAttachTentToPlayer( void ) modelIndex = READ_SHORT(); life = (float)(READ_BYTE() * 0.1f); -// g_pTempEnts->AttachTentToPlayer( clientIndex, modelIndex, zoffset, life ); + g_pTempEnts->AttachTentToPlayer( clientIndex, modelIndex, zoffset, life ); } /* @@ -1003,7 +1081,7 @@ void TE_KillAttachedTents( void ) { int clientIndex = READ_BYTE(); -// g_pTempEnts->KillAttachedTents( clientIndex ); + g_pTempEnts->KillAttachedTents( clientIndex ); } /* @@ -1065,9 +1143,6 @@ void HUD_ParseTempEntity( void ) case TE_SPRITETRAIL: TE_ParseSpriteTrail(); break; - case TE_BEAMLASER: - // FIXME: implement - break; case TE_SPRITE: TE_ParseSprite(); break; @@ -1095,9 +1170,6 @@ void HUD_ParseTempEntity( void ) case TE_STREAK_SPLASH: // FIXME: implement break; - case TE_BEAMRINGPOINT: - // FIXME: implement - break; case TE_ELIGHT: TE_ParseDynamicLight( TE_ELIGHT ); break; @@ -1147,13 +1219,13 @@ void HUD_ParseTempEntity( void ) TE_ParseGunShotDecal(); break; case TE_SPRITE_SPRAY: - TE_ParseSpriteSpray(); + TE_ParseSpriteSpray( TE_SPRITE_SPRAY ); break; case TE_ARMOR_RICOCHET: TE_ParseArmorRicochet(); break; case TE_PLAYERDECAL: - // FIXME: implement + TE_ParsePlayerDecal(); break; case TE_BUBBLES: TE_ParseBubblesEffect(); @@ -1177,7 +1249,7 @@ void HUD_ParseTempEntity( void ) // FIXME: implement break; case TE_SPRAY: - // FIXME: implement + TE_ParseSpriteSpray( TE_SPRAY ); break; case TE_PLAYERSPRITES: // FIXME: implement diff --git a/client/global/enginecallback.h b/client/global/enginecallback.h index 91e1fa0d..915c6537 100644 --- a/client/global/enginecallback.h +++ b/client/global/enginecallback.h @@ -27,6 +27,7 @@ #define SendWeaponAnim (*g_engfuncs.pEventAPI->EV_WeaponAnim) #define GetModelType (*g_engfuncs.pEventAPI->EV_GetModelType) #define GetModelFrames (*g_engfuncs.pEventAPI->EV_GetModFrames) +#define GetModelBounds (*g_engfuncs.pEventAPI->EV_GetModBounds) #define CVAR_REGISTER (*g_engfuncs.pfnRegisterVariable) #define CVAR_SET_FLOAT (*g_engfuncs.pfnCvarSetValue) #define CVAR_GET_FLOAT (*g_engfuncs.pfnGetCvarFloat) @@ -40,6 +41,7 @@ #define CMD_ARGC (*g_engfuncs.pfnCmdArgc) #define CMD_ARGV (*g_engfuncs.pfnCmdArgv) #define ALERT (*g_engfuncs.pfnAlertMessage) +#define IN_GAME (*g_engfuncs.pfnIsInGame) inline void SPR_Set( HSPRITE hPic, int r, int g, int b ) { diff --git a/client/global/r_beams.cpp b/client/global/r_beams.cpp index 8baeabb0..232e8cef 100644 --- a/client/global/r_beams.cpp +++ b/client/global/r_beams.cpp @@ -239,7 +239,7 @@ void Beam_t::SetBrightness( float flBrightness ) const Vector& Beam_t::GetRenderOrigin( void ) { - if (( type == TE_BEAMRING ) || ( type == TE_BEAMRINGPOINT )) + if ( type == TE_BEAMRING ) { // return the center of the ring static Vector org; @@ -265,7 +265,6 @@ void Beam_t::ComputeBounds( void ) } break; case TE_BEAMRING: - case TE_BEAMRINGPOINT: { int radius = delta.Length() * 0.5f; m_Mins.Init( -radius, -radius, -radius ); @@ -778,7 +777,7 @@ Beam_t *CViewRenderBeams::CreateBeamEntPoint( BeamInfo_t &beamInfo ) return NULL; pBeam->type = TE_BEAMPOINTS; - pBeam->flags = FBEAM_SINENOISE; + pBeam->flags = 0; if ( beamInfo.m_pStartEnt ) { @@ -1002,77 +1001,6 @@ Beam_t *CViewRenderBeams::CreateBeamFollow( BeamInfo_t &beamInfo ) return pBeam; } -//----------------------------------------------------------------------------- -// Purpose: Create a beam ring between two entities -// Input : startEnt - -// endEnt - -// modelIndex - -// life - -// width - -// amplitude - -// brightness - -// speed - -// startFrame - -// framerate - -// startEnt - -// Output : Beam_t -//----------------------------------------------------------------------------- -void CViewRenderBeams::CreateBeamRingPoint( const Vector& center, float start_radius, float end_radius, int modelIndex, - float life, float width, float endWidth, float fadeLength, float amplitude, float brightness, - float speed, int startFrame, float framerate, float r, float g, float b ) -{ - BeamInfo_t beamInfo; - - beamInfo.m_nModelIndex = modelIndex; - beamInfo.m_flLife = life; - beamInfo.m_flWidth = width; - beamInfo.m_flEndWidth = endWidth; - beamInfo.m_flFadeLength = fadeLength; - beamInfo.m_flAmplitude = amplitude; - beamInfo.m_flBrightness = brightness; - beamInfo.m_flSpeed = speed; - beamInfo.m_nStartFrame = startFrame; - beamInfo.m_flFrameRate = framerate; - beamInfo.m_flRed = r; - beamInfo.m_flGreen = g; - beamInfo.m_flBlue = b; - beamInfo.m_vecCenter = center; - beamInfo.m_flStartRadius = start_radius; - beamInfo.m_flEndRadius = end_radius; - - CreateBeamRingPoint( beamInfo ); -} - -//----------------------------------------------------------------------------- -// Purpose: Create a beam ring between two entities -// Input: beamInfo - -//----------------------------------------------------------------------------- -Beam_t *CViewRenderBeams::CreateBeamRingPoint( BeamInfo_t &beamInfo ) -{ - // ?? - Vector endpos = beamInfo.m_vecCenter; - - beamInfo.m_vecStart = beamInfo.m_vecCenter; - beamInfo.m_vecEnd = beamInfo.m_vecCenter; - - Beam_t *pBeam = CreateGenericBeam( beamInfo ); - if ( !pBeam ) - return NULL; - - pBeam->type = TE_BEAMRINGPOINT; - pBeam->start_radius = beamInfo.m_flStartRadius; - pBeam->end_radius = beamInfo.m_flEndRadius; - pBeam->attachment[2] = beamInfo.m_vecCenter; - - SetBeamAttributes( pBeam, beamInfo ); - if ( beamInfo.m_flLife == 0 ) - { - pBeam->flags |= FBEAM_FOREVER; - } - - return pBeam; -} - //----------------------------------------------------------------------------- // Purpose: Create a beam ring between two entities // Input : startEnt - @@ -1201,8 +1129,11 @@ void CViewRenderBeams::FreeDeadTrails( BeamTrail_t **trail ) //----------------------------------------------------------------------------- void CViewRenderBeams::UpdateBeam( Beam_t *pbeam, float frametime ) { + pbeam->m_bCulled = false; + if ( GetModelType( pbeam->modelIndex ) == mod_bad ) { + pbeam->m_bCulled = true; // force to ignore pbeam->die = gpGlobals->time; return; } @@ -1245,8 +1176,10 @@ void CViewRenderBeams::UpdateBeam( Beam_t *pbeam, float frametime ) { // Makes sure attachment[0] + attachment[1] are valid if (!RecomputeBeamEndpoints( pbeam )) + { + pbeam->m_bCulled = true; // force to ignore return; - + } // Compute segments from the new endpoints pbeam->delta = pbeam->attachment[1] - pbeam->attachment[0]; if ( pbeam->amplitude >= 0.50f ) @@ -1255,50 +1188,16 @@ void CViewRenderBeams::UpdateBeam( Beam_t *pbeam, float frametime ) pbeam->segments = pbeam->delta.Length( ) * 0.075f + 3.0f; // one per 16 pixels } - float dr; - // Get position data for spline beam switch ( pbeam->type ) { - case TE_BEAMRINGPOINT: - dr = pbeam->end_radius - pbeam->start_radius; - - if ( dr != 0.0f ) - { - float frac = 1.0f; - // Go some portion of the way there based on life - float remaining = pbeam->die - gpGlobals->time; - - if ( remaining < pbeam->life && pbeam->life > 0.0f ) - { - frac = remaining / pbeam->life; - } - frac = min( 1.0f, frac ); - frac = max( 0.0f, frac ); - - frac = 1.0f - frac; - - // Start pos - Vector endpos = pbeam->attachment[2]; - endpos.x += ( pbeam->start_radius + frac * dr ) / 2.0f; - Vector startpos = pbeam->attachment[2]; - startpos.x -= ( pbeam->start_radius + frac * dr ) / 2.0f; - - pbeam->attachment[0] = startpos; - pbeam->attachment[1] = endpos; - - pbeam->delta = pbeam->attachment[1] - pbeam->attachment[0]; - - if ( pbeam->amplitude >= 0.50f ) - pbeam->segments = pbeam->delta.Length( ) * 0.25f + 3.0f; // one per 4 pixels - else pbeam->segments = pbeam->delta.Length( ) * 0.075f + 3.0f; // one per 16 pixels - - } - break; case TE_BEAMPOINTS: // UNDONE: Build culling volumes for other types of beams if ( !CullBeam( pbeam->attachment[0], pbeam->attachment[1], 0 )) + { + pbeam->m_bCulled = true; // force to ignore return; + } break; } @@ -1553,7 +1452,7 @@ void CViewRenderBeams::DrawBeam( Beam_t *pbeam ) ASSERT( pbeam->delta.IsValid() ); // Don't draw really short beams - if ( pbeam->delta.Length() < 0.1f ) + if ( pbeam->m_bCulled || pbeam->delta.Length() < 0.1f ) { return; } @@ -1623,12 +1522,11 @@ void CViewRenderBeams::DrawBeam( Beam_t *pbeam ) DrawBeamFollow( pbeam->modelIndex, pbeam, frame, rendermode, gpGlobals->frametime, color ); break; case TE_BEAMRING: - case TE_BEAMRINGPOINT: DrawRing( NOISE_DIVISIONS, pbeam->rgNoise, FracNoise, pbeam->modelIndex, frame, rendermode, pbeam->attachment[0], pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments, color ); break; - case TE_BEAMLASER: + case TE_BEAMHOSE: DrawLaser( pbeam, frame, rendermode, color, pbeam->modelIndex ); break; default: @@ -1788,12 +1686,12 @@ void CViewRenderBeams::DrawBeam( edict_t *pbeam ) beamInfo.m_pStartEnt = beamInfo.m_pEndEnt = NULL; beamInfo.m_nModelIndex = pbeam->v.modelindex; beamInfo.m_flLife = 0; - beamInfo.m_flWidth = pbeam->v.scale * 0.1f; + beamInfo.m_flWidth = (float)(pbeam->v.scale * 0.1f); beamInfo.m_flEndWidth = beamInfo.m_flWidth; beamInfo.m_flFadeLength = 0.0f; // will be set on first call UpdateBeam beamInfo.m_flAmplitude = (float)(pbeam->v.body * 0.1f); beamInfo.m_flBrightness = pbeam->v.renderamt; - beamInfo.m_flSpeed = pbeam->v.animtime * 0.1f; + beamInfo.m_flSpeed = (float)(pbeam->v.animtime * 0.1f); SetupBeam( &beam, beamInfo ); @@ -1817,8 +1715,8 @@ void CViewRenderBeams::DrawBeam( edict_t *pbeam ) beam.attachmentIndex[1] = ((pbeam->v.colormap & 0xFF00)>>8); beam.numAttachments = (pbeam->v.owner) ? ((pbeam->v.aiment) ? 2 : 1) : 0; break; - case BEAM_LASER: - beam.type = TE_BEAMLASER; + case BEAM_HOSE: + beam.type = TE_BEAMHOSE; beam.flags = FBEAM_STARTENTITY|FBEAM_ENDENTITY; beam.entity[0] = LinkWithViewModel( pbeam->v.aiment ); beam.attachmentIndex[0] = pbeam->v.colormap & 0xFF; @@ -1948,7 +1846,7 @@ void DrawSegs( int noise_divisions, float *prgNoise, int modelIndex, float frame // What fraction of beam should be faded ASSERT( fadeLength >= 0.0f ); - float fadeFraction = fadeLength/ delta.Length(); + float fadeFraction = fadeLength / delta.Length(); // BUGBUG: This code generates NANs when fadeFraction is zero! REVIST! fadeFraction = bound( 1e-6, fadeFraction, 1.0f ); diff --git a/client/global/r_beams.h b/client/global/r_beams.h index 6599c15c..a0640fd1 100644 --- a/client/global/r_beams.h +++ b/client/global/r_beams.h @@ -156,12 +156,13 @@ public: // Popcorn trail for beam follows to use BeamTrail_t *trail; - // for TE_BEAMRINGPOINT + // for TE_BEAMRING float start_radius; float end_radius; // for FBEAM_ONLYNOISEONCE bool m_bCalculatedNoise; + bool m_bCulled; // ignore to drawing float m_flDmgTime; // this is egon stuff }; @@ -225,7 +226,6 @@ public: Beam_t *CreateBeamEntPoint( BeamInfo_t &beamInfo ); Beam_t *CreateBeamPoints( BeamInfo_t &beamInfo ); Beam_t *CreateBeamRing( BeamInfo_t &beamInfo ); - Beam_t *CreateBeamRingPoint( BeamInfo_t &beamInfo ); Beam_t *CreateBeamCirclePoints( BeamInfo_t &beamInfo ); Beam_t *CreateBeamFollow( BeamInfo_t &beamInfo ); @@ -251,10 +251,6 @@ public: void CreateBeamRing( int startEnt, int endEnt, int modelIndex, float life, float width, float endWidth, float fadeLength, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b ); - void CreateBeamRingPoint( const Vector& center, float start_radius, float end_radius, - int modelIndex, float life, float width, float m_nEndWidth, float m_nFadeLength, - float amplitude, float brightness, float speed, int startFrame, float framerate, - float r, float g, float b ); void CreateBeamCirclePoints( int type, Vector& start, Vector& end, int modelIndex, float life, float width, float endWidth, float fadeLength, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b ); diff --git a/client/global/r_tempents.cpp b/client/global/r_tempents.cpp index 25c4fd01..79e9c0a4 100644 --- a/client/global/r_tempents.cpp +++ b/client/global/r_tempents.cpp @@ -134,8 +134,7 @@ int CTempEnts::TE_Update( TEMPENTITY *pTemp ) if( gpGlobals->time > pTemp->m_flSpriteScale ) { // show Sparks -// FIXME: implement -// g_engfuncs.pEfxAPI->R_SparkEffect( pTemp->origin, 8, -200, 200 ); + g_pParticles->SparkParticles( pTemp->origin, g_vecZero ); // reduce life pTemp->m_flFrameRate -= 0.1f; @@ -391,7 +390,7 @@ void CTempEnts :: Update( void ) current = m_pActiveTempEnts; // !!! Don't simulate while paused.... This is sort of a hack, revisit. - if( 0 /* cls.key_dest != key_game */ ) + if( IN_GAME() == 0 ) { while( current ) { @@ -628,8 +627,386 @@ TEMPENTITY *CTempEnts::TempEntAllocCustom( const Vector& org, int modelIndex, in ============================================================== */ +//----------------------------------------------------------------------------- +// Purpose: Create a fizz effect +// Input : *pent - +// modelIndex - +// density - +//----------------------------------------------------------------------------- +void CTempEnts::FizzEffect( edict_t *pent, int modelIndex, int density ) +{ + TEMPENTITY *pTemp; + int i, width, depth, count, frameCount; + float angle, maxHeight, speed, xspeed, yspeed; + Vector origin; + Vector mins, maxs; + + if( !pent || pent->free || GetModelType( modelIndex ) == mod_bad ) + return; + + count = density + 1; + density = count * 3 + 6; + + GetModelBounds( modelIndex, mins, maxs ); + + maxHeight = maxs[2] - mins[2]; + width = maxs[0] - mins[0]; + depth = maxs[1] - mins[1]; + speed = ((int)pent->v.rendercolor.y<<8|(int)pent->v.rendercolor.x); + if( pent->v.rendercolor.z ) speed = -speed; + + ALERT( at_console, "speed %g\n", speed ); + + angle = pent->v.angles[YAW] * M_PI / 180; + yspeed = sin( angle ); + xspeed = cos( angle ); + + xspeed *= speed; + yspeed *= speed; + frameCount = GetModelFrames( modelIndex ); + + for ( i = 0; i < count; i++ ) + { + origin[0] = mins[0] + RANDOM_LONG( 0, width - 1 ); + origin[1] = mins[1] + RANDOM_LONG( 0, depth - 1 ); + origin[2] = mins[2]; + pTemp = TempEntAlloc( origin, modelIndex ); + + if ( !pTemp ) return; + + pTemp->flags |= FTENT_SINEWAVE; + + pTemp->x = origin[0]; + pTemp->y = origin[1]; + + float zspeed = RANDOM_LONG( 80, 140 ); + pTemp->m_vecVelocity = Vector( xspeed, yspeed, zspeed ); + pTemp->die = gpGlobals->time + ( maxHeight / zspeed ) - 0.1f; + pTemp->m_flFrame = RANDOM_LONG( 0, frameCount - 1 ); + // Set sprite scale + pTemp->m_flSpriteScale = 1.0f / RANDOM_FLOAT( 2, 5 ); + pTemp->renderMode = kRenderTransAlpha; + pTemp->renderAmt = pTemp->startAlpha = 255; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Create bubbles +// Input : *mins - +// *maxs - +// height - +// modelIndex - +// count - +// speed - +//----------------------------------------------------------------------------- +void CTempEnts::Bubbles( const Vector &mins, const Vector &maxs, float height, int modelIndex, int count, float speed ) +{ + TEMPENTITY *pTemp; + int i, frameCount; + float sine, cosine; + Vector origin; + + if( GetModelType( modelIndex ) == mod_bad ) + return; + + frameCount = GetModelFrames( modelIndex ); + + for ( i = 0; i < count; i++ ) + { + origin[0] = RANDOM_LONG( mins[0], maxs[0] ); + origin[1] = RANDOM_LONG( mins[1], maxs[1] ); + origin[2] = RANDOM_LONG( mins[2], maxs[2] ); + pTemp = TempEntAlloc( origin, modelIndex ); + if ( !pTemp ) return; + + pTemp->flags |= FTENT_SINEWAVE; + + pTemp->x = origin[0]; + pTemp->y = origin[1]; + float angle = RANDOM_LONG( -M_PI, M_PI ); + sine = sin( angle ); + cosine = cos( angle ); + + float zspeed = RANDOM_LONG( 80, 140 ); + pTemp->m_vecVelocity = Vector( speed * cosine, speed * sine, zspeed ); + pTemp->die = gpGlobals->time + ((height - (origin[2] - mins[2])) / zspeed) - 0.1f; + pTemp->m_flFrame = RANDOM_LONG( 0, frameCount - 1 ); + + // Set sprite scale + pTemp->m_flSpriteScale = 1.0 / RANDOM_FLOAT( 4, 16 ); + pTemp->renderMode = kRenderTransAlpha; + pTemp->renderAmt = pTemp->startAlpha = 192; // g-cont. why difference with FizzEffect ??? + } +} + +//----------------------------------------------------------------------------- +// Purpose: Create bubble trail +// Input : *start - +// *end - +// height - +// modelIndex - +// count - +// speed - +//----------------------------------------------------------------------------- +void CTempEnts::BubbleTrail( const Vector &start, const Vector &end, float flWaterZ, int modelIndex, int count, float speed ) +{ + TEMPENTITY *pTemp; + int i, frameCount; + float dist, angle; + Vector origin; + + if( GetModelType( modelIndex ) == mod_bad ) + return; + + frameCount = GetModelFrames( modelIndex ); + + for ( i = 0; i < count; i++ ) + { + dist = RANDOM_FLOAT( 0, 1.0 ); // g-cont. hmm may be use GetLerpFrac instead ? + + origin = LerpPoint( start, end, dist ); + pTemp = TempEntAlloc( origin, modelIndex ); + if ( !pTemp ) return; + + pTemp->flags |= FTENT_SINEWAVE; + + pTemp->x = origin[0]; + pTemp->y = origin[1]; + angle = RANDOM_LONG( -M_PI, M_PI ); + + float zspeed = RANDOM_LONG( 80, 140 ); + pTemp->m_vecVelocity = Vector( speed * cos( angle ), speed * sin( angle ), zspeed ); + pTemp->die = gpGlobals->time + (( flWaterZ - origin[2]) / zspeed ) - 0.1f; + pTemp->m_flFrame = RANDOM_LONG( 0, frameCount - 1 ); + // Set sprite scale + pTemp->m_flSpriteScale = 1.0 / RANDOM_FLOAT( 4, 8 ); + pTemp->renderMode = kRenderTransAlpha; + pTemp->renderAmt = pTemp->startAlpha = 192; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Attaches entity to player +// Input : client - +// modelIndex - +// zoffset - +// life - +//----------------------------------------------------------------------------- +void CTempEnts::AttachTentToPlayer( int client, int modelIndex, float zoffset, float life ) +{ + TEMPENTITY *pTemp; + Vector position; + int frameCount; + + if ( client <= 0 || client > gpGlobals->maxClients ) + { + ALERT( at_warning, "Bad client in AttachTentToPlayer()!\n" ); + return; + } + + edict_t *pClient = GetEntityByIndex( client ); + if ( !pClient ) + { + ALERT( at_warning, "Couldn't get ClientEntity for %i\n", client ); + return; + } + + if( GetModelType( modelIndex ) == mod_bad ) + { + ALERT( at_console, "No model %d!\n", modelIndex ); + return; + } + + position = pClient->v.origin; + position[2] += zoffset; + + pTemp = TempEntAllocHigh( position, modelIndex ); + if ( !pTemp ) + { + ALERT( at_warning, "No temp ent.\n" ); + return; + } + + pTemp->renderMode = kRenderNormal; + pTemp->renderAmt = pTemp->startAlpha = 192; + pTemp->renderFX = kRenderFxNoDissipation; + + pTemp->clientIndex = client; + pTemp->tentOffset[0] = 0; + pTemp->tentOffset[1] = 0; + pTemp->tentOffset[2] = zoffset; + pTemp->die = gpGlobals->time + life; + pTemp->flags |= FTENT_PLYRATTACHMENT|FTENT_PERSIST; + + // is the model a sprite? + if ( GetModelType( pTemp->modelindex ) == mod_sprite ) + { + frameCount = GetModelFrames( pTemp->modelindex ); + pTemp->m_flFrameMax = frameCount - 1; + pTemp->flags |= FTENT_SPRANIMATE|FTENT_SPRANIMATELOOP; + pTemp->m_flFrameRate = 10; + } + else + { + // no animation support for attached clientside studio models. + pTemp->m_flFrameMax = 0; + } + + pTemp->m_flFrame = 0; +} +#define FOR_EACH_LL( listName, iteratorName ) \ + for( int iteratorName=listName.Head(); iteratorName != listName.InvalidIndex(); iteratorName = listName.Next( iteratorName ) ) + +//----------------------------------------------------------------------------- +// Purpose: Detach entity from player +//----------------------------------------------------------------------------- +void CTempEnts::KillAttachedTents( int client ) +{ + if ( client <= 0 || client > gpGlobals->maxClients ) + { + ALERT( at_warning, "Bad client in KillAttachedTents()!\n" ); + return; + } + + for( int i = 0; i < MAX_TEMP_ENTITIES; i++ ) + { + TEMPENTITY *pTemp = &m_TempEnts[i]; + + if ( pTemp->flags & FTENT_PLYRATTACHMENT ) + { + // this TENT is player attached. + // if it is attached to this client, set it to die instantly. + if ( pTemp->clientIndex == client ) + { + pTemp->die = gpGlobals->time; // good enough, it will die on next tent update. + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Create ricochet sprite +// Input : *pos - +// *pmodel - +// duration - +// scale - +//----------------------------------------------------------------------------- +void CTempEnts::RicochetSprite( const Vector &pos, model_t modelIndex, float scale ) +{ + TEMPENTITY *pTemp; + + pTemp = TempEntAlloc( pos, modelIndex ); + if (!pTemp) + return; + + pTemp->renderMode = kRenderGlow; + pTemp->renderAmt = pTemp->startAlpha = 200; + pTemp->renderFX = kRenderFxNoDissipation; + pTemp->m_flSpriteScale = scale; + pTemp->flags = FTENT_FADEOUT; + pTemp->fadeSpeed = 8; + pTemp->die = gpGlobals->time; + + pTemp->m_flFrame = 0; + pTemp->angles[ROLL] = 45 * RANDOM_LONG( 0, 7 ); +} + void CTempEnts::PlaySound( TEMPENTITY *pTemp, float damp ) { + float fvol; + char soundname[32]; + bool isshellcasing = false; + int zvel; + + switch ( pTemp->hitSound ) + { + default: + return; // null sound + case BOUNCE_GLASS: + { + sprintf( soundname, "debris/glass%i.wav", RANDOM_LONG( 1, 4 )); + } + break; + case BOUNCE_METAL: + { + sprintf( soundname, "debris/metal%i.wav", RANDOM_LONG( 1, 6 )); + } + break; + case BOUNCE_FLESH: + { + sprintf( soundname, "debris/flesh%i.wav", RANDOM_LONG( 1, 7 )); + } + break; + case BOUNCE_WOOD: + { + sprintf( soundname, "debris/wood%i.wav", RANDOM_LONG( 1, 4 )); + } + break; + case BOUNCE_SHRAP: + { + sprintf( soundname, "weapons/ric%i.wav", RANDOM_LONG( 1, 5 )); + } + break; + case BOUNCE_SHOTSHELL: + { + sprintf( soundname, "weapons/sshell%i.wav", RANDOM_LONG( 1, 3 )); + isshellcasing = true; // shell casings have different playback parameters + } + break; + case BOUNCE_SHELL: + { + sprintf( soundname, "player/pl_shell%i.wav", RANDOM_LONG( 1, 3 )); + isshellcasing = true; // shell casings have different playback parameters + } + break; + case BOUNCE_CONCRETE: + { + sprintf( soundname, "debris/concrete%i.wav", RANDOM_LONG( 1, 3 )); + } + break; + } + + zvel = abs( pTemp->m_vecVelocity[2] ); + + // only play one out of every n + + if ( isshellcasing ) + { + // play first bounce, then 1 out of 3 + if ( zvel < 200 && RANDOM_LONG( 0, 3 )) + return; + } + else + { + if ( RANDOM_LONG( 0, 5 )) + return; + } + + fvol = 1.0f; + + if ( damp > 0.0 ) + { + int pitch; + + if ( isshellcasing ) + { + fvol *= min ( 1.0f, ((float)zvel) / 350.0 ); + } + else + { + fvol *= min ( 1.0f, ((float)zvel) / 450.0 ); + } + + if ( !RANDOM_LONG( 0, 3 ) && !isshellcasing ) + { + pitch = RANDOM_LONG( 95, 105 ); + } + else + { + pitch = 100; // FIXME + } + CL_PlaySound( soundname, fvol, pTemp->origin, pitch ); + } } void CTempEnts::RocketFlare( const Vector& pos ) @@ -821,8 +1198,8 @@ void CTempEnts::TempModel( const Vector &pos, const Vector &dir, const Vector &a // keep track of shell type switch( soundtype ) { - case 1: pTemp->hitSound = TE_BOUNCE_SHELL; break; - case 2: pTemp->hitSound = TE_BOUNCE_SHOTSHELL; break; + case TE_BOUNCE_SHELL: pTemp->hitSound = BOUNCE_SHELL; break; + case TE_BOUNCE_SHOTSHELL: pTemp->hitSound = BOUNCE_SHOTSHELL; break; } pTemp->origin = pos; @@ -964,7 +1341,7 @@ void CTempEnts::Sprite_Smoke( TEMPENTITY *pTemp, float scale ) } -void CTempEnts::Sprite_Spray( const Vector &pos, const Vector &dir, int modelIndex, int count, int speed, int iRand ) +void CTempEnts::Sprite_Spray( const Vector &pos, const Vector &dir, int modelIndex, int count, int speed, int iRand, int renderMode ) { TEMPENTITY *pTemp; float noise; @@ -994,7 +1371,7 @@ void CTempEnts::Sprite_Spray( const Vector &pos, const Vector &dir, int modelInd pTemp = TempEntAlloc( pos, modelIndex ); if( !pTemp ) return; - pTemp->renderMode = kRenderTransAlpha; + pTemp->renderMode = renderMode; pTemp->renderFX = kRenderFxNoDissipation; pTemp->m_flSpriteScale = 0.5f; pTemp->flags |= FTENT_FADEOUT|FTENT_SLOWGRAVITY; diff --git a/client/global/r_tempents.h b/client/global/r_tempents.h index 3f4de25e..bd64bd10 100644 --- a/client/global/r_tempents.h +++ b/client/global/r_tempents.h @@ -32,7 +32,7 @@ public: int TE_Update( TEMPENTITY *pTemp ); // return false for instantly die void BloodSprite( const Vector &org, int colorIndex, int modelIndex, int modelIndex2, float size ); - void RicochetSprite( const Vector &pos, int modelIndex, float duration, float scale ); + void RicochetSprite( const Vector &pos, int modelIndex, float scale ); void MuzzleFlash( edict_t *pEnt, int iAttachment, int type ); void TempModel( const Vector &pos, const Vector &dir, const Vector &ang, float life, int modelIndex, int soundtype ); void BreakModel( const Vector &pos, const Vector &size, const Vector &dir, float random, float life, int count, int modelIndex, char flags ); @@ -45,7 +45,7 @@ public: TEMPENTITY *TempSprite( const Vector &pos, const Vector &dir, float scale, int modelIndex, int rendermode, int renderfx, float a, float life, int flags ); void AttachTentToPlayer( int client, int modelIndex, float zoffset, float life ); void KillAttachedTents( int client ); - void Sprite_Spray( const Vector &pos, const Vector &dir, int modelIndex, int count, int speed, int iRand ); + void Sprite_Spray( const Vector &pos, const Vector &dir, int modelIndex, int count, int speed, int iRand, int renderMode = kRenderTransAlpha ); void Sprite_Trail( int type, const Vector &vecStart, const Vector &vecEnd, int modelIndex, int nCount, float flLife, float flSize, float flAmplitude, int nRenderamt, float flSpeed ); void RocketFlare( const Vector& pos ); void PlaySound( TEMPENTITY *pTemp, float damp ); diff --git a/common/beam_def.h b/common/beam_def.h index fa267a51..b02c85af 100644 --- a/common/beam_def.h +++ b/common/beam_def.h @@ -12,7 +12,6 @@ typedef enum BEAM_ENTPOINT, BEAM_ENTS, BEAM_HOSE, - BEAM_LASER, } kBeamType_t; // beam flags diff --git a/common/clgame_api.h b/common/clgame_api.h index f9d58726..dc6c1fa1 100644 --- a/common/clgame_api.h +++ b/common/clgame_api.h @@ -227,6 +227,9 @@ typedef struct cl_enginefuncs_s struct efxapi_s *pEfxAPI; struct event_api_s *pEventAPI; + // new interface starts here + int (*pfnIsInGame)( void ); // return false for menu, console, etc + } cl_enginefuncs_t; typedef struct diff --git a/common/effects_api.h b/common/effects_api.h index f29f1b70..dbce407e 100644 --- a/common/effects_api.h +++ b/common/effects_api.h @@ -33,7 +33,7 @@ typedef struct efxapi_s int (*CL_DecalIndexFromName)( const char *szDecalName ); int (*R_ShootDecal)( HSPRITE hSpr, edict_t *pEnt, const float *pos, int color, float roll, float rad ); void (*CL_AllocDLight)( const float *org, float *rgb, float rad, float lifetime, int flags, int key ); - void (*CL_FindExplosionPlane)( const float *origin, float radius, float *result ); + void (*CL_AllocSLight)( const float *org, float *dir, float rad, float *cone, HSPRITE hLight, int key ); void (*R_LightForPoint)( const float *rgflOrigin, float *lightValue ); int (*CL_IsBoxVisible)( const float *mins, const float *maxs ); int (*R_CullBox)( const float *mins, const float *maxs ); diff --git a/common/event_api.h b/common/event_api.h index 731013fa..68abf372 100644 --- a/common/event_api.h +++ b/common/event_api.h @@ -52,6 +52,7 @@ typedef struct event_api_s void (*EV_StopAllSounds)( edict_t *ent, int entchannel ); modtype_t (*EV_GetModelType)( int modelIndex ); int (*EV_GetModFrames)( int modelIndex ); + void (*EV_GetModBounds)( int modelIndex, float *mins, float *maxs ); } event_api_t; #endif//EVENT_API_H \ No newline at end of file diff --git a/common/te_shared.h b/common/te_shared.h index ba07ddd3..de2648aa 100644 --- a/common/te_shared.h +++ b/common/te_shared.h @@ -111,8 +111,7 @@ // byte (velocity along vector in 10's) // byte (randomness of velocity in 10's) -#define TE_BEAMLASER 16 // UNDONE: dont forget add description -// ??? +#define TE_BEAM 16 // obsolete #define TE_SPRITE 17 // additive sprite, plays 1 cycle // coord, coord, coord (position) @@ -197,8 +196,7 @@ // short (base speed) // short (ramdon velocity) -#define TE_BEAMRINGPOINT 26 // UNDONE: dont forget add description -// ??? +#define TE_BEAMHOSE 26 // obsolete #define TE_DLIGHT 27 // dynamic light, effect world, minor entity effect // coord, coord, coord (pos) diff --git a/engine/client/cl_effects.c b/engine/client/cl_effects.c index 8cd21dba..ccad22cf 100644 --- a/engine/client/cl_effects.c +++ b/engine/client/cl_effects.c @@ -219,6 +219,17 @@ void CL_AddDLight( const float *org, const float *rgb, float radius, float time, dl->fade = (flags & DLIGHT_FADE) ? true : false; } +/* +=============== +CL_AddSLight + +=============== +*/ +void CL_AddSLight( const float *org, float *dir, float rad, float *cone, HSPRITE hLight, int key ) +{ + // FIXME: implement +} + /* =============== CL_AddDLights diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index 18368c9b..9c501eed 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -2045,6 +2045,25 @@ int pfnGetModFrames( model_t modelIndex ) if( pe ) pe->Mod_GetFrames( modelIndex, &numFrames ); return numFrames; } + +/* +============= +pfnGetModBounds + +============= +*/ +void pfnGetModBounds( model_t modelIndex, float *mins, float *maxs ) +{ + if( pe ) + { + pe->Mod_GetBounds( modelIndex, mins, maxs ); + } + else + { + if( mins ) VectorClear( mins ); + if( maxs ) VectorClear( maxs ); + } +} /* ============= @@ -2069,23 +2088,23 @@ void VGui_ViewportPaintBackground( int extents[4] ) // FIXME: implement } +/* +============= +pfnIsInGame + +============= +*/ +int pfnIsInGame( void ) +{ + return ( cls.key_dest == key_game ) ? true : false; +} + /* =============================================================================== EffectsAPI Builtin Functions =============================================================================== */ -/* -================= -pfnFindExplosionPlane - -================= -*/ -static void pfnFindExplosionPlane( const float *origin, float radius, float *result ) -{ - CL_FindExplosionPlane( origin, radius, result ); -} - /* ================= pfnDecalIndexFromName @@ -2431,7 +2450,7 @@ static efxapi_t gEfxApi = pfnDecalIndexFromName, CL_SpawnDecal, CL_AddDLight, - pfnFindExplosionPlane, + CL_AddSLight, CL_LightForPoint, CM_BoxVisible, pfnCullBox, @@ -2457,6 +2476,7 @@ static event_api_t gEventApi = pfnStopAllSounds, pfnGetModelType, pfnGetModFrames, + pfnGetModBounds, }; // engine callbacks @@ -2548,7 +2568,8 @@ static cl_enginefuncs_t gEngfuncs = pfnFreeFile, &gTriApi, &gEfxApi, - &gEventApi + &gEventApi, + pfnIsInGame }; void CL_UnloadProgs( void ) diff --git a/engine/client/client.h b/engine/client/client.h index 4d8f4540..339a284a 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -568,6 +568,7 @@ void CL_FindExplosionPlane( const vec3_t origin, float radius, vec3_t result ); void CL_LightForPoint( const vec3_t point, vec3_t ambientLight ); int CL_SpawnDecal( HSPRITE m_hDecal, edict_t *pEnt, const vec3_t pos, int colorIndex, float roll, float scale ); void CL_AddDLight( const float *org, const float *rgb, float radius, float time, int flags, int key ); +void CL_AddSLight( const float *org, float *dir, float rad, float *cone, HSPRITE hLight, int key ); void CL_ParticleEffect( const vec3_t org, const vec3_t dir, int color, int count ); // q1 legacy void CL_SpawnStaticDecal( vec3_t origin, int decalIndex, int entityIndex, int modelIndex ); void CL_QueueEvent( int flags, int index, float delay, event_args_t *args ); diff --git a/engine/server/sv_move.c b/engine/server/sv_move.c index 7b3dd2fe..c450c829 100644 --- a/engine/server/sv_move.c +++ b/engine/server/sv_move.c @@ -264,9 +264,6 @@ bool SV_StepDirection( edict_t *ent, float yaw, float dist, int iMode ) vec3_t move, oldorigin; float delta; - ent->v.ideal_yaw = yaw; - pfnChangeYaw( ent ); - yaw = yaw * M_PI*2 / 360; VectorSet( move, com.cos( yaw ) * dist, com.sin( yaw ) * dist, 0.0f ); VectorCopy( ent->v.origin, oldorigin ); diff --git a/server/global/client.cpp b/server/global/client.cpp index 62c2b828..b1adb0d9 100644 --- a/server/global/client.cpp +++ b/server/global/client.cpp @@ -1506,7 +1506,7 @@ int AddToFullPack( edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflag { case ED_SKYPORTAL: return 1; // no additional check requires - case ED_BEAM: // FIXME: add check for beam bounding box + case ED_BEAM: case ED_MOVER: case ED_NORMAL: case ED_PORTAL: @@ -1541,15 +1541,22 @@ int AddToFullPack( edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflag } // check visibility - if( !ENGINE_CHECK_PVS( pEdict, pSet )) + if ( !ENGINE_CHECK_PVS( pEdict, pSet )) { float m_flRadius = 1024; // g-cont: tune distance by taste :) - if( pEntity->pev->armorvalue > 0 ) - m_flRadius = pEntity->pev->armorvalue; + if ( pEntity->pev->flags & FL_PHS_FILTER ) + { + if( pEntity->pev->armorvalue > 0 ) + m_flRadius = pEntity->pev->armorvalue; - if( pEntity->pev->flags & FL_PHS_FILTER && delta.Length() > m_flRadius ) + if( delta.Length() > m_flRadius ) + return 0; + } + else if( pEntity->m_iClassType != ED_BEAM ) + { return 0; + } } if( FNullEnt( pHost )) HOST_ERROR( "pHost == NULL\n" ); diff --git a/spirit/client.cpp b/spirit/client.cpp index b94d0dff..11b3b24c 100644 --- a/spirit/client.cpp +++ b/spirit/client.cpp @@ -1338,7 +1338,7 @@ int AddToFullPack( edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflag { case ED_SKYPORTAL: return 1; // no additional check requires - case ED_BEAM: // FIXME: add check for beam bounding box + case ED_BEAM: case ED_MOVER: case ED_NORMAL: case ED_PORTAL: @@ -1373,15 +1373,22 @@ int AddToFullPack( edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflag } // check visibility - if( !ENGINE_CHECK_PVS( pEdict, pSet )) + if ( !ENGINE_CHECK_PVS( pEdict, pSet )) { float m_flRadius = 1024; // g-cont: tune distance by taste :) - if( pEntity->pev->armorvalue > 0 ) - m_flRadius = pEntity->pev->armorvalue; + if ( pEntity->pev->flags & FL_PHS_FILTER ) + { + if( pEntity->pev->armorvalue > 0 ) + m_flRadius = pEntity->pev->armorvalue; - if( pEntity->pev->flags & FL_PHS_FILTER && delta.Length() > m_flRadius ) + if( delta.Length() > m_flRadius ) + return 0; + } + else if( pEntity->m_iClassType != ED_BEAM ) + { return 0; + } } if( FNullEnt( pHost )) HOST_ERROR( "pHost == NULL\n" ); diff --git a/spirit/effects.cpp b/spirit/effects.cpp index 36e5f33f..282a33f4 100644 --- a/spirit/effects.cpp +++ b/spirit/effects.cpp @@ -1073,6 +1073,8 @@ void CLaser::Spawn( void ) SetThink(&CLaser:: SUB_Remove ); return; } + + SetObjectClass( ED_BEAM ); pev->solid = SOLID_NOT; // Remove model & collisions Precache( ); diff --git a/spirit/weapons.cpp b/spirit/weapons.cpp index 31343b62..669c950a 100644 --- a/spirit/weapons.cpp +++ b/spirit/weapons.cpp @@ -505,6 +505,9 @@ void W_Precache(void) PRECACHE_MODEL ("sprites/muzzleflash2.spr"); PRECACHE_MODEL ("sprites/muzzleflash3.spr"); PRECACHE_MODEL ("sprites/muzzleflash.spr"); + + // ricochet + PRECACHE_MODEL ("sprites/richo1.spr"); // used by explosions PRECACHE_MODEL ("models/grenade.mdl"); diff --git a/spirit/world.cpp b/spirit/world.cpp index 9e38c897..3e8c32cb 100644 --- a/spirit/world.cpp +++ b/spirit/world.cpp @@ -534,6 +534,15 @@ void CWorld :: Precache( void ) ALERT ( at_debug, "**COULD NOT CREATE SOUNDENT**\n" ); } + if( pev->message != 0 ) + { + SET_SKYBOX( STRING( pev->message )); + } + else + { + SET_SKYBOX( "desert" ); // it's a default Half-Life skybox, right ? + } + InitBodyQue(); // init sentence group playback stuff from sentences.txt. @@ -668,7 +677,7 @@ void CWorld :: KeyValue( KeyValueData *pkvd ) if( FStrEq( pkvd->szKeyName, "skyname" )) { // Sent over net now. - SET_SKYBOX( pkvd->szValue ); + pev->message = ALLOC_STRING( pkvd->szValue ); pkvd->fHandled = TRUE; } else if ( FStrEq(pkvd->szKeyName, "sounds") ) diff --git a/todo.log b/todo.log index c1cfbb34..b821633b 100644 --- a/todo.log +++ b/todo.log @@ -20,40 +20,12 @@ fopen 1. Поддержка loop для ogg vorbis 2. переписать studiomdl для использования VFS -Beta 13.02.10 - -0. Implement gearcraft map format for bsplib OK -1. finalize LAN game menu (join the game) OK -2. finalize Create game menu (apply game settings) OK -3. fix items pickup sound bug OK -4. rewrite pfnDropToFloor OK -5. revision of all asserts OK -6. revision of all resources -7. fix loaders for ATI1N and ATI2N OK -8. fix sky changelevel bug -9. rewrote UI_Field code OK -10. autocomplete and command history for system console OK -11. create mutex for dedicated server OK -12. revision of Xash Environment System OK -13. implement temp-ents OK -14. implement realtime wind -15. fixup muzzleflashes OK -16. fix CL_GetEntityByIndex: invalid entindex OK -17. implement beams OK -18. implement filetime in file_t -19. complete lights.shader -20. rails2d.shader OK -20. merge abaddon.shader -21. implement all TE_* messages -22. final revision of ClientAPI OK -23. fix Egon and Gauss firing OK -24. revision server physic -25. revision monster moving -26. get rid of fakemirror stuff in spirit OK -27. rewrite engine particle system OK -28. rewrite engine decal system -29. rewrite engine dlight system -30. implemenet remaining tempents -31. fix crash on env_beam.map - +Xash 0.71 Beta 05.05.10 +1. revision of all resources +2. fix sky changelevel bug +3. implement filetime in file_t +4. complete lights.shader +5. revision server physic +6. revision monster moving +7. implement env_laser \ No newline at end of file diff --git a/vid_gl/r_backend.c b/vid_gl/r_backend.c index 6f95af0b..f5f28e55 100644 --- a/vid_gl/r_backend.c +++ b/vid_gl/r_backend.c @@ -3018,6 +3018,10 @@ R_DrawTriangles */ static void R_DrawTriangles( void ) { + // ignore triapi triangles for 'debug_surface' mode + if( triState.fActive && !gl_wireframe->integer && r_speeds->integer == 4 ) + return; + if( gl_wireframe->integer == 2 ) R_SetColorForOutlines(); diff --git a/vid_gl/r_draw.c b/vid_gl/r_draw.c index 3b6c2309..7ddf19c1 100644 --- a/vid_gl/r_draw.c +++ b/vid_gl/r_draw.c @@ -78,7 +78,7 @@ void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, f if( oldframe != glState.draw_frame ) { - if( pic_mbuffer.shaderkey != (int)shader->sortkey ) + if( pic_mbuffer.shaderkey != shader->sortkey ) { // will be rendering on next call oldframe = glState.draw_frame; @@ -239,8 +239,6 @@ static void Tri_DrawPolygon( void ) tri_mesh.colorsArray[0] = tri_colors; tri_mesh.elems = tri_elems; - triState.numVertex = triState.numIndex = triState.numColor = 0; - if( tri_mbuffer.shaderkey != (int)shader->sortkey || -tri_mbuffer.infokey-1+4 > MAX_ARRAY_VERTS ) { if( tri_mbuffer.shaderkey ) @@ -252,7 +250,7 @@ static void Tri_DrawPolygon( void ) tr.iRenderMode = triState.currentRenderMode; tri_mbuffer.shaderkey = shader->sortkey; - tri_mbuffer.infokey -= 4; + tri_mbuffer.infokey -= triState.numVertex; triState.features = shader->features; triState.features |= MF_COLORS; @@ -262,6 +260,15 @@ static void Tri_DrawPolygon( void ) if( triState.noCulling ) triState.features |= MF_NOCULL; + if( tri_mbuffer.shaderkey != shader->sortkey || -tri_mbuffer.infokey-1+4 > MAX_TRIVERTS ) + { + if( tri_mbuffer.shaderkey ) + { + tri_mbuffer.infokey = -1; + R_RenderMeshBuffer( &tri_mbuffer ); + } + } + // upload video right before rendering if( shader->flags & SHADER_VIDEOMAP ) R_UploadCinematicShader( shader ); @@ -269,7 +276,7 @@ static void Tri_DrawPolygon( void ) if( oldframe != glState.draw_frame ) { - if( tri_mbuffer.shaderkey != (int)shader->sortkey ) + if( tri_mbuffer.shaderkey != shader->sortkey ) { // will be rendering on next call oldframe = glState.draw_frame; @@ -282,6 +289,7 @@ static void Tri_DrawPolygon( void ) } oldframe = glState.draw_frame; } + triState.numVertex = triState.numIndex = triState.numColor = 0; } static void Tri_CheckOverflow( int numIndices, int numVertices ) diff --git a/vid_gl/r_surf.c b/vid_gl/r_surf.c index fe90b23d..0f812e3b 100644 --- a/vid_gl/r_surf.c +++ b/vid_gl/r_surf.c @@ -172,8 +172,8 @@ bool R_CullBrushModel( ref_entity_t *e ) { int i; bool rotated; - ref_model_t *model = e->model; - mbrushmodel_t *bmodel = ( mbrushmodel_t * )model->extradata; + ref_model_t *model = e->model; + mbrushmodel_t *bmodel = ( mbrushmodel_t *)model->extradata; if( bmodel->nummodelsurfaces == 0 ) return true; @@ -194,7 +194,7 @@ bool R_CullBrushModel( ref_entity_t *e ) rotated = false; VectorMA( e->origin, e->scale, model->mins, modelmins ); VectorMA( e->origin, e->scale, model->maxs, modelmaxs ); - if( R_CullBox( modelmins, modelmaxs, RI.clipFlags ) ) + if( R_CullBox( modelmins, modelmaxs, RI.clipFlags )) return true; } @@ -202,12 +202,12 @@ bool R_CullBrushModel( ref_entity_t *e ) { if( rotated ) { - if( R_VisCullSphere( e->origin, model->radius * e->scale ) ) + if( R_VisCullSphere( e->origin, model->radius * e->scale )) return true; } else { - if( R_VisCullBox( modelmins, modelmaxs ) ) + if( R_VisCullBox( modelmins, modelmaxs )) return true; } } diff --git a/xtools/bsplib/light.c b/xtools/bsplib/light.c index 99e0b6da..3894470c 100644 --- a/xtools/bsplib/light.c +++ b/xtools/bsplib/light.c @@ -227,7 +227,7 @@ void CreateEntityLights( void ) const char *value; float intensity, scale, deviance, filterRadius; int spawnflags, flags, numSamples; - bool junior, monolight; + bool junior, environment, monolight; double vec[4], col[3]; /* go throught entity list and find lights */ @@ -235,6 +235,7 @@ void CreateEntityLights( void ) { e = &entities[i]; name = ValueForKey( e, "classname" ); + environment = false; // check for lightJunior if( !com.strnicmp( name, "lightJunior", 11 )) @@ -242,6 +243,9 @@ void CreateEntityLights( void ) else if( !com.strnicmp( name, "light", 5 )) junior = false; else continue; + + if( !com.stricmp( name, "light_environment" )) + environment = true; // lights with target names (and therefore styles) are only parsed from BSP target = ValueForKey( e, "targetname" ); @@ -376,6 +380,41 @@ void CreateEntityLights( void ) ColorNormalize( light->color, light->color ); + if( environment ) + { + vec3_t angles; + sun_t sun; + + /* not a spot light */ + numPointLights--; + + /* unlink this light */ + lights = light->next; + + GetVectorForKey( e, "angles", angles ); + AngleVectors( angles, light->normal, NULL, NULL ); + value = ValueForKey( e, "pitch" ); // sun elevation + + /* make a sun */ + VectorScale( light->normal, -1.0f, sun.direction ); + VectorCopy( light->color, sun.color ); + sun.photons = (intensity / pointScale); + sun.deviance = com.atof( value ) / 180.0f * M_PI; + sun.numSamples = numSamples; + sun.style = noStyles ? LS_NORMAL : light->style; + sun.next = NULL; + + /* make a sun light */ + CreateSunLight( &sun ); + + /* free original light */ + Mem_Free( light ); + light = NULL; + + /* skip the rest of this love story */ + continue; + } + // set light scale (sof2) scale = FloatForKey( e, "scale" ); if( scale == 0.0f ) scale = 1.0f;