18 Mar 2010

This commit is contained in:
g-cont 2010-03-18 00:00:00 +03:00 committed by Alibek Omarov
parent c2797ee55e
commit 790df98906
26 changed files with 659 additions and 232 deletions

View File

@ -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

View File

@ -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

View File

@ -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 )
{

View File

@ -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 );

View File

@ -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 );

View File

@ -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;

View File

@ -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 );

View File

@ -12,7 +12,6 @@ typedef enum
BEAM_ENTPOINT,
BEAM_ENTS,
BEAM_HOSE,
BEAM_LASER,
} kBeamType_t;
// beam flags

View File

@ -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

View File

@ -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 );

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 )

View File

@ -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 );

View File

@ -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 );

View File

@ -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" );

View File

@ -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" );

View File

@ -1073,6 +1073,8 @@ void CLaser::Spawn( void )
SetThink(&CLaser:: SUB_Remove );
return;
}
SetObjectClass( ED_BEAM );
pev->solid = SOLID_NOT; // Remove model & collisions
Precache( );

View File

@ -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");

View File

@ -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") )

View File

@ -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

View File

@ -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();

View File

@ -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 )

View File

@ -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;
}
}

View File

@ -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;