2011-02-18 14:31:32 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Copyright ( C ) 1999 - 2005 Id Software , Inc .
2015-11-13 22:41:34 +00:00
Copyright ( C ) 2002 - 2015 Q3Rally Team ( Per Thormann - q3rally @ gmail . com )
2011-02-18 14:31:32 +00:00
This file is part of q3rally source code .
q3rally source code is free software ; you can redistribute it
and / or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation ; either version 2 of the License ,
or ( at your option ) any later version .
q3rally source code is distributed in the hope that it will be
useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with q3rally ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
//
// cg_ents.c -- present snapshot entities, happens every single frame
# include "cg_local.h"
// Q3Rally Code Start
// used to know when to update physics variables from server
//qboolean updateEnts;
// Q3Rally Code END
/*
= = = = = = = = = = = = = = = = = = = = = =
CG_PositionEntityOnTag
Modifies the entities position and axis by the given
tag location
= = = = = = = = = = = = = = = = = = = = = =
*/
void CG_PositionEntityOnTag ( refEntity_t * entity , const refEntity_t * parent ,
qhandle_t parentModel , char * tagName ) {
int i ;
orientation_t lerped ;
// lerp the tag
trap_R_LerpTag ( & lerped , parentModel , parent - > oldframe , parent - > frame ,
1.0 - parent - > backlerp , tagName ) ;
// FIXME: allow origin offsets along tag?
VectorCopy ( parent - > origin , entity - > origin ) ;
for ( i = 0 ; i < 3 ; i + + ) {
VectorMA ( entity - > origin , lerped . origin [ i ] , parent - > axis [ i ] , entity - > origin ) ;
}
// had to cast away the const to avoid compiler problems...
MatrixMultiply ( lerped . axis , ( ( refEntity_t * ) parent ) - > axis , entity - > axis ) ;
entity - > backlerp = parent - > backlerp ;
}
/*
= = = = = = = = = = = = = = = = = = = = = =
CG_PositionRotatedEntityOnTag
Modifies the entities position and axis by the given
tag location
= = = = = = = = = = = = = = = = = = = = = =
*/
void CG_PositionRotatedEntityOnTag ( refEntity_t * entity , const refEntity_t * parent ,
qhandle_t parentModel , char * tagName ) {
int i ;
orientation_t lerped ;
vec3_t tempAxis [ 3 ] ;
//AxisClear( entity->axis );
// lerp the tag
trap_R_LerpTag ( & lerped , parentModel , parent - > oldframe , parent - > frame ,
1.0 - parent - > backlerp , tagName ) ;
// FIXME: allow origin offsets along tag?
VectorCopy ( parent - > origin , entity - > origin ) ;
for ( i = 0 ; i < 3 ; i + + ) {
VectorMA ( entity - > origin , lerped . origin [ i ] , parent - > axis [ i ] , entity - > origin ) ;
}
// had to cast away the const to avoid compiler problems...
MatrixMultiply ( entity - > axis , lerped . axis , tempAxis ) ;
MatrixMultiply ( tempAxis , ( ( refEntity_t * ) parent ) - > axis , entity - > axis ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
FUNCTIONS CALLED EACH FRAME
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = = = = = = = =
CG_SetEntitySoundPosition
Also called by event processing code
= = = = = = = = = = = = = = = = = = = = = =
*/
void CG_SetEntitySoundPosition ( centity_t * cent ) {
if ( cent - > currentState . solid = = SOLID_BMODEL ) {
vec3_t origin ;
float * v ;
v = cgs . inlineModelMidpoints [ cent - > currentState . modelindex ] ;
VectorAdd ( cent - > lerpOrigin , v , origin ) ;
trap_S_UpdateEntityPosition ( cent - > currentState . number , origin ) ;
} else {
trap_S_UpdateEntityPosition ( cent - > currentState . number , cent - > lerpOrigin ) ;
}
}
/*
= = = = = = = = = = = = = = = = = =
CG_EntityEffects
Add continuous entity effects , like local entity emission and lighting
= = = = = = = = = = = = = = = = = =
*/
static void CG_EntityEffects ( centity_t * cent ) {
// update sound origins
CG_SetEntitySoundPosition ( cent ) ;
// add loop sound
2011-07-24 09:09:13 +00:00
if ( cent - > currentState . loopSound ) {
2011-02-18 14:31:32 +00:00
if ( cent - > currentState . eType ! = ET_SPEAKER ) {
trap_S_AddLoopingSound ( cent - > currentState . number , cent - > lerpOrigin , vec3_origin ,
cgs . gameSounds [ cent - > currentState . loopSound ] ) ;
} else {
trap_S_AddRealLoopingSound ( cent - > currentState . number , cent - > lerpOrigin , vec3_origin ,
cgs . gameSounds [ cent - > currentState . loopSound ] ) ;
}
}
2011-07-24 09:09:13 +00:00
else {
trap_S_StopLoopingSound ( cent - > currentState . number ) ;
}
2011-02-18 14:31:32 +00:00
// constant light glow
2011-07-26 08:52:24 +00:00
if ( cent - > currentState . constantLight )
{
2011-02-18 14:31:32 +00:00
int cl ;
2011-07-26 08:52:24 +00:00
float i , r , g , b ;
2011-02-18 14:31:32 +00:00
cl = cent - > currentState . constantLight ;
2011-07-26 08:52:24 +00:00
r = ( float ) ( cl & 0xFF ) / 255.0 ;
g = ( float ) ( ( cl > > 8 ) & 0xFF ) / 255.0 ;
b = ( float ) ( ( cl > > 16 ) & 0xFF ) / 255.0 ;
i = ( float ) ( ( cl > > 24 ) & 0xFF ) * 4.0 ;
trap_R_AddLightToScene ( cent - > lerpOrigin , i , r , g , b ) ;
2011-02-18 14:31:32 +00:00
}
}
/*
= = = = = = = = = = = = = = = = = =
CG_General
= = = = = = = = = = = = = = = = = =
*/
static void CG_General ( centity_t * cent ) {
refEntity_t ent ;
entityState_t * s1 ;
s1 = & cent - > currentState ;
// if set to invisible, skip
if ( ! s1 - > modelindex ) {
return ;
}
memset ( & ent , 0 , sizeof ( ent ) ) ;
// set frame
ent . frame = s1 - > frame ;
ent . oldframe = ent . frame ;
ent . backlerp = 0 ;
VectorCopy ( cent - > lerpOrigin , ent . origin ) ;
VectorCopy ( cent - > lerpOrigin , ent . oldorigin ) ;
ent . hModel = cgs . gameModels [ s1 - > modelindex ] ;
// player model
if ( s1 - > number = = cg . snap - > ps . clientNum ) {
ent . renderfx | = RF_THIRD_PERSON ; // only draw from mirrors
}
// convert angles to axis
AnglesToAxis ( cent - > lerpAngles , ent . axis ) ;
// add to refresh list
trap_R_AddRefEntityToScene ( & ent ) ;
}
/*
= = = = = = = = = = = = = = = = = =
CG_Speaker
Speaker entities can automatically play sounds
= = = = = = = = = = = = = = = = = =
*/
static void CG_Speaker ( centity_t * cent ) {
if ( ! cent - > currentState . clientNum ) { // FIXME: use something other than clientNum...
return ; // not auto triggering
}
if ( cg . time < cent - > miscTime ) {
return ;
}
trap_S_StartSound ( NULL , cent - > currentState . number , CHAN_ITEM , cgs . gameSounds [ cent - > currentState . eventParm ] ) ;
// ent->s.frame = ent->wait * 10;
// ent->s.clientNum = ent->random * 10;
cent - > miscTime = cg . time + cent - > currentState . frame * 100 + cent - > currentState . clientNum * 100 * crandom ( ) ;
}
/*
= = = = = = = = = = = = = = = = = =
CG_Item
= = = = = = = = = = = = = = = = = =
*/
static void CG_Item ( centity_t * cent ) {
refEntity_t ent ;
entityState_t * es ;
gitem_t * item ;
int msec ;
float frac ;
float scale ;
weaponInfo_t * wi ;
es = & cent - > currentState ;
if ( es - > modelindex > = bg_numItems ) {
CG_Error ( " Bad item index %i on entity " , es - > modelindex ) ;
}
// if set to invisible, skip
if ( ! es - > modelindex | | ( es - > eFlags & EF_NODRAW ) ) {
return ;
}
item = & bg_itemlist [ es - > modelindex ] ;
if ( cg_simpleItems . integer & & item - > giType ! = IT_TEAM ) {
memset ( & ent , 0 , sizeof ( ent ) ) ;
ent . reType = RT_SPRITE ;
VectorCopy ( cent - > lerpOrigin , ent . origin ) ;
ent . radius = 14 ;
ent . customShader = cg_items [ es - > modelindex ] . icon ;
ent . shaderRGBA [ 0 ] = 255 ;
ent . shaderRGBA [ 1 ] = 255 ;
ent . shaderRGBA [ 2 ] = 255 ;
ent . shaderRGBA [ 3 ] = 255 ;
trap_R_AddRefEntityToScene ( & ent ) ;
return ;
}
// items bob up and down continuously
scale = 0.005 + cent - > currentState . number * 0.00001 ;
cent - > lerpOrigin [ 2 ] + = 4 + cos ( ( cg . time + 1000 ) * scale ) * 4 ;
memset ( & ent , 0 , sizeof ( ent ) ) ;
// autorotate at one of two speeds
if ( item - > giType = = IT_HEALTH ) {
VectorCopy ( cg . autoAnglesFast , cent - > lerpAngles ) ;
AxisCopy ( cg . autoAxisFast , ent . axis ) ;
} else {
VectorCopy ( cg . autoAngles , cent - > lerpAngles ) ;
AxisCopy ( cg . autoAxis , ent . axis ) ;
}
wi = NULL ;
// the weapons have their origin where they attatch to player
// models, so we need to offset them or they will rotate
// eccentricly
if ( item - > giType = = IT_WEAPON ) {
wi = & cg_weapons [ item - > giTag ] ;
cent - > lerpOrigin [ 0 ] - =
wi - > weaponMidpoint [ 0 ] * ent . axis [ 0 ] [ 0 ] +
wi - > weaponMidpoint [ 1 ] * ent . axis [ 1 ] [ 0 ] +
wi - > weaponMidpoint [ 2 ] * ent . axis [ 2 ] [ 0 ] ;
cent - > lerpOrigin [ 1 ] - =
wi - > weaponMidpoint [ 0 ] * ent . axis [ 0 ] [ 1 ] +
wi - > weaponMidpoint [ 1 ] * ent . axis [ 1 ] [ 1 ] +
wi - > weaponMidpoint [ 2 ] * ent . axis [ 2 ] [ 1 ] ;
cent - > lerpOrigin [ 2 ] - =
wi - > weaponMidpoint [ 0 ] * ent . axis [ 0 ] [ 2 ] +
wi - > weaponMidpoint [ 1 ] * ent . axis [ 1 ] [ 2 ] +
wi - > weaponMidpoint [ 2 ] * ent . axis [ 2 ] [ 2 ] ;
cent - > lerpOrigin [ 2 ] + = 8 ; // an extra height boost
}
2011-07-26 08:52:24 +00:00
if ( item - > giType = = IT_WEAPON & & item - > giTag = = WP_RAILGUN ) {
clientInfo_t * ci = & cgs . clientinfo [ cg . snap - > ps . clientNum ] ;
Byte4Copy ( ci - > c1RGBA , ent . shaderRGBA ) ;
}
2011-02-18 14:31:32 +00:00
ent . hModel = cg_items [ es - > modelindex ] . models [ 0 ] ;
VectorCopy ( cent - > lerpOrigin , ent . origin ) ;
VectorCopy ( cent - > lerpOrigin , ent . oldorigin ) ;
ent . nonNormalizedAxes = qfalse ;
// if just respawned, slowly scale up
msec = cg . time - cent - > miscTime ;
if ( msec > = 0 & & msec < ITEM_SCALEUP_TIME ) {
frac = ( float ) msec / ITEM_SCALEUP_TIME ;
VectorScale ( ent . axis [ 0 ] , frac , ent . axis [ 0 ] ) ;
VectorScale ( ent . axis [ 1 ] , frac , ent . axis [ 1 ] ) ;
VectorScale ( ent . axis [ 2 ] , frac , ent . axis [ 2 ] ) ;
ent . nonNormalizedAxes = qtrue ;
} else {
frac = 1.0 ;
}
// items without glow textures need to keep a minimum light value
// so they are always visible
// Q3Rally Code Start
// if ( ( item->giType == IT_WEAPON ) || ( item->giType == IT_ARMOR ) ) {
if ( ( item - > giType = = IT_WEAPON ) | | ( item - > giType = = IT_RFWEAPON ) | |
( item - > giType = = IT_ARMOR ) ) {
// Q3Rally Code END
ent . renderfx | = RF_MINLIGHT ;
}
// increase the size of the weapons when they are presented as items
if ( item - > giType = = IT_WEAPON ) {
VectorScale ( ent . axis [ 0 ] , 1.5 , ent . axis [ 0 ] ) ;
VectorScale ( ent . axis [ 1 ] , 1.5 , ent . axis [ 1 ] ) ;
VectorScale ( ent . axis [ 2 ] , 1.5 , ent . axis [ 2 ] ) ;
ent . nonNormalizedAxes = qtrue ;
# ifdef MISSIONPACK
trap_S_AddLoopingSound ( cent - > currentState . number , cent - > lerpOrigin , vec3_origin , cgs . media . weaponHoverSound ) ;
# endif
}
# ifdef MISSIONPACK
if ( item - > giType = = IT_HOLDABLE & & item - > giTag = = HI_KAMIKAZE ) {
VectorScale ( ent . axis [ 0 ] , 2 , ent . axis [ 0 ] ) ;
VectorScale ( ent . axis [ 1 ] , 2 , ent . axis [ 1 ] ) ;
VectorScale ( ent . axis [ 2 ] , 2 , ent . axis [ 2 ] ) ;
ent . nonNormalizedAxes = qtrue ;
}
# endif
// Q3Rally Code Start
ent . origin [ 2 ] + = 6 ;
// Q3Rally Code END
// add to refresh list
trap_R_AddRefEntityToScene ( & ent ) ;
2017-07-10 01:33:41 +00:00
if ( item - > giType = = IT_WEAPON & & wi & & wi - > barrelModel ) {
2011-02-18 14:31:32 +00:00
refEntity_t barrel ;
2017-07-10 01:33:41 +00:00
vec3_t angles ;
2011-02-18 14:31:32 +00:00
memset ( & barrel , 0 , sizeof ( barrel ) ) ;
barrel . hModel = wi - > barrelModel ;
VectorCopy ( ent . lightingOrigin , barrel . lightingOrigin ) ;
barrel . shadowPlane = ent . shadowPlane ;
barrel . renderfx = ent . renderfx ;
2017-07-10 01:33:41 +00:00
angles [ YAW ] = 0 ;
angles [ PITCH ] = 0 ;
angles [ ROLL ] = 0 ;
AnglesToAxis ( angles , barrel . axis ) ;
2011-02-18 14:31:32 +00:00
CG_PositionRotatedEntityOnTag ( & barrel , & ent , wi - > weaponModel , " tag_barrel " ) ;
barrel . nonNormalizedAxes = ent . nonNormalizedAxes ;
trap_R_AddRefEntityToScene ( & barrel ) ;
}
// accompanying rings / spheres for powerups
if ( ! cg_simpleItems . integer )
{
vec3_t spinAngles ;
VectorClear ( spinAngles ) ;
// Q3Rally Code Start
// if ( item->giType == IT_HEALTH || item->giType == IT_POWERUP )
if ( item - > giType = = IT_HEALTH | | item - > giType = = IT_POWERUP | | item - > giTag = = HI_TURBO )
// Q3Rally Code END
{
if ( ( ent . hModel = cg_items [ es - > modelindex ] . models [ 1 ] ) ! = 0 )
{
// Q3Rally Code Start
/*
if ( item - > giType = = IT_POWERUP )
{
ent . origin [ 2 ] + = 12 ;
spinAngles [ 1 ] = ( cg . time & 1023 ) * 360 / - 1024.0f ;
}
*/
if ( item - > giType = = IT_POWERUP | | item - > giTag = = HI_TURBO )
{
spinAngles [ ROLL ] = ( ( cg . time / 2 ) & 1023 ) * 360 / - 1024.0f ;
spinAngles [ 1 ] = ( ( cg . time / 2 ) & 1023 ) * 360 / - 1024.0f ;
}
// Q3Rally Code END
AnglesToAxis ( spinAngles , ent . axis ) ;
// scale up if respawning
if ( frac ! = 1.0 ) {
VectorScale ( ent . axis [ 0 ] , frac , ent . axis [ 0 ] ) ;
VectorScale ( ent . axis [ 1 ] , frac , ent . axis [ 1 ] ) ;
VectorScale ( ent . axis [ 2 ] , frac , ent . axis [ 2 ] ) ;
ent . nonNormalizedAxes = qtrue ;
}
trap_R_AddRefEntityToScene ( & ent ) ;
}
}
}
// Q3Rally Code Start
if ( ! cg_simpleItems . integer )
{
vec3_t spinAngles ;
VectorClear ( spinAngles ) ;
if ( item - > giTag = = PW_HASTE ) {
if ( ( ent . hModel = cg_items [ es - > modelindex ] . models [ 2 ] ) ! = 0 )
{
AxisCopy ( cg . autoAxis , ent . axis ) ;
// scale up if respawning
if ( frac ! = 1.0 ) {
VectorScale ( ent . axis [ 0 ] , frac , ent . axis [ 0 ] ) ;
VectorScale ( ent . axis [ 1 ] , frac , ent . axis [ 1 ] ) ;
VectorScale ( ent . axis [ 2 ] , frac , ent . axis [ 2 ] ) ;
ent . nonNormalizedAxes = qtrue ;
}
trap_R_AddRefEntityToScene ( & ent ) ;
}
}
}
// Q3Rally Code END
}
//============================================================================
/*
= = = = = = = = = = = = = = =
CG_Missile
= = = = = = = = = = = = = = =
*/
static void CG_Missile ( centity_t * cent ) {
refEntity_t ent ;
entityState_t * s1 ;
const weaponInfo_t * weapon ;
// int col;
s1 = & cent - > currentState ;
2011-07-26 08:52:24 +00:00
if ( s1 - > weapon > = WP_NUM_WEAPONS ) {
2011-02-18 14:31:32 +00:00
s1 - > weapon = 0 ;
}
weapon = & cg_weapons [ s1 - > weapon ] ;
// calculate the axis
VectorCopy ( s1 - > angles , cent - > lerpAngles ) ;
// add trails
if ( weapon - > missileTrailFunc )
{
weapon - > missileTrailFunc ( cent , weapon ) ;
}
/*
if ( cent - > currentState . modelindex = = TEAM_RED ) {
col = 1 ;
}
else if ( cent - > currentState . modelindex = = TEAM_BLUE ) {
col = 2 ;
}
else {
col = 0 ;
}
// add dynamic light
if ( weapon - > missileDlight ) {
trap_R_AddLightToScene ( cent - > lerpOrigin , weapon - > missileDlight ,
weapon - > missileDlightColor [ col ] [ 0 ] , weapon - > missileDlightColor [ col ] [ 1 ] , weapon - > missileDlightColor [ col ] [ 2 ] ) ;
}
*/
// add dynamic light
if ( weapon - > missileDlight ) {
trap_R_AddLightToScene ( cent - > lerpOrigin , weapon - > missileDlight ,
weapon - > missileDlightColor [ 0 ] , weapon - > missileDlightColor [ 1 ] , weapon - > missileDlightColor [ 2 ] ) ;
}
// add missile sound
if ( weapon - > missileSound ) {
vec3_t velocity ;
BG_EvaluateTrajectoryDelta ( & cent - > currentState . pos , cg . time , velocity ) ;
trap_S_AddLoopingSound ( cent - > currentState . number , cent - > lerpOrigin , velocity , weapon - > missileSound ) ;
}
// create the render entity
memset ( & ent , 0 , sizeof ( ent ) ) ;
VectorCopy ( cent - > lerpOrigin , ent . origin ) ;
VectorCopy ( cent - > lerpOrigin , ent . oldorigin ) ;
if ( cent - > currentState . weapon = = WP_PLASMAGUN ) {
ent . reType = RT_SPRITE ;
ent . radius = 16 ;
ent . rotation = 0 ;
ent . customShader = cgs . media . plasmaBallShader ;
trap_R_AddRefEntityToScene ( & ent ) ;
return ;
}
if ( cent - > currentState . weapon = = WP_FLAME_THROWER ) {
ent . reType = RT_SPRITE ;
ent . radius = 32 ;
ent . rotation = 0 ;
ent . customShader = cgs . media . flameBallShader ;
trap_R_AddRefEntityToScene ( & ent ) ;
return ;
}
// Q3Rally Code Start
if ( cent - > currentState . weapon = = RWP_MINE ) {
if ( cgs . gametype > = GT_TEAM ) {
switch ( cgs . clientinfo [ cent - > currentState . otherEntityNum ] . team ) {
default :
case TEAM_RED :
ent . customSkin = trap_R_RegisterSkin ( " models/rearfire/red.skin " ) ;
break ;
case TEAM_BLUE :
ent . customSkin = trap_R_RegisterSkin ( " models/rearfire/blue.skin " ) ;
break ;
case TEAM_GREEN :
ent . customSkin = trap_R_RegisterSkin ( " models/rearfire/green.skin " ) ;
break ;
case TEAM_YELLOW :
ent . customSkin = trap_R_RegisterSkin ( " models/rearfire/yellow.skin " ) ;
break ;
}
}
else {
ent . skinNum = 0 ;
}
}
else {
// flicker between two skins
ent . skinNum = cg . clientFrame & 1 ;
}
//ent.skinNum = cg.clientFrame & 1;
// Q3Rally Code END
ent . hModel = weapon - > missileModel ;
ent . renderfx = weapon - > missileRenderfx | RF_NOSHADOW ;
# ifdef MISSIONPACK
if ( cent - > currentState . weapon = = WP_PROX_LAUNCHER ) {
if ( s1 - > generic1 = = TEAM_BLUE ) {
ent . hModel = cgs . media . blueProxMine ;
}
}
# endif
// convert direction of travel into axis
if ( VectorNormalize2 ( s1 - > pos . trDelta , ent . axis [ 0 ] ) = = 0 ) {
// Q3Rally Code Start
if ( cent - > currentState . weapon = = RWP_MINE )
AxisClear ( ent . axis ) ;
else
// Q3Rally Code END
ent . axis [ 0 ] [ 2 ] = 1 ;
}
// spin as it moves
if ( s1 - > pos . trType ! = TR_STATIONARY ) {
RotateAroundDirection ( ent . axis , cg . time / 4 ) ;
} else {
# ifdef MISSIONPACK
if ( s1 - > weapon = = WP_PROX_LAUNCHER ) {
AnglesToAxis ( cent - > lerpAngles , ent . axis ) ;
}
else
# endif
{
RotateAroundDirection ( ent . axis , s1 - > time ) ;
}
}
// add to refresh list, possibly with quad glow
CG_AddRefEntityWithPowerups ( & ent , s1 , TEAM_FREE ) ;
}
/*
= = = = = = = = = = = = = = =
CG_Grapple
This is called when the grapple is sitting up against the wall
= = = = = = = = = = = = = = =
*/
// Q3Rally Code Start - removed
/*
static void CG_Grapple ( centity_t * cent ) {
refEntity_t ent ;
entityState_t * s1 ;
const weaponInfo_t * weapon ;
s1 = & cent - > currentState ;
2011-07-26 08:52:24 +00:00
if ( s1 - > weapon > = WP_NUM_WEAPONS ) {
2011-02-18 14:31:32 +00:00
s1 - > weapon = 0 ;
}
weapon = & cg_weapons [ s1 - > weapon ] ;
// calculate the axis
VectorCopy ( s1 - > angles , cent - > lerpAngles ) ;
#if 0 // FIXME add grapple pull sound here..?
// add missile sound
if ( weapon - > missileSound ) {
trap_S_AddLoopingSound ( cent - > currentState . number , cent - > lerpOrigin , vec3_origin , weapon - > missileSound ) ;
}
# endif
// Will draw cable if needed
CG_GrappleTrail ( cent , weapon ) ;
// create the render entity
memset ( & ent , 0 , sizeof ( ent ) ) ;
VectorCopy ( cent - > lerpOrigin , ent . origin ) ;
VectorCopy ( cent - > lerpOrigin , ent . oldorigin ) ;
// flicker between two skins
ent . skinNum = cg . clientFrame & 1 ;
ent . hModel = weapon - > missileModel ;
ent . renderfx = weapon - > missileRenderfx | RF_NOSHADOW ;
// convert direction of travel into axis
if ( VectorNormalize2 ( s1 - > pos . trDelta , ent . axis [ 0 ] ) = = 0 ) {
ent . axis [ 0 ] [ 2 ] = 1 ;
}
trap_R_AddRefEntityToScene ( & ent ) ;
}
*/
/* Q3Rally Code Start
= = = = = = = = = = = = = = = = = =
CG_Auxent
car wheel entities
= = = = = = = = = = = = = = = = = =
*/
static void CG_Auxent ( centity_t * cent ) {
refEntity_t ent ;
entityState_t * s1 ;
s1 = & cent - > currentState ;
if ( s1 - > otherEntityNum = = cg . snap - > ps . clientNum & & ! cg . newSnap )
return ;
cg_entities [ s1 - > otherEntityNum ] . wheelSpeeds [ s1 - > otherEntityNum2 ] = s1 - > apos . trDelta [ 0 ] ;
cg_entities [ s1 - > otherEntityNum ] . wheelSkidding [ s1 - > otherEntityNum2 ] = s1 - > frame ;
cg_entities [ s1 - > otherEntityNum ] . steeringAngle = s1 - > apos . trDelta [ 1 ] ;
if ( s1 - > otherEntityNum = = cg . snap - > ps . clientNum ) {
// Com_Printf("updating wheels\n");
cg . car . sPoints [ s1 - > otherEntityNum2 ] . w = s1 - > apos . trDelta [ 0 ] ;
cg . car . sPoints [ s1 - > otherEntityNum2 ] . slipping = s1 - > frame ;
cg . car . wheelAngle = s1 - > apos . trDelta [ 1 ] ;
VectorCopy ( s1 - > pos . trBase , cg . car . sPoints [ s1 - > otherEntityNum2 ] . r ) ;
VectorCopy ( s1 - > pos . trDelta , cg . car . sPoints [ s1 - > otherEntityNum2 ] . v ) ;
VectorCopy ( s1 - > origin2 , cg . car . sPoints [ s1 - > otherEntityNum2 ] . normals [ 0 ] ) ;
cg . car . sPoints [ s1 - > otherEntityNum2 ] . onGround = s1 - > groundEntityNum ;
}
// if set to invisible, skip
if ( ! s1 - > modelindex ) {
return ;
}
memset ( & ent , 0 , sizeof ( ent ) ) ;
// set frame
ent . frame = s1 - > frame ;
ent . oldframe = ent . frame ;
ent . backlerp = 0 ;
VectorCopy ( cent - > lerpOrigin , ent . origin ) ;
VectorCopy ( cent - > lerpOrigin , ent . oldorigin ) ;
ent . hModel = cgs . gameModels [ s1 - > modelindex ] ;
// player model
if ( s1 - > number = = cg . snap - > ps . clientNum ) {
ent . renderfx | = RF_THIRD_PERSON ; // only draw from mirrors
}
// convert angles to axis
AnglesToAxis ( cent - > lerpAngles , ent . axis ) ;
// add to refresh list
trap_R_AddRefEntityToScene ( & ent ) ;
}
/*
= = = = = = = = = = = = = = = = = =
CG_Weather
= = = = = = = = = = = = = = = = = =
*/
static void CG_Weather ( centity_t * cent ) {
entityState_t * s1 ;
s1 = & cent - > currentState ;
// CG_EffectParse( "T=RAIN,B=5 10,C=0.5,G=0.5 2,BV=0,GV=0 100,W=1 2,D=300" );
CG_Atmospheric_SetParticles ( s1 - > weapon , s1 - > powerups , s1 - > legsAnim ) ;
}
// Q3Rally Code END
/*
= = = = = = = = = = = = = = =
CG_Mover
= = = = = = = = = = = = = = =
*/
static void CG_Mover ( centity_t * cent ) {
refEntity_t ent ;
entityState_t * s1 ;
s1 = & cent - > currentState ;
// create the render entity
memset ( & ent , 0 , sizeof ( ent ) ) ;
VectorCopy ( cent - > lerpOrigin , ent . origin ) ;
VectorCopy ( cent - > lerpOrigin , ent . oldorigin ) ;
AnglesToAxis ( cent - > lerpAngles , ent . axis ) ;
ent . renderfx = RF_NOSHADOW ;
// flicker between two skins (FIXME?)
ent . skinNum = ( cg . time > > 6 ) & 1 ;
// get the model, either as a bmodel or a modelindex
if ( s1 - > solid = = SOLID_BMODEL ) {
ent . hModel = cgs . inlineDrawModel [ s1 - > modelindex ] ;
} else {
ent . hModel = cgs . gameModels [ s1 - > modelindex ] ;
}
// add to refresh list
trap_R_AddRefEntityToScene ( & ent ) ;
// add the secondary model
if ( s1 - > modelindex2 ) {
ent . skinNum = 0 ;
ent . hModel = cgs . gameModels [ s1 - > modelindex2 ] ;
trap_R_AddRefEntityToScene ( & ent ) ;
}
}
/*
= = = = = = = = = = = = = = =
CG_Beam
Also called as an event
= = = = = = = = = = = = = = =
*/
void CG_Beam ( centity_t * cent ) {
refEntity_t ent ;
entityState_t * s1 ;
s1 = & cent - > currentState ;
// create the render entity
memset ( & ent , 0 , sizeof ( ent ) ) ;
VectorCopy ( s1 - > pos . trBase , ent . origin ) ;
VectorCopy ( s1 - > origin2 , ent . oldorigin ) ;
AxisClear ( ent . axis ) ;
ent . reType = RT_BEAM ;
ent . renderfx = RF_NOSHADOW ;
// add to refresh list
trap_R_AddRefEntityToScene ( & ent ) ;
}
/*
= = = = = = = = = = = = = = =
CG_Portal
= = = = = = = = = = = = = = =
*/
static void CG_Portal ( centity_t * cent ) {
refEntity_t ent ;
entityState_t * s1 ;
s1 = & cent - > currentState ;
// create the render entity
memset ( & ent , 0 , sizeof ( ent ) ) ;
VectorCopy ( cent - > lerpOrigin , ent . origin ) ;
VectorCopy ( s1 - > origin2 , ent . oldorigin ) ;
ByteToDir ( s1 - > eventParm , ent . axis [ 0 ] ) ;
PerpendicularVector ( ent . axis [ 1 ] , ent . axis [ 0 ] ) ;
// negating this tends to get the directions like they want
// we really should have a camera roll value
VectorSubtract ( vec3_origin , ent . axis [ 1 ] , ent . axis [ 1 ] ) ;
CrossProduct ( ent . axis [ 0 ] , ent . axis [ 1 ] , ent . axis [ 2 ] ) ;
ent . reType = RT_PORTALSURFACE ;
ent . oldframe = s1 - > powerups ;
ent . frame = s1 - > frame ; // rotation speed
ent . skinNum = s1 - > clientNum / 256.0 * 360 ; // roll offset
// add to refresh list
trap_R_AddRefEntityToScene ( & ent ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = =
CG_AdjustPositionForMover
Also called by client movement prediction code
= = = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-09-15 03:03:44 +00:00
void CG_AdjustPositionForMover ( const vec3_t in , int moverNum , int fromTime , int toTime , vec3_t out , vec3_t angles_in , vec3_t angles_out ) {
2011-02-18 14:31:32 +00:00
centity_t * cent ;
vec3_t oldOrigin , origin , deltaOrigin ;
2012-09-15 03:03:44 +00:00
vec3_t oldAngles , angles , deltaAngles ;
2011-02-18 14:31:32 +00:00
if ( moverNum < = 0 | | moverNum > = ENTITYNUM_MAX_NORMAL ) {
VectorCopy ( in , out ) ;
2012-09-15 03:03:44 +00:00
VectorCopy ( angles_in , angles_out ) ;
2011-02-18 14:31:32 +00:00
return ;
}
cent = & cg_entities [ moverNum ] ;
if ( cent - > currentState . eType ! = ET_MOVER ) {
VectorCopy ( in , out ) ;
2012-09-15 03:03:44 +00:00
VectorCopy ( angles_in , angles_out ) ;
2011-02-18 14:31:32 +00:00
return ;
}
BG_EvaluateTrajectory ( & cent - > currentState . pos , fromTime , oldOrigin ) ;
BG_EvaluateTrajectory ( & cent - > currentState . apos , fromTime , oldAngles ) ;
BG_EvaluateTrajectory ( & cent - > currentState . pos , toTime , origin ) ;
BG_EvaluateTrajectory ( & cent - > currentState . apos , toTime , angles ) ;
VectorSubtract ( origin , oldOrigin , deltaOrigin ) ;
2012-09-15 03:03:44 +00:00
VectorSubtract ( angles , oldAngles , deltaAngles ) ;
2011-02-18 14:31:32 +00:00
VectorAdd ( in , deltaOrigin , out ) ;
2012-09-15 03:03:44 +00:00
VectorAdd ( angles_in , deltaAngles , angles_out ) ;
2011-02-18 14:31:32 +00:00
// FIXME: origin change when on a rotating object
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = =
CG_InterpolateEntityPosition
= = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
static void CG_InterpolateEntityPosition ( centity_t * cent ) {
vec3_t current , next ;
float f ;
// it would be an internal error to find an entity that interpolates without
// a snapshot ahead of the current one
if ( cg . nextSnap = = NULL ) {
CG_Error ( " CG_InterpoateEntityPosition: cg.nextSnap == NULL " ) ;
}
f = cg . frameInterpolation ;
// this will linearize a sine or parabolic curve, but it is important
// to not extrapolate player positions if more recent data is available
BG_EvaluateTrajectory ( & cent - > currentState . pos , cg . snap - > serverTime , current ) ;
BG_EvaluateTrajectory ( & cent - > nextState . pos , cg . nextSnap - > serverTime , next ) ;
cent - > lerpOrigin [ 0 ] = current [ 0 ] + f * ( next [ 0 ] - current [ 0 ] ) ;
cent - > lerpOrigin [ 1 ] = current [ 1 ] + f * ( next [ 1 ] - current [ 1 ] ) ;
cent - > lerpOrigin [ 2 ] = current [ 2 ] + f * ( next [ 2 ] - current [ 2 ] ) ;
BG_EvaluateTrajectory ( & cent - > currentState . apos , cg . snap - > serverTime , current ) ;
BG_EvaluateTrajectory ( & cent - > nextState . apos , cg . nextSnap - > serverTime , next ) ;
cent - > lerpAngles [ 0 ] = LerpAngle ( current [ 0 ] , next [ 0 ] , f ) ;
cent - > lerpAngles [ 1 ] = LerpAngle ( current [ 1 ] , next [ 1 ] , f ) ;
cent - > lerpAngles [ 2 ] = LerpAngle ( current [ 2 ] , next [ 2 ] , f ) ;
}
/*
= = = = = = = = = = = = = = =
CG_CalcEntityLerpPositions
= = = = = = = = = = = = = = =
*/
static void CG_CalcEntityLerpPositions ( centity_t * cent ) {
// if this player does not want to see extrapolated players
if ( ! cg_smoothClients . integer ) {
// make sure the clients use TR_INTERPOLATE
if ( cent - > currentState . number < MAX_CLIENTS ) {
cent - > currentState . pos . trType = TR_INTERPOLATE ;
cent - > nextState . pos . trType = TR_INTERPOLATE ;
// Q3Rally Code Start
cent - > currentState . apos . trType = TR_INTERPOLATE ;
cent - > nextState . apos . trType = TR_INTERPOLATE ;
// Q3Rally Code END
}
}
if ( cent - > interpolate & & cent - > currentState . pos . trType = = TR_INTERPOLATE ) {
CG_InterpolateEntityPosition ( cent ) ;
return ;
}
// first see if we can interpolate between two snaps for
// linear extrapolated clients
if ( cent - > interpolate & & cent - > currentState . pos . trType = = TR_LINEAR_STOP & &
cent - > currentState . number < MAX_CLIENTS ) {
CG_InterpolateEntityPosition ( cent ) ;
return ;
}
// just use the current frame and evaluate as best we can
BG_EvaluateTrajectory ( & cent - > currentState . pos , cg . time , cent - > lerpOrigin ) ;
BG_EvaluateTrajectory ( & cent - > currentState . apos , cg . time , cent - > lerpAngles ) ;
// Q3Rally Code Start
/*
if ( ! cg_paused . integer & &
cent - > currentState . number < MAX_CLIENTS & &
cent - > currentState . number ! = cg . snap - > ps . clientNum )
{
Com_Printf ( " angles %f %f %f \n " , cent - > lerpAngles [ 0 ] , cent - > lerpAngles [ 1 ] , cent - > lerpAngles [ 2 ] ) ;
}
*/
// Q3Rally Code END
// adjust for riding a mover if it wasn't rolled into the predicted
// player state
if ( cent ! = & cg . predictedPlayerEntity ) {
CG_AdjustPositionForMover ( cent - > lerpOrigin , cent - > currentState . groundEntityNum ,
2012-09-15 03:03:44 +00:00
cg . snap - > serverTime , cg . time , cent - > lerpOrigin , cent - > lerpAngles , cent - > lerpAngles ) ;
2011-02-18 14:31:32 +00:00
}
}
/*
= = = = = = = = = = = = = = =
CG_TeamBase
= = = = = = = = = = = = = = =
*/
static void CG_TeamBase ( centity_t * cent ) {
refEntity_t model ;
# ifdef MISSIONPACK
vec3_t angles ;
int t , h ;
float c ;
if ( cgs . gametype = = GT_CTF | | cgs . gametype = = GT_1FCTF ) {
# else
if ( cgs . gametype = = GT_CTF ) {
# endif
// show the flag base
memset ( & model , 0 , sizeof ( model ) ) ;
model . reType = RT_MODEL ;
VectorCopy ( cent - > lerpOrigin , model . lightingOrigin ) ;
VectorCopy ( cent - > lerpOrigin , model . origin ) ;
AnglesToAxis ( cent - > currentState . angles , model . axis ) ;
if ( cent - > currentState . modelindex = = TEAM_RED ) {
model . hModel = cgs . media . redFlagBaseModel ;
}
else if ( cent - > currentState . modelindex = = TEAM_BLUE ) {
model . hModel = cgs . media . blueFlagBaseModel ;
}
else {
model . hModel = cgs . media . neutralFlagBaseModel ;
}
trap_R_AddRefEntityToScene ( & model ) ;
}
# ifdef MISSIONPACK
else if ( cgs . gametype = = GT_OBELISK ) {
// show the obelisk
memset ( & model , 0 , sizeof ( model ) ) ;
model . reType = RT_MODEL ;
VectorCopy ( cent - > lerpOrigin , model . lightingOrigin ) ;
VectorCopy ( cent - > lerpOrigin , model . origin ) ;
AnglesToAxis ( cent - > currentState . angles , model . axis ) ;
model . hModel = cgs . media . overloadBaseModel ;
trap_R_AddRefEntityToScene ( & model ) ;
// if hit
if ( cent - > currentState . frame = = 1 ) {
// show hit model
// modelindex2 is the health value of the obelisk
c = cent - > currentState . modelindex2 ;
model . shaderRGBA [ 0 ] = 0xff ;
model . shaderRGBA [ 1 ] = c ;
model . shaderRGBA [ 2 ] = c ;
model . shaderRGBA [ 3 ] = 0xff ;
//
model . hModel = cgs . media . overloadEnergyModel ;
trap_R_AddRefEntityToScene ( & model ) ;
}
// if respawning
if ( cent - > currentState . frame = = 2 ) {
if ( ! cent - > miscTime ) {
cent - > miscTime = cg . time ;
}
t = cg . time - cent - > miscTime ;
h = ( cg_obeliskRespawnDelay . integer - 5 ) * 1000 ;
//
if ( t > h ) {
c = ( float ) ( t - h ) / h ;
if ( c > 1 )
c = 1 ;
}
else {
c = 0 ;
}
// show the lights
AnglesToAxis ( cent - > currentState . angles , model . axis ) ;
//
model . shaderRGBA [ 0 ] = c * 0xff ;
model . shaderRGBA [ 1 ] = c * 0xff ;
model . shaderRGBA [ 2 ] = c * 0xff ;
model . shaderRGBA [ 3 ] = c * 0xff ;
model . hModel = cgs . media . overloadLightsModel ;
trap_R_AddRefEntityToScene ( & model ) ;
// show the target
if ( t > h ) {
if ( ! cent - > muzzleFlashTime ) {
trap_S_StartSound ( cent - > lerpOrigin , ENTITYNUM_NONE , CHAN_BODY , cgs . media . obeliskRespawnSound ) ;
cent - > muzzleFlashTime = 1 ;
}
VectorCopy ( cent - > currentState . angles , angles ) ;
2012-09-15 08:01:58 +00:00
angles [ YAW ] + = ( float ) 16 * Q_acos ( 1 - c ) * 180 / M_PI ;
2011-02-18 14:31:32 +00:00
AnglesToAxis ( angles , model . axis ) ;
VectorScale ( model . axis [ 0 ] , c , model . axis [ 0 ] ) ;
VectorScale ( model . axis [ 1 ] , c , model . axis [ 1 ] ) ;
VectorScale ( model . axis [ 2 ] , c , model . axis [ 2 ] ) ;
model . shaderRGBA [ 0 ] = 0xff ;
model . shaderRGBA [ 1 ] = 0xff ;
model . shaderRGBA [ 2 ] = 0xff ;
model . shaderRGBA [ 3 ] = 0xff ;
//
model . origin [ 2 ] + = 56 ;
model . hModel = cgs . media . overloadTargetModel ;
trap_R_AddRefEntityToScene ( & model ) ;
}
else {
//FIXME: show animated smoke
}
}
else {
cent - > miscTime = 0 ;
cent - > muzzleFlashTime = 0 ;
// modelindex2 is the health value of the obelisk
c = cent - > currentState . modelindex2 ;
model . shaderRGBA [ 0 ] = 0xff ;
model . shaderRGBA [ 1 ] = c ;
model . shaderRGBA [ 2 ] = c ;
model . shaderRGBA [ 3 ] = 0xff ;
// show the lights
model . hModel = cgs . media . overloadLightsModel ;
trap_R_AddRefEntityToScene ( & model ) ;
// show the target
model . origin [ 2 ] + = 56 ;
model . hModel = cgs . media . overloadTargetModel ;
trap_R_AddRefEntityToScene ( & model ) ;
}
}
else if ( cgs . gametype = = GT_HARVESTER ) {
// show harvester model
memset ( & model , 0 , sizeof ( model ) ) ;
model . reType = RT_MODEL ;
VectorCopy ( cent - > lerpOrigin , model . lightingOrigin ) ;
VectorCopy ( cent - > lerpOrigin , model . origin ) ;
AnglesToAxis ( cent - > currentState . angles , model . axis ) ;
if ( cent - > currentState . modelindex = = TEAM_RED ) {
model . hModel = cgs . media . harvesterModel ;
model . customSkin = cgs . media . harvesterRedSkin ;
}
else if ( cent - > currentState . modelindex = = TEAM_BLUE ) {
model . hModel = cgs . media . harvesterModel ;
model . customSkin = cgs . media . harvesterBlueSkin ;
}
else {
model . hModel = cgs . media . harvesterNeutralModel ;
model . customSkin = 0 ;
}
trap_R_AddRefEntityToScene ( & model ) ;
}
# endif
}
/*
= = = = = = = = = = = = = = =
CG_AddCEntity
= = = = = = = = = = = = = = =
*/
// Q3Rally Code Start
// static void CG_AddCEntity( centity_t *cent ) {
void CG_AddCEntity ( centity_t * cent ) {
// Q3Rally Code END
// event-only entities will have been dealt with already
if ( cent - > currentState . eType > = ET_EVENTS ) {
return ;
}
// calculate the current origin
CG_CalcEntityLerpPositions ( cent ) ;
// add automatic effects
CG_EntityEffects ( cent ) ;
switch ( cent - > currentState . eType ) {
default :
2012-09-15 03:03:44 +00:00
CG_Error ( " Bad entity type: %i " , cent - > currentState . eType ) ;
2011-02-18 14:31:32 +00:00
break ;
// Q3Rally Code Start
case ET_CHECKPOINT :
// Q3Rally Code END
case ET_INVISIBLE :
case ET_PUSH_TRIGGER :
case ET_TELEPORT_TRIGGER :
break ;
case ET_GENERAL :
CG_General ( cent ) ;
break ;
case ET_PLAYER :
CG_Player ( cent ) ;
break ;
case ET_ITEM :
CG_Item ( cent ) ;
break ;
case ET_MISSILE :
CG_Missile ( cent ) ;
break ;
case ET_MOVER :
CG_Mover ( cent ) ;
break ;
// Q3Rally Code Start
case ET_BREAKGLASS :
CG_Mover ( cent ) ;
break ;
case ET_BREAKWOOD :
CG_Mover ( cent ) ;
break ;
case ET_BREAKMETAL :
CG_Mover ( cent ) ;
break ;
// Q3Rally Code END
case ET_BEAM :
CG_Beam ( cent ) ;
break ;
case ET_PORTAL :
CG_Portal ( cent ) ;
break ;
case ET_SPEAKER :
CG_Speaker ( cent ) ;
break ;
// Q3Rally Code Start
/*
case ET_GRAPPLE :
CG_Grapple ( cent ) ;
break ;
*/
case ET_AUXENT :
CG_Auxent ( cent ) ;
break ;
case ET_WEATHER :
CG_Weather ( cent ) ;
break ;
case ET_SCRIPTED :
CG_Scripted_Object ( cent ) ;
break ;
// Q3Rally Code END
case ET_TEAM :
CG_TeamBase ( cent ) ;
break ;
}
}
/*
= = = = = = = = = = = = = = =
CG_AddPacketEntities
= = = = = = = = = = = = = = =
*/
// Q3Rally Code Start
//static vec3_t lastVel;
//static vec3_t lastAngM;
//static int lastPMType;
// Q3Rally Code END
void CG_AddPacketEntities ( void ) {
int num ;
centity_t * cent ;
playerState_t * ps ;
// Q3Rally Code Start
// char value[16];
// int i;
// Q3Rally Code END
// set cg.frameInterpolation
if ( cg . nextSnap ) {
int delta ;
delta = ( cg . nextSnap - > serverTime - cg . snap - > serverTime ) ;
if ( delta = = 0 ) {
cg . frameInterpolation = 0 ;
} else {
cg . frameInterpolation = ( float ) ( cg . time - cg . snap - > serverTime ) / delta ;
}
} else {
cg . frameInterpolation = 0 ; // actually, it should never be used, because
// no entities should be marked as interpolating
}
// the auto-rotating items will all have the same axis
cg . autoAngles [ 0 ] = 0 ;
cg . autoAngles [ 1 ] = ( cg . time & 2047 ) * 360 / 2048.0 ;
cg . autoAngles [ 2 ] = 0 ;
cg . autoAnglesFast [ 0 ] = 0 ;
cg . autoAnglesFast [ 1 ] = ( cg . time & 1023 ) * 360 / 1024.0f ;
cg . autoAnglesFast [ 2 ] = 0 ;
AnglesToAxis ( cg . autoAngles , cg . autoAxis ) ;
AnglesToAxis ( cg . autoAnglesFast , cg . autoAxisFast ) ;
// generate and add the entity from the playerstate
ps = & cg . predictedPlayerState ;
BG_PlayerStateToEntityState ( ps , & cg . predictedPlayerEntity . currentState , qfalse ) ;
CG_AddCEntity ( & cg . predictedPlayerEntity ) ;
// lerp the non-predicted value for lightning gun origins
CG_CalcEntityLerpPositions ( & cg_entities [ cg . snap - > ps . clientNum ] ) ;
// add each entity sent over by the server
for ( num = 0 ; num < cg . snap - > numEntities ; num + + ) {
cent = & cg_entities [ cg . snap - > entities [ num ] . number ] ;
CG_AddCEntity ( cent ) ;
}
// Q3Rally Code Start
if ( cg_drawBotPaths . integer )
CG_DrawCheckpointLinks ( ) ;
if ( cg . newSnap )
{
// int weaponTime;
/*
float m [ 3 ] [ 3 ] ;
float m2 [ 3 ] [ 3 ] ;
vec3_t angles , delta_angles ;
float time = 0.5f ;
*/
// Com_Printf("updating car body variables\n");
if ( ! cg_paused . integer & & cg_debugpredict . integer )
Com_Printf ( " updateEnts \n " ) ;
/*
if ( ! cg_paused . integer )
{
int frontTime ;
int rearTime ;
int newFrontTime ;
int newRearTime ;
rearTime = ( cg . predictedPlayerState . weaponTime & REAR_WEAPON_TIME_MASK ) > > 16 ;
newRearTime = ( cg . snap - > ps . weaponTime & REAR_WEAPON_TIME_MASK ) > > 16 ;
Com_Printf ( " cg forward: cur weapon time %i new weap time %i \n " , cg . predictedPlayerState . weaponTime & NORMAL_WEAPON_TIME_MASK , cg . snap - > ps . weaponTime & NORMAL_WEAPON_TIME_MASK ) ;
Com_Printf ( " cg rear: cur weapon time %i new weap time %i \n " , rearTime , newRearTime ) ;
Com_Printf ( " cg: cur weapon time %i new weap time %i \n " , cg . predictedPlayerState . weaponTime , cg . snap - > ps . weaponTime ) ;
}
*/
// cg.predictedPlayerState = cg.snap->ps;
// HACK: save the rear weapon time because for some stupid reason q3
// engine fucks that part up when it sends the weapon time.
{
int rearTime = cg . predictedPlayerState . weaponTime & REAR_WEAPON_TIME_MASK ;
cg . predictedPlayerState = cg . snap - > ps ;
cg . predictedPlayerState . weaponTime & = ~ REAR_WEAPON_TIME_MASK ;
cg . predictedPlayerState . weaponTime | = rearTime ;
}
CG_UpdateCarFromPS ( & cg . snap - > ps ) ;
/*
m [ 0 ] [ 0 ] = 0 ; m [ 0 ] [ 1 ] = time * - cg . car . sBody . w [ 2 ] ; m [ 0 ] [ 2 ] = time * cg . car . sBody . w [ 1 ] ;
m [ 1 ] [ 0 ] = time * cg . car . sBody . w [ 2 ] ; m [ 1 ] [ 1 ] = 0 ; m [ 1 ] [ 2 ] = time * - cg . car . sBody . w [ 0 ] ;
m [ 2 ] [ 0 ] = time * - cg . car . sBody . w [ 1 ] ; m [ 2 ] [ 1 ] = time * cg . car . sBody . w [ 0 ] ; m [ 2 ] [ 2 ] = 0 ;
MatrixMultiply ( m , cg . car . sBody . t , m2 ) ;
MatrixAdd ( cg . car . sBody . t , m2 , cg . car . tBody . t ) ;
OrthonormalizeOrientation ( cg . car . tBody . t ) ;
OrientationToAngles ( cg . car . tBody . t , angles ) ;
OrientationToDeltaAngles ( cg . car . sBody . t , cg . car . sBody . w , delta_angles ) ;
Com_Printf ( " view angles1 (%f %f %f) \n " , cg . snap - > ps . viewangles [ 0 ] , cg . snap - > ps . viewangles [ 1 ] , cg . snap - > ps . viewangles [ 2 ] ) ;
Com_Printf ( " delta angles (%f %f %f) \n " , delta_angles [ 0 ] , delta_angles [ 1 ] , delta_angles [ 2 ] ) ;
Com_Printf ( " view angles2 (%f %f %f) \n " , angles [ 0 ] , angles [ 1 ] , angles [ 2 ] ) ;
*/
if ( ! cg_paused . integer ) {
// Com_Printf("client time %d\n", ps->commandTime);
/* Car
Com_Printf ( " springStrength %f \n " , cg . car . springStrength ) ;
Com_Printf ( " springMaxLength %f \n " , cg . car . springMaxLength ) ;
Com_Printf ( " springMinLength %f \n " , cg . car . springMinLength ) ;
Com_Printf ( " shockStrength %f \n " , cg . car . shockStrength ) ;
Com_Printf ( " wheelAngle %f \n " , cg . car . wheelAngle ) ;
Com_Printf ( " throttle %f \n " , cg . car . throttle ) ;
Com_Printf ( " gear %d \n " , cg . car . gear ) ;
Com_Printf ( " rpm %f \n " , cg . car . rpm ) ;
Com_Printf ( " aCOF %f \n " , cg . car . aCOF ) ;
Com_Printf ( " sCOF %f \n " , cg . car . sCOF ) ;
Com_Printf ( " kCOF %f \n " , cg . car . kCOF ) ;
Com_Printf ( " dfCOF %f \n " , cg . car . dfCOF ) ;
Com_Printf ( " ewCOF %f \n " , cg . car . ewCOF ) ;
Com_Printf ( " inverseBodyInertiaTensor: \n " ) ;
Com_Printf ( " %f, %f, %f \n " , cg . car . inverseBodyInertiaTensor [ 0 ] [ 0 ] , cg . car . inverseBodyInertiaTensor [ 0 ] [ 1 ] , cg . car . inverseBodyInertiaTensor [ 0 ] [ 2 ] ) ;
Com_Printf ( " %f, %f, %f \n " , cg . car . inverseBodyInertiaTensor [ 1 ] [ 0 ] , cg . car . inverseBodyInertiaTensor [ 1 ] [ 1 ] , cg . car . inverseBodyInertiaTensor [ 1 ] [ 2 ] ) ;
Com_Printf ( " %f, %f, %f \n " , cg . car . inverseBodyInertiaTensor [ 2 ] [ 0 ] , cg . car . inverseBodyInertiaTensor [ 2 ] [ 1 ] , cg . car . inverseBodyInertiaTensor [ 2 ] [ 2 ] ) ;
*/
/* Body
Com_Printf ( " r %f, %f, %f \n " , cg . car . sBody . r [ 0 ] , cg . car . sBody . r [ 1 ] , cg . car . sBody . r [ 2 ] ) ;
Com_Printf ( " v %f, %f, %f \n " , cg . car . sBody . v [ 0 ] , cg . car . sBody . v [ 1 ] , cg . car . sBody . v [ 2 ] ) ;
Com_Printf ( " w %f, %f, %f \n " , cg . car . sBody . w [ 0 ] , cg . car . sBody . w [ 1 ] , cg . car . sBody . w [ 2 ] ) ;
Com_Printf ( " L %f, %f, %f \n " , cg . car . sBody . L [ 0 ] , cg . car . sBody . L [ 1 ] , cg . car . sBody . L [ 2 ] ) ;
Com_Printf ( " CoM %f, %f, %f \n " , cg . car . sBody . CoM [ 0 ] , cg . car . sBody . CoM [ 1 ] , cg . car . sBody . CoM [ 2 ] ) ;
Com_Printf ( " t: \n " ) ;
Com_Printf ( " %f, %f, %f \n " , cg . car . sBody . t [ 0 ] [ 0 ] , cg . car . sBody . t [ 0 ] [ 1 ] , cg . car . sBody . t [ 0 ] [ 2 ] ) ;
Com_Printf ( " %f, %f, %f \n " , cg . car . sBody . t [ 1 ] [ 0 ] , cg . car . sBody . t [ 1 ] [ 1 ] , cg . car . sBody . t [ 1 ] [ 2 ] ) ;
Com_Printf ( " %f, %f, %f \n " , cg . car . sBody . t [ 2 ] [ 0 ] , cg . car . sBody . t [ 2 ] [ 1 ] , cg . car . sBody . t [ 2 ] [ 2 ] ) ;
*/
/* Point
i = 4 ;
Com_Printf ( " r %f, %f, %f \n " , cg . car . tPoints [ i ] . r [ 0 ] , cg . car . tPoints [ i ] . r [ 1 ] , cg . car . tPoints [ i ] . r [ 2 ] ) ;
Com_Printf ( " v %f, %f, %f \n " , cg . car . tPoints [ i ] . v [ 0 ] , cg . car . tPoints [ i ] . v [ 1 ] , cg . car . tPoints [ i ] . v [ 2 ] ) ;
Com_Printf ( " w %f \n " , cg . car . tPoints [ i ] . w ) ;
Com_Printf ( " netForce %f, %f, %f \n " , cg . car . sPoints [ i ] . netForce [ 0 ] , cg . car . sPoints [ i ] . netForce [ 1 ] , cg . car . sPoints [ i ] . netForce [ 2 ] ) ;
Com_Printf ( " netMoment %f \n " , cg . car . sPoints [ i ] . netMoment ) ;
Com_Printf ( " normals %f, %f, %f \n " , cg . car . sPoints [ i ] . normals [ 0 ] [ 0 ] , cg . car . sPoints [ i ] . normals [ 0 ] [ 1 ] , cg . car . sPoints [ i ] . normals [ 0 ] [ 2 ] ) ;
Com_Printf ( " mass %f \n " , cg . car . sPoints [ i ] . mass ) ;
Com_Printf ( " elasticity %f \n " , cg . car . sPoints [ i ] . elasticity ) ;
Com_Printf ( " kcof %f \n " , cg . car . sPoints [ i ] . kcof ) ;
Com_Printf ( " scof %f \n " , cg . car . sPoints [ i ] . scof ) ;
Com_Printf ( " fluidDensity %f \n " , cg . car . sPoints [ i ] . fluidDensity ) ;
Com_Printf ( " onGround %d \n " , cg . car . sPoints [ i ] . onGround ) ;
Com_Printf ( " slipping %d \n " , cg . car . sPoints [ i ] . slipping ) ;
*/
}
}
// VectorCopy(cg.snap->ps.velocity, lastVel);
// VectorCopy(cg.snap->ps.origin, lastAngM);
// lastPMType = cg.snap->ps.pm_type;
cg . newSnap = qfalse ;
// Q3Rally Code END
}