diff options
Diffstat (limited to 'mod/src')
76 files changed, 0 insertions, 85117 deletions
diff --git a/mod/src/cgame/cg_animation.c b/mod/src/cgame/cg_animation.c deleted file mode 100644 index 5295998e..00000000 --- a/mod/src/cgame/cg_animation.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -/* -=============== -CG_RunLerpFrame - -Sets cg.snap, cg.oldFrame, and cg.backlerp -cg.time should be between oldFrameTime and frameTime after exit -=============== -*/ -void CG_RunLerpFrame( lerpFrame_t *lf ) -{ -  int     f, numFrames; -  animation_t *anim; - -  // debugging tool to get no animations -  if( cg_animSpeed.integer == 0 ) -  { -    lf->oldFrame = lf->frame = lf->backlerp = 0; -    return; -  } - -  // if we have passed the current frame, move it to -  // oldFrame and calculate a new frame -  if( cg.time >= lf->frameTime ) -  { -    lf->oldFrame = lf->frame; -    lf->oldFrameTime = lf->frameTime; - -    // get the next frame based on the animation -    anim = lf->animation; -    if( !anim->frameLerp ) -      return;   // shouldn't happen - -    if( cg.time < lf->animationTime ) -      lf->frameTime = lf->animationTime;    // initial lerp -    else -      lf->frameTime = lf->oldFrameTime + anim->frameLerp; - -    f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp; -    numFrames = anim->numFrames; -    if( anim->flipflop ) -      numFrames *= 2; - -    if( f >= numFrames ) -    { -      f -= numFrames; -      if( anim->loopFrames ) -      { -        f %= anim->loopFrames; -        f += anim->numFrames - anim->loopFrames; -      } -      else -      { -        f = numFrames - 1; -        // the animation is stuck at the end, so it -        // can immediately transition to another sequence -        lf->frameTime = cg.time; -      } -    } - -    if( anim->reversed ) -      lf->frame = anim->firstFrame + anim->numFrames - 1 - f; -    else if( anim->flipflop && f >= anim->numFrames ) -      lf->frame = anim->firstFrame + anim->numFrames - 1 - ( f % anim->numFrames ); -    else -      lf->frame = anim->firstFrame + f; - -    if( cg.time > lf->frameTime ) -    { -      lf->frameTime = cg.time; -      if( cg_debugAnim.integer ) -        CG_Printf( "Clamp lf->frameTime\n" ); -    } -  } - -  if( lf->frameTime > cg.time + 200 ) -    lf->frameTime = cg.time; - -  if( lf->oldFrameTime > cg.time ) -    lf->oldFrameTime = cg.time; - -  // calculate current lerp value -  if( lf->frameTime == lf->oldFrameTime ) -    lf->backlerp = 0; -  else -    lf->backlerp = 1.0 - (float)( cg.time - lf->oldFrameTime ) / ( lf->frameTime - lf->oldFrameTime ); -} diff --git a/mod/src/cgame/cg_animmapobj.c b/mod/src/cgame/cg_animmapobj.c deleted file mode 100644 index f0e964bf..00000000 --- a/mod/src/cgame/cg_animmapobj.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - - -/* -=============== -CG_DoorAnimation -=============== -*/ -static void CG_DoorAnimation( centity_t *cent, int *old, int *now, float *backLerp ) -{ -  CG_RunLerpFrame( ¢->lerpFrame ); - -  *old      = cent->lerpFrame.oldFrame; -  *now      = cent->lerpFrame.frame; -  *backLerp = cent->lerpFrame.backlerp; -} - - -/* -=============== -CG_ModelDoor -=============== -*/ -void CG_ModelDoor( centity_t *cent ) -{ -  refEntity_t     ent; -  entityState_t   *es; -  animation_t     anim; -  lerpFrame_t     *lf = ¢->lerpFrame; - -  es = ¢->currentState; - -  if( !es->modelindex ) -    return; - -  //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; - -  //add the door model -  ent.skinNum = 0; -  ent.hModel = cgs.gameModels[ es->modelindex ]; - -  //scale the door -  VectorScale( ent.axis[ 0 ], es->origin2[ 0 ], ent.axis[ 0 ] ); -  VectorScale( ent.axis[ 1 ], es->origin2[ 1 ], ent.axis[ 1 ] ); -  VectorScale( ent.axis[ 2 ], es->origin2[ 2 ], ent.axis[ 2 ] ); -  ent.nonNormalizedAxes = qtrue; - -  //setup animation -  anim.firstFrame   = es->powerups; -  anim.numFrames    = es->weapon; -  anim.reversed     = !es->legsAnim; -  anim.flipflop     = qfalse; -  anim.loopFrames   = 0; -  anim.frameLerp    = 1000 / es->torsoAnim; -  anim.initialLerp  = 1000 / es->torsoAnim; - -  //door changed state -  if( es->legsAnim != cent->doorState ) -  { -    lf->animationTime = lf->frameTime + anim.initialLerp; -    cent->doorState = es->legsAnim; -  } - -  lf->animation = &anim; - -  //run animation -  CG_DoorAnimation( cent, &ent.oldframe, &ent.frame, &ent.backlerp ); - -  trap_R_AddRefEntityToScene( &ent ); -} - - -/* -=============== -CG_AMOAnimation -=============== -*/ -static void CG_AMOAnimation( centity_t *cent, int *old, int *now, float *backLerp ) -{ -  if( !( cent->currentState.eFlags & EF_MOVER_STOP ) ) -  { -    int delta = cg.time - cent->miscTime; - -    //hack to prevent "pausing" mucking up the lerping -    if( delta > 900 ) -    { -      cent->lerpFrame.oldFrameTime  += delta; -      cent->lerpFrame.frameTime     += delta; -    } - -    CG_RunLerpFrame( ¢->lerpFrame ); -    cent->miscTime = cg.time; -  } - -  *old      = cent->lerpFrame.oldFrame; -  *now      = cent->lerpFrame.frame; -  *backLerp = cent->lerpFrame.backlerp; -} - - -/* -================== -CG_animMapObj -================== -*/ -void CG_AnimMapObj( centity_t *cent ) -{ -  refEntity_t     ent; -  entityState_t   *es; -  float           scale; -  animation_t     anim; - -  es = ¢->currentState; - -  // if set to invisible, skip -  if( !es->modelindex || ( es->eFlags & EF_NODRAW ) ) -    return; - -  memset( &ent, 0, sizeof( ent ) ); - -  VectorCopy( es->angles, cent->lerpAngles ); -  AnglesToAxis( cent->lerpAngles, ent.axis ); - -  ent.hModel = cgs.gameModels[ es->modelindex ]; - -  VectorCopy( cent->lerpOrigin, ent.origin); -  VectorCopy( cent->lerpOrigin, ent.oldorigin); - -  ent.nonNormalizedAxes = qfalse; - -  //scale the model -  if( es->angles2[ 0 ] ) -  { -    scale = es->angles2[ 0 ]; -    VectorScale( ent.axis[ 0 ], scale, ent.axis[ 0 ] ); -    VectorScale( ent.axis[ 1 ], scale, ent.axis[ 1 ] ); -    VectorScale( ent.axis[ 2 ], scale, ent.axis[ 2 ] ); -    ent.nonNormalizedAxes = qtrue; -  } - -  //setup animation -  anim.firstFrame = es->powerups; -  anim.numFrames = es->weapon; -  anim.reversed = qfalse; -  anim.flipflop = qfalse; - -  // if numFrames is negative the animation is reversed -  if( anim.numFrames < 0 ) -  { -    anim.numFrames = -anim.numFrames; -    anim.reversed = qtrue; -  } - -  anim.loopFrames = es->torsoAnim; - -  if( !es->legsAnim ) -  { -    anim.frameLerp = 1000; -    anim.initialLerp = 1000; -  } -  else -  { -    anim.frameLerp = 1000 / es->legsAnim; -    anim.initialLerp = 1000 / es->legsAnim; -  } - -  cent->lerpFrame.animation = &anim; - -  //run animation -  CG_AMOAnimation( cent, &ent.oldframe, &ent.frame, &ent.backlerp ); - -  // add to refresh list -  trap_R_AddRefEntityToScene(&ent); -} diff --git a/mod/src/cgame/cg_attachment.c b/mod/src/cgame/cg_attachment.c deleted file mode 100644 index a256318b..00000000 --- a/mod/src/cgame/cg_attachment.c +++ /dev/null @@ -1,395 +0,0 @@ -// cg_attachment.c -- an abstract attachment system - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -/* -=============== -CG_AttachmentPoint - -Return the attachment point -=============== -*/ -qboolean CG_AttachmentPoint( attachment_t *a, vec3_t v ) -{ -  centity_t   *cent; - -  if( !a ) -    return qfalse; - -  // if it all breaks, then use the last point we know was correct -  VectorCopy( a->lastValidAttachmentPoint, v ); - -  switch( a->type ) -  { -    case AT_STATIC: -      if( !a->staticValid ) -        return qfalse; - -      VectorCopy( a->origin, v ); -      break; - -    case AT_TAG: -      if( !a->tagValid ) -        return qfalse; - -      AxisCopy( axisDefault, a->re.axis ); -      CG_PositionRotatedEntityOnTag( &a->re, &a->parent, -                                     a->model, a->tagName ); -      VectorCopy( a->re.origin, v ); -      break; - -    case AT_CENT: -      if( !a->centValid ) -        return qfalse; - -      if( a->centNum == cg.predictedPlayerState.clientNum ) -      { -        // this is smoother if it's the local client -        VectorCopy( cg.predictedPlayerState.origin, v ); -      } -      else -      { -        cent = &cg_entities[ a->centNum ]; -        VectorCopy( cent->lerpOrigin, v ); -      } -      break; - -    case AT_PARTICLE: -      if( !a->particleValid ) -        return qfalse; - -      if( !a->particle->valid ) -      { -        a->particleValid = qfalse; -        return qfalse; -      } -      else -        VectorCopy( a->particle->origin, v ); -      break; - -    default: -      CG_Printf( S_COLOR_RED "ERROR: Invalid attachmentType_t in attachment\n" ); -      break; -  } - -  if( a->hasOffset ) -    VectorAdd( v, a->offset, v ); - -  VectorCopy( v, a->lastValidAttachmentPoint ); - -  return qtrue; -} - -/* -=============== -CG_AttachmentDir - -Return the attachment direction -=============== -*/ -qboolean CG_AttachmentDir( attachment_t *a, vec3_t v ) -{ -  vec3_t      forward; -  centity_t   *cent; - -  if( !a ) -    return qfalse; - -  switch( a->type ) -  { -    case AT_STATIC: -      return qfalse; -      break; - -    case AT_TAG: -      if( !a->tagValid ) -        return qfalse; - -      VectorCopy( a->re.axis[ 0 ], v ); -      break; - -    case AT_CENT: -      if( !a->centValid ) -        return qfalse; - -      cent = &cg_entities[ a->centNum ]; -      AngleVectors( cent->lerpAngles, forward, NULL, NULL ); -      VectorCopy( forward, v ); -      break; - -    case AT_PARTICLE: -      if( !a->particleValid ) -        return qfalse; - -      if( !a->particle->valid ) -      { -        a->particleValid = qfalse; -        return qfalse; -      } -      else -        VectorCopy( a->particle->velocity, v ); -      break; - -    default: -      CG_Printf( S_COLOR_RED "ERROR: Invalid attachmentType_t in attachment\n" ); -      break; -  } - -  VectorNormalize( v ); -  return qtrue; -} - -/* -=============== -CG_AttachmentAxis - -Return the attachment axis -=============== -*/ -qboolean CG_AttachmentAxis( attachment_t *a, vec3_t axis[ 3 ] ) -{ -  centity_t   *cent; - -  if( !a ) -    return qfalse; - -  switch( a->type ) -  { -    case AT_STATIC: -      return qfalse; -      break; - -    case AT_TAG: -      if( !a->tagValid ) -        return qfalse; - -      AxisCopy( a->re.axis, axis ); -      break; - -    case AT_CENT: -      if( !a->centValid ) -        return qfalse; - -      cent = &cg_entities[ a->centNum ]; -      AnglesToAxis( cent->lerpAngles, axis ); -      break; - -    case AT_PARTICLE: -      return qfalse; -      break; - -    default: -      CG_Printf( S_COLOR_RED "ERROR: Invalid attachmentType_t in attachment\n" ); -      break; -  } - -  return qtrue; -} - -/* -=============== -CG_AttachmentVelocity - -If the attachment can have velocity, return it -=============== -*/ -qboolean CG_AttachmentVelocity( attachment_t *a, vec3_t v ) -{ -  if( !a ) -    return qfalse; - -  if( a->particleValid && a->particle->valid ) -  { -    VectorCopy( a->particle->velocity, v ); -    return qtrue; -  } -  else if( a->centValid ) -  { -    centity_t *cent = &cg_entities[ a->centNum ]; - -    VectorCopy( cent->currentState.pos.trDelta, v ); -    return qtrue; -  } - -  return qfalse; -} - -/* -=============== -CG_AttachmentCentNum - -If the attachment has a centNum, return it -=============== -*/ -int CG_AttachmentCentNum( attachment_t *a ) -{ -  if( !a || !a->centValid ) -    return -1; - -  return a->centNum; -} - -/* -=============== -CG_Attached - -If the attachment is valid, return qtrue -=============== -*/ -qboolean CG_Attached( attachment_t *a ) -{ -  if( !a ) -    return qfalse; - -  return a->attached; -} - -/* -=============== -CG_AttachToPoint - -Attach to a point in space -=============== -*/ -void CG_AttachToPoint( attachment_t *a ) -{ -  if( !a || !a->staticValid ) -    return; - -  a->type = AT_STATIC; -  a->attached = qtrue; -} - -/* -=============== -CG_AttachToCent - -Attach to a centity_t -=============== -*/ -void CG_AttachToCent( attachment_t *a ) -{ -  if( !a || !a->centValid ) -    return; - -  a->type = AT_CENT; -  a->attached = qtrue; -} - -/* -=============== -CG_AttachToTag - -Attach to a model tag -=============== -*/ -void CG_AttachToTag( attachment_t *a ) -{ -  if( !a || !a->tagValid ) -    return; - -  a->type = AT_TAG; -  a->attached = qtrue; -} - -/* -=============== -CG_AttachToParticle - -Attach to a particle -=============== -*/ -void CG_AttachToParticle( attachment_t *a ) -{ -  if( !a || !a->particleValid ) -    return; - -  a->type = AT_PARTICLE; -  a->attached = qtrue; -} - -/* -=============== -CG_SetAttachmentPoint -=============== -*/ -void CG_SetAttachmentPoint( attachment_t *a, vec3_t v ) -{ -  if( !a ) -    return; - -  VectorCopy( v, a->origin ); -  a->staticValid = qtrue; -} - -/* -=============== -CG_SetAttachmentCent -=============== -*/ -void CG_SetAttachmentCent( attachment_t *a, centity_t *cent ) -{ -  if( !a || !cent ) -    return; - -  a->centNum = cent->currentState.number; -  a->centValid = qtrue; -} - -/* -=============== -CG_SetAttachmentTag -=============== -*/ -void CG_SetAttachmentTag( attachment_t *a, refEntity_t parent, -    qhandle_t model, char *tagName ) -{ -  if( !a ) -    return; - -  a->parent = parent; -  a->model = model; -  strncpy( a->tagName, tagName, MAX_STRING_CHARS ); -  a->tagValid = qtrue; -} - -/* -=============== -CG_SetAttachmentParticle -=============== -*/ -void CG_SetAttachmentParticle( attachment_t *a, particle_t *p ) -{ -  if( !a ) -    return; - -  a->particle = p; -  a->particleValid = qtrue; -} - -/* -=============== -CG_SetAttachmentOffset -=============== -*/ -void CG_SetAttachmentOffset( attachment_t *a, vec3_t v ) -{ -  if( !a ) -    return; - -  VectorCopy( v, a->offset ); -  a->hasOffset = qtrue; -} diff --git a/mod/src/cgame/cg_buildable.c b/mod/src/cgame/cg_buildable.c deleted file mode 100644 index 348bb433..00000000 --- a/mod/src/cgame/cg_buildable.c +++ /dev/null @@ -1,1051 +0,0 @@ -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -char *cg_buildableSoundNames[ MAX_BUILDABLE_ANIMATIONS ] = -{ -  "construct1.wav", -  "construct2.wav", -  "idle1.wav", -  "idle2.wav", -  "idle3.wav", -  "attack1.wav", -  "attack2.wav", -  "spawn1.wav", -  "spawn2.wav", -  "pain1.wav", -  "pain2.wav", -  "destroy1.wav", -  "destroy2.wav", -  "destroyed.wav" -}; - -static sfxHandle_t defaultAlienSounds[ MAX_BUILDABLE_ANIMATIONS ]; -static sfxHandle_t defaultHumanSounds[ MAX_BUILDABLE_ANIMATIONS ]; - -/* -=================== -CG_AlienBuildableExplosion - -Generated a bunch of gibs launching out from a location -=================== -*/ -void CG_AlienBuildableExplosion( vec3_t origin, vec3_t dir ) -{ -  particleSystem_t  *ps; - -  trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.alienBuildableExplosion ); - -  //particle system -  ps = CG_SpawnNewParticleSystem( cgs.media.alienBuildableDestroyedPS ); - -  if( CG_IsParticleSystemValid( &ps ) ) -  { -    CG_SetAttachmentPoint( &ps->attachment, origin ); -    CG_SetParticleSystemNormal( ps, dir ); -    CG_AttachToPoint( &ps->attachment ); -  } -} - -/* -================= -CG_HumanBuildableExplosion - -Called for human buildables as they are destroyed -================= -*/ -void CG_HumanBuildableExplosion( vec3_t origin, vec3_t dir ) -{ -  particleSystem_t  *ps; - -  trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.humanBuildableExplosion ); - -  //particle system -  ps = CG_SpawnNewParticleSystem( cgs.media.humanBuildableDestroyedPS ); - -  if( CG_IsParticleSystemValid( &ps ) ) -  { -    CG_SetAttachmentPoint( &ps->attachment, origin ); -    CG_SetParticleSystemNormal( ps, dir ); -    CG_AttachToPoint( &ps->attachment ); -  } -} - - -#define CREEP_SIZE            64.0f - -/* -================== -CG_Creep -================== -*/ -static void CG_Creep( centity_t *cent ) -{ -  int           msec; -  float         size, frac; -  trace_t       tr; -  vec3_t        temp, origin; -  int           scaleUpTime = BG_FindBuildTimeForBuildable( cent->currentState.modelindex ); -  int           time; - -  time = cent->currentState.time; - -  //should the creep be growing or receding? -  if( time >= 0 ) -  { -    msec = cg.time - time; -    if( msec >= 0 && msec < scaleUpTime ) -      frac = (float)msec / scaleUpTime; -    else -      frac = 1.0f; -  } -  else if( time < 0 ) -  { -    msec = cg.time + time; -    if( msec >= 0 && msec < CREEP_SCALEDOWN_TIME ) -      frac = 1.0f - ( (float)msec / CREEP_SCALEDOWN_TIME ); -    else -      frac = 0.0f; -  } - -  VectorCopy( cent->currentState.origin2, temp ); -  VectorScale( temp, -4096, temp ); -  VectorAdd( temp, cent->lerpOrigin, temp ); - -  CG_Trace( &tr, cent->lerpOrigin, NULL, NULL, temp, cent->currentState.number, MASK_SOLID ); - -  VectorCopy( tr.endpos, origin ); - -  size = CREEP_SIZE * frac; - -  if( size > 0.0f ) -    CG_ImpactMark( cgs.media.creepShader, origin, cent->currentState.origin2, -                   0.0f, 1.0f, 1.0f, 1.0f, 1.0f, qfalse, size, qtrue ); -} - -/* -====================== -CG_ParseBuildableAnimationFile - -Read a configuration file containing animation counts and rates -models/buildables/hivemind/animation.cfg, etc -====================== -*/ -static qboolean CG_ParseBuildableAnimationFile( const char *filename, buildable_t buildable ) -{ -  char          *text_p; -  int           len; -  int           i; -  char          *token; -  float         fps; -  char          text[ 20000 ]; -  fileHandle_t  f; -  animation_t   *animations; - -  animations = cg_buildables[ buildable ].animations; - -  // load the file -  len = trap_FS_FOpenFile( filename, &f, FS_READ ); -  if( len <= 0 ) -    return qfalse; - -  if( len >= sizeof( text ) - 1 ) -  { -    CG_Printf( "File %s too long\n", filename ); -    return qfalse; -  } - -  trap_FS_Read( text, len, f ); -  text[ len ] = 0; -  trap_FS_FCloseFile( f ); - -  // parse the text -  text_p = text; - -  // read information for each frame -  for( i = BANIM_NONE + 1; i < MAX_BUILDABLE_ANIMATIONS; i++ ) -  { - -    token = COM_Parse( &text_p ); -    if( !*token ) -      break; - -    animations[ i ].firstFrame = atoi( token ); - -    token = COM_Parse( &text_p ); -    if( !*token ) -      break; - -    animations[ i ].numFrames = atoi( token ); -    animations[ i ].reversed = qfalse; -    animations[ i ].flipflop = qfalse; - -    // if numFrames is negative the animation is reversed -    if( animations[ i ].numFrames < 0 ) -    { -      animations[ i ].numFrames = -animations[ i ].numFrames; -      animations[ i ].reversed = qtrue; -    } - -    token = COM_Parse( &text_p ); -    if ( !*token ) -      break; - -    animations[i].loopFrames = atoi( token ); - -    token = COM_Parse( &text_p ); -    if( !*token ) -      break; - -    fps = atof( token ); -    if( fps == 0 ) -      fps = 1; - -    animations[ i ].frameLerp = 1000 / fps; -    animations[ i ].initialLerp = 1000 / fps; -  } - -  if( i != MAX_BUILDABLE_ANIMATIONS ) -  { -    CG_Printf( "Error parsing animation file: %s\n", filename ); -    return qfalse; -  } - -  return qtrue; -} - -/* -====================== -CG_ParseBuildableSoundFile - -Read a configuration file containing sound properties -sound/buildables/hivemind/sound.cfg, etc -====================== -*/ -static qboolean CG_ParseBuildableSoundFile( const char *filename, buildable_t buildable ) -{ -  char          *text_p; -  int           len; -  int           i; -  char          *token; -  char          text[ 20000 ]; -  fileHandle_t  f; -  sound_t       *sounds; - -  sounds = cg_buildables[ buildable ].sounds; - -  // load the file -  len = trap_FS_FOpenFile( filename, &f, FS_READ ); -  if ( len <= 0 ) -    return qfalse; - -  if ( len >= sizeof( text ) - 1 ) -  { -    CG_Printf( "File %s too long\n", filename ); -    return qfalse; -  } - -  trap_FS_Read( text, len, f ); -  text[len] = 0; -  trap_FS_FCloseFile( f ); - -  // parse the text -  text_p = text; - -  // read information for each frame -  for( i = BANIM_NONE + 1; i < MAX_BUILDABLE_ANIMATIONS; i++ ) -  { - -    token = COM_Parse( &text_p ); -    if ( !*token ) -      break; - -    sounds[ i ].enabled = atoi( token ); - -    token = COM_Parse( &text_p ); -    if ( !*token ) -      break; - -    sounds[ i ].looped = atoi( token ); - -  } - -  if( i != MAX_BUILDABLE_ANIMATIONS ) -  { -    CG_Printf( "Error parsing sound file: %s\n", filename ); -    return qfalse; -  } - -  return qtrue; -} -/* -=============== -CG_InitBuildables - -Initialises the animation db -=============== -*/ -void CG_InitBuildables( void ) -{ -  char          filename[ MAX_QPATH ]; -  char          soundfile[ MAX_QPATH ]; -  char          *buildableName; -  char          *modelFile; -  int           i; -  int           j; -  fileHandle_t  f; - -  memset( cg_buildables, 0, sizeof( cg_buildables ) ); - -  //default sounds -  for( j = BANIM_NONE + 1; j < MAX_BUILDABLE_ANIMATIONS; j++ ) -  { -    strcpy( soundfile, cg_buildableSoundNames[ j - 1 ] ); - -    Com_sprintf( filename, sizeof( filename ), "sound/buildables/alien/%s", soundfile ); -    defaultAlienSounds[ j ] = trap_S_RegisterSound( filename, qfalse ); - -    Com_sprintf( filename, sizeof( filename ), "sound/buildables/human/%s", soundfile ); -    defaultHumanSounds[ j ] = trap_S_RegisterSound( filename, qfalse ); -  } - -  cg.buildablesFraction = 0.0f; - -  for( i = BA_NONE + 1; i < BA_NUM_BUILDABLES; i++ ) -  { -    buildableName = BG_FindNameForBuildable( i ); - -    //animation.cfg -    Com_sprintf( filename, sizeof( filename ), "models/buildables/%s/animation.cfg", buildableName ); -    if ( !CG_ParseBuildableAnimationFile( filename, i ) ) -      Com_Printf( S_COLOR_YELLOW "WARNING: failed to load animation file %s\n", filename ); - -    //sound.cfg -    Com_sprintf( filename, sizeof( filename ), "sound/buildables/%s/sound.cfg", buildableName ); -    if ( !CG_ParseBuildableSoundFile( filename, i ) ) -      Com_Printf( S_COLOR_YELLOW "WARNING: failed to load sound file %s\n", filename ); - -    //models -    for( j = 0; j <= 3; j++ ) -    { -      if( ( modelFile = BG_FindModelsForBuildable( i, j ) ) ) -        cg_buildables[ i ].models[ j ] = trap_R_RegisterModel( modelFile ); -    } - -    //sounds -    for( j = BANIM_NONE + 1; j < MAX_BUILDABLE_ANIMATIONS; j++ ) -    { -      strcpy( soundfile, cg_buildableSoundNames[ j - 1 ] ); -      Com_sprintf( filename, sizeof( filename ), "sound/buildables/%s/%s", buildableName, soundfile ); - -      if( cg_buildables[ i ].sounds[ j ].enabled ) -      { -        if( trap_FS_FOpenFile( filename, &f, FS_READ ) > 0 ) -        { -          //file exists so close it -          trap_FS_FCloseFile( f ); - -          cg_buildables[ i ].sounds[ j ].sound = trap_S_RegisterSound( filename, qfalse ); -        } -        else -        { -          //file doesn't exist - use default -          if( BG_FindTeamForBuildable( i ) == BIT_ALIENS ) -            cg_buildables[ i ].sounds[ j ].sound = defaultAlienSounds[ j ]; -          else -            cg_buildables[ i ].sounds[ j ].sound = defaultHumanSounds[ j ]; -        } -      } -    } - -    cg.buildablesFraction = (float)i / (float)( BA_NUM_BUILDABLES - 1 ); -    trap_UpdateScreen( ); -  } - -  cgs.media.teslaZapTS = CG_RegisterTrailSystem( "models/buildables/tesla/zap" ); -} - -/* -=============== -CG_SetBuildableLerpFrameAnimation - -may include ANIM_TOGGLEBIT -=============== -*/ -static void CG_SetBuildableLerpFrameAnimation( buildable_t buildable, lerpFrame_t *lf, int newAnimation ) -{ -  animation_t *anim; - -  lf->animationNumber = newAnimation; - -  if( newAnimation < 0 || newAnimation >= MAX_BUILDABLE_ANIMATIONS ) -    CG_Error( "Bad animation number: %i", newAnimation ); - -  anim = &cg_buildables[ buildable ].animations[ newAnimation ]; - -  //this item has just spawned so lf->frameTime will be zero -  if( !lf->animation ) -    lf->frameTime = cg.time + 1000; //1 sec delay before starting the spawn anim - -  lf->animation = anim; -  lf->animationTime = lf->frameTime + anim->initialLerp; - -  if( cg_debugAnim.integer ) -    CG_Printf( "Anim: %i\n", newAnimation ); -} - -/* -=============== -CG_RunBuildableLerpFrame - -Sets cg.snap, cg.oldFrame, and cg.backlerp -cg.time should be between oldFrameTime and frameTime after exit -=============== -*/ -static void CG_RunBuildableLerpFrame( centity_t *cent ) -{ -  int                   f, numFrames; -  buildable_t           buildable = cent->currentState.modelindex; -  lerpFrame_t           *lf = ¢->lerpFrame; -  animation_t           *anim; -  buildableAnimNumber_t newAnimation = cent->buildableAnim & ~( ANIM_TOGGLEBIT|ANIM_FORCEBIT ); - -  // debugging tool to get no animations -  if( cg_animSpeed.integer == 0 ) -  { -    lf->oldFrame = lf->frame = lf->backlerp = 0; -    return; -  } - -  // see if the animation sequence is switching -  if( newAnimation != lf->animationNumber || !lf->animation ) -  { -    if( cg_debugRandom.integer ) -      CG_Printf( "newAnimation: %d lf->animationNumber: %d lf->animation: %d\n", -                 newAnimation, lf->animationNumber, lf->animation ); - -    CG_SetBuildableLerpFrameAnimation( buildable, lf, newAnimation ); - -    if( !cg_buildables[ buildable ].sounds[ newAnimation ].looped && -        cg_buildables[ buildable ].sounds[ newAnimation ].enabled ) -    { -      if( cg_debugRandom.integer ) -        CG_Printf( "Sound for animation %d for a %s\n", -            newAnimation, BG_FindHumanNameForBuildable( buildable ) ); - -      trap_S_StartSound( cent->lerpOrigin, cent->currentState.number, CHAN_AUTO, -        cg_buildables[ buildable ].sounds[ newAnimation ].sound ); -    } -  } - -  if( cg_buildables[ buildable ].sounds[ lf->animationNumber ].looped && -      cg_buildables[ buildable ].sounds[ lf->animationNumber ].enabled ) -    trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, -      cg_buildables[ buildable ].sounds[ lf->animationNumber ].sound ); - -  // if we have passed the current frame, move it to -  // oldFrame and calculate a new frame -  if( cg.time >= lf->frameTime ) -  { -    lf->oldFrame = lf->frame; -    lf->oldFrameTime = lf->frameTime; - -    // get the next frame based on the animation -    anim = lf->animation; -    if( !anim->frameLerp ) -      return;   // shouldn't happen - -    if ( cg.time < lf->animationTime ) -      lf->frameTime = lf->animationTime;    // initial lerp -    else -      lf->frameTime = lf->oldFrameTime + anim->frameLerp; - -    f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp; -    numFrames = anim->numFrames; -    if(anim->flipflop) -      numFrames *= 2; - -    if( f >= numFrames ) -    { -      f -= numFrames; -      if( anim->loopFrames ) -      { -        f %= anim->loopFrames; -        f += anim->numFrames - anim->loopFrames; -      } -      else -      { -        f = numFrames - 1; -        // the animation is stuck at the end, so it -        // can immediately transition to another sequence -        lf->frameTime = cg.time; -        cent->buildableAnim = cent->currentState.torsoAnim; -      } -    } - -    if( anim->reversed ) -      lf->frame = anim->firstFrame + anim->numFrames - 1 - f; -    else if( anim->flipflop && f >= anim->numFrames ) -      lf->frame = anim->firstFrame + anim->numFrames - 1 - ( f % anim->numFrames ); -    else -      lf->frame = anim->firstFrame + f; - -    if( cg.time > lf->frameTime ) -    { -      lf->frameTime = cg.time; -      if( cg_debugAnim.integer ) -        CG_Printf( "Clamp lf->frameTime\n"); -    } -  } - -  if( lf->frameTime > cg.time + 200 ) -    lf->frameTime = cg.time; - -  if( lf->oldFrameTime > cg.time ) -    lf->oldFrameTime = cg.time; - -  // calculate current lerp value -  if( lf->frameTime == lf->oldFrameTime ) -    lf->backlerp = 0; -  else -    lf->backlerp = 1.0 - (float)( cg.time - lf->oldFrameTime ) / ( lf->frameTime - lf->oldFrameTime ); -} - -/* -=============== -CG_BuildableAnimation -=============== -*/ -static void CG_BuildableAnimation( centity_t *cent, int *old, int *now, float *backLerp ) -{ -  entityState_t *es = ¢->currentState; - -  //if no animation is set default to idle anim -  if( cent->buildableAnim == BANIM_NONE ) -    cent->buildableAnim = es->torsoAnim; - -  //display the first frame of the construction anim if not yet spawned -  if( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) ) -  { -    animation_t *anim = &cg_buildables[ es->modelindex ].animations[ BANIM_CONSTRUCT1 ]; - -    //so that when animation starts for real it has sensible numbers -    cent->lerpFrame.oldFrameTime = -      cent->lerpFrame.frameTime = -      cent->lerpFrame.animationTime = -      cg.time; - -    *old      = cent->lerpFrame.oldFrame = anim->firstFrame; -    *now      = cent->lerpFrame.frame    = anim->firstFrame; -    *backLerp = cent->lerpFrame.backlerp = 0.0f; - -    //ensure that an animation is triggered once the buildable has spawned -    cent->oldBuildableAnim = BANIM_NONE; -  } -  else -  { -    if( ( cent->oldBuildableAnim ^ es->legsAnim ) & ANIM_TOGGLEBIT ) -    { -      if( cg_debugAnim.integer ) -        CG_Printf( "%d->%d l:%d t:%d %s(%d)\n", -                   cent->oldBuildableAnim, cent->buildableAnim, -                   es->legsAnim, es->torsoAnim, -                   BG_FindHumanNameForBuildable( es->modelindex ), es->number ); - -      if( cent->buildableAnim == es->torsoAnim || es->legsAnim & ANIM_FORCEBIT ) -        cent->buildableAnim = cent->oldBuildableAnim = es->legsAnim; -      else -        cent->buildableAnim = cent->oldBuildableAnim = es->torsoAnim; -    } - -    CG_RunBuildableLerpFrame( cent ); - -    *old      = cent->lerpFrame.oldFrame; -    *now      = cent->lerpFrame.frame; -    *backLerp = cent->lerpFrame.backlerp; -  } -} - -#define TRACE_DEPTH 64.0f - -/* -=============== -CG_PositionAndOrientateBuildable -=============== -*/ -static void CG_PositionAndOrientateBuildable( const vec3_t angles, const vec3_t inOrigin, -                                              const vec3_t normal, const int skipNumber, -                                              const vec3_t mins, const vec3_t maxs, -                                              vec3_t outAxis[ 3 ], vec3_t outOrigin ) -{ -  vec3_t  forward, start, end; -  trace_t tr; - -  AngleVectors( angles, forward, NULL, NULL ); -  VectorCopy( normal, outAxis[ 2 ] ); -  ProjectPointOnPlane( outAxis[ 0 ], forward, outAxis[ 2 ] ); - -  if( !VectorNormalize( outAxis[ 0 ] ) ) -  { -    AngleVectors( angles, NULL, NULL, forward ); -    ProjectPointOnPlane( outAxis[ 0 ], forward, outAxis[ 2 ] ); -    VectorNormalize( outAxis[ 0 ] ); -  } - -  CrossProduct( outAxis[ 0 ], outAxis[ 2 ], outAxis[ 1 ] ); -  outAxis[ 1 ][ 0 ] = -outAxis[ 1 ][ 0 ]; -  outAxis[ 1 ][ 1 ] = -outAxis[ 1 ][ 1 ]; -  outAxis[ 1 ][ 2 ] = -outAxis[ 1 ][ 2 ]; - -  VectorMA( inOrigin, -TRACE_DEPTH, normal, end ); -  VectorMA( inOrigin, 1.0f, normal, start ); -  CG_CapTrace( &tr, start, mins, maxs, end, skipNumber, MASK_SOLID ); - -  if( tr.fraction == 1.0f ) -  { -    //erm we missed completely - try again with a box trace -    CG_Trace( &tr, start, mins, maxs, end, skipNumber, MASK_SOLID ); -  } - -  VectorMA( inOrigin, tr.fraction * -TRACE_DEPTH, normal, outOrigin ); -} - -/* -================== -CG_GhostBuildable -================== -*/ -void CG_GhostBuildable( buildable_t buildable ) -{ -  refEntity_t     ent; -  playerState_t   *ps; -  vec3_t          angles, entity_origin; -  vec3_t          mins, maxs; -  trace_t         tr; -  float           scale; - -  ps = &cg.predictedPlayerState; - -  memset( &ent, 0, sizeof( ent ) ); - -  BG_FindBBoxForBuildable( buildable, mins, maxs ); - -  BG_PositionBuildableRelativeToPlayer( ps, mins, maxs, CG_Trace, entity_origin, angles, &tr ); - -  CG_PositionAndOrientateBuildable( ps->viewangles, entity_origin, tr.plane.normal, ps->clientNum, -                                    mins, maxs, ent.axis, ent.origin ); - -  //offset on the Z axis if required -  VectorMA( ent.origin, BG_FindZOffsetForBuildable( buildable ), tr.plane.normal, ent.origin ); - -  VectorCopy( ent.origin, ent.lightingOrigin ); -  VectorCopy( ent.origin, ent.oldorigin ); // don't positionally lerp at all - -  ent.hModel = cg_buildables[ buildable ].models[ 0 ]; - -  if( ps->stats[ STAT_BUILDABLE ] & SB_VALID_TOGGLEBIT ) -    ent.customShader = cgs.media.greenBuildShader; -  else -    ent.customShader = cgs.media.redBuildShader; - -  //rescale the model -  scale = BG_FindModelScaleForBuildable( buildable ); - -  if( scale != 1.0f ) -  { -    VectorScale( ent.axis[ 0 ], scale, ent.axis[ 0 ] ); -    VectorScale( ent.axis[ 1 ], scale, ent.axis[ 1 ] ); -    VectorScale( ent.axis[ 2 ], scale, ent.axis[ 2 ] ); - -    ent.nonNormalizedAxes = qtrue; -  } -  else -    ent.nonNormalizedAxes = qfalse; - -  // add to refresh list -  trap_R_AddRefEntityToScene( &ent ); -} - -/* -================== -CG_BuildableParticleEffects -================== -*/ -static void CG_BuildableParticleEffects( centity_t *cent ) -{ -  entityState_t   *es = ¢->currentState; -  buildableTeam_t team = BG_FindTeamForBuildable( es->modelindex ); -  int             health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT ); -  float           healthFrac = (float)health / B_HEALTH_SCALE; - -  if( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) ) -    return; - -  if( team == BIT_HUMANS ) -  { -    if( healthFrac < 0.33f && !CG_IsParticleSystemValid( ¢->buildablePS ) ) -    { -      cent->buildablePS = CG_SpawnNewParticleSystem( cgs.media.humanBuildableDamagedPS ); - -      if( CG_IsParticleSystemValid( ¢->buildablePS ) ) -      { -        CG_SetAttachmentCent( ¢->buildablePS->attachment, cent ); -        CG_AttachToCent( ¢->buildablePS->attachment ); -      } -    } -    else if( healthFrac >= 0.33f && CG_IsParticleSystemValid( ¢->buildablePS ) ) -      CG_DestroyParticleSystem( ¢->buildablePS ); -  } -  else if( team == BIT_ALIENS ) -  { -    if( healthFrac < 0.33f && !CG_IsParticleSystemValid( ¢->buildablePS ) ) -    { -      cent->buildablePS = CG_SpawnNewParticleSystem( cgs.media.alienBuildableDamagedPS ); - -      if( CG_IsParticleSystemValid( ¢->buildablePS ) ) -      { -        CG_SetAttachmentCent( ¢->buildablePS->attachment, cent ); -        CG_SetParticleSystemNormal( cent->buildablePS, es->origin2 ); -        CG_AttachToCent( ¢->buildablePS->attachment ); -      } -    } -    else if( healthFrac >= 0.33f && CG_IsParticleSystemValid( ¢->buildablePS ) ) -      CG_DestroyParticleSystem( ¢->buildablePS ); -  } -} - - -#define HEALTH_BAR_WIDTH  50.0f -#define HEALTH_BAR_HEIGHT 5.0f - -/* -================== -CG_BuildableHealthBar -================== -*/ -static void CG_BuildableHealthBar( centity_t *cent ) -{ -  vec3_t          origin, origin2, down, right, back, downLength, rightLength; -  float           rimWidth = HEALTH_BAR_HEIGHT / 15.0f; -  float           doneWidth, leftWidth, progress; -  int             health; -  qhandle_t       shader; -  entityState_t   *es; -  vec3_t          mins, maxs; - -  es = ¢->currentState; - -  health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT ); -  progress = (float)health / B_HEALTH_SCALE; - -  if( progress < 0.0f ) -    progress = 0.0f; -  else if( progress > 1.0f ) -    progress = 1.0f; - -  if( progress < 0.33f ) -    shader = cgs.media.redBuildShader; -  else -    shader = cgs.media.greenBuildShader; - -  doneWidth = ( HEALTH_BAR_WIDTH - 2 * rimWidth ) * progress; -  leftWidth = ( HEALTH_BAR_WIDTH - 2 * rimWidth ) - doneWidth; - -  VectorCopy( cg.refdef.viewaxis[ 2 ], down ); -  VectorInverse( down ); -  VectorCopy( cg.refdef.viewaxis[ 1 ], right ); -  VectorInverse( right ); -  VectorSubtract( cg.refdef.vieworg, cent->lerpOrigin, back ); -  VectorNormalize( back ); -  VectorCopy( cent->lerpOrigin, origin ); - -  BG_FindBBoxForBuildable( es->modelindex, mins, maxs ); -  VectorMA( origin, 48.0f, es->origin2, origin ); -  VectorMA( origin, -HEALTH_BAR_WIDTH / 2.0f, right, origin ); -  VectorMA( origin, maxs[ 0 ] + 8.0f, back, origin ); - -  VectorCopy( origin, origin2 ); -  VectorScale( right, rimWidth + doneWidth, rightLength ); -  VectorScale( down, HEALTH_BAR_HEIGHT, downLength ); -  CG_DrawPlane( origin2, downLength, rightLength, shader ); - -  VectorMA( origin, rimWidth + doneWidth, right, origin2 ); -  VectorScale( right, leftWidth, rightLength ); -  VectorScale( down, rimWidth, downLength ); -  CG_DrawPlane( origin2, downLength, rightLength, shader ); - -  VectorMA( origin, rimWidth + doneWidth, right, origin2 ); -  VectorMA( origin2, HEALTH_BAR_HEIGHT - rimWidth, down, origin2 ); -  VectorScale( right, leftWidth, rightLength ); -  VectorScale( down, rimWidth, downLength ); -  CG_DrawPlane( origin2, downLength, rightLength, shader ); - -  VectorMA( origin, HEALTH_BAR_WIDTH - rimWidth, right, origin2 ); -  VectorScale( right, rimWidth, rightLength ); -  VectorScale( down, HEALTH_BAR_HEIGHT, downLength ); -  CG_DrawPlane( origin2, downLength, rightLength, shader ); - -  if( !( es->generic1 & B_POWERED_TOGGLEBIT ) && -      BG_FindTeamForBuildable( es->modelindex ) == BIT_HUMANS ) -  { -    VectorMA( origin, 15.0f, right, origin2 ); -    VectorMA( origin2, HEALTH_BAR_HEIGHT + 5.0f, down, origin2 ); -    VectorScale( right, HEALTH_BAR_WIDTH / 2.0f - 5.0f, rightLength ); -    VectorScale( down,  HEALTH_BAR_WIDTH / 2.0f - 5.0f, downLength ); -    CG_DrawPlane( origin2, downLength, rightLength, cgs.media.noPowerShader ); -  } -} - -#define BUILDABLE_SOUND_PERIOD  500 - -/* -================== -CG_Buildable -================== -*/ -void CG_Buildable( centity_t *cent ) -{ -  refEntity_t     ent; -  entityState_t   *es = ¢->currentState; -  vec3_t          angles; -  vec3_t          surfNormal, xNormal, mins, maxs; -  vec3_t          refNormal = { 0.0f, 0.0f, 1.0f }; -  float           rotAngle; -  buildableTeam_t team = BG_FindTeamForBuildable( es->modelindex ); -  float           scale; -  int             health; -  float           healthScale; - -  //must be before EF_NODRAW check -  if( team == BIT_ALIENS ) -    CG_Creep( cent ); - -  // if set to invisible, skip -  if( es->eFlags & EF_NODRAW ) -  { -    if( CG_IsParticleSystemValid( ¢->buildablePS ) ) -      CG_DestroyParticleSystem( ¢->buildablePS ); - -    return; -  } - -  memset ( &ent, 0, sizeof( ent ) ); - -  VectorCopy( cent->lerpOrigin, ent.origin ); -  VectorCopy( cent->lerpOrigin, ent.oldorigin ); -  VectorCopy( cent->lerpOrigin, ent.lightingOrigin ); - -  VectorCopy( es->origin2, surfNormal ); - -  VectorCopy( es->angles, angles ); -  BG_FindBBoxForBuildable( es->modelindex, mins, maxs ); - -  if( es->pos.trType == TR_STATIONARY ) -    CG_PositionAndOrientateBuildable( angles, ent.origin, surfNormal, es->number, -                                      mins, maxs, ent.axis, ent.origin ); - -  //offset on the Z axis if required -  VectorMA( ent.origin, BG_FindZOffsetForBuildable( es->modelindex ), surfNormal, ent.origin ); - -  VectorCopy( ent.origin, ent.oldorigin ); // don't positionally lerp at all -  VectorCopy( ent.origin, ent.lightingOrigin ); - -  ent.hModel = cg_buildables[ es->modelindex ].models[ 0 ]; - -  if( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) ) -  { -    sfxHandle_t prebuildSound = cgs.media.humanBuildablePrebuild; - -    if( team == BIT_HUMANS ) -    { -      ent.customShader = cgs.media.humanSpawningShader; -      prebuildSound = cgs.media.humanBuildablePrebuild; -    } -    else if( team == BIT_ALIENS ) -      prebuildSound = cgs.media.alienBuildablePrebuild; - -    trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, prebuildSound ); -  } - -  CG_BuildableAnimation( cent, &ent.oldframe, &ent.frame, &ent.backlerp ); - -  //rescale the model -  scale = BG_FindModelScaleForBuildable( es->modelindex ); - -  if( scale != 1.0f ) -  { -    VectorScale( ent.axis[ 0 ], scale, ent.axis[ 0 ] ); -    VectorScale( ent.axis[ 1 ], scale, ent.axis[ 1 ] ); -    VectorScale( ent.axis[ 2 ], scale, ent.axis[ 2 ] ); - -    ent.nonNormalizedAxes = qtrue; -  } -  else -    ent.nonNormalizedAxes = qfalse; - - -  //add to refresh list -  trap_R_AddRefEntityToScene( &ent ); - -  CrossProduct( surfNormal, refNormal, xNormal ); -  VectorNormalize( xNormal ); -  rotAngle = RAD2DEG( acos( DotProduct( surfNormal, refNormal ) ) ); - -  //turret barrel bit -  if( cg_buildables[ es->modelindex ].models[ 1 ] ) -  { -    refEntity_t turretBarrel; -    vec3_t      flatAxis[ 3 ]; - -    memset( &turretBarrel, 0, sizeof( turretBarrel ) ); - -    turretBarrel.hModel = cg_buildables[ es->modelindex ].models[ 1 ]; - -    CG_PositionEntityOnTag( &turretBarrel, &ent, ent.hModel, "tag_turret" ); -    VectorCopy( cent->lerpOrigin, turretBarrel.lightingOrigin ); -    AnglesToAxis( es->angles2, flatAxis ); - -    RotatePointAroundVector( turretBarrel.axis[ 0 ], xNormal, flatAxis[ 0 ], -rotAngle ); -    RotatePointAroundVector( turretBarrel.axis[ 1 ], xNormal, flatAxis[ 1 ], -rotAngle ); -    RotatePointAroundVector( turretBarrel.axis[ 2 ], xNormal, flatAxis[ 2 ], -rotAngle ); - -    turretBarrel.oldframe = ent.oldframe; -    turretBarrel.frame    = ent.frame; -    turretBarrel.backlerp = ent.backlerp; - -    turretBarrel.customShader = ent.customShader; - -    if( scale != 1.0f ) -    { -      VectorScale( turretBarrel.axis[ 0 ], scale, turretBarrel.axis[ 0 ] ); -      VectorScale( turretBarrel.axis[ 1 ], scale, turretBarrel.axis[ 1 ] ); -      VectorScale( turretBarrel.axis[ 2 ], scale, turretBarrel.axis[ 2 ] ); - -      turretBarrel.nonNormalizedAxes = qtrue; -    } -    else -      turretBarrel.nonNormalizedAxes = qfalse; - -    trap_R_AddRefEntityToScene( &turretBarrel ); -  } - -  //turret barrel bit -  if( cg_buildables[ es->modelindex ].models[ 2 ] ) -  { -    refEntity_t turretTop; -    vec3_t      flatAxis[ 3 ]; -    vec3_t      swivelAngles; - -    memset( &turretTop, 0, sizeof( turretTop ) ); - -    VectorCopy( es->angles2, swivelAngles ); -    swivelAngles[ PITCH ] = 0.0f; - -    turretTop.hModel = cg_buildables[ es->modelindex ].models[ 2 ]; - -    CG_PositionRotatedEntityOnTag( &turretTop, &ent, ent.hModel, "tag_turret" ); -    VectorCopy( cent->lerpOrigin, turretTop.lightingOrigin ); -    AnglesToAxis( swivelAngles, flatAxis ); - -    RotatePointAroundVector( turretTop.axis[ 0 ], xNormal, flatAxis[ 0 ], -rotAngle ); -    RotatePointAroundVector( turretTop.axis[ 1 ], xNormal, flatAxis[ 1 ], -rotAngle ); -    RotatePointAroundVector( turretTop.axis[ 2 ], xNormal, flatAxis[ 2 ], -rotAngle ); - -    turretTop.oldframe = ent.oldframe; -    turretTop.frame    = ent.frame; -    turretTop.backlerp = ent.backlerp; - -    turretTop.customShader = ent.customShader; - -    if( scale != 1.0f ) -    { -      VectorScale( turretTop.axis[ 0 ], scale, turretTop.axis[ 0 ] ); -      VectorScale( turretTop.axis[ 1 ], scale, turretTop.axis[ 1 ] ); -      VectorScale( turretTop.axis[ 2 ], scale, turretTop.axis[ 2 ] ); - -      turretTop.nonNormalizedAxes = qtrue; -    } -    else -      turretTop.nonNormalizedAxes = qfalse; - -    trap_R_AddRefEntityToScene( &turretTop ); -  } - -  switch( cg.predictedPlayerState.weapon ) -  { -    case WP_ABUILD: -    case WP_ABUILD2: -    case WP_HBUILD: -    case WP_HBUILD2: -      if( BG_FindTeamForBuildable( es->modelindex ) == -          BG_FindTeamForWeapon( cg.predictedPlayerState.weapon ) ) -        CG_BuildableHealthBar( cent ); -      break; - -    default: -      break; -  } - -  //weapon effects for turrets -  if( es->eFlags & EF_FIRING ) -  { -    weaponInfo_t  *weapon = &cg_weapons[ es->weapon ]; - -    if( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME || -        BG_FindProjTypeForBuildable( es->modelindex ) == WP_TESLAGEN ) -    { -      if( weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 0 ] || -          weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 1 ] || -          weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 2 ] ) -      { -        trap_R_AddLightToScene( cent->lerpOrigin, 300 + ( rand( ) & 31 ), -            weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 0 ], -            weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 1 ], -            weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 2 ] ); -      } -    } - -    if( weapon->wim[ WPM_PRIMARY ].firingSound ) -    { -      trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, -          weapon->wim[ WPM_PRIMARY ].firingSound ); -    } -    else if( weapon->readySound ) -      trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, weapon->readySound ); -  } - -  health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT ); -  healthScale = (float)health / B_HEALTH_SCALE; - -  if( healthScale < cent->lastBuildableHealthScale && ( es->generic1 & B_SPAWNED_TOGGLEBIT ) ) -  { -    if( cent->lastBuildableDamageSoundTime + BUILDABLE_SOUND_PERIOD < cg.time ) -    { -      if( team == BIT_HUMANS ) -      { -        int i = rand( ) % 4; -        trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.humanBuildableDamage[ i ] ); -      } -      else if( team == BIT_ALIENS ) -        trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.alienBuildableDamage ); - -      cent->lastBuildableDamageSoundTime = cg.time; -    } -  } - -  cent->lastBuildableHealthScale = healthScale; - -  //smoke etc for damaged buildables -  CG_BuildableParticleEffects( cent ); -} diff --git a/mod/src/cgame/cg_consolecmds.c b/mod/src/cgame/cg_consolecmds.c deleted file mode 100644 index c875fa48..00000000 --- a/mod/src/cgame/cg_consolecmds.c +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_consolecmds.c -- text commands typed in at the local console, or -// executed by a key binding - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - - - -void CG_TargetCommand_f( void ) -{ -  int   targetNum; -  char  test[ 4 ]; - -  targetNum = CG_CrosshairPlayer( ); -  if( !targetNum ) -    return; - -  trap_Argv( 1, test, 4 ); -  trap_SendConsoleCommand( va( "gc %i %i", targetNum, atoi( test ) ) ); -} - - - -/* -================= -CG_SizeUp_f - -Keybinding command -================= -*/ -static void CG_SizeUp_f( void ) -{ -  trap_Cvar_Set( "cg_viewsize", va( "%i", (int)( cg_viewsize.integer + 10 ) ) ); -} - - -/* -================= -CG_SizeDown_f - -Keybinding command -================= -*/ -static void CG_SizeDown_f( void ) -{ -  trap_Cvar_Set( "cg_viewsize", va( "%i", (int)( cg_viewsize.integer - 10 ) ) ); -} - - -/* -============= -CG_Viewpos_f - -Debugging command to print the current position -============= -*/ -static void CG_Viewpos_f( void ) -{ -  CG_Printf( "(%i %i %i) : %i\n", (int)cg.refdef.vieworg[ 0 ], -    (int)cg.refdef.vieworg[ 1 ], (int)cg.refdef.vieworg[ 2 ], -    (int)cg.refdefViewAngles[ YAW ] ); -} - - -static void CG_ScoresDown_f( void ) -{ -  if( cg.scoresRequestTime + 2000 < cg.time ) -  { -    // the scores are more than two seconds out of data, -    // so request new ones -    cg.scoresRequestTime = cg.time; -    //TA: added \n SendClientCommand doesn't call flush( )? -    trap_SendClientCommand( "score\n" ); - -    // leave the current scores up if they were already -    // displayed, but if this is the first hit, clear them out -    if( !cg.showScores ) -    { -      if( cg_debugRandom.integer ) -        CG_Printf( "CG_ScoresDown_f: scores out of date\n" ); - -      cg.showScores = qtrue; -      cg.numScores = 0; -    } -  } -  else -  { -    // show the cached contents even if they just pressed if it -    // is within two seconds -    cg.showScores = qtrue; -  } -} - -static void CG_ScoresUp_f( void ) -{ -  if( cg.showScores ) -  { -    cg.showScores = qfalse; -    cg.scoreFadeTime = cg.time; -  } -} - -static void CG_TellTarget_f( void ) -{ -  int   clientNum; -  char  command[ 128 ]; -  char  message[ 128 ]; - -  clientNum = CG_CrosshairPlayer( ); -  if( clientNum == -1 ) -    return; - -  trap_Args( message, 128 ); -  Com_sprintf( command, 128, "tell %i %s", clientNum, message ); -  trap_SendClientCommand( command ); -} - -static void CG_TellAttacker_f( void ) -{ -  int   clientNum; -  char  command[ 128 ]; -  char  message[ 128 ]; - -  clientNum = CG_LastAttacker( ); -  if( clientNum == -1 ) -    return; - -  trap_Args( message, 128 ); -  Com_sprintf( command, 128, "tell %i %s", clientNum, message ); -  trap_SendClientCommand( command ); -} - -typedef struct -{ -  char  *cmd; -  void  (*function)( void ); -} consoleCommand_t; - -static consoleCommand_t commands[ ] = -{ -  { "testgun", CG_TestGun_f }, -  { "testmodel", CG_TestModel_f }, -  { "nextframe", CG_TestModelNextFrame_f }, -  { "prevframe", CG_TestModelPrevFrame_f }, -  { "nextskin", CG_TestModelNextSkin_f }, -  { "prevskin", CG_TestModelPrevSkin_f }, -  { "viewpos", CG_Viewpos_f }, -  { "+scores", CG_ScoresDown_f }, -  { "-scores", CG_ScoresUp_f }, -  { "+zoom", CG_ZoomDown_f }, -  { "-zoom", CG_ZoomUp_f }, -  { "sizeup", CG_SizeUp_f }, -  { "sizedown", CG_SizeDown_f }, -  { "weapnext", CG_NextWeapon_f }, -  { "weapprev", CG_PrevWeapon_f }, -  { "weapon", CG_Weapon_f }, -  { "tell_target", CG_TellTarget_f }, -  { "tell_attacker", CG_TellAttacker_f }, -  { "tcmd", CG_TargetCommand_f }, -  { "testPS", CG_TestPS_f }, -  { "destroyTestPS", CG_DestroyTestPS_f }, -  { "testTS", CG_TestTS_f }, -  { "destroyTestTS", CG_DestroyTestTS_f }, -}; - - -/* -================= -CG_ConsoleCommand - -The string has been tokenized and can be retrieved with -Cmd_Argc() / Cmd_Argv() -================= -*/ -qboolean CG_ConsoleCommand( void ) -{ -  const char  *cmd; -  const char  *arg1; -  int         i; - -  cmd = CG_Argv( 0 ); - -  //TA: ugly hacky special case -  if( !Q_stricmp( cmd, "ui_menu" ) ) -  { -    arg1 = CG_Argv( 1 ); -    trap_SendConsoleCommand( va( "menu %s\n", arg1 ) ); -    return qtrue; -  } - -  for( i = 0; i < sizeof( commands ) / sizeof( commands[ 0 ] ); i++ ) -  { -    if( !Q_stricmp( cmd, commands[ i ].cmd ) ) -    { -      commands[ i ].function( ); -      return qtrue; -    } -  } - -  return qfalse; -} - - -/* -================= -CG_InitConsoleCommands - -Let the client system know about all of our commands -so it can perform tab completion -================= -*/ -void CG_InitConsoleCommands( void ) -{ -  int   i; - -  for( i = 0 ; i < sizeof( commands ) / sizeof( commands[ 0 ] ) ; i++ ) -    trap_AddCommand( commands[ i ].cmd ); - -  // -  // the game server will interpret these commands, which will be automatically -  // forwarded to the server after they are not recognized locally -  // -  trap_AddCommand( "kill" ); -  trap_AddCommand( "say" ); -  trap_AddCommand( "say_team" ); -  trap_AddCommand( "tell" ); -  trap_AddCommand( "vsay" ); -  trap_AddCommand( "vsay_team" ); -  trap_AddCommand( "vtell" ); -  trap_AddCommand( "vtaunt" ); -  trap_AddCommand( "vosay" ); -  trap_AddCommand( "vosay_team" ); -  trap_AddCommand( "votell" ); -  trap_AddCommand( "give" ); -  trap_AddCommand( "god" ); -  trap_AddCommand( "notarget" ); -  trap_AddCommand( "noclip" ); -  trap_AddCommand( "team" ); -  trap_AddCommand( "follow" ); -  trap_AddCommand( "levelshot" ); -  trap_AddCommand( "addbot" ); -  trap_AddCommand( "setviewpos" ); -  trap_AddCommand( "callvote" ); -  trap_AddCommand( "vote" ); -  trap_AddCommand( "callteamvote" ); -  trap_AddCommand( "teamvote" ); -  trap_AddCommand( "stats" ); -  trap_AddCommand( "teamtask" ); -  trap_AddCommand( "class" ); -  trap_AddCommand( "build" ); -  trap_AddCommand( "buy" ); -  trap_AddCommand( "sell" ); -  trap_AddCommand( "reload" ); -  trap_AddCommand( "itemact" ); -  trap_AddCommand( "itemdeact" ); -  trap_AddCommand( "itemtoggle" ); -  trap_AddCommand( "destroy" ); -  trap_AddCommand( "deconstruct" ); -  trap_AddCommand( "menu" ); -  trap_AddCommand( "ui_menu" ); -  trap_AddCommand( "mapRotation" ); -  trap_AddCommand( "stopMapRotation" ); -  trap_AddCommand( "alienWin" ); -  trap_AddCommand( "humanWin" ); -} diff --git a/mod/src/cgame/cg_draw.c b/mod/src/cgame/cg_draw.c deleted file mode 100644 index d7c07036..00000000 --- a/mod/src/cgame/cg_draw.c +++ /dev/null @@ -1,3393 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_draw.c -- draw all of the graphical elements during -// active (after loading) gameplay - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" -#include "../ui/ui_shared.h" - -// used for scoreboard -extern    displayContextDef_t cgDC; -menuDef_t *menuScoreboard = NULL; - -int drawTeamOverlayModificationCount = -1; - -int   sortedTeamPlayers[ TEAM_MAXOVERLAY ]; -int   numSortedTeamPlayers; -char  systemChat[ 256 ]; -char  teamChat1[ 256 ]; -char  teamChat2[ 256 ]; - -//TA UI -int CG_Text_Width( const char *text, float scale, int limit ) -{ -  int         count,len; -  float       out; -  glyphInfo_t *glyph; -  float       useScale; -// FIXME: see ui_main.c, same problem -//  const unsigned char *s = text; -  const char  *s = text; -  fontInfo_t  *font = &cgDC.Assets.textFont; - -  if( scale <= cg_smallFont.value ) -    font = &cgDC.Assets.smallFont; -  else if( scale > cg_bigFont.value ) -    font = &cgDC.Assets.bigFont; - -  useScale = scale * font->glyphScale; -  out = 0; - -  if( text ) -  { -    len = strlen( text ); -    if( limit > 0 && len > limit ) -      len = limit; - -    count = 0; -    while( s && *s && count < len ) -    { -      if( Q_IsColorString( s ) ) -      { -        s += 2; -        continue; -      } -      else -      { -        glyph = &font->glyphs[ (int)*s ]; -        //TTimo: FIXME: getting nasty warnings without the cast, -        //hopefully this doesn't break the VM build -        out += glyph->xSkip; -        s++; -        count++; -      } -    } -  } - -  return out * useScale; -} - -int CG_Text_Height( const char *text, float scale, int limit ) -{ -  int         len, count; -  float       max; -  glyphInfo_t *glyph; -  float       useScale; -// TTimo: FIXME -//  const unsigned char *s = text; -  const char  *s = text; -  fontInfo_t  *font = &cgDC.Assets.textFont; - -  if( scale <= cg_smallFont.value ) -    font = &cgDC.Assets.smallFont; -  else if( scale > cg_bigFont.value ) -    font = &cgDC.Assets.bigFont; - -  useScale = scale * font->glyphScale; -  max = 0; - -  if( text ) -  { -    len = strlen( text ); -    if( limit > 0 && len > limit ) -      len = limit; - -    count = 0; -    while( s && *s && count < len ) -    { -      if( Q_IsColorString( s ) ) -      { -        s += 2; -        continue; -      } -      else -      { -        glyph = &font->glyphs[ (int)*s ]; -        //TTimo: FIXME: getting nasty warnings without the cast, -        //hopefully this doesn't break the VM build -        if( max < glyph->height ) -          max = glyph->height; - -        s++; -        count++; -      } -    } -  } - -  return max * useScale; -} - -void CG_Text_PaintChar( float x, float y, float width, float height, float scale, -                        float s, float t, float s2, float t2, qhandle_t hShader ) -{ -  float w, h; -  w = width * scale; -  h = height * scale; -  CG_AdjustFrom640( &x, &y, &w, &h ); -  trap_R_DrawStretchPic( x, y, w, h, s, t, s2, t2, hShader ); -} - -void CG_Text_Paint( float x, float y, float scale, vec4_t color, const char *text, -                    float adjust, int limit, int style ) -{ -  int         len, count; -  vec4_t      newColor; -  glyphInfo_t *glyph; -  float       useScale; -  fontInfo_t  *font = &cgDC.Assets.textFont; - -  if( scale <= cg_smallFont.value ) -    font = &cgDC.Assets.smallFont; -  else if( scale > cg_bigFont.value ) -    font = &cgDC.Assets.bigFont; - -  useScale = scale * font->glyphScale; -  if( text ) -  { -// TTimo: FIXME -//    const unsigned char *s = text; -    const char *s = text; - -    trap_R_SetColor( color ); -    memcpy( &newColor[ 0 ], &color[ 0 ], sizeof( vec4_t ) ); -    len = strlen( text ); - -    if( limit > 0 && len > limit ) -      len = limit; - -    count = 0; -    while( s && *s && count < len ) -    { -      glyph = &font->glyphs[ (int)*s ]; -      //TTimo: FIXME: getting nasty warnings without the cast, -      //hopefully this doesn't break the VM build - -      if( Q_IsColorString( s ) ) -      { -        memcpy( newColor, g_color_table[ ColorIndex( *( s + 1 ) ) ], sizeof( newColor ) ); -        newColor[ 3 ] = color[ 3 ]; -        trap_R_SetColor( newColor ); -        s += 2; -        continue; -      } -      else -      { -        float yadj = useScale * glyph->top; -        if( style == ITEM_TEXTSTYLE_SHADOWED || -            style == ITEM_TEXTSTYLE_SHADOWEDMORE ) -        { -          int ofs = style == ITEM_TEXTSTYLE_SHADOWED ? 1 : 2; -          colorBlack[ 3 ] = newColor[ 3 ]; -          trap_R_SetColor( colorBlack ); -          CG_Text_PaintChar( x + ofs, y - yadj + ofs, -                             glyph->imageWidth, -                             glyph->imageHeight, -                             useScale, -                             glyph->s, -                             glyph->t, -                             glyph->s2, -                             glyph->t2, -                             glyph->glyph ); - -          colorBlack[ 3 ] = 1.0; -          trap_R_SetColor( newColor ); -        } -        else if( style == ITEM_TEXTSTYLE_NEON ) -        { -          vec4_t glow, outer, inner, white; - -          glow[ 0 ] = newColor[ 0 ] * 0.5; -          glow[ 1 ] = newColor[ 1 ] * 0.5; -          glow[ 2 ] = newColor[ 2 ] * 0.5; -          glow[ 3 ] = newColor[ 3 ] * 0.2; - -          outer[ 0 ] = newColor[ 0 ]; -          outer[ 1 ] = newColor[ 1 ]; -          outer[ 2 ] = newColor[ 2 ]; -          outer[ 3 ] = newColor[ 3 ]; - -          inner[ 0 ] = newColor[ 0 ] * 1.5 > 1.0f ? 1.0f : newColor[ 0 ] * 1.5; -          inner[ 1 ] = newColor[ 1 ] * 1.5 > 1.0f ? 1.0f : newColor[ 1 ] * 1.5; -          inner[ 2 ] = newColor[ 2 ] * 1.5 > 1.0f ? 1.0f : newColor[ 2 ] * 1.5; -          inner[ 3 ] = newColor[ 3 ]; - -          white[ 0 ] = white[ 1 ] = white[ 2 ] = white[ 3 ] = 1.0f; - -          trap_R_SetColor( glow ); -          CG_Text_PaintChar(  x - 3, y - yadj - 3, -                              glyph->imageWidth + 6, -                              glyph->imageHeight + 6, -                              useScale, -                              glyph->s, -                              glyph->t, -                              glyph->s2, -                              glyph->t2, -                              glyph->glyph ); - -          trap_R_SetColor( outer ); -          CG_Text_PaintChar(  x - 1, y - yadj - 1, -                              glyph->imageWidth + 2, -                              glyph->imageHeight + 2, -                              useScale, -                              glyph->s, -                              glyph->t, -                              glyph->s2, -                              glyph->t2, -                              glyph->glyph ); - -          trap_R_SetColor( inner ); -          CG_Text_PaintChar(  x - 0.5, y - yadj - 0.5, -                              glyph->imageWidth + 1, -                              glyph->imageHeight + 1, -                              useScale, -                              glyph->s, -                              glyph->t, -                              glyph->s2, -                              glyph->t2, -                              glyph->glyph ); - -          trap_R_SetColor( white ); -        } - - -        CG_Text_PaintChar( x, y - yadj, -                           glyph->imageWidth, -                           glyph->imageHeight, -                           useScale, -                           glyph->s, -                           glyph->t, -                           glyph->s2, -                           glyph->t2, -                           glyph->glyph ); - -        x += ( glyph->xSkip * useScale ) + adjust; -        s++; -        count++; -      } -    } - -    trap_R_SetColor( NULL ); -  } -} - -/* -============== -CG_DrawFieldPadded - -Draws large numbers for status bar and powerups -============== -*/ -static void CG_DrawFieldPadded( int x, int y, int width, int cw, int ch, int value ) -{ -  char  num[ 16 ], *ptr; -  int   l, orgL; -  int   frame; -  int   charWidth, charHeight; - -  if( !( charWidth = cw ) ) -    charWidth = CHAR_WIDTH; - -  if( !( charHeight = ch ) ) -    charWidth = CHAR_HEIGHT; - -  if( width < 1 ) -    return; - -  // draw number string -  if( width > 4 ) -    width = 4; - -  switch( width ) -  { -    case 1: -      value = value > 9 ? 9 : value; -      value = value < 0 ? 0 : value; -      break; -    case 2: -      value = value > 99 ? 99 : value; -      value = value < -9 ? -9 : value; -      break; -    case 3: -      value = value > 999 ? 999 : value; -      value = value < -99 ? -99 : value; -      break; -    case 4: -      value = value > 9999 ? 9999 : value; -      value = value < -999 ? -999 : value; -      break; -  } - -  Com_sprintf( num, sizeof( num ), "%d", value ); -  l = strlen( num ); - -  if( l > width ) -    l = width; - -  orgL = l; - -  x += 2; - -  ptr = num; -  while( *ptr && l ) -  { -    if( width > orgL ) -    { -      CG_DrawPic( x,y, charWidth, charHeight, cgs.media.numberShaders[ 0 ] ); -      width--; -      x += charWidth; -      continue; -    } - -    if( *ptr == '-' ) -      frame = STAT_MINUS; -    else -      frame = *ptr - '0'; - -    CG_DrawPic( x,y, charWidth, charHeight, cgs.media.numberShaders[ frame ] ); -    x += charWidth; -    ptr++; -    l--; -  } -} - -/* -============== -CG_DrawField - -Draws large numbers for status bar and powerups -============== -*/ -static void CG_DrawField( int x, int y, int width, int cw, int ch, int value ) -{ -  char  num[ 16 ], *ptr; -  int   l; -  int   frame; -  int   charWidth, charHeight; - -  if( !( charWidth = cw ) ) -    charWidth = CHAR_WIDTH; - -  if( !( charHeight = ch ) ) -    charWidth = CHAR_HEIGHT; - -  if( width < 1 ) -    return; - -  // draw number string -  if( width > 4 ) -    width = 4; - -  switch( width ) -  { -    case 1: -      value = value > 9 ? 9 : value; -      value = value < 0 ? 0 : value; -      break; -    case 2: -      value = value > 99 ? 99 : value; -      value = value < -9 ? -9 : value; -      break; -    case 3: -      value = value > 999 ? 999 : value; -      value = value < -99 ? -99 : value; -      break; -    case 4: -      value = value > 9999 ? 9999 : value; -      value = value < -999 ? -999 : value; -      break; -  } - -  Com_sprintf( num, sizeof( num ), "%d", value ); -  l = strlen( num ); - -  if( l > width ) -    l = width; - -  x += 2 + charWidth * ( width - l ); - -  ptr = num; -  while( *ptr && l ) -  { -    if( *ptr == '-' ) -      frame = STAT_MINUS; -    else -      frame = *ptr -'0'; - -    CG_DrawPic( x,y, charWidth, charHeight, cgs.media.numberShaders[ frame ] ); -    x += charWidth; -    ptr++; -    l--; -  } -} - -static void CG_DrawProgressBar( rectDef_t *rect, vec4_t color, float scale, -                                int align, int textStyle, int special, float progress ) -{ -  float   rimWidth = rect->h / 20.0f; -  float   doneWidth, leftWidth; -  float   tx, ty, tw, th; -  char    textBuffer[ 8 ]; - -  if( rimWidth < 0.6f ) -    rimWidth = 0.6f; - -  if( special >= 0.0f ) -    rimWidth = special; - -  if( progress < 0.0f ) -    progress = 0.0f; -  else if( progress > 1.0f ) -    progress = 1.0f; - -  doneWidth = ( rect->w - 2 * rimWidth ) * progress; -  leftWidth = ( rect->w - 2 * rimWidth ) - doneWidth; - -  trap_R_SetColor( color ); - -  //draw rim and bar -  if( align == ITEM_ALIGN_RIGHT ) -  { -    CG_DrawPic( rect->x, rect->y, rimWidth, rect->h, cgs.media.whiteShader ); -    CG_DrawPic( rect->x + rimWidth, rect->y, -      leftWidth, rimWidth, cgs.media.whiteShader ); -    CG_DrawPic( rect->x + rimWidth, rect->y + rect->h - rimWidth, -      leftWidth, rimWidth, cgs.media.whiteShader ); -    CG_DrawPic( rect->x + rimWidth + leftWidth, rect->y, -      rimWidth + doneWidth, rect->h, cgs.media.whiteShader ); -  } -  else -  { -    CG_DrawPic( rect->x, rect->y, rimWidth + doneWidth, rect->h, cgs.media.whiteShader ); -    CG_DrawPic( rimWidth + rect->x + doneWidth, rect->y, -      leftWidth, rimWidth, cgs.media.whiteShader ); -    CG_DrawPic( rimWidth + rect->x + doneWidth, rect->y + rect->h - rimWidth, -      leftWidth, rimWidth, cgs.media.whiteShader ); -    CG_DrawPic( rect->x + rect->w - rimWidth, rect->y, rimWidth, rect->h, cgs.media.whiteShader ); -  } - -  trap_R_SetColor( NULL ); - -  //draw text -  if( scale > 0.0 ) -  { -    Com_sprintf( textBuffer, sizeof( textBuffer ), "%d%%", (int)( progress * 100 ) ); -    tw = CG_Text_Width( textBuffer, scale, 0 ); -    th = scale * 40.0f; - -    switch( align ) -    { -      case ITEM_ALIGN_LEFT: -        tx = rect->x + ( rect->w / 10.0f ); -        ty = rect->y + ( rect->h / 2.0f ) + ( th / 2.0f ); -        break; - -      case ITEM_ALIGN_RIGHT: -        tx = rect->x + rect->w - ( rect->w / 10.0f ) - tw; -        ty = rect->y + ( rect->h / 2.0f ) + ( th / 2.0f ); -        break; - -      case ITEM_ALIGN_CENTER: -        tx = rect->x + ( rect->w / 2.0f ) - ( tw / 2.0f ); -        ty = rect->y + ( rect->h / 2.0f ) + ( th / 2.0f ); -        break; - -      default: -        tx = ty = 0.0f; -    } - -    CG_Text_Paint( tx, ty, scale, color, textBuffer, 0, 0, textStyle ); -  } -} - -//=============== TA: was cg_newdraw.c - -void CG_InitTeamChat( void ) -{ -  memset( teamChat1,  0, sizeof( teamChat1 ) ); -  memset( teamChat2,  0, sizeof( teamChat2 ) ); -  memset( systemChat, 0, sizeof( systemChat ) ); -} - -void CG_SetPrintString( int type, const char *p ) -{ -  if( type == SYSTEM_PRINT ) -  { -    strcpy( systemChat, p ); -  } -  else -  { -    strcpy( teamChat2, teamChat1 ); -    strcpy( teamChat1, p ); -  } -} - -/* -=============== -CG_AtHighestClass - -Is the local client at the highest class possible? -=============== -*/ -static qboolean CG_AtHighestClass( void ) -{ -  int       i; -  qboolean  superiorClasses = qfalse; - -  for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ ) -  { -    if( BG_ClassCanEvolveFromTo( -          cg.predictedPlayerState.stats[ STAT_PCLASS ], i, -          ALIEN_MAX_KILLS, 0 ) >= 0 && -        BG_FindStagesForClass( i, cgs.alienStage ) -        /*FIXME && G_ClassIsAllowed( i )*/ ) -    { -      superiorClasses = qtrue; -      break; -    } -  } - -  return !superiorClasses; -} - -#define NO_CREDITS_TIME 2000 - -static void CG_DrawPlayerCreditsValue( rectDef_t *rect, vec4_t color, qboolean padding ) -{ -  int           value; -  playerState_t *ps; -  centity_t     *cent; - -  cent = &cg_entities[ cg.snap->ps.clientNum ]; -  ps = &cg.snap->ps; - -  //if the build timer pie is showing don't show this -  if( ( cent->currentState.weapon == WP_ABUILD || -      cent->currentState.weapon == WP_ABUILD2 ) && ps->stats[ STAT_MISC ] ) -    return; - -  value = ps->persistant[ PERS_CREDIT ]; -  if( value > -1 ) -  { -    if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS && -        !CG_AtHighestClass( ) ) -    { -      if( cg.time - cg.lastEvolveAttempt <= NO_CREDITS_TIME ) -      { -        if( ( ( cg.time - cg.lastEvolveAttempt ) / 300 ) % 2 ) -          color[ 3 ] = 0.0f; -      } -    } - -    trap_R_SetColor( color ); - -    if( padding ) -      CG_DrawFieldPadded( rect->x, rect->y, 4, rect->w / 4, rect->h, value ); -    else -      CG_DrawField( rect->x, rect->y, 1, rect->w, rect->h, value ); - -    trap_R_SetColor( NULL ); -  } -} - -static void CG_DrawPlayerBankValue( rectDef_t *rect, vec4_t color, qboolean padding ) -{ -  int           value; -  playerState_t *ps; - -  ps = &cg.snap->ps; - -  value = ps->persistant[ PERS_BANK ]; -  if( value > -1 ) -  { -    trap_R_SetColor( color ); - -    if( padding ) -      CG_DrawFieldPadded( rect->x, rect->y, 4, rect->w / 4, rect->h, value ); -    else -      CG_DrawField( rect->x, rect->y, 1, rect->w, rect->h, value ); - -    trap_R_SetColor( NULL ); -  } -} - -#define HH_MIN_ALPHA  0.2f -#define HH_MAX_ALPHA  0.8f -#define HH_ALPHA_DIFF (HH_MAX_ALPHA-HH_MIN_ALPHA) - -#define AH_MIN_ALPHA  0.2f -#define AH_MAX_ALPHA  0.8f -#define AH_ALPHA_DIFF (AH_MAX_ALPHA-AH_MIN_ALPHA) - -/* -============== -CG_DrawPlayerStamina1 -============== -*/ -static void CG_DrawPlayerStamina1( rectDef_t *rect, vec4_t color, qhandle_t shader ) -{ -  playerState_t *ps = &cg.snap->ps; -  float         stamina = ps->stats[ STAT_STAMINA ]; -  float         maxStaminaBy3 = (float)MAX_STAMINA / 3.0f; -  float         progress; - -  stamina -= ( 2 * (int)maxStaminaBy3 ); -  progress = stamina / maxStaminaBy3; - -  if( progress > 1.0f ) -    progress  = 1.0f; -  else if( progress < 0.0f ) -    progress = 0.0f; - -  color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF ); - -  trap_R_SetColor( color ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -  trap_R_SetColor( NULL ); -} - -/* -============== -CG_DrawPlayerStamina2 -============== -*/ -static void CG_DrawPlayerStamina2( rectDef_t *rect, vec4_t color, qhandle_t shader ) -{ -  playerState_t *ps = &cg.snap->ps; -  float         stamina = ps->stats[ STAT_STAMINA ]; -  float         maxStaminaBy3 = (float)MAX_STAMINA / 3.0f; -  float         progress; - -  stamina -= (int)maxStaminaBy3; -  progress = stamina / maxStaminaBy3; - -  if( progress > 1.0f ) -    progress  = 1.0f; -  else if( progress < 0.0f ) -    progress = 0.0f; - -  color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF ); - -  trap_R_SetColor( color ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -  trap_R_SetColor( NULL ); -} - -/* -============== -CG_DrawPlayerStamina3 -============== -*/ -static void CG_DrawPlayerStamina3( rectDef_t *rect, vec4_t color, qhandle_t shader ) -{ -  playerState_t *ps = &cg.snap->ps; -  float         stamina = ps->stats[ STAT_STAMINA ]; -  float         maxStaminaBy3 = (float)MAX_STAMINA / 3.0f; -  float         progress; - -  progress = stamina / maxStaminaBy3; - -  if( progress > 1.0f ) -    progress  = 1.0f; -  else if( progress < 0.0f ) -    progress = 0.0f; - -  color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF ); - -  trap_R_SetColor( color ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -  trap_R_SetColor( NULL ); -} - -/* -============== -CG_DrawPlayerStamina4 -============== -*/ -static void CG_DrawPlayerStamina4( rectDef_t *rect, vec4_t color, qhandle_t shader ) -{ -  playerState_t *ps = &cg.snap->ps; -  float         stamina = ps->stats[ STAT_STAMINA ]; -  float         progress; - -  stamina += (float)MAX_STAMINA; -  progress = stamina / (float)MAX_STAMINA; - -  if( progress > 1.0f ) -    progress  = 1.0f; -  else if( progress < 0.0f ) -    progress = 0.0f; - -  color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF ); - -  trap_R_SetColor( color ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -  trap_R_SetColor( NULL ); -} - -/* -============== -CG_DrawPlayerStaminaBolt -============== -*/ -static void CG_DrawPlayerStaminaBolt( rectDef_t *rect, vec4_t color, qhandle_t shader ) -{ -  playerState_t *ps = &cg.snap->ps; -  float         stamina = ps->stats[ STAT_STAMINA ]; - -  if( stamina < 0 ) -    color[ 3 ] = HH_MIN_ALPHA; -  else -    color[ 3 ] = HH_MAX_ALPHA; - -  trap_R_SetColor( color ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -  trap_R_SetColor( NULL ); -} - -/* -============== -CG_DrawPlayerClipsRing -============== -*/ -static void CG_DrawPlayerClipsRing( rectDef_t *rect, vec4_t color, qhandle_t shader ) -{ -  playerState_t *ps = &cg.snap->ps; -  centity_t     *cent; -  float         buildTime = ps->stats[ STAT_MISC ]; -  float         progress; -  float         maxDelay; - -  cent = &cg_entities[ cg.snap->ps.clientNum ]; - -  switch( cent->currentState.weapon ) -  { -    case WP_ABUILD: -    case WP_ABUILD2: -    case WP_HBUILD: -    case WP_HBUILD2: -      maxDelay = (float)BG_FindBuildDelayForWeapon( cent->currentState.weapon ); - -      if( buildTime > maxDelay ) -        buildTime = maxDelay; - -      progress = ( maxDelay - buildTime ) / maxDelay; - -      color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF ); -      break; - -    default: -      if( ps->weaponstate == WEAPON_RELOADING ) -      { -        maxDelay = (float)BG_FindReloadTimeForWeapon( cent->currentState.weapon ); -        progress = ( maxDelay - (float)ps->weaponTime ) / maxDelay; - -        color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF ); -      } -      break; -  } - -  trap_R_SetColor( color ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -  trap_R_SetColor( NULL ); -} - -/* -============== -CG_DrawPlayerBuildTimerRing -============== -*/ -static void CG_DrawPlayerBuildTimerRing( rectDef_t *rect, vec4_t color, qhandle_t shader ) -{ -  playerState_t *ps = &cg.snap->ps; -  centity_t     *cent; -  float         buildTime = ps->stats[ STAT_MISC ]; -  float         progress; -  float         maxDelay; - -  cent = &cg_entities[ cg.snap->ps.clientNum ]; - -  maxDelay = (float)BG_FindBuildDelayForWeapon( cent->currentState.weapon ); - -  if( buildTime > maxDelay ) -    buildTime = maxDelay; - -  progress = ( maxDelay - buildTime ) / maxDelay; - -  color[ 3 ] = AH_MIN_ALPHA + ( progress * AH_ALPHA_DIFF ); - -  trap_R_SetColor( color ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -  trap_R_SetColor( NULL ); -} - -/* -============== -CG_DrawPlayerBoosted -============== -*/ -static void CG_DrawPlayerBoosted( rectDef_t *rect, vec4_t color, qhandle_t shader ) -{ -  playerState_t *ps = &cg.snap->ps; -  qboolean      boosted = ps->stats[ STAT_STATE ] & SS_BOOSTED; - -  if( boosted ) -    color[ 3 ] = AH_MAX_ALPHA; -  else -    color[ 3 ] = AH_MIN_ALPHA; - -  trap_R_SetColor( color ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -  trap_R_SetColor( NULL ); -} - -/* -============== -CG_DrawPlayerBoosterBolt -============== -*/ -static void CG_DrawPlayerBoosterBolt( rectDef_t *rect, vec4_t color, qhandle_t shader ) -{ -  playerState_t *ps = &cg.snap->ps; -  qboolean      boosted = ps->stats[ STAT_STATE ] & SS_BOOSTED; -  vec4_t        localColor; - -  Vector4Copy( color, localColor ); - -  if( boosted ) -  { -    if( ps->stats[ STAT_BOOSTTIME ] > BOOST_TIME - 3000 ) -    { -      qboolean flash = ( ps->stats[ STAT_BOOSTTIME ] / 500 ) % 2; - -      if( flash ) -        localColor[ 3 ] = 1.0f; -    } -  } - -  trap_R_SetColor( localColor ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -  trap_R_SetColor( NULL ); -} - -/* -============== -CG_DrawPlayerPoisonBarbs -============== -*/ -static void CG_DrawPlayerPoisonBarbs( rectDef_t *rect, vec4_t color, qhandle_t shader ) -{ -  playerState_t *ps = &cg.snap->ps; -  int           x = rect->x; -  int           y = rect->y; -  int           width = rect->w; -  int           height = rect->h; -  qboolean      vertical; -  int           iconsize, numBarbs, i; - -  BG_UnpackAmmoArray( ps->weapon, ps->ammo, ps->powerups, &numBarbs, NULL ); - -  if( height > width ) -  { -    vertical = qtrue; -    iconsize = width; -  } -  else if( height <= width ) -  { -    vertical = qfalse; -    iconsize = height; -  } - -  if( color[ 3 ] != 0.0 ) -    trap_R_SetColor( color ); - -  for( i = 0; i < numBarbs; i ++ ) -  { -    if( vertical ) -      y += iconsize; -    else -      x += iconsize; - -    CG_DrawPic( x, y, iconsize, iconsize, shader ); -  } - -  trap_R_SetColor( NULL ); -} - -/* -============== -CG_DrawPlayerWallclimbing -============== -*/ -static void CG_DrawPlayerWallclimbing( rectDef_t *rect, vec4_t color, qhandle_t shader ) -{ -  playerState_t *ps = &cg.snap->ps; -  qboolean      ww = ps->stats[ STAT_STATE ] & SS_WALLCLIMBING; - -  if( ww ) -    color[ 3 ] = AH_MAX_ALPHA; -  else -    color[ 3 ] = AH_MIN_ALPHA; - -  trap_R_SetColor( color ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -  trap_R_SetColor( NULL ); -} - -static void CG_DrawPlayerStamina( rectDef_t *rect, vec4_t color, float scale, -                                  int align, int textStyle, int special ) -{ -  playerState_t *ps = &cg.snap->ps; -  int           stamina = ps->stats[ STAT_STAMINA ]; -  float         progress = ( (float)stamina + (float)MAX_STAMINA ) / ( (float)MAX_STAMINA * 2.0f ); - -  CG_DrawProgressBar( rect, color, scale, align, textStyle, special, progress ); -} - -static void CG_DrawPlayerAmmoValue( rectDef_t *rect, vec4_t color ) -{ -  int           value; -  centity_t     *cent; -  playerState_t *ps; - -  cent = &cg_entities[ cg.snap->ps.clientNum ]; -  ps = &cg.snap->ps; - -  if( cent->currentState.weapon ) -  { -    switch( cent->currentState.weapon ) -    { -      case WP_ABUILD: -      case WP_ABUILD2: -        //percentage of BP remaining -        value = cgs.alienBuildPoints; -        break; - -      case WP_HBUILD: -      case WP_HBUILD2: -        //percentage of BP remaining -        value = cgs.humanBuildPoints; -        break; - -      default: -        BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, &value, NULL ); -        break; -    } - -    if( value > 999 ) -      value = 999; - -    if( value > -1 ) -    { -      trap_R_SetColor( color ); -      CG_DrawField( rect->x, rect->y, 4, rect->w / 4, rect->h, value ); -      trap_R_SetColor( NULL ); -    } -  } -} - - -/* -============== -CG_DrawAlienSense -============== -*/ -static void CG_DrawAlienSense( rectDef_t *rect ) -{ -  if( BG_ClassHasAbility( cg.snap->ps.stats[ STAT_PCLASS ], SCA_ALIENSENSE ) ) -    CG_AlienSense( rect ); -} - - -/* -============== -CG_DrawHumanScanner -============== -*/ -static void CG_DrawHumanScanner( rectDef_t *rect, qhandle_t shader, vec4_t color ) -{ -  if( BG_InventoryContainsUpgrade( UP_HELMET, cg.snap->ps.stats ) ) -    CG_Scanner( rect, shader, color ); -} - - -/* -============== -CG_DrawUsableBuildable -============== -*/ -static void CG_DrawUsableBuildable( rectDef_t *rect, qhandle_t shader, vec4_t color ) -{ -  vec3_t        view, point; -  trace_t       trace; -  entityState_t *es; - -  AngleVectors( cg.refdefViewAngles, view, NULL, NULL ); -  VectorMA( cg.refdef.vieworg, 64, view, point ); -  CG_Trace( &trace, cg.refdef.vieworg, NULL, NULL, -            point, cg.predictedPlayerState.clientNum, MASK_SHOT ); - -  es = &cg_entities[ trace.entityNum ].currentState; - -  if( es->eType == ET_BUILDABLE && BG_FindUsableForBuildable( es->modelindex ) && -      cg.predictedPlayerState.stats[ STAT_PTEAM ] == BG_FindTeamForBuildable( es->modelindex ) ) -  { -    //hack to prevent showing the usable buildable when you aren't carrying an energy weapon -    if( ( es->modelindex == BA_H_REACTOR || es->modelindex == BA_H_REPEATER ) && -        ( !BG_FindUsesEnergyForWeapon( cg.snap->ps.weapon ) || -          BG_FindInfinteAmmoForWeapon( cg.snap->ps.weapon ) ) ) -      return; - -    trap_R_SetColor( color ); -    CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -    trap_R_SetColor( NULL ); -  } -} - - -#define BUILD_DELAY_TIME  2000 - -static void CG_DrawPlayerBuildTimer( rectDef_t *rect, vec4_t color ) -{ -  float         progress; -  int           index; -  centity_t     *cent; -  playerState_t *ps; - -  cent = &cg_entities[ cg.snap->ps.clientNum ]; -  ps = &cg.snap->ps; - -  if( cent->currentState.weapon ) -  { -    switch( cent->currentState.weapon ) -    { -      case WP_ABUILD: -        progress = (float)ps->stats[ STAT_MISC ] / (float)ABUILDER_BASE_DELAY; -        break; - -      case WP_ABUILD2: -        progress = (float)ps->stats[ STAT_MISC ] / (float)ABUILDER_ADV_DELAY; -        break; - -      case WP_HBUILD: -        progress = (float)ps->stats[ STAT_MISC ] / (float)HBUILD_DELAY; -        break; - -      case WP_HBUILD2: -        progress = (float)ps->stats[ STAT_MISC ] / (float)HBUILD2_DELAY; -        break; - -      default: -        return; -        break; -    } - -    if( !ps->stats[ STAT_MISC ] ) -      return; - -    index = (int)( progress * 8.0f ); - -    if( index > 7 ) -      index = 7; -    else if( index < 0 ) -      index = 0; - -    if( cg.time - cg.lastBuildAttempt <= BUILD_DELAY_TIME ) -    { -      if( ( ( cg.time - cg.lastBuildAttempt ) / 300 ) % 2 ) -      { -        color[ 0 ] = 1.0f; -        color[ 1 ] = color[ 2 ] = 0.0f; -        color[ 3 ] = 1.0f; -      } -    } - -    trap_R_SetColor( color ); -    CG_DrawPic( rect->x, rect->y, rect->w, rect->h, -      cgs.media.buildWeaponTimerPie[ index ] ); -    trap_R_SetColor( NULL ); -  } -} - -static void CG_DrawPlayerClipsValue( rectDef_t *rect, vec4_t color ) -{ -  int           value; -  centity_t     *cent; -  playerState_t *ps; - -  cent = &cg_entities[ cg.snap->ps.clientNum ]; -  ps = &cg.snap->ps; - -  if( cent->currentState.weapon ) -  { -    switch( cent->currentState.weapon ) -    { -      case WP_ABUILD: -      case WP_ABUILD2: -      case WP_HBUILD: -      case WP_HBUILD2: -        break; - -      default: -        BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, NULL, &value ); - -        if( value > -1 ) -        { -          trap_R_SetColor( color ); -          CG_DrawField( rect->x, rect->y, 4, rect->w / 4, rect->h, value ); -          trap_R_SetColor( NULL ); -        } -        break; -    } -  } -} - -static void CG_DrawPlayerHealthValue( rectDef_t *rect, vec4_t color ) -{ -  playerState_t *ps; -  int value; - -  ps = &cg.snap->ps; - -  value = ps->stats[ STAT_HEALTH ]; - -  trap_R_SetColor( color ); -  CG_DrawField( rect->x, rect->y, 4, rect->w / 4, rect->h, value ); -  trap_R_SetColor( NULL ); -} - -static void CG_DrawPlayerHealthBar( rectDef_t *rect, vec4_t color, float scale, -                                    int align, int textStyle, int special ) -{ -  playerState_t *ps; -  float total; - -  ps = &cg.snap->ps; - -  total = ( (float)ps->stats[ STAT_HEALTH ] / (float)ps->stats[ STAT_MAX_HEALTH ] ); -  CG_DrawProgressBar( rect, color, scale, align, textStyle, special, total ); -} - -/* -============== -CG_DrawPlayerHealthCross -============== -*/ -static void CG_DrawPlayerHealthCross( rectDef_t *rect, vec4_t color, qhandle_t shader ) -{ -  playerState_t *ps = &cg.snap->ps; -  int           health = ps->stats[ STAT_HEALTH ]; - -  if( health < 10 ) -  { -    color[ 0 ] = 1.0f; -    color[ 1 ] = color[ 2 ] = 0.0f; -  } - -  trap_R_SetColor( color ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -  trap_R_SetColor( NULL ); -} - -static void CG_DrawProgressLabel( rectDef_t *rect, float text_x, float text_y, vec4_t color, -                                  float scale, int align, const char *s, float fraction ) -{ -  vec4_t white = { 1.0f, 1.0f, 1.0f, 1.0f }; -  float tx, tw = CG_Text_Width( s, scale, 0 ); - -  switch( align ) -  { -    case ITEM_ALIGN_LEFT: -      tx = 0.0f; -      break; - -    case ITEM_ALIGN_RIGHT: -      tx = rect->w - tw; -      break; - -    case ITEM_ALIGN_CENTER: -      tx = ( rect->w / 2.0f ) - ( tw / 2.0f ); -      break; - -    default: -      tx = 0.0f; -  } - -  if( fraction < 1.0f ) -    CG_Text_Paint( rect->x + text_x + tx, rect->y + text_y, scale, white, -      s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); -  else -    CG_Text_Paint( rect->x + text_x + tx, rect->y + text_y, scale, color, -      s, 0, 0, ITEM_TEXTSTYLE_NEON ); -} - -static void CG_DrawMediaProgress( rectDef_t *rect, vec4_t color, float scale, -                                  int align, int textStyle, int special ) -{ -  CG_DrawProgressBar( rect, color, scale, align, textStyle, special, cg.mediaFraction ); -} - -static void CG_DrawMediaProgressLabel( rectDef_t *rect, float text_x, float text_y, -                                       vec4_t color, float scale, int align ) -{ -  CG_DrawProgressLabel( rect, text_x, text_y, color, scale, align, "Map and Textures", cg.mediaFraction ); -} - -static void CG_DrawBuildablesProgress( rectDef_t *rect, vec4_t color, float scale, -                                       int align, int textStyle, int special ) -{ -  CG_DrawProgressBar( rect, color, scale, align, textStyle, special, cg.buildablesFraction ); -} - -static void CG_DrawBuildablesProgressLabel( rectDef_t *rect, float text_x, float text_y, -                                            vec4_t color, float scale, int align ) -{ -  CG_DrawProgressLabel( rect, text_x, text_y, color, scale, align, "Buildable Models", cg.buildablesFraction ); -} - -static void CG_DrawCharModelProgress( rectDef_t *rect, vec4_t color, float scale, -                                      int align, int textStyle, int special ) -{ -  CG_DrawProgressBar( rect, color, scale, align, textStyle, special, cg.charModelFraction ); -} - -static void CG_DrawCharModelProgressLabel( rectDef_t *rect, float text_x, float text_y, -                                           vec4_t color, float scale, int align ) -{ -  CG_DrawProgressLabel( rect, text_x, text_y, color, scale, align, "Character Models", cg.charModelFraction ); -} - -static void CG_DrawOverallProgress( rectDef_t *rect, vec4_t color, float scale, -                                    int align, int textStyle, int special ) -{ -  float total; - -  total = ( cg.charModelFraction + cg.buildablesFraction + cg.mediaFraction ) / 3.0f; -  CG_DrawProgressBar( rect, color, scale, align, textStyle, special, total ); -} - -static void CG_DrawLevelShot( rectDef_t *rect ) -{ -  const char  *s; -  const char  *info; -  qhandle_t   levelshot; -  qhandle_t   detail; - -  info = CG_ConfigString( CS_SERVERINFO ); -  s = Info_ValueForKey( info, "mapname" ); -  levelshot = trap_R_RegisterShaderNoMip( va( "levelshots/%s.tga", s ) ); - -  if( !levelshot ) -    levelshot = trap_R_RegisterShaderNoMip( "gfx/2d/load_screen" ); - -  trap_R_SetColor( NULL ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, levelshot ); - -  // blend a detail texture over it -  detail = trap_R_RegisterShader( "levelShotDetail" ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, detail ); -} - -static void CG_DrawLoadingString( rectDef_t *rect, float text_x, float text_y, vec4_t color, -                                  float scale, int align, int textStyle, const char *s ) -{ -  float tw, th, tx; -  int   pos, i; -  char  buffer[ 1024 ]; -  char  *end; - -  if( !s[ 0 ] ) -    return; - -  strcpy( buffer, s ); -  tw = CG_Text_Width( s, scale, 0 ); -  th = scale * 40.0f; - -  pos = i = 0; - -  while( pos < strlen( s ) ) -  { -    strcpy( buffer, &s[ pos ] ); -    tw = CG_Text_Width( buffer, scale, 0 ); - -    while( tw > rect->w ) -    { -      end = strrchr( buffer, ' ' ); - -      if( end == NULL ) -        break; - -      *end = '\0'; -      tw = CG_Text_Width( buffer, scale, 0 ); -    } - -    switch( align ) -    { -      case ITEM_ALIGN_LEFT: -        tx = rect->x; -        break; - -      case ITEM_ALIGN_RIGHT: -        tx = rect->x + rect->w - tw; -        break; - -      case ITEM_ALIGN_CENTER: -        tx = rect->x + ( rect->w / 2.0f ) - ( tw / 2.0f ); -        break; - -      default: -        tx = 0.0f; -    } - -    CG_Text_Paint( tx + text_x, rect->y + text_y + i * ( th + 3 ), scale, color, -      buffer, 0, 0, textStyle ); - -    pos += strlen( buffer ) + 1; -    i++; -  } -} - -static void CG_DrawLevelName( rectDef_t *rect, float text_x, float text_y, -                              vec4_t color, float scale, int align, int textStyle ) -{ -  const char  *s; - -  s = CG_ConfigString( CS_MESSAGE ); - -  CG_DrawLoadingString( rect, text_x, text_y, color, scale, align, textStyle, s ); -} - -static void CG_DrawMOTD( rectDef_t *rect, float text_x, float text_y, -                         vec4_t color, float scale, int align, int textStyle ) -{ -  const char  *s; - -  s = CG_ConfigString( CS_MOTD ); - -  CG_DrawLoadingString( rect, text_x, text_y, color, scale, align, textStyle, s ); -} - -static void CG_DrawHostname( rectDef_t *rect, float text_x, float text_y, -                             vec4_t color, float scale, int align, int textStyle ) -{ -  char buffer[ 1024 ]; -  const char  *info; - -  info = CG_ConfigString( CS_SERVERINFO ); - -  Q_strncpyz( buffer, Info_ValueForKey( info, "sv_hostname" ), 1024 ); -  Q_CleanStr( buffer ); - -  CG_DrawLoadingString( rect, text_x, text_y, color, scale, align, textStyle, buffer ); -} - -/* -====================== -CG_UpdateMediaFraction - -====================== -*/ -void CG_UpdateMediaFraction( float newFract ) -{ -  cg.mediaFraction = newFract; - -  trap_UpdateScreen( ); -} - -/* -==================== -CG_DrawLoadingScreen - -Draw all the status / pacifier stuff during level loading -==================== -*/ -void CG_DrawLoadingScreen( void ) -{ -  Menu_Paint( Menus_FindByName( "Loading" ), qtrue ); -} - -float CG_GetValue( int ownerDraw ) -{ -  centity_t *cent; -  playerState_t *ps; - -  cent = &cg_entities[ cg.snap->ps.clientNum ]; -  ps = &cg.snap->ps; - -  switch( ownerDraw ) -  { -    case CG_PLAYER_AMMO_VALUE: -      if( cent->currentState.weapon ) -      { -        int value; - -        BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, -           &value, NULL ); - -        return value; -      } -      break; -    case CG_PLAYER_CLIPS_VALUE: -      if( cent->currentState.weapon ) -      { -        int value; - -        BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, -           NULL, &value ); - -        return value; -      } -      break; -    case CG_PLAYER_HEALTH: -      return ps->stats[ STAT_HEALTH ]; -      break; -    default: -      break; -  } - -  return -1; -} - -static void CG_DrawAreaSystemChat( rectDef_t *rect, float scale, vec4_t color, qhandle_t shader ) -{ -  CG_Text_Paint( rect->x, rect->y + rect->h, scale, color, systemChat, 0, 0, 0 ); -} - -static void CG_DrawAreaTeamChat( rectDef_t *rect, float scale, vec4_t color, qhandle_t shader ) -{ -  CG_Text_Paint( rect->x, rect->y + rect->h, scale, color,teamChat1, 0, 0, 0 ); -} - -static void CG_DrawAreaChat(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader) -{ -  CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, teamChat2, 0, 0, 0); -} - -const char *CG_GetKillerText( ) -{ -  const char *s = ""; -  if( cg.killerName[ 0 ] ) -    s = va( "Fragged by %s", cg.killerName ); - -  return s; -} - - -static void CG_DrawKiller( rectDef_t *rect, float scale, vec4_t color, -                           qhandle_t shader, int textStyle ) -{ -  // fragged by ... line - if( cg.killerName[ 0 ] ) - { -   int x = rect->x + rect->w / 2; -   CG_Text_Paint( x - CG_Text_Width( CG_GetKillerText( ), scale, 0 ) / 2, -     rect->y + rect->h, scale, color, CG_GetKillerText( ), 0, 0, textStyle ); -  } -} - - -static void CG_Text_Paint_Limit( float *maxX, float x, float y, float scale, -                                 vec4_t color, const char* text, float adjust, int limit ) -{ -  int         len, count; -  vec4_t      newColor; -  glyphInfo_t *glyph; - -  if( text ) -  { -// TTimo: FIXME -//    const unsigned char *s = text; // bk001206 - unsigned -    const char *s = text; -    float max = *maxX; -    float useScale; -    fontInfo_t *font = &cgDC.Assets.textFont; - -    if( scale <= cg_smallFont.value ) -      font = &cgDC.Assets.smallFont; -    else if( scale > cg_bigFont.value ) -      font = &cgDC.Assets.bigFont; - -    useScale = scale * font->glyphScale; -    trap_R_SetColor( color ); -    len = strlen( text ); - -    if( limit > 0 && len > limit ) -      len = limit; - -    count = 0; - -    while( s && *s && count < len ) -    { -      glyph = &font->glyphs[ (int)*s ]; -      //TTimo: FIXME: getting nasty warnings without the cast, -      //hopefully this doesn't break the VM build - -      if( Q_IsColorString( s ) ) -      { -        memcpy( newColor, g_color_table[ ColorIndex( *(s+1) ) ], sizeof( newColor ) ); -        newColor[ 3 ] = color[ 3 ]; -        trap_R_SetColor( newColor ); -        s += 2; -        continue; -      } -      else -      { -        float yadj = useScale * glyph->top; - -        if( CG_Text_Width( s, useScale, 1 ) + x > max ) -        { -          *maxX = 0; -          break; -        } - -        CG_Text_PaintChar( x, y - yadj, -                           glyph->imageWidth, -                           glyph->imageHeight, -                           useScale, -                           glyph->s, -                           glyph->t, -                           glyph->s2, -                           glyph->t2, -                           glyph->glyph ); -        x += ( glyph->xSkip * useScale ) + adjust; -        *maxX = x; -        count++; -        s++; -      } -    } - -    trap_R_SetColor( NULL ); -  } -} - -static void CG_DrawTeamSpectators( rectDef_t *rect, float scale, vec4_t color, qhandle_t shader ) -{ -  if( cg.spectatorLen ) -  { -    float maxX; - -    if( cg.spectatorWidth == -1 ) -    { -      cg.spectatorWidth = 0; -      cg.spectatorPaintX = rect->x + 1; -      cg.spectatorPaintX2 = -1; -    } - -    if( cg.spectatorOffset > cg.spectatorLen ) -    { -      cg.spectatorOffset = 0; -      cg.spectatorPaintX = rect->x + 1; -      cg.spectatorPaintX2 = -1; -    } - -    if( cg.time > cg.spectatorTime ) -    { -      cg.spectatorTime = cg.time + 10; - -      if( cg.spectatorPaintX <= rect->x + 2 ) -      { -        if( cg.spectatorOffset < cg.spectatorLen ) -        { -          //TA: skip colour directives -          if( Q_IsColorString( &cg.spectatorList[ cg.spectatorOffset ] ) ) -            cg.spectatorOffset += 2; -          else -          { -            cg.spectatorPaintX += CG_Text_Width( &cg.spectatorList[ cg.spectatorOffset ], scale, 1 ) - 1; -            cg.spectatorOffset++; -          } -        } -        else -        { -          cg.spectatorOffset = 0; - -          if( cg.spectatorPaintX2 >= 0 ) -            cg.spectatorPaintX = cg.spectatorPaintX2; -          else -            cg.spectatorPaintX = rect->x + rect->w - 2; - -          cg.spectatorPaintX2 = -1; -        } -      } -      else -      { -        cg.spectatorPaintX--; - -        if( cg.spectatorPaintX2 >= 0 ) -          cg.spectatorPaintX2--; -      } -    } - -    maxX = rect->x + rect->w - 2; - -    CG_Text_Paint_Limit( &maxX, cg.spectatorPaintX, rect->y + rect->h - 3, scale, color, -                         &cg.spectatorList[ cg.spectatorOffset ], 0, 0 ); - -    if( cg.spectatorPaintX2 >= 0 ) -    { -      float maxX2 = rect->x + rect->w - 2; -      CG_Text_Paint_Limit( &maxX2, cg.spectatorPaintX2, rect->y + rect->h - 3, scale, -                           color, cg.spectatorList, 0, cg.spectatorOffset ); -    } - -    if( cg.spectatorOffset && maxX > 0 ) -    { -      // if we have an offset ( we are skipping the first part of the string ) and we fit the string -      if( cg.spectatorPaintX2 == -1 ) -        cg.spectatorPaintX2 = rect->x + rect->w - 2; -    } -    else -      cg.spectatorPaintX2 = -1; -  } -} - -/* -================== -CG_DrawStageReport -================== -*/ -static void CG_DrawStageReport( rectDef_t *rect, float text_x, float text_y, -    vec4_t color, float scale, int align, int textStyle ) -{ -  char  s[ MAX_TOKEN_CHARS ]; -  int   tx, w, kills; - -  if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR && !cg.intermissionStarted ) -    return; - -  if( cg.intermissionStarted ) -  { -    Com_sprintf( s, MAX_TOKEN_CHARS, -        "Stage %d" //PH34R MY MAD-LEET CODING SKILLZ -        "                                                       " -        "Stage %d", -        cgs.alienStage + 1, cgs.humanStage + 1 ); -  } -  else if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -  { -    kills = cgs.alienNextStageThreshold - cgs.alienKills; - -    if( cgs.alienNextStageThreshold < 0 ) -      Com_sprintf( s, MAX_TOKEN_CHARS, "Stage %d", cgs.alienStage + 1 ); -    else if( kills == 1 ) -      Com_sprintf( s, MAX_TOKEN_CHARS, "Stage %d, %d kill for next stage", -          cgs.alienStage + 1, kills ); -    else -      Com_sprintf( s, MAX_TOKEN_CHARS, "Stage %d, %d kills for next stage", -          cgs.alienStage + 1, kills ); -  } -  else if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -  { -    kills = cgs.humanNextStageThreshold - cgs.humanKills; - -    if( cgs.humanNextStageThreshold < 0 ) -      Com_sprintf( s, MAX_TOKEN_CHARS, "Stage %d", cgs.humanStage + 1 ); -    else if( kills == 1 ) -      Com_sprintf( s, MAX_TOKEN_CHARS, "Stage %d, %d kill for next stage", -          cgs.humanStage + 1, kills ); -    else -      Com_sprintf( s, MAX_TOKEN_CHARS, "Stage %d, %d kills for next stage", -          cgs.humanStage + 1, kills ); -  } - -  w = CG_Text_Width( s, scale, 0 ); - -  switch( align ) -  { -    case ITEM_ALIGN_LEFT: -      tx = rect->x; -      break; - -    case ITEM_ALIGN_RIGHT: -      tx = rect->x + rect->w - w; -      break; - -    case ITEM_ALIGN_CENTER: -      tx = rect->x + ( rect->w / 2.0f ) - ( w / 2.0f ); -      break; - -    default: -      tx = 0.0f; -  } - -  CG_Text_Paint( text_x + tx, rect->y + text_y, scale, color, s, 0, 0, textStyle ); -} - -/* -================== -CG_DrawFPS -================== -*/ -//TA: personally i think this should be longer - it should really be a cvar -#define FPS_FRAMES  20 -#define FPS_STRING  "fps" -static void CG_DrawFPS( rectDef_t *rect, float text_x, float text_y, -                        float scale, vec4_t color, int align, int textStyle, -                        qboolean scalableText ) -{ -  char        *s; -  int         tx, w, totalWidth, strLength; -  static int  previousTimes[ FPS_FRAMES ]; -  static int  index; -  int         i, total; -  int         fps; -  static int  previous; -  int         t, frameTime; - -  if( !cg_drawFPS.integer ) -    return; - -  // don't use serverTime, because that will be drifting to -  // correct for internet lag changes, timescales, timedemos, etc -  t = trap_Milliseconds( ); -  frameTime = t - previous; -  previous = t; - -  previousTimes[ index % FPS_FRAMES ] = frameTime; -  index++; - -  if( index > FPS_FRAMES ) -  { -    // average multiple frames together to smooth changes out a bit -    total = 0; - -    for( i = 0 ; i < FPS_FRAMES ; i++ ) -      total += previousTimes[ i ]; - -    if( !total ) -      total = 1; - -    fps = 1000 * FPS_FRAMES / total; - -    s = va( "%d", fps ); -    w = CG_Text_Width( "0", scale, 0 ); -    strLength = CG_DrawStrlen( s ); -    totalWidth = CG_Text_Width( FPS_STRING, scale, 0 ) + w * strLength; - -    switch( align ) -    { -      case ITEM_ALIGN_LEFT: -        tx = rect->x; -        break; - -      case ITEM_ALIGN_RIGHT: -        tx = rect->x + rect->w - totalWidth; -        break; - -      case ITEM_ALIGN_CENTER: -        tx = rect->x + ( rect->w / 2.0f ) - ( totalWidth / 2.0f ); -        break; - -      default: -        tx = 0.0f; -    } - -    if( scalableText ) -    { -      for( i = 0; i < strLength; i++ ) -      { -        char c[ 2 ]; - -        c[ 0 ] = s[ i ]; -        c[ 1 ] = '\0'; - -        CG_Text_Paint( text_x + tx + i * w, rect->y + text_y, scale, color, c, 0, 0, textStyle ); -      } -    } -    else -    { -      trap_R_SetColor( color ); -      CG_DrawField( rect->x, rect->y, 3, rect->w / 3, rect->h, fps ); -      trap_R_SetColor( NULL ); -    } - -    if( scalableText ) -      CG_Text_Paint( text_x + tx + i * w, rect->y + text_y, scale, color, FPS_STRING, 0, 0, textStyle ); -  } -} - - -/* -================= -CG_DrawTimerMins -================= -*/ -static void CG_DrawTimerMins( rectDef_t *rect, vec4_t color ) -{ -  int     mins, seconds; -  int     msec; - -  if( !cg_drawTimer.integer ) -    return; - -  msec = cg.time - cgs.levelStartTime; - -  seconds = msec / 1000; -  mins = seconds / 60; -  seconds -= mins * 60; - -  trap_R_SetColor( color ); -  CG_DrawField( rect->x, rect->y, 3, rect->w / 3, rect->h, mins ); -  trap_R_SetColor( NULL ); -} - - -/* -================= -CG_DrawTimerSecs -================= -*/ -static void CG_DrawTimerSecs( rectDef_t *rect, vec4_t color ) -{ -  int     mins, seconds; -  int     msec; - -  if( !cg_drawTimer.integer ) -    return; - -  msec = cg.time - cgs.levelStartTime; - -  seconds = msec / 1000; -  mins = seconds / 60; -  seconds -= mins * 60; - -  trap_R_SetColor( color ); -  CG_DrawFieldPadded( rect->x, rect->y, 2, rect->w / 2, rect->h, seconds ); -  trap_R_SetColor( NULL ); -} - - -/* -================= -CG_DrawTimer -================= -*/ -static void CG_DrawTimer( rectDef_t *rect, float text_x, float text_y, -                          float scale, vec4_t color, int align, int textStyle ) -{ -  char    *s; -  int     i, tx, w, totalWidth, strLength; -  int     mins, seconds, tens; -  int     msec; - -  if( !cg_drawTimer.integer ) -    return; - -  msec = cg.time - cgs.levelStartTime; - -  seconds = msec / 1000; -  mins = seconds / 60; -  seconds -= mins * 60; -  tens = seconds / 10; -  seconds -= tens * 10; - -  s = va( "%d:%d%d", mins, tens, seconds ); -  w = CG_Text_Width( "0", scale, 0 ); -  strLength = CG_DrawStrlen( s ); -  totalWidth = w * strLength; - -  switch( align ) -  { -    case ITEM_ALIGN_LEFT: -      tx = rect->x; -      break; - -    case ITEM_ALIGN_RIGHT: -      tx = rect->x + rect->w - totalWidth; -      break; - -    case ITEM_ALIGN_CENTER: -      tx = rect->x + ( rect->w / 2.0f ) - ( totalWidth / 2.0f ); -      break; - -    default: -      tx = 0.0f; -  } - -  for( i = 0; i < strLength; i++ ) -  { -    char c[ 2 ]; - -    c[ 0 ] = s[ i ]; -    c[ 1 ] = '\0'; - -    CG_Text_Paint( text_x + tx + i * w, rect->y + text_y, scale, color, c, 0, 0, textStyle ); -  } -} - -/* -================== -CG_DrawSnapshot -================== -*/ -static void CG_DrawSnapshot( rectDef_t *rect, float text_x, float text_y, -                             float scale, vec4_t color, int align, int textStyle ) -{ -  char    *s; -  int     w, tx; - -  if( !cg_drawSnapshot.integer ) -    return; - -  s = va( "time:%d snap:%d cmd:%d", cg.snap->serverTime, -    cg.latestSnapshotNum, cgs.serverCommandSequence ); -  w = CG_Text_Width( s, scale, 0 ); - -  switch( align ) -  { -    case ITEM_ALIGN_LEFT: -      tx = rect->x; -      break; - -    case ITEM_ALIGN_RIGHT: -      tx = rect->x + rect->w - w; -      break; - -    case ITEM_ALIGN_CENTER: -      tx = rect->x + ( rect->w / 2.0f ) - ( w / 2.0f ); -      break; - -    default: -      tx = 0.0f; -  } - -  CG_Text_Paint( text_x + tx, rect->y + text_y, scale, color, s, 0, 0, textStyle ); -} - -/* -=============================================================================== - -LAGOMETER - -=============================================================================== -*/ - -#define LAG_SAMPLES   128 - -typedef struct -{ -  int frameSamples[ LAG_SAMPLES ]; -  int frameCount; -  int snapshotFlags[ LAG_SAMPLES ]; -  int snapshotSamples[ LAG_SAMPLES ]; -  int snapshotCount; -} lagometer_t; - -lagometer_t   lagometer; - -/* -============== -CG_AddLagometerFrameInfo - -Adds the current interpolate / extrapolate bar for this frame -============== -*/ -void CG_AddLagometerFrameInfo( void ) -{ -  int     offset; - -  offset = cg.time - cg.latestSnapshotTime; -  lagometer.frameSamples[ lagometer.frameCount & ( LAG_SAMPLES - 1 ) ] = offset; -  lagometer.frameCount++; -} - -/* -============== -CG_AddLagometerSnapshotInfo - -Each time a snapshot is received, log its ping time and -the number of snapshots that were dropped before it. - -Pass NULL for a dropped packet. -============== -*/ -void CG_AddLagometerSnapshotInfo( snapshot_t *snap ) -{ -  // dropped packet -  if( !snap ) -  { -    lagometer.snapshotSamples[ lagometer.snapshotCount & ( LAG_SAMPLES - 1 ) ] = -1; -    lagometer.snapshotCount++; -    return; -  } - -  // add this snapshot's info -  lagometer.snapshotSamples[ lagometer.snapshotCount & ( LAG_SAMPLES - 1 ) ] = snap->ping; -  lagometer.snapshotFlags[ lagometer.snapshotCount & ( LAG_SAMPLES - 1 ) ] = snap->snapFlags; -  lagometer.snapshotCount++; -} - -/* -============== -CG_DrawDisconnect - -Should we draw something differnet for long lag vs no packets? -============== -*/ -static void CG_DrawDisconnect( void ) -{ -  float       x, y; -  int         cmdNum; -  usercmd_t   cmd; -  const char  *s; -  int         w; -  vec4_t      color = { 1.0f, 1.0f, 1.0f, 1.0f }; - -  // draw the phone jack if we are completely past our buffers -  cmdNum = trap_GetCurrentCmdNumber( ) - CMD_BACKUP + 1; -  trap_GetUserCmd( cmdNum, &cmd ); - -  // special check for map_restart -  if( cmd.serverTime <= cg.snap->ps.commandTime || cmd.serverTime > cg.time ) -    return; - -  // also add text in center of screen -  s = "Connection Interrupted"; -  w = CG_Text_Width( s, 0.7f, 0 ); -  CG_Text_Paint( 320 - w / 2, 100, 0.7f, color, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); - -  // blink the icon -  if( ( cg.time >> 9 ) & 1 ) -    return; - -  x = 640 - 48; -  y = 480 - 48; - -  CG_DrawPic( x, y, 48, 48, trap_R_RegisterShader( "gfx/2d/net.tga" ) ); -} - -#define MAX_LAGOMETER_PING  900 -#define MAX_LAGOMETER_RANGE 300 - -#define PING_FRAMES 40 - -/* -============== -CG_DrawLagometer -============== -*/ -static void CG_DrawLagometer( rectDef_t *rect, float text_x, float text_y, -    float scale, vec4_t textColor ) -{ -  int     a, x, y, i; -  float   v; -  float   ax, ay, aw, ah, mid, range; -  int     color; -  vec4_t  adjustedColor; -  float   vscale; -  vec4_t  white = { 1.0f, 1.0f, 1.0f, 1.0f }; - -  if( cg.snap->ps.pm_type == PM_INTERMISSION ) -    return; - -  if( !cg_lagometer.integer ) -    return; - -  if( cg.demoPlayback ) -    return; - -  Vector4Copy( textColor, adjustedColor ); -  adjustedColor[ 3 ] = 0.25f; - -  trap_R_SetColor( adjustedColor ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cgs.media.whiteShader ); -  trap_R_SetColor( NULL ); - -  // -  // draw the graph -  // -  ax = x = rect->x; -  ay = y = rect->y; -  aw = rect->w; -  ah = rect->h; - -  trap_R_SetColor( NULL ); - -  CG_AdjustFrom640( &ax, &ay, &aw, &ah ); - -  color = -1; -  range = ah / 3; -  mid = ay + range; - -  vscale = range / MAX_LAGOMETER_RANGE; - -  // draw the frame interpoalte / extrapolate graph -  for( a = 0 ; a < aw ; a++ ) -  { -    i = ( lagometer.frameCount - 1 - a ) & ( LAG_SAMPLES - 1 ); -    v = lagometer.frameSamples[ i ]; -    v *= vscale; - -    if( v > 0 ) -    { -      if( color != 1 ) -      { -        color = 1; -        trap_R_SetColor( g_color_table[ ColorIndex( COLOR_YELLOW ) ] ); -      } - -      if( v > range ) -        v = range; - -      trap_R_DrawStretchPic( ax + aw - a, mid - v, 1, v, 0, 0, 0, 0, cgs.media.whiteShader ); -    } -    else if( v < 0 ) -    { -      if( color != 2 ) -      { -        color = 2; -        trap_R_SetColor( g_color_table[ ColorIndex( COLOR_BLUE ) ] ); -      } - -      v = -v; -      if( v > range ) -        v = range; - -      trap_R_DrawStretchPic( ax + aw - a, mid, 1, v, 0, 0, 0, 0, cgs.media.whiteShader ); -    } -  } - -  // draw the snapshot latency / drop graph -  range = ah / 2; -  vscale = range / MAX_LAGOMETER_PING; - -  for( a = 0 ; a < aw ; a++ ) -  { -    i = ( lagometer.snapshotCount - 1 - a ) & ( LAG_SAMPLES - 1 ); -    v = lagometer.snapshotSamples[ i ]; - -    if( v > 0 ) -    { -      if( lagometer.snapshotFlags[ i ] & SNAPFLAG_RATE_DELAYED ) -      { -        if( color != 5 ) -        { -          color = 5;  // YELLOW for rate delay -          trap_R_SetColor( g_color_table[ ColorIndex( COLOR_YELLOW ) ] ); -        } -      } -      else -      { -        if( color != 3 ) -        { -          color = 3; - -          trap_R_SetColor( g_color_table[ ColorIndex( COLOR_GREEN ) ] ); -        } -      } - -      v = v * vscale; - -      if( v > range ) -        v = range; - -      trap_R_DrawStretchPic( ax + aw - a, ay + ah - v, 1, v, 0, 0, 0, 0, cgs.media.whiteShader ); -    } -    else if( v < 0 ) -    { -      if( color != 4 ) -      { -        color = 4;    // RED for dropped snapshots -        trap_R_SetColor( g_color_table[ ColorIndex( COLOR_RED ) ] ); -      } - -      trap_R_DrawStretchPic( ax + aw - a, ay + ah - range, 1, range, 0, 0, 0, 0, cgs.media.whiteShader ); -    } -  } - -  trap_R_SetColor( NULL ); - -  if( cg_nopredict.integer || cg_synchronousClients.integer ) -    CG_Text_Paint( ax, ay, 0.5, white, "snc", 0, 0, ITEM_TEXTSTYLE_NORMAL ); -  else -  { -    static int  previousPings[ PING_FRAMES ]; -    static int  index; -    int         i, ping = 0; -    char        *s; - -    previousPings[ index++ ] = cg.snap->ping; -    index = index % PING_FRAMES; - -    for( i = 0; i < PING_FRAMES; i++ ) -      ping += previousPings[ i ]; - -    ping /= PING_FRAMES; - -    s = va( "%d", ping ); -    ax = rect->x + ( rect->w / 2.0f ) - ( CG_Text_Width( s, scale, 0 ) / 2.0f ) + text_x; -    ay = rect->y + ( rect->h / 2.0f ) + ( CG_Text_Height( s, scale, 0 ) / 2.0f ) + text_y; - -    Vector4Copy( textColor, adjustedColor ); -    adjustedColor[ 3 ] = 0.5f; -    CG_Text_Paint( ax, ay, scale, adjustedColor, s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); -  } - -  CG_DrawDisconnect( ); -} - -/* -============== -CG_DrawConsole -============== -*/ -static void CG_DrawConsole( rectDef_t *rect, float text_x, float text_y, vec4_t color, -                            float scale, int align, int textStyle ) -{ -  float     x, y, w, h; - -  //for some reason if these are stored locally occasionally rendering fails -  //even though they are both live until the end of the function, hence static -  //possible compiler bug?? -  static menuDef_t dummyParent; -  static itemDef_t textItem; - -  //offset the text -  x = rect->x; -  y = rect->y; -  w = rect->w - ( 16 + ( 2 * text_x ) ); //16 to ensure text within frame -  h = rect->h; - -  textItem.text = cg.consoleText; - -  textItem.parent = &dummyParent; -  memcpy( textItem.window.foreColor, color, sizeof( vec4_t ) ); -  textItem.window.flags = 0; - -  switch( align ) -  { -    case ITEM_ALIGN_LEFT: -      textItem.window.rect.x = x; -      break; - -    case ITEM_ALIGN_RIGHT: -      textItem.window.rect.x = x + w; -      break; - -    case ITEM_ALIGN_CENTER: -      textItem.window.rect.x = x + ( w / 2 ); -      break; - -    default: -      textItem.window.rect.x = x; -      break; -  } - -  textItem.window.rect.y = y; -  textItem.window.rect.w = w; -  textItem.window.rect.h = h; -  textItem.window.borderSize = 0; -  textItem.textRect.x = 0; -  textItem.textRect.y = 0; -  textItem.textRect.w = 0; -  textItem.textRect.h = 0; -  textItem.textalignment = align; -  textItem.textalignx = text_x; -  textItem.textaligny = text_y; -  textItem.textscale = scale; -  textItem.textStyle = textStyle; - -  //hack to utilise existing autowrap code -  Item_Text_AutoWrapped_Paint( &textItem ); -} - -/* -=================== -CG_DrawWeaponIcon -=================== -*/ -void CG_DrawWeaponIcon( rectDef_t *rect, vec4_t color ) -{ -  int           ammo, clips, maxAmmo; -  centity_t     *cent; -  playerState_t *ps; - -  cent = &cg_entities[ cg.snap->ps.clientNum ]; -  ps = &cg.snap->ps; - -  BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, &ammo, &clips ); -  BG_FindAmmoForWeapon( cent->currentState.weapon, &maxAmmo, NULL ); - -  // don't display if dead -  if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 ) -    return; - -  if( cent->currentState.weapon == 0 ) -    return; - -  CG_RegisterWeapon( cent->currentState.weapon ); - -  if( clips == 0 && !BG_FindInfinteAmmoForWeapon( cent->currentState.weapon ) ) -  { -    float ammoPercent = (float)ammo / (float)maxAmmo; - -    if( ammoPercent < 0.33f ) -    { -      color[ 0 ] = 1.0f; -      color[ 1 ] = color[ 2 ] = 0.0f; -    } -  } - -  if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS && CG_AtHighestClass( ) ) -  { -    if( cg.time - cg.lastEvolveAttempt <= NO_CREDITS_TIME ) -    { -      if( ( ( cg.time - cg.lastEvolveAttempt ) / 300 ) % 2 ) -        color[ 3 ] = 0.0f; -    } -  } - -  trap_R_SetColor( color ); -  CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cg_weapons[ cent->currentState.weapon ].weaponIcon ); -  trap_R_SetColor( NULL ); -} - - - -/* -================================================================================ - -CROSSHAIR - -================================================================================ -*/ - - -/* -================= -CG_DrawCrosshair -================= -*/ -static void CG_DrawCrosshair( void ) -{ -  float         w, h; -  qhandle_t     hShader; -  float         x, y; -  weaponInfo_t  *wi; - -  if( !cg_drawCrosshair.integer ) -    return; - -  if( ( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) || -      ( cg.snap->ps.stats[ STAT_STATE ] & SS_INFESTING ) || -      ( cg.snap->ps.stats[ STAT_STATE ] & SS_HOVELING ) ) -    return; - -  if( cg.renderingThirdPerson ) -    return; - -  wi = &cg_weapons[ cg.snap->ps.weapon ]; - -  w = h = wi->crossHairSize; - -  x = cg_crosshairX.integer; -  y = cg_crosshairY.integer; -  CG_AdjustFrom640( &x, &y, &w, &h ); - -  hShader = wi->crossHair; - -  if( hShader != 0 ) -  { -    trap_R_DrawStretchPic( x + cg.refdef.x + 0.5 * ( cg.refdef.width - w ), -      y + cg.refdef.y + 0.5 * ( cg.refdef.height - h ), -      w, h, 0, 0, 1, 1, hShader ); -  } -} - - - -/* -================= -CG_ScanForCrosshairEntity -================= -*/ -static void CG_ScanForCrosshairEntity( void ) -{ -  trace_t   trace; -  vec3_t    start, end; -  int       content; -  pTeam_t   team; - -  VectorCopy( cg.refdef.vieworg, start ); -  VectorMA( start, 131072, cg.refdef.viewaxis[ 0 ], end ); - -  CG_Trace( &trace, start, vec3_origin, vec3_origin, end, -    cg.snap->ps.clientNum, CONTENTS_SOLID|CONTENTS_BODY ); - -  if( trace.entityNum >= MAX_CLIENTS ) -    return; - -  // if the player is in fog, don't show it -  content = trap_CM_PointContents( trace.endpos, 0 ); -  if( content & CONTENTS_FOG ) -    return; - -  team = cgs.clientinfo[ trace.entityNum ].team; - -  if( cg.snap->ps.persistant[ PERS_TEAM ] != TEAM_SPECTATOR ) -  { -    //only display team names of those on the same team as this player -    if( team != cg.snap->ps.stats[ STAT_PTEAM ] ) -      return; -  } - -  // update the fade timer -  cg.crosshairClientNum = trace.entityNum; -  cg.crosshairClientTime = cg.time; -} - - -/* -===================== -CG_DrawCrosshairNames -===================== -*/ -static void CG_DrawCrosshairNames( rectDef_t *rect, float scale, int textStyle ) -{ -  float   *color; -  char    *name; -  float   w, x; - -  if( !cg_drawCrosshair.integer ) -    return; - -  if( !cg_drawCrosshairNames.integer ) -    return; - -  if( cg.renderingThirdPerson ) -    return; - -  // scan the known entities to see if the crosshair is sighted on one -  CG_ScanForCrosshairEntity( ); - -  // draw the name of the player being looked at -  color = CG_FadeColor( cg.crosshairClientTime, 1000 ); -  if( !color ) -  { -    trap_R_SetColor( NULL ); -    return; -  } - -  name = cgs.clientinfo[ cg.crosshairClientNum ].name; -  w = CG_Text_Width( name, scale, 0 ); -  x = rect->x + rect->w / 2; -  CG_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle ); -  trap_R_SetColor( NULL ); -} - - -/* -=============== -CG_OwnerDraw - -Draw an owner drawn item -=============== -*/ -void CG_OwnerDraw( float x, float y, float w, float h, float text_x, -                   float text_y, int ownerDraw, int ownerDrawFlags, -                   int align, float special, float scale, vec4_t color, -                   qhandle_t shader, int textStyle ) -{ -  rectDef_t rect; - -  if( cg_drawStatus.integer == 0 ) -    return; - -  rect.x = x; -  rect.y = y; -  rect.w = w; -  rect.h = h; - -  switch( ownerDraw ) -  { -    case CG_PLAYER_CREDITS_VALUE: -      CG_DrawPlayerCreditsValue( &rect, color, qtrue ); -      break; -    case CG_PLAYER_BANK_VALUE: -      CG_DrawPlayerBankValue( &rect, color, qtrue ); -      break; -    case CG_PLAYER_CREDITS_VALUE_NOPAD: -      CG_DrawPlayerCreditsValue( &rect, color, qfalse ); -      break; -    case CG_PLAYER_BANK_VALUE_NOPAD: -      CG_DrawPlayerBankValue( &rect, color, qfalse ); -      break; -    case CG_PLAYER_STAMINA: -      CG_DrawPlayerStamina( &rect, color, scale, align, textStyle, special ); -      break; -    case CG_PLAYER_STAMINA_1: -      CG_DrawPlayerStamina1( &rect, color, shader ); -      break; -    case CG_PLAYER_STAMINA_2: -      CG_DrawPlayerStamina2( &rect, color, shader ); -      break; -    case CG_PLAYER_STAMINA_3: -      CG_DrawPlayerStamina3( &rect, color, shader ); -      break; -    case CG_PLAYER_STAMINA_4: -      CG_DrawPlayerStamina4( &rect, color, shader ); -      break; -    case CG_PLAYER_STAMINA_BOLT: -      CG_DrawPlayerStaminaBolt( &rect, color, shader ); -      break; -    case CG_PLAYER_AMMO_VALUE: -      CG_DrawPlayerAmmoValue( &rect, color ); -      break; -    case CG_PLAYER_CLIPS_VALUE: -      CG_DrawPlayerClipsValue( &rect, color ); -      break; -    case CG_PLAYER_BUILD_TIMER: -      CG_DrawPlayerBuildTimer( &rect, color ); -      break; -    case CG_PLAYER_HEALTH: -      CG_DrawPlayerHealthValue( &rect, color ); -      break; -    case CG_PLAYER_HEALTH_BAR: -      CG_DrawPlayerHealthBar( &rect, color, scale, align, textStyle, special ); -      break; -    case CG_PLAYER_HEALTH_CROSS: -      CG_DrawPlayerHealthCross( &rect, color, shader ); -      break; -    case CG_PLAYER_CLIPS_RING: -      CG_DrawPlayerClipsRing( &rect, color, shader ); -      break; -    case CG_PLAYER_BUILD_TIMER_RING: -      CG_DrawPlayerBuildTimerRing( &rect, color, shader ); -      break; -    case CG_PLAYER_WALLCLIMBING: -      CG_DrawPlayerWallclimbing( &rect, color, shader ); -      break; -    case CG_PLAYER_BOOSTED: -      CG_DrawPlayerBoosted( &rect, color, shader ); -      break; -    case CG_PLAYER_BOOST_BOLT: -      CG_DrawPlayerBoosterBolt( &rect, color, shader ); -      break; -    case CG_PLAYER_POISON_BARBS: -      CG_DrawPlayerPoisonBarbs( &rect, color, shader ); -      break; -    case CG_PLAYER_ALIEN_SENSE: -      CG_DrawAlienSense( &rect ); -      break; -    case CG_PLAYER_HUMAN_SCANNER: -      CG_DrawHumanScanner( &rect, shader, color ); -      break; -    case CG_PLAYER_USABLE_BUILDABLE: -      CG_DrawUsableBuildable( &rect, shader, color ); -      break; -    case CG_AREA_SYSTEMCHAT: -      CG_DrawAreaSystemChat( &rect, scale, color, shader ); -      break; -    case CG_AREA_TEAMCHAT: -      CG_DrawAreaTeamChat( &rect, scale, color, shader ); -      break; -    case CG_AREA_CHAT: -      CG_DrawAreaChat( &rect, scale, color, shader ); -      break; -    case CG_KILLER: -      CG_DrawKiller( &rect, scale, color, shader, textStyle ); -      break; -    case CG_PLAYER_SELECT: -      CG_DrawItemSelect( &rect, color ); -      break; -    case CG_PLAYER_WEAPONICON: -      CG_DrawWeaponIcon( &rect, color ); -      break; -    case CG_PLAYER_SELECTTEXT: -      CG_DrawItemSelectText( &rect, scale, textStyle ); -      break; -    case CG_SPECTATORS: -      CG_DrawTeamSpectators( &rect, scale, color, shader ); -      break; -    case CG_PLAYER_CROSSHAIRNAMES: -      CG_DrawCrosshairNames( &rect, scale, textStyle ); -      break; -    case CG_STAGE_REPORT_TEXT: -      CG_DrawStageReport( &rect, text_x, text_y, color, scale, align, textStyle ); -      break; - -    //loading screen -    case CG_LOAD_LEVELSHOT: -      CG_DrawLevelShot( &rect ); -      break; -    case CG_LOAD_MEDIA: -      CG_DrawMediaProgress( &rect, color, scale, align, textStyle, special ); -      break; -    case CG_LOAD_MEDIA_LABEL: -      CG_DrawMediaProgressLabel( &rect, text_x, text_y, color, scale, align ); -      break; -    case CG_LOAD_BUILDABLES: -      CG_DrawBuildablesProgress( &rect, color, scale, align, textStyle, special ); -      break; -    case CG_LOAD_BUILDABLES_LABEL: -      CG_DrawBuildablesProgressLabel( &rect, text_x, text_y, color, scale, align ); -      break; -    case CG_LOAD_CHARMODEL: -      CG_DrawCharModelProgress( &rect, color, scale, align, textStyle, special ); -      break; -    case CG_LOAD_CHARMODEL_LABEL: -      CG_DrawCharModelProgressLabel( &rect, text_x, text_y, color, scale, align ); -      break; -    case CG_LOAD_OVERALL: -      CG_DrawOverallProgress( &rect, color, scale, align, textStyle, special ); -      break; -    case CG_LOAD_LEVELNAME: -      CG_DrawLevelName( &rect, text_x, text_y, color, scale, align, textStyle ); -      break; -    case CG_LOAD_MOTD: -      CG_DrawMOTD( &rect, text_x, text_y, color, scale, align, textStyle ); -      break; -    case CG_LOAD_HOSTNAME: -      CG_DrawHostname( &rect, text_x, text_y, color, scale, align, textStyle ); -      break; - -    case CG_FPS: -      CG_DrawFPS( &rect, text_x, text_y, scale, color, align, textStyle, qtrue ); -      break; -    case CG_FPS_FIXED: -      CG_DrawFPS( &rect, text_x, text_y, scale, color, align, textStyle, qfalse ); -      break; -    case CG_TIMER: -      CG_DrawTimer( &rect, text_x, text_y, scale, color, align, textStyle ); -      break; -    case CG_TIMER_MINS: -      CG_DrawTimerMins( &rect, color ); -      break; -    case CG_TIMER_SECS: -      CG_DrawTimerSecs( &rect, color ); -      break; -    case CG_SNAPSHOT: -      CG_DrawSnapshot( &rect, text_x, text_y, scale, color, align, textStyle ); -      break; -    case CG_LAGOMETER: -      CG_DrawLagometer( &rect, text_x, text_y, scale, color ); -      break; - -    case CG_CONSOLE: -      CG_DrawConsole( &rect, text_x, text_y, color, scale, align, textStyle ); -      break; - -    default: -      break; -  } -} - -void CG_MouseEvent( int x, int y ) -{ -  int n; - -  if( ( cg.predictedPlayerState.pm_type == PM_NORMAL || -        cg.predictedPlayerState.pm_type == PM_SPECTATOR ) && -        cg.showScores == qfalse ) -  { -    trap_Key_SetCatcher( 0 ); -    return; -  } - -  cgs.cursorX += x; -  if( cgs.cursorX < 0 ) -    cgs.cursorX = 0; -  else if( cgs.cursorX > 640 ) -    cgs.cursorX = 640; - -  cgs.cursorY += y; -  if( cgs.cursorY < 0 ) -    cgs.cursorY = 0; -  else if( cgs.cursorY > 480 ) -    cgs.cursorY = 480; - -  n = Display_CursorType( cgs.cursorX, cgs.cursorY ); -  cgs.activeCursor = 0; -  if( n == CURSOR_ARROW ) -    cgs.activeCursor = cgs.media.selectCursor; -  else if( n == CURSOR_SIZER ) -    cgs.activeCursor = cgs.media.sizeCursor; - -  if( cgs.capturedItem ) -    Display_MouseMove( cgs.capturedItem, x, y ); -  else -    Display_MouseMove( NULL, cgs.cursorX, cgs.cursorY ); -} - -/* -================== -CG_HideTeamMenus -================== - -*/ -void CG_HideTeamMenu( ) -{ -  Menus_CloseByName( "teamMenu" ); -  Menus_CloseByName( "getMenu" ); -} - -/* -================== -CG_ShowTeamMenus -================== - -*/ -void CG_ShowTeamMenu( ) -{ -  Menus_OpenByName( "teamMenu" ); -} - -/* -================== -CG_EventHandling -================== - type 0 - no event handling -      1 - team menu -      2 - hud editor - -*/ -void CG_EventHandling( int type ) -{ -  cgs.eventHandling = type; - -  if( type == CGAME_EVENT_NONE ) -    CG_HideTeamMenu( ); -} - - - -void CG_KeyEvent( int key, qboolean down ) -{ -  if( !down ) -    return; - -  if( cg.predictedPlayerState.pm_type == PM_NORMAL || -      ( cg.predictedPlayerState.pm_type == PM_SPECTATOR && -        cg.showScores == qfalse ) ) -  { -    CG_EventHandling( CGAME_EVENT_NONE ); -    trap_Key_SetCatcher( 0 ); -    return; -  } - -  Display_HandleKey( key, down, cgs.cursorX, cgs.cursorY ); - -  if( cgs.capturedItem ) -    cgs.capturedItem = NULL; -  else -  { -    if( key == K_MOUSE2 && down ) -      cgs.capturedItem = Display_CaptureItem( cgs.cursorX, cgs.cursorY ); -  } -} - -int CG_ClientNumFromName( const char *p ) -{ -  int i; - -  for( i = 0; i < cgs.maxclients; i++ ) -  { -    if( cgs.clientinfo[ i ].infoValid && -        Q_stricmp( cgs.clientinfo[ i ].name, p ) == 0 ) -      return i; -  } - -  return -1; -} - -void CG_RunMenuScript( char **args ) -{ -} - - -void CG_GetTeamColor( vec4_t *color ) -{ -  (*color)[ 0 ] = (*color)[ 2 ] = 0.0f; -  (*color)[ 1 ] = 0.17f; -  (*color)[ 3 ] = 0.25f; -} -//END TA UI - - -/* -================ -CG_DrawLighting - -================ -*/ -static void CG_DrawLighting( void ) -{ -  centity_t   *cent; - -  cent = &cg_entities[ cg.snap->ps.clientNum ]; - -  //fade to black if stamina is low -  if( ( cg.snap->ps.stats[ STAT_STAMINA ] < -800 ) && -      ( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) ) -  { -    vec4_t black = { 0, 0, 0, 0 }; -    black[ 3 ] = 1.0 - ( (float)( cg.snap->ps.stats[ STAT_STAMINA ] + 1000 ) / 200.0f ); -    trap_R_SetColor( black ); -    CG_DrawPic( 0, 0, 640, 480, cgs.media.whiteShader ); -    trap_R_SetColor( NULL ); -  } -} - -/* -=============================================================================== - -CENTER PRINTING - -=============================================================================== -*/ - - -/* -============== -CG_CenterPrint - -Called for important messages that should stay in the center of the screen -for a few moments -============== -*/ -void CG_CenterPrint( const char *str, int y, int charWidth ) -{ -  char  *s; - -  Q_strncpyz( cg.centerPrint, str, sizeof( cg.centerPrint ) ); - -  cg.centerPrintTime = cg.time; -  cg.centerPrintY = y; -  cg.centerPrintCharWidth = charWidth; - -  // count the number of lines for centering -  cg.centerPrintLines = 1; -  s = cg.centerPrint; -  while( *s ) -  { -    if( *s == '\n' ) -      cg.centerPrintLines++; - -    s++; -  } -} - - -/* -=================== -CG_DrawCenterString -=================== -*/ -static void CG_DrawCenterString( void ) -{ -  char  *start; -  int   l; -  int   x, y, w; -  int h; -  float *color; - -  if( !cg.centerPrintTime ) -    return; - -  color = CG_FadeColor( cg.centerPrintTime, 1000 * cg_centertime.value ); -  if( !color ) -    return; - -  trap_R_SetColor( color ); - -  start = cg.centerPrint; - -  y = cg.centerPrintY - cg.centerPrintLines * BIGCHAR_HEIGHT / 2; - -  while( 1 ) -  { -    char linebuffer[ 1024 ]; - -    for( l = 0; l < 50; l++ ) -    { -      if( !start[ l ] || start[ l ] == '\n' ) -        break; - -      linebuffer[ l ] = start[ l ]; -    } - -    linebuffer[ l ] = 0; - -    w = CG_Text_Width( linebuffer, 0.5, 0 ); -    h = CG_Text_Height( linebuffer, 0.5, 0 ); -    x = ( SCREEN_WIDTH - w ) / 2; -    CG_Text_Paint( x, y + h, 0.5, color, linebuffer, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE ); -    y += h + 6; - -    while( *start && ( *start != '\n' ) ) -      start++; - -    if( !*start ) -      break; - -    start++; -  } - -  trap_R_SetColor( NULL ); -} - - - - - -//============================================================================== - -//FIXME: both vote notes are hardcoded, change to ownerdrawn? - -/* -================= -CG_DrawVote -================= -*/ -static void CG_DrawVote( void ) -{ -  char    *s; -  int     sec; -  vec4_t  white = { 1.0f, 1.0f, 1.0f, 1.0f }; - -  if( !cgs.voteTime ) -    return; - -  // play a talk beep whenever it is modified -  if( cgs.voteModified ) -  { -    cgs.voteModified = qfalse; -    trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND ); -  } - -  sec = ( VOTE_TIME - ( cg.time - cgs.voteTime ) ) / 1000; - -  if( sec < 0 ) -    sec = 0; - -  s = va( "VOTE(%i): \"%s\"  Yes:%i No:%i", sec, cgs.voteString, cgs.voteYes, cgs.voteNo ); -  CG_Text_Paint( 8, 340, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); -} - -/* -================= -CG_DrawTeamVote -================= -*/ -static void CG_DrawTeamVote( void ) -{ -  char    *s; -  int     sec, cs_offset; -  vec4_t  white = { 1.0f, 1.0f, 1.0f, 1.0f }; - -  if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS ) -    cs_offset = 0; -  else if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS ) -    cs_offset = 1; -  else -    return; - -  if( !cgs.teamVoteTime[ cs_offset ] ) -    return; - -  // play a talk beep whenever it is modified -  if ( cgs.teamVoteModified[ cs_offset ] ) -  { -    cgs.teamVoteModified[ cs_offset ] = qfalse; -    trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND ); -  } - -  sec = ( VOTE_TIME - ( cg.time - cgs.teamVoteTime[ cs_offset ] ) ) / 1000; - -  if( sec < 0 ) -    sec = 0; - -  s = va( "TEAMVOTE(%i): \"%s\"  Yes:%i No:%i", sec, cgs.teamVoteString[ cs_offset ], -              cgs.teamVoteYes[cs_offset], cgs.teamVoteNo[ cs_offset ] ); - -  CG_Text_Paint( 8, 360, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); -} - - -static qboolean CG_DrawScoreboard( void ) -{ -  static qboolean firstTime = qtrue; -  float fade, *fadeColor; - -  if( menuScoreboard ) -    menuScoreboard->window.flags &= ~WINDOW_FORCED; - -  if( cg_paused.integer ) -  { -    cg.deferredPlayerLoading = 0; -    firstTime = qtrue; -    return qfalse; -  } - -  if( cg.showScores || -      cg.predictedPlayerState.pm_type == PM_INTERMISSION ) -  { -    fade = 1.0; -    fadeColor = colorWhite; -  } -  else -  { -    cg.deferredPlayerLoading = 0; -    cg.killerName[ 0 ] = 0; -    firstTime = qtrue; -    return qfalse; -  } - - -  if( menuScoreboard == NULL ) -    menuScoreboard = Menus_FindByName( "teamscore_menu" ); - -  if( menuScoreboard ) -  { -    if( firstTime ) -    { -      CG_SetScoreSelection( menuScoreboard ); -      firstTime = qfalse; -    } - -    Menu_Paint( menuScoreboard, qtrue ); -  } - -  return qtrue; -} - -/* -================= -CG_DrawIntermission -================= -*/ -static void CG_DrawIntermission( void ) -{ -  if( cg_drawStatus.integer ) -    Menu_Paint( Menus_FindByName( "default_hud" ), qtrue ); - -  cg.scoreFadeTime = cg.time; -  cg.scoreBoardShowing = CG_DrawScoreboard( ); -} - -#define FOLLOWING_STRING "following " - -/* -================= -CG_DrawFollow -================= -*/ -static qboolean CG_DrawFollow( void ) -{ -  float       w; -  vec4_t      color; -  char        buffer[ MAX_STRING_CHARS ]; - -  if( !( cg.snap->ps.pm_flags & PMF_FOLLOW ) ) -    return qfalse; - -  color[ 0 ] = 1; -  color[ 1 ] = 1; -  color[ 2 ] = 1; -  color[ 3 ] = 1; - -  strcpy( buffer, FOLLOWING_STRING ); -  strcat( buffer, cgs.clientinfo[ cg.snap->ps.clientNum ].name ); - -  w = CG_Text_Width( buffer, 0.7f, 0 ); -  CG_Text_Paint( 320 - w / 2, 400, 0.7f, color, buffer, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); - -  return qtrue; -} - -/* -================= -CG_DrawQueue -================= -*/ -static qboolean CG_DrawQueue( void ) -{ -  float       w; -  vec4_t      color; -  char        buffer[ MAX_STRING_CHARS ]; - -  if( !( cg.snap->ps.pm_flags & PMF_QUEUED ) ) -    return qfalse; - -  color[ 0 ] = 1; -  color[ 1 ] = 1; -  color[ 2 ] = 1; -  color[ 3 ] = 1; - -  Com_sprintf( buffer, MAX_STRING_CHARS, "You are in position %d of the spawn queue.", -               cg.snap->ps.persistant[ PERS_QUEUEPOS ] + 1 ); - -  w = CG_Text_Width( buffer, 0.7f, 0 ); -  CG_Text_Paint( 320 - w / 2, 360, 0.7f, color, buffer, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); - -  if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -  { -    if( cgs.numAlienSpawns == 1 ) -      Com_sprintf( buffer, MAX_STRING_CHARS, "There is 1 spawn remaining." ); -    else -      Com_sprintf( buffer, MAX_STRING_CHARS, "There are %d spawns remaining.", -                   cgs.numAlienSpawns ); -  } -  else if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -  { -    if( cgs.numHumanSpawns == 1 ) -      Com_sprintf( buffer, MAX_STRING_CHARS, "There is 1 spawn remaining." ); -    else -      Com_sprintf( buffer, MAX_STRING_CHARS, "There are %d spawns remaining.", -                   cgs.numHumanSpawns ); -  } - -  w = CG_Text_Width( buffer, 0.7f, 0 ); -  CG_Text_Paint( 320 - w / 2, 400, 0.7f, color, buffer, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); - -  return qtrue; -} - -//================================================================================== - -#define SPECTATOR_STRING "SPECTATOR" -/* -================= -CG_Draw2D -================= -*/ -static void CG_Draw2D( void ) -{ -  vec4_t    color; -  float     w; -  menuDef_t *menu = NULL, *defaultMenu; - -  color[ 0 ] = color[ 1 ] = color[ 2 ] = color[ 3 ] = 1.0f; - -  // if we are taking a levelshot for the menu, don't draw anything -  if( cg.levelShot ) -    return; - -  if( cg_draw2D.integer == 0 ) -    return; - -  if( cg.snap->ps.pm_type == PM_INTERMISSION ) -  { -    CG_DrawIntermission( ); -    return; -  } - -  //TA: draw the lighting effects e.g. nvg -  CG_DrawLighting( ); - - -  defaultMenu = Menus_FindByName( "default_hud" ); - -  if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) -  { -    w = CG_Text_Width( SPECTATOR_STRING, 0.7f, 0 ); -    CG_Text_Paint( 320 - w / 2, 440, 0.7f, color, SPECTATOR_STRING, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); -  } -  else -    menu = Menus_FindByName( BG_FindHudNameForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] ) ); - -  if( !( cg.snap->ps.stats[ STAT_STATE ] & SS_INFESTING ) && -      !( cg.snap->ps.stats[ STAT_STATE ] & SS_HOVELING ) && menu && -      ( cg.snap->ps.stats[ STAT_HEALTH ] > 0 ) ) -  { -    if( cg_drawStatus.integer ) -      Menu_Paint( menu, qtrue ); - -    CG_DrawCrosshair( ); -  } -  else if( cg_drawStatus.integer ) -    Menu_Paint( defaultMenu, qtrue ); - -  CG_DrawVote( ); -  CG_DrawTeamVote( ); -  CG_DrawFollow( ); -  CG_DrawQueue( ); - -  // don't draw center string if scoreboard is up -  cg.scoreBoardShowing = CG_DrawScoreboard( ); - -  if( !cg.scoreBoardShowing ) -    CG_DrawCenterString( ); -} - -#define PAINBLEND_BORDER_W    0.15f -#define PAINBLEND_BORDER_H    0.07f - -/* -=============== -CG_PainBlend -=============== -*/ -static void CG_PainBlend( void ) -{ -  vec4_t      color; -  int         damage; -  float       damageAsFracOfMax; -  qhandle_t   shader = cgs.media.viewBloodShader; -  float       x, y, w, h; - -  damage = cg.lastHealth - cg.snap->ps.stats[ STAT_HEALTH ]; - -  if( damage < 0 ) -    damage = 0; - -  damageAsFracOfMax = (float)damage / cg.snap->ps.stats[ STAT_MAX_HEALTH ]; -  cg.lastHealth = cg.snap->ps.stats[ STAT_HEALTH ]; - -  cg.painBlendValue += damageAsFracOfMax * cg_painBlendScale.value; - -  if( cg.painBlendValue > 0.0f ) -  { -    cg.painBlendValue -= ( cg.frametime / 1000.0f ) * -      cg_painBlendDownRate.value; -  } - -  if( cg.painBlendValue > 1.0f ) -    cg.painBlendValue = 1.0f; -  else if( cg.painBlendValue <= 0.0f ) -  { -    cg.painBlendValue = 0.0f; -    return; -  } - -  if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -    VectorSet( color, 0.43f, 0.8f, 0.37f ); -  else if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -    VectorSet( color, 0.8f, 0.0f, 0.0f ); - -  if( cg.painBlendValue > cg.painBlendTarget ) -  { -    cg.painBlendTarget += ( cg.frametime / 1000.0f ) * -      cg_painBlendUpRate.value; -  } -  else if( cg.painBlendValue < cg.painBlendTarget ) -    cg.painBlendTarget = cg.painBlendValue; - -  if( cg.painBlendTarget > cg_painBlendMax.value ) -    cg.painBlendTarget = cg_painBlendMax.value; - -  color[ 3 ] = cg.painBlendTarget; - -  trap_R_SetColor( color ); - -  //left -  x = 0.0f; y = 0.0f; -  w = PAINBLEND_BORDER_W * 640.0f; h = 480.0f; -  CG_AdjustFrom640( &x, &y, &w, &h ); -  trap_R_DrawStretchPic( x, y, w, h, -      cg_painBlendZoom.value, cg_painBlendZoom.value, -      cg_painBlendZoom.value + PAINBLEND_BORDER_W, 1.0f - cg_painBlendZoom.value, -      shader ); - -  //right -  x = 640.0f - ( PAINBLEND_BORDER_W * 640.0f ); y = 0.0f; -  w = PAINBLEND_BORDER_W * 640.0f; h = 480.0f; -  CG_AdjustFrom640( &x, &y, &w, &h ); -  trap_R_DrawStretchPic( x, y, w, h, -      1.0f - cg_painBlendZoom.value - PAINBLEND_BORDER_W, cg_painBlendZoom.value, -      1.0f - cg_painBlendZoom.value, 1.0f - cg_painBlendZoom.value, -      shader ); - -  //top -  x = PAINBLEND_BORDER_W * 640.0f; y = 0.0f; -  w = 640.0f - ( 2 * PAINBLEND_BORDER_W * 640.0f ); h = PAINBLEND_BORDER_H * 480.0f; -  CG_AdjustFrom640( &x, &y, &w, &h ); -  trap_R_DrawStretchPic( x, y, w, h, -      cg_painBlendZoom.value + PAINBLEND_BORDER_W, cg_painBlendZoom.value, -      1.0f - cg_painBlendZoom.value - PAINBLEND_BORDER_W, cg_painBlendZoom.value + PAINBLEND_BORDER_H, -      shader ); - -  //bottom -  x = PAINBLEND_BORDER_W * 640.0f; y = 480.0f - ( PAINBLEND_BORDER_H * 480.0f ); -  w = 640.0f - ( 2 * PAINBLEND_BORDER_W * 640.0f ); h = PAINBLEND_BORDER_H * 480.0f; -  CG_AdjustFrom640( &x, &y, &w, &h ); -  trap_R_DrawStretchPic( x, y, w, h, -      cg_painBlendZoom.value + PAINBLEND_BORDER_W, 1.0f - cg_painBlendZoom.value - PAINBLEND_BORDER_H, -      1.0f - cg_painBlendZoom.value - PAINBLEND_BORDER_W, 1.0f - cg_painBlendZoom.value, -      shader ); - -  trap_R_SetColor( NULL ); -} - -/* -===================== -CG_ResetPainBlend -===================== -*/ -void CG_ResetPainBlend( void ) -{ -  cg.painBlendValue = 0.0f; -  cg.painBlendTarget = 0.0f; -  cg.lastHealth = cg.snap->ps.stats[ STAT_MAX_HEALTH ]; -} - -/* -===================== -CG_DrawActive - -Perform all drawing needed to completely fill the screen -===================== -*/ -void CG_DrawActive( stereoFrame_t stereoView ) -{ -  float   separation; -  vec3_t    baseOrg; - -  // optionally draw the info screen instead -  if( !cg.snap ) -    return; - -  switch ( stereoView ) -  { -    case STEREO_CENTER: -      separation = 0; -      break; -    case STEREO_LEFT: -      separation = -cg_stereoSeparation.value / 2; -      break; -    case STEREO_RIGHT: -      separation = cg_stereoSeparation.value / 2; -      break; -    default: -      separation = 0; -      CG_Error( "CG_DrawActive: Undefined stereoView" ); -  } - -  // clear around the rendered view if sized down -  CG_TileClear( ); - -  // offset vieworg appropriately if we're doing stereo separation -  VectorCopy( cg.refdef.vieworg, baseOrg ); - -  if( separation != 0 ) -    VectorMA( cg.refdef.vieworg, -separation, cg.refdef.viewaxis[ 1 ], -              cg.refdef.vieworg ); - -  // draw 3D view -  trap_R_RenderScene( &cg.refdef ); - -  // restore original viewpoint if running stereo -  if( separation != 0 ) -    VectorCopy( baseOrg, cg.refdef.vieworg ); - -  // first person blend blobs, done after AnglesToAxis -  if( !cg.renderingThirdPerson ) -    CG_PainBlend( ); - -  // draw status bar and other floating elements -  CG_Draw2D( ); -} - - diff --git a/mod/src/cgame/cg_drawtools.c b/mod/src/cgame/cg_drawtools.c deleted file mode 100644 index b1f0d9ab..00000000 --- a/mod/src/cgame/cg_drawtools.c +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_drawtools.c -- helper functions called by cg_draw, cg_scoreboard, cg_info, etc - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -/* -=============== -CG_DrawPlane - -Draw a quad in 3 space - basically CG_DrawPic in 3 space -=============== -*/ -void CG_DrawPlane( vec3_t origin, vec3_t down, vec3_t right, qhandle_t shader ) -{ -  polyVert_t  verts[ 4 ]; -  vec3_t      temp; - -  VectorCopy( origin, verts[ 0 ].xyz ); -  verts[ 0 ].st[ 0 ] = 0; -  verts[ 0 ].st[ 1 ] = 0; -  verts[ 0 ].modulate[ 0 ] = 255; -  verts[ 0 ].modulate[ 1 ] = 255; -  verts[ 0 ].modulate[ 2 ] = 255; -  verts[ 0 ].modulate[ 3 ] = 255; - -  VectorAdd( origin, right, temp ); -  VectorCopy( temp, verts[ 1 ].xyz ); -  verts[ 1 ].st[ 0 ] = 1; -  verts[ 1 ].st[ 1 ] = 0; -  verts[ 1 ].modulate[ 0 ] = 255; -  verts[ 1 ].modulate[ 1 ] = 255; -  verts[ 1 ].modulate[ 2 ] = 255; -  verts[ 1 ].modulate[ 3 ] = 255; - -  VectorAdd( origin, right, temp ); -  VectorAdd( temp, down, temp ); -  VectorCopy( temp, verts[ 2 ].xyz ); -  verts[ 2 ].st[ 0 ] = 1; -  verts[ 2 ].st[ 1 ] = 1; -  verts[ 2 ].modulate[ 0 ] = 255; -  verts[ 2 ].modulate[ 1 ] = 255; -  verts[ 2 ].modulate[ 2 ] = 255; -  verts[ 2 ].modulate[ 3 ] = 255; - -  VectorAdd( origin, down, temp ); -  VectorCopy( temp, verts[ 3 ].xyz ); -  verts[ 3 ].st[ 0 ] = 0; -  verts[ 3 ].st[ 1 ] = 1; -  verts[ 3 ].modulate[ 0 ] = 255; -  verts[ 3 ].modulate[ 1 ] = 255; -  verts[ 3 ].modulate[ 2 ] = 255; -  verts[ 3 ].modulate[ 3 ] = 255; - -  trap_R_AddPolyToScene( shader, 4, verts ); -} - -/* -================ -CG_AdjustFrom640 - -Adjusted for resolution and screen aspect ratio -================ -*/ -void CG_AdjustFrom640( float *x, float *y, float *w, float *h ) -{ -#if 0 -  // adjust for wide screens -  if ( cgs.glconfig.vidWidth * 480 > cgs.glconfig.vidHeight * 640 ) { -    *x += 0.5 * ( cgs.glconfig.vidWidth - ( cgs.glconfig.vidHeight * 640 / 480 ) ); -  } -#endif -  // scale for screen sizes -  *x *= cgs.screenXScale; -  *y *= cgs.screenYScale; -  *w *= cgs.screenXScale; -  *h *= cgs.screenYScale; -} - -/* -================ -CG_FillRect - -Coordinates are 640*480 virtual values -================= -*/ -void CG_FillRect( float x, float y, float width, float height, const float *color ) -{ -  trap_R_SetColor( color ); - -  CG_AdjustFrom640( &x, &y, &width, &height ); -  trap_R_DrawStretchPic( x, y, width, height, 0, 0, 0, 0, cgs.media.whiteShader ); - -  trap_R_SetColor( NULL ); -} - - -/* -================ -CG_DrawSides - -Coords are virtual 640x480 -================ -*/ -void CG_DrawSides( float x, float y, float w, float h, float size ) -{ -  CG_AdjustFrom640( &x, &y, &w, &h ); -  size *= cgs.screenXScale; -  trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, cgs.media.whiteShader ); -  trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, cgs.media.whiteShader ); -} - -void CG_DrawTopBottom( float x, float y, float w, float h, float size ) -{ -  CG_AdjustFrom640( &x, &y, &w, &h ); -  size *= cgs.screenYScale; -  trap_R_DrawStretchPic( x, y, w, size, 0, 0, 0, 0, cgs.media.whiteShader ); -  trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, cgs.media.whiteShader ); -} - - -/* -================ -CG_DrawRect - -Coordinates are 640*480 virtual values -================= -*/ -void CG_DrawRect( float x, float y, float width, float height, float size, const float *color ) -{ -  trap_R_SetColor( color ); - -  CG_DrawTopBottom( x, y, width, height, size ); -  CG_DrawSides( x, y, width, height, size ); - -  trap_R_SetColor( NULL ); -} - - -/* -================ -CG_DrawPic - -Coordinates are 640*480 virtual values -================= -*/ -void CG_DrawPic( float x, float y, float width, float height, qhandle_t hShader ) -{ -  CG_AdjustFrom640( &x, &y, &width, &height ); -  trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, hShader ); -} - - - -/* -================ -CG_DrawFadePic - -Coordinates are 640*480 virtual values -================= -*/ -void CG_DrawFadePic( float x, float y, float width, float height, vec4_t fcolor, -                     vec4_t tcolor, float amount, qhandle_t hShader ) -{ -  vec4_t  finalcolor; -  float   inverse; - -  inverse = 100 - amount; - -  CG_AdjustFrom640( &x, &y, &width, &height ); - -  finalcolor[ 0 ] = ( ( inverse * fcolor[ 0 ] ) + ( amount * tcolor[ 0 ] ) ) / 100; -  finalcolor[ 1 ] = ( ( inverse * fcolor[ 1 ] ) + ( amount * tcolor[ 1 ] ) ) / 100; -  finalcolor[ 2 ] = ( ( inverse * fcolor[ 2 ] ) + ( amount * tcolor[ 2 ] ) ) / 100; -  finalcolor[ 3 ] = ( ( inverse * fcolor[ 3 ] ) + ( amount * tcolor[ 3 ] ) ) / 100; - -  trap_R_SetColor( finalcolor ); -  trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, hShader ); -  trap_R_SetColor( NULL ); -} - -/* -================= -CG_DrawStrlen - -Returns character count, skiping color escape codes -================= -*/ -int CG_DrawStrlen( const char *str ) -{ -  const char  *s = str; -  int         count = 0; - -  while( *s ) -  { -    if( Q_IsColorString( s ) ) -      s += 2; -    else -    { -      count++; -      s++; -    } -  } - -  return count; -} - -/* -============= -CG_TileClearBox - -This repeats a 64*64 tile graphic to fill the screen around a sized down -refresh window. -============= -*/ -static void CG_TileClearBox( int x, int y, int w, int h, qhandle_t hShader ) -{ -  float s1, t1, s2, t2; - -  s1 = x / 64.0; -  t1 = y / 64.0; -  s2 = ( x + w ) / 64.0; -  t2 = ( y + h ) / 64.0; -  trap_R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, hShader ); -} - - - -/* -============== -CG_TileClear - -Clear around a sized down screen -============== -*/ -void CG_TileClear( void ) -{ -  int   top, bottom, left, right; -  int   w, h; - -  w = cgs.glconfig.vidWidth; -  h = cgs.glconfig.vidHeight; - -  if( cg.refdef.x == 0 && cg.refdef.y == 0 && -      cg.refdef.width == w && cg.refdef.height == h ) -    return;   // full screen rendering - -  top = cg.refdef.y; -  bottom = top + cg.refdef.height - 1; -  left = cg.refdef.x; -  right = left + cg.refdef.width - 1; - -  // clear above view screen -  CG_TileClearBox( 0, 0, w, top, cgs.media.backTileShader ); - -  // clear below view screen -  CG_TileClearBox( 0, bottom, w, h - bottom, cgs.media.backTileShader ); - -  // clear left of view screen -  CG_TileClearBox( 0, top, left, bottom - top + 1, cgs.media.backTileShader ); - -  // clear right of view screen -  CG_TileClearBox( right, top, w - right, bottom - top + 1, cgs.media.backTileShader ); -} - - - -/* -================ -CG_FadeColor -================ -*/ -float *CG_FadeColor( int startMsec, int totalMsec ) -{ -  static vec4_t   color; -  int     t; - -  if( startMsec == 0 ) -    return NULL; - -  t = cg.time - startMsec; - -  if( t >= totalMsec ) -    return NULL; - -  // fade out -  if( totalMsec - t < FADE_TIME ) -    color[ 3 ] = ( totalMsec - t ) * 1.0 / FADE_TIME; -  else -    color[ 3 ] = 1.0; - -  color[ 0 ] = color[ 1 ] = color[ 2 ] = 1; - -  return color; -} diff --git a/mod/src/cgame/cg_ents.c b/mod/src/cgame/cg_ents.c deleted file mode 100644 index b622d2f3..00000000 --- a/mod/src/cgame/cg_ents.c +++ /dev/null @@ -1,1225 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_ents.c -- present snapshot entities, happens every single frame - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -/* -====================== -CG_DrawBoxFace - -Draws a bounding box face -====================== -*/ -static void CG_DrawBoxFace( vec3_t a, vec3_t b, vec3_t c, vec3_t d ) -{ -  polyVert_t  verts[ 4 ]; -  vec4_t      color = { 255.0f, 0.0f, 0.0f, 128.0f }; - -  VectorCopy( d, verts[ 0 ].xyz ); -  verts[ 0 ].st[ 0 ] = 1; -  verts[ 0 ].st[ 1 ] = 1; -  Vector4Copy( color, verts[ 0 ].modulate ); - -  VectorCopy( c, verts[ 1 ].xyz ); -  verts[ 1 ].st[ 0 ] = 1; -  verts[ 1 ].st[ 1 ] = 0; -  Vector4Copy( color, verts[ 1 ].modulate ); - -  VectorCopy( b, verts[ 2 ].xyz ); -  verts[ 2 ].st[ 0 ] = 0; -  verts[ 2 ].st[ 1 ] = 0; -  Vector4Copy( color, verts[ 2 ].modulate ); - -  VectorCopy( a, verts[ 3 ].xyz ); -  verts[ 3 ].st[ 0 ] = 0; -  verts[ 3 ].st[ 1 ] = 1; -  Vector4Copy( color, verts[ 3 ].modulate ); - -  trap_R_AddPolyToScene( cgs.media.outlineShader, 4, verts ); -} - -/* -====================== -CG_DrawBoundingBox - -Draws a bounding box -====================== -*/ -void CG_DrawBoundingBox( vec3_t origin, vec3_t mins, vec3_t maxs ) -{ -  vec3_t  ppp, mpp, mmp, pmp; -  vec3_t  mmm, pmm, ppm, mpm; - -  ppp[ 0 ] = origin[ 0 ] + maxs[ 0 ]; -  ppp[ 1 ] = origin[ 1 ] + maxs[ 1 ]; -  ppp[ 2 ] = origin[ 2 ] + maxs[ 2 ]; - -  mpp[ 0 ] = origin[ 0 ] + mins[ 0 ]; -  mpp[ 1 ] = origin[ 1 ] + maxs[ 1 ]; -  mpp[ 2 ] = origin[ 2 ] + maxs[ 2 ]; - -  mmp[ 0 ] = origin[ 0 ] + mins[ 0 ]; -  mmp[ 1 ] = origin[ 1 ] + mins[ 1 ]; -  mmp[ 2 ] = origin[ 2 ] + maxs[ 2 ]; - -  pmp[ 0 ] = origin[ 0 ] + maxs[ 0 ]; -  pmp[ 1 ] = origin[ 1 ] + mins[ 1 ]; -  pmp[ 2 ] = origin[ 2 ] + maxs[ 2 ]; - -  ppm[ 0 ] = origin[ 0 ] + maxs[ 0 ]; -  ppm[ 1 ] = origin[ 1 ] + maxs[ 1 ]; -  ppm[ 2 ] = origin[ 2 ] + mins[ 2 ]; - -  mpm[ 0 ] = origin[ 0 ] + mins[ 0 ]; -  mpm[ 1 ] = origin[ 1 ] + maxs[ 1 ]; -  mpm[ 2 ] = origin[ 2 ] + mins[ 2 ]; - -  mmm[ 0 ] = origin[ 0 ] + mins[ 0 ]; -  mmm[ 1 ] = origin[ 1 ] + mins[ 1 ]; -  mmm[ 2 ] = origin[ 2 ] + mins[ 2 ]; - -  pmm[ 0 ] = origin[ 0 ] + maxs[ 0 ]; -  pmm[ 1 ] = origin[ 1 ] + mins[ 1 ]; -  pmm[ 2 ] = origin[ 2 ] + mins[ 2 ]; - -  //phew! - -  CG_DrawBoxFace( ppp, mpp, mmp, pmp ); -  CG_DrawBoxFace( ppp, pmp, pmm, ppm ); -  CG_DrawBoxFace( mpp, ppp, ppm, mpm ); -  CG_DrawBoxFace( mmp, mpp, mpm, mmm ); -  CG_DrawBoxFace( pmp, mmp, mmm, pmm ); -  CG_DrawBoxFace( mmm, mpm, ppm, pmm ); -} - - -/* -====================== -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 -  if( cent->currentState.loopSound ) -  { -    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 ] ); -    } -  } - - -  // constant light glow -  if ( cent->currentState.constantLight ) -  { -    int   cl; -    int   i, r, g, b; - -    cl = cent->currentState.constantLight; -    r = cl & 255; -    g = ( cl >> 8 ) & 255; -    b = ( cl >> 16 ) & 255; -    i = ( ( cl >> 24 ) & 255 ) * 4; -    trap_R_AddLightToScene( cent->lerpOrigin, i, r, g, b ); -  } - -  if( cg.time > cent->muzzleTSDeathTime && CG_IsTrailSystemValid( ¢->muzzleTS ) ) -    CG_DestroyTrailSystem( ¢->muzzleTS ); -} - - -/* -================== -CG_General -================== -*/ -static void CG_General( centity_t *cent ) -{ -  refEntity_t     ent; -  entityState_t   *s1; - -  s1 = ¢->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_LaunchMissile -=============== -*/ -static void CG_LaunchMissile( centity_t *cent ) -{ -  entityState_t       *es; -  const weaponInfo_t  *wi; -  particleSystem_t    *ps; -  trailSystem_t       *ts; -  weapon_t            weapon; -  weaponMode_t        weaponMode; - -  es = ¢->currentState; - -  weapon = es->weapon; -  if( weapon > WP_NUM_WEAPONS ) -    weapon = WP_NONE; - -  wi = &cg_weapons[ weapon ]; -  weaponMode = es->generic1; - -  if( wi->wim[ weaponMode ].missileParticleSystem ) -  { -    ps = CG_SpawnNewParticleSystem( wi->wim[ weaponMode ].missileParticleSystem ); - -    if( CG_IsParticleSystemValid( &ps ) ) -    { -      CG_SetAttachmentCent( &ps->attachment, cent ); -      CG_AttachToCent( &ps->attachment ); -    } -  } - -  if( wi->wim[ weaponMode ].missileTrailSystem ) -  { -    ts = CG_SpawnNewTrailSystem( wi->wim[ weaponMode ].missileTrailSystem ); - -    if( CG_IsTrailSystemValid( &ts ) ) -    { -      CG_SetAttachmentCent( &ts->frontAttachment, cent ); -      CG_AttachToCent( &ts->frontAttachment ); -    } -  } -} - -/* -=============== -CG_Missile -=============== -*/ -static void CG_Missile( centity_t *cent ) -{ -  refEntity_t             ent; -  entityState_t           *es; -  const weaponInfo_t      *wi; -  weapon_t                weapon; -  weaponMode_t            weaponMode; -  const weaponInfoMode_t  *wim; - -  es = ¢->currentState; - -  weapon = es->weapon; -  if( weapon > WP_NUM_WEAPONS ) -    weapon = WP_NONE; - -  wi = &cg_weapons[ weapon ]; -  weaponMode = es->generic1; - -  wim = &wi->wim[ weaponMode ]; - -  // calculate the axis -  VectorCopy( es->angles, cent->lerpAngles ); - -  // add dynamic light -  if( wim->missileDlight ) -  { -    trap_R_AddLightToScene( cent->lerpOrigin, wim->missileDlight, -      wim->missileDlightColor[ 0 ], -      wim->missileDlightColor[ 1 ], -      wim->missileDlightColor[ 2 ] ); -  } - -  // add missile sound -  if( wim->missileSound ) -  { -    vec3_t  velocity; - -    BG_EvaluateTrajectoryDelta( ¢->currentState.pos, cg.time, velocity ); - -    trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, velocity, wim->missileSound ); -  } - -  // create the render entity -  memset( &ent, 0, sizeof( ent ) ); -  VectorCopy( cent->lerpOrigin, ent.origin ); -  VectorCopy( cent->lerpOrigin, ent.oldorigin ); - -  if( wim->usesSpriteMissle ) -  { -    ent.reType = RT_SPRITE; -    ent.radius = wim->missileSpriteSize; -    ent.rotation = 0; -    ent.customShader = wim->missileSprite; -    ent.shaderRGBA[ 0 ] = 0xFF; -    ent.shaderRGBA[ 1 ] = 0xFF; -    ent.shaderRGBA[ 2 ] = 0xFF; -    ent.shaderRGBA[ 3 ] = 0xFF; -  } -  else -  { -    ent.hModel = wim->missileModel; -    ent.renderfx = wim->missileRenderfx | RF_NOSHADOW; - -    // convert direction of travel into axis -    if( VectorNormalize2( es->pos.trDelta, ent.axis[ 0 ] ) == 0 ) -      ent.axis[ 0 ][ 2 ] = 1; - -    // spin as it moves -    if( es->pos.trType != TR_STATIONARY && wim->missileRotates ) -      RotateAroundDirection( ent.axis, cg.time / 4 ); -    else -      RotateAroundDirection( ent.axis, es->time ); - -    if( wim->missileAnimates ) -    { -      int timeSinceStart = cg.time - es->time; - -      if( wim->missileAnimLooping ) -      { -        ent.frame = wim->missileAnimStartFrame + -          (int)( ( timeSinceStart / 1000.0f ) * wim->missileAnimFrameRate ) % -          wim->missileAnimNumFrames; -      } -      else -      { -        ent.frame = wim->missileAnimStartFrame + -          (int)( ( timeSinceStart / 1000.0f ) * wim->missileAnimFrameRate ); - -        if( ent.frame > ( wim->missileAnimStartFrame + wim->missileAnimNumFrames ) ) -          ent.frame = wim->missileAnimStartFrame + wim->missileAnimNumFrames; -      } -    } -  } - -  //only refresh if there is something to display -  if( wim->missileSprite || wim->missileModel ) -    trap_R_AddRefEntityToScene( &ent ); -} - -/* -=============== -CG_Mover -=============== -*/ -static void CG_Mover( centity_t *cent ) -{ -  refEntity_t     ent; -  entityState_t   *s1; - -  s1 = ¢->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 = ¢->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 = ¢->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 ); -} - -//============================================================================ - -#define SETBOUNDS(v1,v2,r)  ((v1)[0]=(-r/2),(v1)[1]=(-r/2),(v1)[2]=(-r/2),\ -                             (v2)[0]=(r/2),(v2)[1]=(r/2),(v2)[2]=(r/2)) -#define RADIUSSTEP          0.5f - -#define FLARE_OFF       0 -#define FLARE_NOFADE    1 -#define FLARE_TIMEFADE  2 -#define FLARE_REALFADE  3 - -/* -========================= -CG_LightFlare -========================= -*/ -static void CG_LightFlare( centity_t *cent ) -{ -  refEntity_t   flare; -  entityState_t *es; -  vec3_t        forward, delta; -  float         len; -  trace_t       tr; -  float         maxAngle; -  vec3_t        mins, maxs, start, end; -  float         srcRadius, srLocal, ratio = 1.0f; -  int           entityNum; - -  es = ¢->currentState; - -  if( cg.renderingThirdPerson ) -    entityNum = MAGIC_TRACE_HACK; -  else -    entityNum = cg.predictedPlayerState.clientNum; - -  //don't draw light flares -  if( cg_lightFlare.integer == FLARE_OFF ) -    return; - -  //flare is "off" -  if( es->eFlags & EF_NODRAW ) -    return; - -  CG_Trace( &tr, cg.refdef.vieworg, NULL, NULL, es->angles2, -            entityNum, MASK_SHOT ); - -  //if there is no los between the view and the flare source -  //it definately cannot be seen -  if( tr.fraction < 1.0f || tr.allsolid ) -    return; - -  memset( &flare, 0, sizeof( flare ) ); - -  flare.reType = RT_SPRITE; -  flare.customShader = cgs.gameShaders[ es->modelindex ]; -  flare.shaderRGBA[ 0 ] = 0xFF; -  flare.shaderRGBA[ 1 ] = 0xFF; -  flare.shaderRGBA[ 2 ] = 0xFF; -  flare.shaderRGBA[ 3 ] = 0xFF; - -  //flares always drawn before the rest of the scene -  flare.renderfx |= RF_DEPTHHACK; - -  //bunch of geometry -  AngleVectors( es->angles, forward, NULL, NULL ); -  VectorCopy( cent->lerpOrigin, flare.origin ); -  VectorSubtract( flare.origin, cg.refdef.vieworg, delta ); -  len = VectorLength( delta ); -  VectorNormalize( delta ); - -  //flare is too close to camera to be drawn -  if( len < es->generic1 ) -    return; - -  //don't bother for flares behind the view plane -  if( DotProduct( delta, cg.refdef.viewaxis[ 0 ] ) < 0.0 ) -    return; - -  //only recalculate radius and ratio every three frames -  if( !( cg.clientFrame % 2 ) ) -  { -    //can only see the flare when in front of it -    flare.radius = len / es->origin2[ 0 ]; - -    if( es->origin2[ 2 ] == 0 ) -      srcRadius = srLocal = flare.radius / 2.0f; -    else -      srcRadius = srLocal = len / es->origin2[ 2 ]; - -    maxAngle = es->origin2[ 1 ]; - -    if( maxAngle > 0.0f ) -    { -      float radiusMod = 1.0f - ( 180.0f - RAD2DEG( -            acos( DotProduct( delta, forward ) ) ) ) / maxAngle; - -      if( es->eFlags & EF_NODRAW ) -        flare.radius *= radiusMod; -      else if( radiusMod < 0.0f ) -        flare.radius = 0.0f; -    } - -    if( flare.radius < 0.0f ) -      flare.radius = 0.0f; - -    VectorMA( flare.origin, -flare.radius, delta, end ); -    VectorMA( cg.refdef.vieworg, flare.radius, delta, start ); - -    if( cg_lightFlare.integer == FLARE_REALFADE ) -    { -      //draw "correct" albeit inefficient flares -      srLocal = cent->lfs.lastSrcRadius; - -      //flare radius is likely to be the same as last frame so start with it -      do -      { -        srLocal += RADIUSSTEP; -        SETBOUNDS( mins, maxs, srLocal ); -        CG_Trace( &tr, start, mins, maxs, end, -                  entityNum, MASK_SHOT ); - -      } while( ( tr.fraction == 1.0f && !tr.startsolid ) && ( srLocal < srcRadius ) ); - -      srLocal -= RADIUSSTEP; - -      //shink the flare until there is a los -      do -      { -        SETBOUNDS( mins, maxs, srLocal ); -        CG_Trace( &tr, start, mins, maxs, end, -                  entityNum, MASK_SHOT ); - -        srLocal -= RADIUSSTEP; -      } while( ( tr.fraction < 1.0f || tr.startsolid ) && ( srLocal > 0.0f ) ); - -      ratio = srLocal / srcRadius; - -      cent->lfs.lastSrcRadius = srLocal; -    } -    else if( cg_lightFlare.integer == FLARE_TIMEFADE ) -    { -      //draw timed flares -      SETBOUNDS( mins, maxs, srcRadius ); -      CG_Trace( &tr, start, mins, maxs, end, -                entityNum, MASK_SHOT ); - -      if( ( tr.fraction < 1.0f || tr.startsolid ) && cent->lfs.status ) -      { -        cent->lfs.status = qfalse; -        cent->lfs.lastTime = cg.time; -      } -      else if( ( tr.fraction == 1.0f && !tr.startsolid ) && !cent->lfs.status ) -      { -        cent->lfs.status = qtrue; -        cent->lfs.lastTime = cg.time; -      } - -      //fade flare up -      if( cent->lfs.status ) -      { -        if( cent->lfs.lastTime + es->time > cg.time ) -          ratio = (float)( cg.time - cent->lfs.lastTime ) / es->time; -      } - -      //fade flare down -      if( !cent->lfs.status ) -      { -        if( cent->lfs.lastTime + es->time > cg.time ) -        { -          ratio = (float)( cg.time - cent->lfs.lastTime ) / es->time; -          ratio = 1.0f - ratio; -        } -        else -          ratio = 0.0f; -      } -    } -    else if( cg_lightFlare.integer == FLARE_NOFADE ) -    { -      //draw nofade flares -      SETBOUNDS( mins, maxs, srcRadius ); -      CG_Trace( &tr, start, mins, maxs, end, -                entityNum, MASK_SHOT ); - -      //flare source occluded -      if( ( tr.fraction < 1.0f || tr.startsolid ) ) -        ratio = 0.0f; -    } -  } -  else -  { -    ratio        = cent->lfs.lastRatio; -    flare.radius = cent->lfs.lastRadius; -  } - -  cent->lfs.lastRatio  = ratio; -  cent->lfs.lastRadius = flare.radius; - -  if( ratio < 1.0f ) -  { -    flare.radius *= ratio; -    flare.shaderRGBA[ 3 ] = (byte)( (float)flare.shaderRGBA[ 3 ] * ratio ); -  } - -  if( flare.radius <= 0.0f ) -    return; - -  trap_R_AddRefEntityToScene( &flare ); -} - -/* -========================= -CG_Lev2ZapChain -========================= -*/ -static void CG_Lev2ZapChain( centity_t *cent ) -{ -  int           i; -  entityState_t *es; -  centity_t     *source, *target; - -  es = ¢->currentState; - -  for( i = 0; i <= 2; i++ ) -  { -    switch( i ) -    { -      case 0: -        if( es->time <= 0 ) -          continue; - -        source = &cg_entities[ es->powerups ]; -        target = &cg_entities[ es->time ]; -        break; - -      case 1: -        if( es->time2 <= 0 ) -          continue; - -        source = &cg_entities[ es->time ]; -        target = &cg_entities[ es->time2 ]; -        break; - -      case 2: -        if( es->constantLight <= 0 ) -          continue; - -        source = &cg_entities[ es->time2 ]; -        target = &cg_entities[ es->constantLight ]; -        break; -    } - -    if( !CG_IsTrailSystemValid( ¢->level2ZapTS[ i ] ) ) -      cent->level2ZapTS[ i ] = CG_SpawnNewTrailSystem( cgs.media.level2ZapTS ); - -    if( CG_IsTrailSystemValid( ¢->level2ZapTS[ i ] ) ) -    { -      CG_SetAttachmentCent( ¢->level2ZapTS[ i ]->frontAttachment, source ); -      CG_SetAttachmentCent( ¢->level2ZapTS[ i ]->backAttachment, target ); -      CG_AttachToCent( ¢->level2ZapTS[ i ]->frontAttachment ); -      CG_AttachToCent( ¢->level2ZapTS[ i ]->backAttachment ); -    } -  } -} - -/* -========================= -CG_AdjustPositionForMover - -Also called by client movement prediction code -========================= -*/ -void CG_AdjustPositionForMover( const vec3_t in, int moverNum, int fromTime, int toTime, vec3_t out ) -{ -  centity_t *cent; -  vec3_t    oldOrigin, origin, deltaOrigin; -  vec3_t    oldAngles, angles, deltaAngles; - -  if( moverNum <= 0 || moverNum >= ENTITYNUM_MAX_NORMAL ) -  { -    VectorCopy( in, out ); -    return; -  } - -  cent = &cg_entities[ moverNum ]; - -  if( cent->currentState.eType != ET_MOVER ) -  { -    VectorCopy( in, out ); -    return; -  } - -  BG_EvaluateTrajectory( ¢->currentState.pos, fromTime, oldOrigin ); -  BG_EvaluateTrajectory( ¢->currentState.apos, fromTime, oldAngles ); - -  BG_EvaluateTrajectory( ¢->currentState.pos, toTime, origin ); -  BG_EvaluateTrajectory( ¢->currentState.apos, toTime, angles ); - -  VectorSubtract( origin, oldOrigin, deltaOrigin ); -  VectorSubtract( angles, oldAngles, deltaAngles ); - -  VectorAdd( in, deltaOrigin, out ); - -  // 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( ¢->currentState.pos, cg.snap->serverTime, current ); -  BG_EvaluateTrajectory( ¢->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( ¢->currentState.apos, cg.snap->serverTime, current ); -  BG_EvaluateTrajectory( ¢->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; -    } -  } - -  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( ¢->currentState.pos, cg.time, cent->lerpOrigin ); -  BG_EvaluateTrajectory( ¢->currentState.apos, cg.time, cent->lerpAngles ); - -  // 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, -                               cg.snap->serverTime, cg.time, cent->lerpOrigin ); -  } -} - - -/* -=============== -CG_CEntityPVSEnter - -=============== -*/ -static void CG_CEntityPVSEnter( centity_t *cent ) -{ -  entityState_t *es = ¢->currentState; - -  if( cg_debugPVS.integer ) -    CG_Printf( "Entity %d entered PVS\n", cent->currentState.number ); - -  switch( es->eType ) -  { -    case ET_MISSILE: -      CG_LaunchMissile( cent ); -      break; -  } - -  //clear any particle systems from previous uses of this centity_t -  cent->muzzlePS = NULL; -  cent->muzzlePsTrigger = qfalse; -  cent->jetPackPS = NULL; -  cent->jetPackState = JPS_OFF; -  cent->buildablePS = NULL; -  cent->entityPS = NULL; -  cent->entityPSMissing = qfalse; - -  //make sure that the buildable animations are in a consistent state -  //when a buildable enters the PVS -  cent->buildableAnim = cent->lerpFrame.animationNumber = BANIM_NONE; -  cent->oldBuildableAnim = es->legsAnim; -} - - -/* -=============== -CG_CEntityPVSLeave - -=============== -*/ -static void CG_CEntityPVSLeave( centity_t *cent ) -{ -  int           i; -  entityState_t *es = ¢->currentState; - -  if( cg_debugPVS.integer ) -    CG_Printf( "Entity %d left PVS\n", cent->currentState.number ); - -  switch( es->eType ) -  { -    case ET_LEV2_ZAP_CHAIN: -      for( i = 0; i <= 2; i++ ) -      { -        if( CG_IsTrailSystemValid( ¢->level2ZapTS[ i ] ) ) -          CG_DestroyTrailSystem( ¢->level2ZapTS[ i ] ); -      } -      break; -  } -} - - -/* -=============== -CG_AddCEntity - -=============== -*/ -static void CG_AddCEntity( centity_t *cent ) -{ -  // 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: -      CG_Error( "Bad entity type: %i\n", cent->currentState.eType ); -      break; - -    case ET_INVISIBLE: -    case ET_PUSH_TRIGGER: -    case ET_TELEPORT_TRIGGER: -      break; - -    case ET_GENERAL: -      CG_General( cent ); -      break; - -    case ET_CORPSE: -      CG_Corpse( cent ); -      break; - -    case ET_PLAYER: -      CG_Player( cent ); -      break; - -    case ET_BUILDABLE: -      CG_Buildable( cent ); -      break; - -    case ET_MISSILE: -      CG_Missile( cent ); -      break; - -    case ET_MOVER: -      CG_Mover( cent ); -      break; - -    case ET_BEAM: -      CG_Beam( cent ); -      break; - -    case ET_PORTAL: -      CG_Portal( cent ); -      break; - -    case ET_SPEAKER: -      CG_Speaker( cent ); -      break; - -    case ET_PARTICLE_SYSTEM: -      CG_ParticleSystemEntity( cent ); -      break; - -    case ET_ANIMMAPOBJ: -      CG_AnimMapObj( cent ); -      break; - -    case ET_MODELDOOR: -      CG_ModelDoor( cent ); -      break; - -    case ET_LIGHTFLARE: -      CG_LightFlare( cent ); -      break; - -    case ET_LEV2_ZAP_CHAIN: -      CG_Lev2ZapChain( cent ); -      break; -  } -} - -/* -=============== -CG_AddPacketEntities - -=============== -*/ -void CG_AddPacketEntities( void ) -{ -  int             num; -  centity_t       *cent; -  playerState_t   *ps; - -  // 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.predictedPlayerEntity.valid = qtrue; -  CG_AddCEntity( &cg.predictedPlayerEntity ); - -  // lerp the non-predicted value for lightning gun origins -  CG_CalcEntityLerpPositions( &cg_entities[ cg.snap->ps.clientNum ] ); - -  // scanner -  CG_UpdateEntityPositions( ); - -  for( num = 0; num < MAX_GENTITIES; num++ ) -    cg_entities[ num ].valid = qfalse; - -  // add each entity sent over by the server -  for( num = 0; num < cg.snap->numEntities; num++ ) -  { -    cent = &cg_entities[ cg.snap->entities[ num ].number ]; -    cent->valid = qtrue; -  } - -  for( num = 0; num < MAX_GENTITIES; num++ ) -  { -    cent = &cg_entities[ num ]; - -    if( cent->valid && !cent->oldValid ) -      CG_CEntityPVSEnter( cent ); -    else if( !cent->valid && cent->oldValid ) -      CG_CEntityPVSLeave( cent ); - -    cent->oldValid = cent->valid; -  } - -  // 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 ); -  } - -  //make an attempt at drawing bounding boxes of selected entity types -  if( cg_drawBBOX.integer ) -  { -    for( num = 0; num < cg.snap->numEntities; num++ ) -    { -      float         x, zd, zu; -      vec3_t        mins, maxs; -      entityState_t *es; - -      cent = &cg_entities[ cg.snap->entities[ num ].number ]; -      es = ¢->currentState; - -      switch( es->eType ) -      { -        case ET_BUILDABLE: -        case ET_MISSILE: -        case ET_CORPSE: -          x = ( es->solid & 255 ); -          zd = ( ( es->solid >> 8 ) & 255 ); -          zu = ( ( es->solid >> 16 ) & 255 ) - 32; - -          mins[ 0 ] = mins[ 1 ] = -x; -          maxs[ 0 ] = maxs[ 1 ] = x; -          mins[ 2 ] = -zd; -          maxs[ 2 ] = zu; - -          CG_DrawBoundingBox( cent->lerpOrigin, mins, maxs ); -          break; - -        default: -          break; -      } -    } -  } -} - diff --git a/mod/src/cgame/cg_event.c b/mod/src/cgame/cg_event.c deleted file mode 100644 index b89c8e7c..00000000 --- a/mod/src/cgame/cg_event.c +++ /dev/null @@ -1,1011 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_event.c -- handle entity events at snapshot or playerstate transitions - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -/* -============= -CG_Obituary -============= -*/ -static void CG_Obituary( entityState_t *ent ) -{ -  int           mod; -  int           target, attacker; -  char          *message; -  char          *message2; -  const char    *targetInfo; -  const char    *attackerInfo; -  char          targetName[ 32 ]; -  char          attackerName[ 32 ]; -  char          className[ 64 ]; -  gender_t      gender; -  clientInfo_t  *ci; - -  target = ent->otherEntityNum; -  attacker = ent->otherEntityNum2; -  mod = ent->eventParm; - -  if( target < 0 || target >= MAX_CLIENTS ) -    CG_Error( "CG_Obituary: target out of range" ); - -  ci = &cgs.clientinfo[ target ]; - -  if( attacker < 0 || attacker >= MAX_CLIENTS ) -  { -    attacker = ENTITYNUM_WORLD; -    attackerInfo = NULL; -  } -  else -    attackerInfo = CG_ConfigString( CS_PLAYERS + attacker ); - -  targetInfo = CG_ConfigString( CS_PLAYERS + target ); - -  if( !targetInfo ) -    return; - -  Q_strncpyz( targetName, Info_ValueForKey( targetInfo, "n" ), sizeof( targetName ) - 2 ); -  strcat( targetName, S_COLOR_WHITE ); - -  message2 = ""; - -  // check for single client messages - -  switch( mod ) -  { -    case MOD_SUICIDE: -      message = "suicides"; -      break; -    case MOD_FALLING: -      message = "fell fowl to gravity"; -      break; -    case MOD_CRUSH: -      message = "was squished"; -      break; -    case MOD_WATER: -      message = "forgot to pack a snorkel"; -      break; -    case MOD_SLIME: -      message = "melted"; -      break; -    case MOD_LAVA: -      message = "does a back flip into the lava"; -      break; -    case MOD_TARGET_LASER: -      message = "saw the light"; -      break; -    case MOD_TRIGGER_HURT: -      message = "was in the wrong place"; -      break; -    case MOD_HSPAWN: -      message = "should have ran further"; -      break; -    case MOD_ASPAWN: -      message = "shouldn't have trod in the acid"; -      break; -    case MOD_MGTURRET: -      message = "was gunned down by a turret"; -      break; -    case MOD_TESLAGEN: -      message = "was zapped by a tesla generator"; -      break; -    case MOD_ATUBE: -      message = "was melted by an acid tube"; -      break; -    case MOD_OVERMIND: -      message = "got too close to the overmind"; -      break; -    case MOD_REACTOR: -      message = "got too close to the reactor"; -      break; -    case MOD_SLOWBLOB: -      message = "should have visited a medical station"; -      break; -    case MOD_SWARM: -      message = "was hunted down by the swarm"; -      break; -    default: -      message = NULL; -      break; -  } - -  if( attacker == target ) -  { -    gender = ci->gender; -    switch( mod ) -    { -      case MOD_FLAMER_SPLASH: -        if( gender == GENDER_FEMALE ) -          message = "toasted herself"; -        else if( gender == GENDER_NEUTER ) -          message = "toasted itself"; -        else -          message = "toasted himself"; -        break; - -      case MOD_LCANNON_SPLASH: -        if( gender == GENDER_FEMALE ) -          message = "irradiated herself"; -        else if( gender == GENDER_NEUTER ) -          message = "irradiated itself"; -        else -          message = "irradiated himself"; -        break; - -      case MOD_GRENADE: -        if( gender == GENDER_FEMALE ) -          message = "blew herself up"; -        else if( gender == GENDER_NEUTER ) -          message = "blew itself up"; -        else -          message = "blew himself up"; -        break; - -      default: -        if( gender == GENDER_FEMALE ) -          message = "killed herself"; -        else if( gender == GENDER_NEUTER ) -          message = "killed itself"; -        else -          message = "killed himself"; -        break; -    } -  } - -  if( message ) -  { -    CG_Printf( "%s %s.\n", targetName, message ); -    return; -  } - -  // check for double client messages -  if( !attackerInfo ) -  { -    attacker = ENTITYNUM_WORLD; -    strcpy( attackerName, "noname" ); -  } -  else -  { -    Q_strncpyz( attackerName, Info_ValueForKey( attackerInfo, "n" ), sizeof( attackerName ) - 2); -    strcat( attackerName, S_COLOR_WHITE ); -    // check for kill messages about the current clientNum -    if( target == cg.snap->ps.clientNum ) -      Q_strncpyz( cg.killerName, attackerName, sizeof( cg.killerName ) ); -  } - -  if( attacker != ENTITYNUM_WORLD ) -  { -    switch( mod ) -    { -      case MOD_PAINSAW: -        message = "was sawn by"; -        break; -      case MOD_BLASTER: -        message = "was blasted by"; -        break; -      case MOD_MACHINEGUN: -        message = "was machinegunned by"; -        break; -      case MOD_CHAINGUN: -        message = "was chaingunned by"; -        break; -      case MOD_SHOTGUN: -        message = "was gunned down by"; -        break; -      case MOD_PRIFLE: -        message = "was pulse rifled by"; -        break; -      case MOD_MDRIVER: -        message = "was mass driven by"; -        break; -      case MOD_LASGUN: -        message = "was lasgunned by"; -        break; -      case MOD_FLAMER: -        message = "was grilled by"; -        message2 = "'s flamer"; -        break; -      case MOD_FLAMER_SPLASH: -        message = "was toasted by"; -        message2 = "'s flamer"; -        break; -      case MOD_LCANNON: -        message = "felt the full force of"; -        message2 = "'s lucifer cannon"; -        break; -      case MOD_LCANNON_SPLASH: -        message = "was caught in the fallout of"; -        message2 = "'s lucifer cannon"; -        break; -      case MOD_GRENADE: -        message = "couldn't escape"; -        message2 = "'s grenade"; -        break; - -      case MOD_ABUILDER_CLAW: -        message = "should leave"; -        message2 = "'s buildings alone"; -        break; -      case MOD_LEVEL0_BITE: -        message = "was bitten by"; -        break; -      case MOD_LEVEL1_CLAW: -        message = "was swiped by"; -        Com_sprintf( className, 64, "'s %s", -            BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL1 ) ); -        message2 = className; -        break; -      case MOD_LEVEL2_CLAW: -        message = "was clawed by"; -        Com_sprintf( className, 64, "'s %s", -            BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL2 ) ); -        message2 = className; -        break; -      case MOD_LEVEL2_ZAP: -        message = "was zapped by"; -        Com_sprintf( className, 64, "'s %s", -            BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL2 ) ); -        message2 = className; -        break; -      case MOD_LEVEL3_CLAW: -        message = "was chomped by"; -        Com_sprintf( className, 64, "'s %s", -            BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL3 ) ); -        message2 = className; -        break; -      case MOD_LEVEL3_POUNCE: -        message = "was pounced upon by"; -        Com_sprintf( className, 64, "'s %s", -            BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL3 ) ); -        message2 = className; -        break; -      case MOD_LEVEL3_BOUNCEBALL: -        message = "was sniped by"; -        Com_sprintf( className, 64, "'s %s", -            BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL3 ) ); -        message2 = className; -        break; -      case MOD_LEVEL4_CLAW: -        message = "was mauled by"; -        Com_sprintf( className, 64, "'s %s", -            BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL4 ) ); -        message2 = className; -        break; -      case MOD_LEVEL4_CHARGE: -        message = "should have gotten out of the way of"; -        Com_sprintf( className, 64, "'s %s", -            BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL4 ) ); -        message2 = className; -        break; - -      case MOD_POISON: -        message = "should have used a medkit against"; -        message2 = "'s poison"; -        break; -      case MOD_LEVEL1_PCLOUD: -        message = "was gassed by"; -        Com_sprintf( className, 64, "'s %s", -            BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL1 ) ); -        message2 = className; -        break; - - -      case MOD_TELEFRAG: -        message = "tried to invade"; -        message2 = "'s personal space"; -        break; -      default: -        message = "was killed by"; -        break; -    } - -    if( message ) -    { -      CG_Printf( "%s %s %s%s\n", -        targetName, message, attackerName, message2 ); -      return; -    } -  } - -  // we don't know what it was -  CG_Printf( "%s died.\n", targetName ); -} - -//========================================================================== - -/* -================ -CG_PainEvent - -Also called by playerstate transition -================ -*/ -void CG_PainEvent( centity_t *cent, int health ) -{ -  char  *snd; - -  // don't do more than two pain sounds a second -  if( cg.time - cent->pe.painTime < 500 ) -    return; - -  if( health < 25 ) -    snd = "*pain25_1.wav"; -  else if( health < 50 ) -    snd = "*pain50_1.wav"; -  else if( health < 75 ) -    snd = "*pain75_1.wav"; -  else -    snd = "*pain100_1.wav"; - -  trap_S_StartSound( NULL, cent->currentState.number, CHAN_VOICE, -    CG_CustomSound( cent->currentState.number, snd ) ); - -  // save pain time for programitic twitch animation -  cent->pe.painTime = cg.time; -  cent->pe.painDirection ^= 1; -} - -/* -============== -CG_EntityEvent - -An entity has an event value -also called by CG_CheckPlayerstateEvents -============== -*/ -#define DEBUGNAME(x) if(cg_debugEvents.integer){CG_Printf(x"\n");} -void CG_EntityEvent( centity_t *cent, vec3_t position ) -{ -  entityState_t *es; -  int           event; -  vec3_t        dir; -  const char    *s; -  int           clientNum; -  clientInfo_t  *ci; -  int           steptime; - -  if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) -    steptime = 200; -  else -    steptime = BG_FindSteptimeForClass( cg.snap->ps.stats[ STAT_PCLASS ] ); - -  es = ¢->currentState; -  event = es->event & ~EV_EVENT_BITS; - -  if( cg_debugEvents.integer ) -    CG_Printf( "ent:%3i  event:%3i ", es->number, event ); - -  if( !event ) -  { -    DEBUGNAME("ZEROEVENT"); -    return; -  } - -  clientNum = es->clientNum; -  if( clientNum < 0 || clientNum >= MAX_CLIENTS ) -    clientNum = 0; - -  ci = &cgs.clientinfo[ clientNum ]; - -  switch( event ) -  { -    // -    // movement generated events -    // -    case EV_FOOTSTEP: -      DEBUGNAME( "EV_FOOTSTEP" ); -      if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE ) -      { -        if( ci->footsteps == FOOTSTEP_CUSTOM ) -          trap_S_StartSound( NULL, es->number, CHAN_BODY, -            ci->customFootsteps[ rand( ) & 3 ] ); -        else -          trap_S_StartSound( NULL, es->number, CHAN_BODY, -            cgs.media.footsteps[ ci->footsteps ][ rand( ) & 3 ] ); -      } -      break; - -    case EV_FOOTSTEP_METAL: -      DEBUGNAME( "EV_FOOTSTEP_METAL" ); -      if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE ) -      { -        if( ci->footsteps == FOOTSTEP_CUSTOM ) -          trap_S_StartSound( NULL, es->number, CHAN_BODY, -            ci->customMetalFootsteps[ rand( ) & 3 ] ); -        else -          trap_S_StartSound( NULL, es->number, CHAN_BODY, -            cgs.media.footsteps[ FOOTSTEP_METAL ][ rand( ) & 3 ] ); -      } -      break; - -    case EV_FOOTSTEP_SQUELCH: -      DEBUGNAME( "EV_FOOTSTEP_SQUELCH" ); -      if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE ) -      { -        trap_S_StartSound( NULL, es->number, CHAN_BODY, -          cgs.media.footsteps[ FOOTSTEP_FLESH ][ rand( ) & 3 ] ); -      } -      break; - -    case EV_FOOTSPLASH: -      DEBUGNAME( "EV_FOOTSPLASH" ); -      if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE ) -      { -        trap_S_StartSound( NULL, es->number, CHAN_BODY, -          cgs.media.footsteps[ FOOTSTEP_SPLASH ][ rand( ) & 3 ] ); -      } -      break; - -    case EV_FOOTWADE: -      DEBUGNAME( "EV_FOOTWADE" ); -      if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE ) -      { -        trap_S_StartSound( NULL, es->number, CHAN_BODY, -          cgs.media.footsteps[ FOOTSTEP_SPLASH ][ rand( ) & 3 ] ); -      } -      break; - -    case EV_SWIM: -      DEBUGNAME( "EV_SWIM" ); -      if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE ) -      { -        trap_S_StartSound( NULL, es->number, CHAN_BODY, -          cgs.media.footsteps[ FOOTSTEP_SPLASH ][ rand( ) & 3 ] ); -      } -      break; - - -    case EV_FALL_SHORT: -      DEBUGNAME( "EV_FALL_SHORT" ); -      trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.landSound ); - -      if( clientNum == cg.predictedPlayerState.clientNum ) -      { -        // smooth landing z changes -        cg.landChange = -8; -        cg.landTime = cg.time; -      } -      break; - -    case EV_FALL_MEDIUM: -      DEBUGNAME( "EV_FALL_MEDIUM" ); -      // use normal pain sound -      trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*pain100_1.wav" ) ); - -      if( clientNum == cg.predictedPlayerState.clientNum ) -      { -        // smooth landing z changes -        cg.landChange = -16; -        cg.landTime = cg.time; -      } -      break; - -    case EV_FALL_FAR: -      DEBUGNAME( "EV_FALL_FAR" ); -      trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*fall1.wav" ) ); -      cent->pe.painTime = cg.time;  // don't play a pain sound right after this - -      if( clientNum == cg.predictedPlayerState.clientNum ) -      { -        // smooth landing z changes -        cg.landChange = -24; -        cg.landTime = cg.time; -      } -      break; - -    case EV_FALLING: -      DEBUGNAME( "EV_FALLING" ); -      trap_S_StartSound( NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*falling1.wav" ) ); -      break; - -    case EV_STEP_4: -    case EV_STEP_8: -    case EV_STEP_12: -    case EV_STEP_16:    // smooth out step up transitions -    case EV_STEPDN_4: -    case EV_STEPDN_8: -    case EV_STEPDN_12: -    case EV_STEPDN_16:    // smooth out step down transitions -      DEBUGNAME( "EV_STEP" ); -      { -        float  oldStep; -        int    delta; -        int    step; - -        if( clientNum != cg.predictedPlayerState.clientNum ) -          break; - -        // if we are interpolating, we don't need to smooth steps -        if( cg.demoPlayback || ( cg.snap->ps.pm_flags & PMF_FOLLOW ) || -            cg_nopredict.integer || cg_synchronousClients.integer ) -          break; - -        // check for stepping up before a previous step is completed -        delta = cg.time - cg.stepTime; - -        if( delta < steptime ) -          oldStep = cg.stepChange * ( steptime - delta ) / steptime; -        else -          oldStep = 0; - -        // add this amount -        if( event >= EV_STEPDN_4 ) -        { -          step = 4 * ( event - EV_STEPDN_4 + 1 ); -          cg.stepChange = oldStep - step; -        } -        else -        { -          step = 4 * ( event - EV_STEP_4 + 1 ); -          cg.stepChange = oldStep + step; -        } - -        if( cg.stepChange > MAX_STEP_CHANGE ) -          cg.stepChange = MAX_STEP_CHANGE; -        else if( cg.stepChange < -MAX_STEP_CHANGE ) -          cg.stepChange = -MAX_STEP_CHANGE; - -        cg.stepTime = cg.time; -        break; -      } - -    case EV_JUMP: -      DEBUGNAME( "EV_JUMP" ); -      trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) ); - -      if( BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_PCLASS ], SCA_WALLJUMPER ) ) -      { -        vec3_t  surfNormal, refNormal = { 0.0f, 0.0f, 1.0f }; -        vec3_t  rotAxis; - -        if( clientNum != cg.predictedPlayerState.clientNum ) -          break; - -        //set surfNormal -        VectorCopy( cg.predictedPlayerState.grapplePoint, surfNormal ); - -        //if we are moving from one surface to another smooth the transition -        if( !VectorCompare( surfNormal, cg.lastNormal ) && surfNormal[ 2 ] != 1.0f ) -        { -          CrossProduct( refNormal, surfNormal, rotAxis ); -          VectorNormalize( rotAxis ); - -          //add the op -          CG_addSmoothOp( rotAxis, 15.0f, 1.0f ); -        } - -        //copy the current normal to the lastNormal -        VectorCopy( surfNormal, cg.lastNormal ); -      } - -      break; - -    case EV_LEV1_GRAB: -      DEBUGNAME( "EV_LEV1_GRAB" ); -      trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL1Grab ); -      break; - -    case EV_LEV4_CHARGE_PREPARE: -      DEBUGNAME( "EV_LEV4_CHARGE_PREPARE" ); -      trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL4ChargePrepare ); -      break; - -    case EV_LEV4_CHARGE_START: -      DEBUGNAME( "EV_LEV4_CHARGE_START" ); -      //FIXME: stop cgs.media.alienL4ChargePrepare playing here -      trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL4ChargeStart ); -      break; - -    case EV_TAUNT: -      DEBUGNAME( "EV_TAUNT" ); -      trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*taunt.wav" ) ); -      break; - -    case EV_WATER_TOUCH: -      DEBUGNAME( "EV_WATER_TOUCH" ); -      trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.watrInSound ); -      break; - -    case EV_WATER_LEAVE: -      DEBUGNAME( "EV_WATER_LEAVE" ); -      trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound ); -      break; - -    case EV_WATER_UNDER: -      DEBUGNAME( "EV_WATER_UNDER" ); -      trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound ); -      break; - -    case EV_WATER_CLEAR: -      DEBUGNAME( "EV_WATER_CLEAR" ); -      trap_S_StartSound( NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*gasp.wav" ) ); -      break; - -    // -    // weapon events -    // -    case EV_NOAMMO: -      DEBUGNAME( "EV_NOAMMO" ); -      { -      } -      break; - -    case EV_CHANGE_WEAPON: -      DEBUGNAME( "EV_CHANGE_WEAPON" ); -      trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.selectSound ); -      break; - -    case EV_FIRE_WEAPON: -      DEBUGNAME( "EV_FIRE_WEAPON" ); -      CG_FireWeapon( cent, WPM_PRIMARY ); -      break; - -    case EV_FIRE_WEAPON2: -      DEBUGNAME( "EV_FIRE_WEAPON2" ); -      CG_FireWeapon( cent, WPM_SECONDARY ); -      break; - -    case EV_FIRE_WEAPON3: -      DEBUGNAME( "EV_FIRE_WEAPON3" ); -      CG_FireWeapon( cent, WPM_TERTIARY ); -      break; - -    //================================================================= - -    // -    // other events -    // -    case EV_PLAYER_TELEPORT_IN: -      DEBUGNAME( "EV_PLAYER_TELEPORT_IN" ); -      //deprecated -      break; - -    case EV_PLAYER_TELEPORT_OUT: -      DEBUGNAME( "EV_PLAYER_TELEPORT_OUT" ); -      CG_PlayerDisconnect( position ); -      break; - -    case EV_BUILD_CONSTRUCT: -      DEBUGNAME( "EV_BUILD_CONSTRUCT" ); -      //do something useful here -      break; - -    case EV_BUILD_DESTROY: -      DEBUGNAME( "EV_BUILD_DESTROY" ); -      //do something useful here -      break; - -    case EV_RPTUSE_SOUND: -      DEBUGNAME( "EV_RPTUSE_SOUND" ); -      trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.repeaterUseSound ); -      break; - -    case EV_GRENADE_BOUNCE: -      DEBUGNAME( "EV_GRENADE_BOUNCE" ); -      if( rand( ) & 1 ) -        trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.hgrenb1aSound ); -      else -        trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.hgrenb2aSound ); -      break; - -    // -    // missile impacts -    // -    case EV_MISSILE_HIT: -      DEBUGNAME( "EV_MISSILE_HIT" ); -      ByteToDir( es->eventParm, dir ); -      CG_MissileHitPlayer( es->weapon, es->generic1, position, dir, es->otherEntityNum ); -      break; - -    case EV_MISSILE_MISS: -      DEBUGNAME( "EV_MISSILE_MISS" ); -      ByteToDir( es->eventParm, dir ); -      CG_MissileHitWall( es->weapon, es->generic1, 0, position, dir, IMPACTSOUND_DEFAULT ); -      break; - -    case EV_MISSILE_MISS_METAL: -      DEBUGNAME( "EV_MISSILE_MISS_METAL" ); -      ByteToDir( es->eventParm, dir ); -      CG_MissileHitWall( es->weapon, es->generic1, 0, position, dir, IMPACTSOUND_METAL ); -      break; - -    case EV_HUMAN_BUILDABLE_EXPLOSION: -      DEBUGNAME( "EV_HUMAN_BUILDABLE_EXPLOSION" ); -      ByteToDir( es->eventParm, dir ); -      CG_HumanBuildableExplosion( position, dir ); -      break; - -    case EV_ALIEN_BUILDABLE_EXPLOSION: -      DEBUGNAME( "EV_ALIEN_BUILDABLE_EXPLOSION" ); -      ByteToDir( es->eventParm, dir ); -      CG_AlienBuildableExplosion( position, dir ); -      break; - -    case EV_TESLATRAIL: -      DEBUGNAME( "EV_TESLATRAIL" ); -      cent->currentState.weapon = WP_TESLAGEN; -      { -        centity_t *source = &cg_entities[ es->generic1 ]; -        centity_t *target = &cg_entities[ es->clientNum ]; -        vec3_t    sourceOffset = { 0.0f, 0.0f, 28.0f }; - -        if( !CG_IsTrailSystemValid( &source->muzzleTS ) ) -        { -          source->muzzleTS = CG_SpawnNewTrailSystem( cgs.media.teslaZapTS ); - -          if( CG_IsTrailSystemValid( &source->muzzleTS ) ) -          { -            CG_SetAttachmentCent( &source->muzzleTS->frontAttachment, source ); -            CG_SetAttachmentCent( &source->muzzleTS->backAttachment, target ); -            CG_AttachToCent( &source->muzzleTS->frontAttachment ); -            CG_AttachToCent( &source->muzzleTS->backAttachment ); -            CG_SetAttachmentOffset( &source->muzzleTS->frontAttachment, sourceOffset ); - -            source->muzzleTSDeathTime = cg.time + cg_teslaTrailTime.integer; -          } -        } -      } -      break; - -    case EV_BULLET_HIT_WALL: -      DEBUGNAME( "EV_BULLET_HIT_WALL" ); -      ByteToDir( es->eventParm, dir ); -      CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD ); -      break; - -    case EV_BULLET_HIT_FLESH: -      DEBUGNAME( "EV_BULLET_HIT_FLESH" ); -      CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm ); -      break; - -    case EV_SHOTGUN: -      DEBUGNAME( "EV_SHOTGUN" ); -      CG_ShotgunFire( es ); -      break; - -    case EV_GENERAL_SOUND: -      DEBUGNAME( "EV_GENERAL_SOUND" ); -      if( cgs.gameSounds[ es->eventParm ] ) -        trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] ); -      else -      { -        s = CG_ConfigString( CS_SOUNDS + es->eventParm ); -        trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) ); -      } -      break; - -    case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes -      DEBUGNAME( "EV_GLOBAL_SOUND" ); -      if( cgs.gameSounds[ es->eventParm ] ) -        trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ] ); -      else -      { -        s = CG_ConfigString( CS_SOUNDS + es->eventParm ); -        trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound( es->number, s ) ); -      } -      break; - -    case EV_PAIN: -      // local player sounds are triggered in CG_CheckLocalSounds, -      // so ignore events on the player -      DEBUGNAME( "EV_PAIN" ); -      if( cent->currentState.number != cg.snap->ps.clientNum ) -        CG_PainEvent( cent, es->eventParm ); -      break; - -    case EV_DEATH1: -    case EV_DEATH2: -    case EV_DEATH3: -      DEBUGNAME( "EV_DEATHx" ); -      trap_S_StartSound( NULL, es->number, CHAN_VOICE, -          CG_CustomSound( es->number, va( "*death%i.wav", event - EV_DEATH1 + 1 ) ) ); -      break; - -    case EV_OBITUARY: -      DEBUGNAME( "EV_OBITUARY" ); -      CG_Obituary( es ); -      break; - -    case EV_GIB_PLAYER: -      DEBUGNAME( "EV_GIB_PLAYER" ); -      // no gibbing -      break; - -    case EV_STOPLOOPINGSOUND: -      DEBUGNAME( "EV_STOPLOOPINGSOUND" ); -      trap_S_StopLoopingSound( es->number ); -      es->loopSound = 0; -      break; - -    case EV_DEBUG_LINE: -      DEBUGNAME( "EV_DEBUG_LINE" ); -      CG_Beam( cent ); -      break; - -    case EV_BUILD_DELAY: -      DEBUGNAME( "EV_BUILD_DELAY" ); -      if( clientNum == cg.predictedPlayerState.clientNum ) -      { -        trap_S_StartLocalSound( cgs.media.buildableRepairedSound, CHAN_LOCAL_SOUND ); -        cg.lastBuildAttempt = cg.time; -      } -      break; - -    case EV_BUILD_REPAIR: -      DEBUGNAME( "EV_BUILD_REPAIR" ); -      trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.buildableRepairSound ); -      break; - -    case EV_BUILD_REPAIRED: -      DEBUGNAME( "EV_BUILD_REPAIRED" ); -      trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.buildableRepairedSound ); -      break; - -    case EV_OVERMIND_ATTACK: -      DEBUGNAME( "EV_OVERMIND_ATTACK" ); -      if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS ) -      { -        trap_S_StartLocalSound( cgs.media.alienOvermindAttack, CHAN_ANNOUNCER ); -        CG_CenterPrint( "The Overmind is under attack!", 200, GIANTCHAR_WIDTH * 4 ); -      } -      break; - -    case EV_OVERMIND_DYING: -      DEBUGNAME( "EV_OVERMIND_DYING" ); -      if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS ) -      { -        trap_S_StartLocalSound( cgs.media.alienOvermindDying, CHAN_ANNOUNCER ); -        CG_CenterPrint( "The Overmind is dying!", 200, GIANTCHAR_WIDTH * 4 ); -      } -      break; - -    case EV_DCC_ATTACK: -      DEBUGNAME( "EV_DCC_ATTACK" ); -      if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS ) -      { -        //trap_S_StartLocalSound( cgs.media.humanDCCAttack, CHAN_ANNOUNCER ); -        CG_CenterPrint( "Our base is under attack!", 200, GIANTCHAR_WIDTH * 4 ); -      } -      break; - -    case EV_OVERMIND_SPAWNS: -      DEBUGNAME( "EV_OVERMIND_SPAWNS" ); -      if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS ) -      { -        trap_S_StartLocalSound( cgs.media.alienOvermindSpawns, CHAN_ANNOUNCER ); -        CG_CenterPrint( "The Overmind needs spawns!", 200, GIANTCHAR_WIDTH * 4 ); -      } -      break; - -    case EV_ALIEN_EVOLVE: -      DEBUGNAME( "EV_ALIEN_EVOLVE" ); -      trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.alienEvolveSound ); -      { -        particleSystem_t *ps = CG_SpawnNewParticleSystem( cgs.media.alienEvolvePS ); - -        if( CG_IsParticleSystemValid( &ps ) ) -        { -          CG_SetAttachmentCent( &ps->attachment, cent ); -          CG_AttachToCent( &ps->attachment ); -        } -      } - -      if( es->number == cg.clientNum ) -      { -        CG_ResetPainBlend( ); -        cg.spawnTime = cg.time; -      } -      break; - -    case EV_ALIEN_EVOLVE_FAILED: -      DEBUGNAME( "EV_ALIEN_EVOLVE_FAILED" ); -      if( clientNum == cg.predictedPlayerState.clientNum ) -      { -        //FIXME: change to "negative" sound -        trap_S_StartLocalSound( cgs.media.buildableRepairedSound, CHAN_LOCAL_SOUND ); -        cg.lastEvolveAttempt = cg.time; -      } -      break; - -    case EV_ALIEN_ACIDTUBE: -      DEBUGNAME( "EV_ALIEN_ACIDTUBE" ); -      { -        particleSystem_t *ps = CG_SpawnNewParticleSystem( cgs.media.alienAcidTubePS ); - -        if( CG_IsParticleSystemValid( &ps ) ) -        { -          CG_SetAttachmentCent( &ps->attachment, cent ); -          ByteToDir( es->eventParm, dir ); -          CG_SetParticleSystemNormal( ps, dir ); -          CG_AttachToCent( &ps->attachment ); -        } -      } -      break; - -    case EV_MEDKIT_USED: -      DEBUGNAME( "EV_MEDKIT_USED" ); -      trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.medkitUseSound ); -      break; - -    case EV_PLAYER_RESPAWN: -      DEBUGNAME( "EV_PLAYER_RESPAWN" ); -      if( es->number == cg.clientNum ) -        cg.spawnTime = cg.time; -      break; - -    default: -      DEBUGNAME( "UNKNOWN" ); -      CG_Error( "Unknown event: %i", event ); -      break; -  } -} - - -/* -============== -CG_CheckEvents - -============== -*/ -void CG_CheckEvents( centity_t *cent ) -{ -  entity_event_t event; -  entity_event_t oldEvent = EV_NONE; - -  // check for event-only entities -  if( cent->currentState.eType > ET_EVENTS ) -  { -    event = cent->currentState.eType - ET_EVENTS; - -    if( cent->previousEvent ) -      return; // already fired - -    cent->previousEvent = 1; - -    cent->currentState.event = cent->currentState.eType - ET_EVENTS; -     -    // Move the pointer to the entity that the -    // event was originally attached to -    if( cent->currentState.eFlags & EF_PLAYER_EVENT ) -    { -      cent = &cg_entities[ cent->currentState.otherEntityNum ]; -      oldEvent = cent->currentState.event; -      cent->currentState.event = event; -    } -  } -  else -  { -    // check for events riding with another entity -    if( cent->currentState.event == cent->previousEvent ) -      return; - -    cent->previousEvent = cent->currentState.event; -    if( ( cent->currentState.event & ~EV_EVENT_BITS ) == 0 ) -      return; -  } - -  // calculate the position at exactly the frame time -  BG_EvaluateTrajectory( ¢->currentState.pos, cg.snap->serverTime, cent->lerpOrigin ); -  CG_SetEntitySoundPosition( cent ); - -  CG_EntityEvent( cent, cent->lerpOrigin ); -   -  // If this was a reattached spilled event, restore the original event -  if( oldEvent != EV_NONE ) -    cent->currentState.event = oldEvent; -} - diff --git a/mod/src/cgame/cg_local.h b/mod/src/cgame/cg_local.h deleted file mode 100644 index 88df61ba..00000000 --- a/mod/src/cgame/cg_local.h +++ /dev/null @@ -1,2003 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "../game/q_shared.h" -#include "tr_types.h" -#include "../game/bg_public.h" -#include "cg_public.h" -#include "../ui/ui_shared.h" - -// The entire cgame module is unloaded and reloaded on each level change, -// so there is NO persistant data between levels on the client side. -// If you absolutely need something stored, it can either be kept -// by the server in the server stored userinfos, or stashed in a cvar. - -#define CG_FONT_THRESHOLD 0.1 - -#define POWERUP_BLINKS      5 - -#define POWERUP_BLINK_TIME  1000 -#define FADE_TIME           200 -#define PULSE_TIME          200 -#define DAMAGE_DEFLECT_TIME 100 -#define DAMAGE_RETURN_TIME  400 -#define DAMAGE_TIME         500 -#define LAND_DEFLECT_TIME   150 -#define LAND_RETURN_TIME    300 -#define DUCK_TIME           100 -#define PAIN_TWITCH_TIME    200 -#define WEAPON_SELECT_TIME  1400 -#define ITEM_SCALEUP_TIME   1000 -#define ZOOM_TIME           150 -#define ITEM_BLOB_TIME      200 -#define MUZZLE_FLASH_TIME   20 -#define SINK_TIME           1000    // time for fragments to sink into ground before going away -#define ATTACKER_HEAD_TIME  10000 -#define REWARD_TIME         3000 - -#define PULSE_SCALE         1.5     // amount to scale up the icons when activating - -#define MAX_STEP_CHANGE     32 - -#define MAX_VERTS_ON_POLY   10 -#define MAX_MARK_POLYS      256 - -#define STAT_MINUS          10  // num frame for '-' stats digit - -#define ICON_SIZE           48 -#define CHAR_WIDTH          32 -#define CHAR_HEIGHT         48 -#define TEXT_ICON_SPACE     4 - -#define TEAMCHAT_WIDTH      80 -#define TEAMCHAT_HEIGHT     8 - -// very large characters -#define GIANT_WIDTH         32 -#define GIANT_HEIGHT        48 - -#define NUM_CROSSHAIRS      10 - -#define TEAM_OVERLAY_MAXNAME_WIDTH  12 -#define TEAM_OVERLAY_MAXLOCATION_WIDTH  16 - -#define DEFAULT_MODEL       "sarge" -#define DEFAULT_TEAM_MODEL  "sarge" -#define DEFAULT_TEAM_HEAD   "sarge" - -#define DEFAULT_REDTEAM_NAME    "Stroggs" -#define DEFAULT_BLUETEAM_NAME   "Pagans" - -typedef enum -{ -  FOOTSTEP_NORMAL, -  FOOTSTEP_BOOT, -  FOOTSTEP_FLESH, -  FOOTSTEP_MECH, -  FOOTSTEP_ENERGY, -  FOOTSTEP_METAL, -  FOOTSTEP_SPLASH, -  FOOTSTEP_CUSTOM, -  FOOTSTEP_NONE, - -  FOOTSTEP_TOTAL -} footstep_t; - -typedef enum -{ -  IMPACTSOUND_DEFAULT, -  IMPACTSOUND_METAL, -  IMPACTSOUND_FLESH -} impactSound_t; - -typedef enum -{ -  JPS_OFF, -  JPS_DESCENDING, -  JPS_HOVERING, -  JPS_ASCENDING -} jetPackState_t; - -//====================================================================== - -// when changing animation, set animationTime to frameTime + lerping time -// The current lerp will finish out, then it will lerp to the new animation -typedef struct -{ -  int         oldFrame; -  int         oldFrameTime;     // time when ->oldFrame was exactly on - -  int         frame; -  int         frameTime;        // time when ->frame will be exactly on - -  float       backlerp; - -  float       yawAngle; -  qboolean    yawing; -  float       pitchAngle; -  qboolean    pitching; - -  int         animationNumber;  // may include ANIM_TOGGLEBIT -  animation_t *animation; -  int         animationTime;    // time when the first frame of the animation will be exact -} lerpFrame_t; - -//====================================================================== - -//attachment system -typedef enum -{ -  AT_STATIC, -  AT_TAG, -  AT_CENT, -  AT_PARTICLE -} attachmentType_t; - -//forward declaration for particle_t -struct particle_s; - -typedef struct attachment_s -{ -  attachmentType_t  type; -  qboolean          attached; - -  qboolean          staticValid; -  qboolean          tagValid; -  qboolean          centValid; -  qboolean          particleValid; - -  qboolean          hasOffset; -  vec3_t            offset; - -  vec3_t            lastValidAttachmentPoint; - -  //AT_STATIC -  vec3_t            origin; - -  //AT_TAG -  refEntity_t       re;     //FIXME: should be pointers? -  refEntity_t       parent; // -  qhandle_t         model; -  char              tagName[ MAX_STRING_CHARS ]; - -  //AT_CENT -  int               centNum; - -  //AT_PARTICLE -  struct particle_s *particle; -} attachment_t; - -//====================================================================== - -//particle system stuff -#define MAX_PS_SHADER_FRAMES      32 -#define MAX_PS_MODELS             8 -#define MAX_EJECTORS_PER_SYSTEM   4 -#define MAX_PARTICLES_PER_EJECTOR 4 - -#define MAX_BASEPARTICLE_SYSTEMS  192 -#define MAX_BASEPARTICLE_EJECTORS MAX_BASEPARTICLE_SYSTEMS*MAX_EJECTORS_PER_SYSTEM -#define MAX_BASEPARTICLES         MAX_BASEPARTICLE_EJECTORS*MAX_PARTICLES_PER_EJECTOR - -#define MAX_PARTICLE_SYSTEMS      48 -#define MAX_PARTICLE_EJECTORS     MAX_PARTICLE_SYSTEMS*MAX_EJECTORS_PER_SYSTEM -#define MAX_PARTICLES             MAX_PARTICLE_EJECTORS*5 - -#define PARTICLES_INFINITE        -1 -#define PARTICLES_SAME_AS_INITIAL -2 - -//COMPILE TIME STRUCTURES -typedef enum -{ -  PMT_STATIC, -  PMT_STATIC_TRANSFORM, -  PMT_TAG, -  PMT_CENT_ANGLES, -  PMT_NORMAL -} pMoveType_t; - -typedef enum -{ -  PMD_LINEAR, -  PMD_POINT -} pDirType_t; - -typedef struct pMoveValues_u -{ -  pDirType_t  dirType; - -  //PMD_LINEAR -  vec3_t      dir; -  float       dirRandAngle; - -  //PMD_POINT -  vec3_t      point; -  float       pointRandAngle; - -  float       mag; -  float       magRandFrac; - -  float       parentVelFrac; -  float       parentVelFracRandFrac; -} pMoveValues_t; - -typedef struct pLerpValues_s -{ -  int   delay; -  float delayRandFrac; - -  float initial; -  float initialRandFrac; - -  float final; -  float finalRandFrac; - -  float randFrac; -} pLerpValues_t; - -//particle template -typedef struct baseParticle_s -{ -  vec3_t          displacement; -  float           randDisplacement; -  float           normalDisplacement; - -  pMoveType_t     velMoveType; -  pMoveValues_t   velMoveValues; - -  pMoveType_t     accMoveType; -  pMoveValues_t   accMoveValues; - -  int             lifeTime; -  float           lifeTimeRandFrac; - -  float           bounceFrac; -  float           bounceFracRandFrac; -  qboolean        bounceCull; - -  char            bounceMarkName[ MAX_QPATH ]; -  qhandle_t       bounceMark; -  float           bounceMarkRadius; -  float           bounceMarkRadiusRandFrac; -  float           bounceMarkCount; -  float           bounceMarkCountRandFrac; - -  char            bounceSoundName[ MAX_QPATH ]; -  qhandle_t       bounceSound; -  float           bounceSoundCount; -  float           bounceSoundCountRandFrac; - -  pLerpValues_t   radius; -  pLerpValues_t   alpha; -  pLerpValues_t   rotation; -   -  qboolean        dynamicLight; -  pLerpValues_t   dLightRadius; -  byte            dLightColor[ 3 ]; - -  int             colorDelay; -  float           colorDelayRandFrac; -  byte            initialColor[ 3 ]; -  byte            finalColor[ 3 ]; - -  char            childSystemName[ MAX_QPATH ]; -  qhandle_t       childSystemHandle; - -  char            onDeathSystemName[ MAX_QPATH ]; -  qhandle_t       onDeathSystemHandle; - -  char            childTrailSystemName[ MAX_QPATH ]; -  qhandle_t       childTrailSystemHandle; - -  //particle invariant stuff -  char            shaderNames[ MAX_PS_SHADER_FRAMES ][ MAX_QPATH ]; -  qhandle_t       shaders[ MAX_PS_SHADER_FRAMES ]; -  int             numFrames; -  float           framerate; - -  char            modelNames[ MAX_PS_MODELS ][ MAX_QPATH ]; -  qhandle_t       models[ MAX_PS_MODELS ]; -  int             numModels; -  animation_t     modelAnimation; - -  qboolean        overdrawProtection; -  qboolean        realLight; -  qboolean        cullOnStartSolid; -} baseParticle_t; - - -//ejector template -typedef struct baseParticleEjector_s -{ -  baseParticle_t  *particles[ MAX_PARTICLES_PER_EJECTOR ]; -  int             numParticles; - -  pLerpValues_t   eject;          //zero period indicates creation of all particles at once - -  int             totalParticles;         //can be infinite -  float           totalParticlesRandFrac; -} baseParticleEjector_t; - - -//particle system template -typedef struct baseParticleSystem_s -{ -  char                  name[ MAX_QPATH ]; -  baseParticleEjector_t *ejectors[ MAX_EJECTORS_PER_SYSTEM ]; -  int                   numEjectors; - -  qboolean              thirdPersonOnly; -  qboolean              registered; //whether or not the assets for this particle have been loaded -} baseParticleSystem_t; - - -//RUN TIME STRUCTURES -typedef struct particleSystem_s -{ -  baseParticleSystem_t  *class; - -  attachment_t          attachment; - -  qboolean              valid; -  qboolean              lazyRemove; //mark this system for later removal - -  //for PMT_NORMAL -  qboolean              normalValid; -  vec3_t                normal; -} particleSystem_t; - - -typedef struct particleEjector_s -{ -  baseParticleEjector_t *class; -  particleSystem_t      *parent; - -  pLerpValues_t         ejectPeriod; - -  int                   count; -  int                   totalParticles; - -  int                   nextEjectionTime; - -  qboolean              valid; -} particleEjector_t; - - -//used for actual particle evaluation -typedef struct particle_s -{ -  baseParticle_t    *class; -  particleEjector_t *parent; - -  int               birthTime; -  int               lifeTime; - -  float             bounceMarkRadius; -  int               bounceMarkCount; -  int               bounceSoundCount; -  qboolean          atRest; - -  vec3_t            origin; -  vec3_t            velocity; - -  pMoveType_t       accMoveType; -  pMoveValues_t     accMoveValues; - -  int               lastEvalTime; - -  int               nextChildTime; - -  pLerpValues_t     radius; -  pLerpValues_t     alpha; -  pLerpValues_t     rotation; - -  pLerpValues_t     dLightRadius; - -  int               colorDelay; - -  qhandle_t         model; -  lerpFrame_t       lf; -  vec3_t            lastAxis[ 3 ]; - -  qboolean          valid; -  int               frameWhenInvalidated; - -  int               sortKey; -} particle_t; - -//====================================================================== - -//trail system stuff -#define MAX_BEAMS_PER_SYSTEM      4 - -#define MAX_BASETRAIL_SYSTEMS     64 -#define MAX_BASETRAIL_BEAMS       MAX_BASETRAIL_SYSTEMS*MAX_BEAMS_PER_SYSTEM - -#define MAX_TRAIL_SYSTEMS         32 -#define MAX_TRAIL_BEAMS           MAX_TRAIL_SYSTEMS*MAX_BEAMS_PER_SYSTEM -#define MAX_TRAIL_BEAM_NODES      128 - -#define MAX_TRAIL_BEAM_JITTERS    4 - -typedef enum -{ -  TBTT_STRETCH, -  TBTT_REPEAT -} trailBeamTextureType_t; - -typedef struct baseTrailJitter_s -{ -  float   magnitude; -  int     period; -} baseTrailJitter_t; - -//beam template -typedef struct baseTrailBeam_s -{ -  int                     numSegments; -  float                   frontWidth; -  float                   backWidth; -  float                   frontAlpha; -  float                   backAlpha; -  byte                    frontColor[ 3 ]; -  byte                    backColor[ 3 ]; - -  // the time it takes for a segment to vanish (single attached only) -  int                     segmentTime; - -  // the time it takes for a beam to fade out (double attached only) -  int                     fadeOutTime; - -  char                    shaderName[ MAX_QPATH ]; -  qhandle_t               shader; - -  trailBeamTextureType_t  textureType; - -  //TBTT_STRETCH -  float                   frontTextureCoord; -  float                   backTextureCoord; - -  //TBTT_REPEAT -  float                   repeatLength; -  qboolean                clampToBack; - -  qboolean                realLight; - -  int                     numJitters; -  baseTrailJitter_t       jitters[ MAX_TRAIL_BEAM_JITTERS ]; -  qboolean                jitterAttachments; -} baseTrailBeam_t; - - -//trail system template -typedef struct baseTrailSystem_s -{ -  char            name[ MAX_QPATH ]; -  baseTrailBeam_t *beams[ MAX_BEAMS_PER_SYSTEM ]; -  int             numBeams; - -  qboolean        thirdPersonOnly; -  qboolean        registered; //whether or not the assets for this trail have been loaded -} baseTrailSystem_t; - -typedef struct trailSystem_s -{ -  baseTrailSystem_t   *class; - -  attachment_t        frontAttachment; -  attachment_t        backAttachment; - -  int                 destroyTime; -  qboolean            valid; -} trailSystem_t; - -typedef struct trailBeamNode_s -{ -  vec3_t                  refPosition; -  vec3_t                  position; - -  int                     timeLeft; - -  float                   textureCoord; -  float                   halfWidth; -  byte                    alpha; -  byte                    color[ 3 ]; - -  vec2_t                  jitters[ MAX_TRAIL_BEAM_JITTERS ]; - -  struct trailBeamNode_s  *prev; -  struct trailBeamNode_s  *next; - -  qboolean                used; -} trailBeamNode_t; - -typedef struct trailBeam_s -{ -  baseTrailBeam_t   *class; -  trailSystem_t     *parent; - -  trailBeamNode_t   nodePool[ MAX_TRAIL_BEAM_NODES ]; -  trailBeamNode_t   *nodes; - -  int               lastEvalTime; - -  qboolean          valid; - -  int               nextJitterTimes[ MAX_TRAIL_BEAM_JITTERS ]; -} trailBeam_t; - -//====================================================================== - -// player entities need to track more information -// than any other type of entity. - -// note that not every player entity is a client entity, -// because corpses after respawn are outside the normal -// client numbering range - -//TA: smoothing of view and model for WW transitions -#define   MAXSMOOTHS          32 - -typedef struct -{ -  float     time; -  float     timeMod; - -  vec3_t    rotAxis; -  float     rotAngle; -} smooth_t; - - -typedef struct -{ -  lerpFrame_t legs, torso, flag, nonseg; -  int         painTime; -  int         painDirection;  // flip from 0 to 1 - -  // machinegun spinning -  float       barrelAngle; -  int         barrelTime; -  qboolean    barrelSpinning; - -  vec3_t      lastNormal; -  vec3_t      lastAxis[ 3 ]; -  smooth_t    sList[ MAXSMOOTHS ]; -} playerEntity_t; - -typedef struct lightFlareStatus_s -{ -  float     lastSrcRadius; //caching of likely flare source radius -  float     lastRadius;    //caching of likely flare radius -  float     lastRatio;     //caching of likely flare ratio -  int       lastTime;      //last time flare was visible/occluded -  qboolean  status;        //flare is visble? -} lightFlareStatus_t; - -//================================================= - -// centity_t have a direct corespondence with gentity_t in the game, but -// only the entityState_t is directly communicated to the cgame -typedef struct centity_s -{ -  entityState_t         currentState;     // from cg.frame -  entityState_t         nextState;        // from cg.nextFrame, if available -  qboolean              interpolate;      // true if next is valid to interpolate to -  qboolean              currentValid;     // true if cg.frame holds this entity - -  int                   muzzleFlashTime;  // move to playerEntity? -  int                   muzzleFlashTime2; // move to playerEntity? -  int                   muzzleFlashTime3; // move to playerEntity? -  int                   previousEvent; -  int                   teleportFlag; - -  int                   trailTime;        // so missile trails can handle dropped initial packets -  int                   dustTrailTime; -  int                   miscTime; -  int                   snapShotTime;     // last time this entity was found in a snapshot - -  playerEntity_t        pe; - -  int                   errorTime;        // decay the error from this time -  vec3_t                errorOrigin; -  vec3_t                errorAngles; - -  qboolean              extrapolated;     // false if origin / angles is an interpolation -  vec3_t                rawOrigin; -  vec3_t                rawAngles; - -  vec3_t                beamEnd; - -  // exact interpolated position of entity on this frame -  vec3_t                lerpOrigin; -  vec3_t                lerpAngles; - -  lerpFrame_t           lerpFrame; - -  //TA: -  buildableAnimNumber_t buildableAnim;    //persistant anim number -  buildableAnimNumber_t oldBuildableAnim; //to detect when new anims are set -  particleSystem_t      *buildablePS; -  float                 lastBuildableHealthScale; -  int                   lastBuildableDamageSoundTime; - -  lightFlareStatus_t    lfs; - -  qboolean              doorState; - -  particleSystem_t      *muzzlePS; -  qboolean              muzzlePsTrigger; - -  particleSystem_t      *jetPackPS; -  jetPackState_t        jetPackState; - -  particleSystem_t      *entityPS; -  qboolean              entityPSMissing; - -  trailSystem_t         *level2ZapTS[ 3 ]; - -  trailSystem_t         *muzzleTS; //used for the tesla and reactor -  int                   muzzleTSDeathTime; - -  qboolean              valid; -  qboolean              oldValid; -} centity_t; - - -//====================================================================== - -typedef struct markPoly_s -{ -  struct markPoly_s *prevMark, *nextMark; -  int               time; -  qhandle_t         markShader; -  qboolean          alphaFade;    // fade alpha instead of rgb -  float             color[ 4 ]; -  poly_t            poly; -  polyVert_t        verts[ MAX_VERTS_ON_POLY ]; -} markPoly_t; - -//====================================================================== - - -typedef struct -{ -  int       client; -  int       score; -  int       ping; -  int       time; -  int       team; -  weapon_t  weapon; -  upgrade_t upgrade; -} score_t; - -// each client has an associated clientInfo_t -// that contains media references necessary to present the -// client model and other color coded effects -// this is regenerated each time a client's configstring changes, -// usually as a result of a userinfo (name, model, etc) change -#define MAX_CUSTOM_SOUNDS 32 -typedef struct -{ -  qboolean    infoValid; - -  char        name[ MAX_QPATH ]; -  pTeam_t     team; - -  int         botSkill;                   // 0 = not bot, 1-5 = bot - -  vec3_t      color1; -  vec3_t      color2; - -  int         score;                      // updated by score servercmds -  int         location;                   // location index for team mode -  int         health;                     // you only get this info about your teammates -  int         armor; -  int         curWeapon; - -  int         handicap; -  int         wins, losses;               // in tourney mode - -  int         teamTask;                   // task in teamplay (offence/defence) -  qboolean    teamLeader;                 // true when this is a team leader - -  int         powerups;                   // so can display quad/flag status - -  int         medkitUsageTime; -  int         invulnerabilityStartTime; -  int         invulnerabilityStopTime; - -  int         breathPuffTime; - -  // when clientinfo is changed, the loading of models/skins/sounds -  // can be deferred until you are dead, to prevent hitches in -  // gameplay -  char        modelName[ MAX_QPATH ]; -  char        skinName[ MAX_QPATH ]; -  char        headModelName[ MAX_QPATH ]; -  char        headSkinName[ MAX_QPATH ]; -  char        redTeam[ MAX_TEAMNAME ]; -  char        blueTeam[ MAX_TEAMNAME ]; - -  qboolean    newAnims;                   // true if using the new mission pack animations -  qboolean    fixedlegs;                  // true if legs yaw is always the same as torso yaw -  qboolean    fixedtorso;                 // true if torso never changes yaw -  qboolean    nonsegmented;               // true if model is Q2 style nonsegmented - -  vec3_t      headOffset;                 // move head in icon views -  footstep_t  footsteps; -  gender_t    gender;                     // from model - -  qhandle_t   legsModel; -  qhandle_t   legsSkin; - -  qhandle_t   torsoModel; -  qhandle_t   torsoSkin; - -  qhandle_t   headModel; -  qhandle_t   headSkin; - -  qhandle_t   nonSegModel;                //non-segmented model system -  qhandle_t   nonSegSkin;                 //non-segmented model system - -  qhandle_t   modelIcon; - -  animation_t animations[ MAX_PLAYER_TOTALANIMATIONS ]; - -  sfxHandle_t sounds[ MAX_CUSTOM_SOUNDS ]; - -  sfxHandle_t customFootsteps[ 4 ]; -  sfxHandle_t customMetalFootsteps[ 4 ]; -} clientInfo_t; - - -typedef struct weaponInfoMode_s -{ -  float       flashDlight; -  vec3_t      flashDlightColor; -  sfxHandle_t flashSound[ 4 ];  // fast firing weapons randomly choose -  qboolean    continuousFlash; - -  qhandle_t   missileModel; -  sfxHandle_t missileSound; -  float       missileDlight; -  vec3_t      missileDlightColor; -  int         missileRenderfx; -  qboolean    usesSpriteMissle; -  qhandle_t   missileSprite; -  int         missileSpriteSize; -  qhandle_t   missileParticleSystem; -  qhandle_t   missileTrailSystem; -  qboolean    missileRotates; -  qboolean    missileAnimates; -  int         missileAnimStartFrame; -  int         missileAnimNumFrames; -  int         missileAnimFrameRate; -  int         missileAnimLooping; - -  sfxHandle_t firingSound; -  qboolean    loopFireSound; - -  qhandle_t   muzzleParticleSystem; - -  qboolean    alwaysImpact; -  qhandle_t   impactParticleSystem; -  qhandle_t   impactMark; -  qhandle_t   impactMarkSize; -  sfxHandle_t impactSound[ 4 ]; //random impact sound -  sfxHandle_t impactFleshSound[ 4 ]; //random impact sound -} weaponInfoMode_t; - -// each WP_* weapon enum has an associated weaponInfo_t -// that contains media references necessary to present the -// weapon and its effects -typedef struct weaponInfo_s -{ -  qboolean          registered; -  char              *humanName; - -  qhandle_t         handsModel;       // the hands don't actually draw, they just position the weapon -  qhandle_t         weaponModel; -  qhandle_t         barrelModel; -  qhandle_t         flashModel; - -  vec3_t            weaponMidpoint;   // so it will rotate centered instead of by tag - -  qhandle_t         weaponIcon; -  qhandle_t         ammoIcon; - -  qhandle_t         crossHair; -  int               crossHairSize; - -  sfxHandle_t       readySound; - -  qboolean          disableIn3rdPerson; - -  weaponInfoMode_t  wim[ WPM_NUM_WEAPONMODES ]; -} weaponInfo_t; - -typedef struct upgradeInfo_s -{ -  qboolean    registered; -  char        *humanName; - -  qhandle_t   upgradeIcon; -} upgradeInfo_t; - -typedef struct -{ -  qboolean    looped; -  qboolean    enabled; - -  sfxHandle_t sound; -} sound_t; - -typedef struct -{ -  qhandle_t   models[ MAX_BUILDABLE_MODELS ]; -  animation_t animations[ MAX_BUILDABLE_ANIMATIONS ]; - -  //same number of sounds as animations -  sound_t     sounds[ MAX_BUILDABLE_ANIMATIONS ]; -} buildableInfo_t; - -#define MAX_REWARDSTACK   10 -#define MAX_SOUNDBUFFER   20 - -//====================================================================== - -//TA: -typedef struct -{ -  vec3_t    alienBuildablePos[ MAX_GENTITIES ]; -  int       alienBuildableTimes[ MAX_GENTITIES ]; -  int       numAlienBuildables; - -  vec3_t    humanBuildablePos[ MAX_GENTITIES ]; -  int       numHumanBuildables; - -  vec3_t    alienClientPos[ MAX_CLIENTS ]; -  int       numAlienClients; - -  vec3_t    humanClientPos[ MAX_CLIENTS ]; -  int       numHumanClients; - -  int       lastUpdateTime; -  vec3_t    origin; -  vec3_t    vangles; -} entityPos_t; - -typedef struct -{ -  int time; -  int length; -} consoleLine_t; - -#define MAX_CONSOLE_TEXT  8192 -#define MAX_CONSOLE_LINES 32 - -// all cg.stepTime, cg.duckTime, cg.landTime, etc are set to cg.time when the action -// occurs, and they will have visible effects for #define STEP_TIME or whatever msec after - -#define MAX_PREDICTED_EVENTS  16 - -typedef struct -{ -  int           clientFrame;                        // incremented each frame - -  int           clientNum; - -  qboolean      demoPlayback; -  qboolean      levelShot;                          // taking a level menu screenshot -  int           deferredPlayerLoading; -  qboolean      loading;                            // don't defer players at initial startup -  qboolean      intermissionStarted;                // don't play voice rewards, because game will end shortly - -  // there are only one or two snapshot_t that are relevent at a time -  int           latestSnapshotNum;                  // the number of snapshots the client system has received -  int           latestSnapshotTime;                 // the time from latestSnapshotNum, so we don't need to read the snapshot yet - -  snapshot_t    *snap;                              // cg.snap->serverTime <= cg.time -  snapshot_t    *nextSnap;                          // cg.nextSnap->serverTime > cg.time, or NULL -  snapshot_t    activeSnapshots[ 2 ]; - -  float         frameInterpolation;                 // (float)( cg.time - cg.frame->serverTime ) / -                                                    // (cg.nextFrame->serverTime - cg.frame->serverTime) - -  qboolean      thisFrameTeleport; -  qboolean      nextFrameTeleport; - -  int           frametime;                          // cg.time - cg.oldTime - -  int           time;                               // this is the time value that the client -                                                    // is rendering at. -  int           oldTime;                            // time at last frame, used for missile trails and prediction checking - -  int           physicsTime;                        // either cg.snap->time or cg.nextSnap->time - -  int           timelimitWarnings;                  // 5 min, 1 min, overtime -  int           fraglimitWarnings; - -  qboolean      mapRestart;                         // set on a map restart to set back the weapon - -  qboolean      renderingThirdPerson;               // during deaths, chasecams, etc - -  // prediction state -  qboolean      hyperspace;                         // true if prediction has hit a trigger_teleport -  playerState_t predictedPlayerState; -  centity_t     predictedPlayerEntity; -  qboolean      validPPS;                           // clear until the first call to CG_PredictPlayerState -  int           predictedErrorTime; -  vec3_t        predictedError; - -  int           eventSequence; -  int           predictableEvents[MAX_PREDICTED_EVENTS]; - -  float         stepChange;                         // for stair up smoothing -  int           stepTime; - -  float         duckChange;                         // for duck viewheight smoothing -  int           duckTime; - -  float         landChange;                         // for landing hard -  int           landTime; - -  // input state sent to server -  int           weaponSelect; - -  // auto rotating items -  vec3_t        autoAngles; -  vec3_t        autoAxis[ 3 ]; -  vec3_t        autoAnglesFast; -  vec3_t        autoAxisFast[ 3 ]; - -  // view rendering -  refdef_t      refdef; -  vec3_t        refdefViewAngles;                   // will be converted to refdef.viewaxis - -  // zoom key -  qboolean      zoomed; -  int           zoomTime; -  float         zoomSensitivity; - -  // information screen text during loading -  char          infoScreenText[ MAX_STRING_CHARS ]; - -  // scoreboard -  int           scoresRequestTime; -  int           numScores; -  int           selectedScore; -  int           teamScores[ 2 ]; -  score_t       scores[MAX_CLIENTS]; -  qboolean      showScores; -  qboolean      scoreBoardShowing; -  int           scoreFadeTime; -  char          killerName[ MAX_NAME_LENGTH ]; -  char          spectatorList[ MAX_STRING_CHARS ];  // list of names -  int           spectatorLen;                       // length of list -  float         spectatorWidth;                     // width in device units -  int           spectatorTime;                      // next time to offset -  int           spectatorPaintX;                    // current paint x -  int           spectatorPaintX2;                   // current paint x -  int           spectatorOffset;                    // current offset from start -  int           spectatorPaintLen;                  // current offset from start - -  // centerprinting -  int           centerPrintTime; -  int           centerPrintCharWidth; -  int           centerPrintY; -  char          centerPrint[ 1024 ]; -  int           centerPrintLines; - -  // low ammo warning state -  int           lowAmmoWarning;   // 1 = low, 2 = empty - -  // kill timers for carnage reward -  int           lastKillTime; - -  // crosshair client ID -  int           crosshairClientNum; -  int           crosshairClientTime; - -  // powerup active flashing -  int           powerupActive; -  int           powerupTime; - -  // attacking player -  int           attackerTime; -  int           voiceTime; - -  // reward medals -  int           rewardStack; -  int           rewardTime; -  int           rewardCount[ MAX_REWARDSTACK ]; -  qhandle_t     rewardShader[ MAX_REWARDSTACK ]; -  qhandle_t     rewardSound[ MAX_REWARDSTACK ]; - -  // sound buffer mainly for announcer sounds -  int           soundBufferIn; -  int           soundBufferOut; -  int           soundTime; -  qhandle_t     soundBuffer[ MAX_SOUNDBUFFER ]; - -  // for voice chat buffer -  int           voiceChatTime; -  int           voiceChatBufferIn; -  int           voiceChatBufferOut; - -  // warmup countdown -  int           warmup; -  int           warmupCount; - -  //========================== - -  int           itemPickup; -  int           itemPickupTime; -  int           itemPickupBlendTime;                // the pulse around the crosshair is timed seperately - -  int           weaponSelectTime; -  int           weaponAnimation; -  int           weaponAnimationTime; - -  // blend blobs -  float         damageTime; -  float         damageX, damageY, damageValue; - -  // status bar head -  float         headYaw; -  float         headEndPitch; -  float         headEndYaw; -  int           headEndTime; -  float         headStartPitch; -  float         headStartYaw; -  int           headStartTime; - -  // view movement -  float         v_dmg_time; -  float         v_dmg_pitch; -  float         v_dmg_roll; - -  vec3_t        kick_angles;                        // weapon kicks -  vec3_t        kick_origin; - -  // temp working variables for player view -  float         bobfracsin; -  int           bobcycle; -  float         xyspeed; -  int           nextOrbitTime; - -  // development tool -  refEntity_t   testModelEntity; -  refEntity_t   testModelBarrelEntity; -  char          testModelName[MAX_QPATH]; -  char          testModelBarrelName[MAX_QPATH]; -  qboolean      testGun; - -  int           spawnTime;                          //TA: fovwarp -  int           weapon1Time;                        //TA: time when BUTTON_ATTACK went t->f f->t -  int           weapon2Time;                        //TA: time when BUTTON_ATTACK2 went t->f f->t -  int           weapon3Time;                        //TA: time when BUTTON_USE_HOLDABLE went t->f f->t -  qboolean      weapon1Firing; -  qboolean      weapon2Firing; -  qboolean      weapon3Firing; - -  int           poisonedTime; - -  vec3_t        lastNormal;                         //TA: view smoothage -  vec3_t        lastVangles;                        //TA: view smoothage -  smooth_t      sList[ MAXSMOOTHS ];                //TA: WW smoothing - -  int           forwardMoveTime;                    //TA: for struggling -  int           rightMoveTime; -  int           upMoveTime; - -  float         charModelFraction;                  //TA: loading percentages -  float         mediaFraction; -  float         buildablesFraction; - -  int           lastBuildAttempt; -  int           lastEvolveAttempt; - -  char          consoleText[ MAX_CONSOLE_TEXT ]; -  consoleLine_t consoleLines[ MAX_CONSOLE_LINES ]; -  int           numConsoleLines; -  qboolean      consoleValid; - -  particleSystem_t *poisonCloudPS; - -  float         painBlendValue; -  float         painBlendTarget; -  int           lastHealth; -} cg_t; - - -// all of the model, shader, and sound references that are -// loaded at gamestate time are stored in cgMedia_t -// Other media that can be tied to clients, weapons, or items are -// stored in the clientInfo_t, itemInfo_t, weaponInfo_t, and powerupInfo_t -typedef struct -{ -  qhandle_t   charsetShader; -  qhandle_t   whiteShader; -  qhandle_t   outlineShader; - -  qhandle_t   level2ZapTS; - -  qhandle_t   balloonShader; -  qhandle_t   connectionShader; - -  qhandle_t   selectShader; -  qhandle_t   viewBloodShader; -  qhandle_t   tracerShader; -  qhandle_t   crosshairShader[ WP_NUM_WEAPONS ]; -  qhandle_t   backTileShader; - -  qhandle_t   creepShader; - -  qhandle_t   scannerShader; -  qhandle_t   scannerBlipShader; -  qhandle_t   scannerLineShader; - - -  qhandle_t   numberShaders[ 11 ]; - -  qhandle_t   shadowMarkShader; -  qhandle_t   wakeMarkShader; - -  // buildable shaders -  qhandle_t   greenBuildShader; -  qhandle_t   redBuildShader; -  qhandle_t   noPowerShader; -  qhandle_t   humanSpawningShader; - -  // disconnect -  qhandle_t   disconnectPS; -  qhandle_t   disconnectSound; - -  // sounds -  sfxHandle_t tracerSound; -  sfxHandle_t selectSound; -  sfxHandle_t footsteps[ FOOTSTEP_TOTAL ][ 4 ]; -  sfxHandle_t talkSound; -  sfxHandle_t landSound; -  sfxHandle_t fallSound; - -  sfxHandle_t hgrenb1aSound; -  sfxHandle_t hgrenb2aSound; - -  sfxHandle_t voteNow; -  sfxHandle_t votePassed; -  sfxHandle_t voteFailed; - -  sfxHandle_t watrInSound; -  sfxHandle_t watrOutSound; -  sfxHandle_t watrUnSound; - -  sfxHandle_t jetpackDescendSound; -  sfxHandle_t jetpackIdleSound; -  sfxHandle_t jetpackAscendSound; - -  qhandle_t   jetPackDescendPS; -  qhandle_t   jetPackHoverPS; -  qhandle_t   jetPackAscendPS; - -  sfxHandle_t medkitUseSound; - -  sfxHandle_t alienStageTransition; -  sfxHandle_t humanStageTransition; - -  sfxHandle_t alienOvermindAttack; -  sfxHandle_t alienOvermindDying; -  sfxHandle_t alienOvermindSpawns; - -  sfxHandle_t alienBuildableExplosion; -  sfxHandle_t alienBuildableDamage; -  sfxHandle_t alienBuildablePrebuild; -  sfxHandle_t humanBuildableExplosion; -  sfxHandle_t humanBuildablePrebuild; -  sfxHandle_t humanBuildableDamage[ 4 ]; - -  sfxHandle_t alienL1Grab; -  sfxHandle_t alienL4ChargePrepare; -  sfxHandle_t alienL4ChargeStart; - -  qhandle_t   cursor; -  qhandle_t   selectCursor; -  qhandle_t   sizeCursor; - -  //light armour -  qhandle_t larmourHeadSkin; -  qhandle_t larmourLegsSkin; -  qhandle_t larmourTorsoSkin; - -  qhandle_t jetpackModel; -  qhandle_t jetpackFlashModel; -  qhandle_t battpackModel; - -  sfxHandle_t repeaterUseSound; - -  sfxHandle_t buildableRepairSound; -  sfxHandle_t buildableRepairedSound; - -  qhandle_t   poisonCloudPS; -  qhandle_t   alienEvolvePS; -  qhandle_t   alienAcidTubePS; - -  sfxHandle_t alienEvolveSound; - -  qhandle_t   humanBuildableDamagedPS; -  qhandle_t   humanBuildableDestroyedPS; -  qhandle_t   alienBuildableDamagedPS; -  qhandle_t   alienBuildableDestroyedPS; - -  qhandle_t   alienBleedPS; -  qhandle_t   humanBleedPS; - -  qhandle_t   teslaZapTS; - -  sfxHandle_t lCannonWarningSound; - -  qhandle_t   buildWeaponTimerPie[ 8 ]; -  qhandle_t   upgradeClassIconShader; -} cgMedia_t; - - -// The client game static (cgs) structure hold everything -// loaded or calculated from the gamestate.  It will NOT -// be cleared when a tournement restart is done, allowing -// all clients to begin playing instantly -typedef struct -{ -  gameState_t   gameState;              // gamestate from server -  glconfig_t    glconfig;               // rendering configuration -  float         screenXScale;           // derived from glconfig -  float         screenYScale; -  float         screenXBias; - -  int           serverCommandSequence;  // reliable command stream counter -  int           processedSnapshotNum;   // the number of snapshots cgame has requested - -  qboolean      localServer;            // detected on startup by checking sv_running - -  // parsed from serverinfo -  int           dmflags; -  int           teamflags; -  int           timelimit; -  int           maxclients; -  char          mapname[ MAX_QPATH ]; - -  int           voteTime; -  int           voteYes; -  int           voteNo; -  qboolean      voteModified;           // beep whenever changed -  char          voteString[ MAX_STRING_TOKENS ]; - -  int           teamVoteTime[ 2 ]; -  int           teamVoteYes[ 2 ]; -  int           teamVoteNo[ 2 ]; -  qboolean      teamVoteModified[ 2 ];  // beep whenever changed -  char          teamVoteString[ 2 ][ MAX_STRING_TOKENS ]; - -  int           levelStartTime; - -  int           scores1, scores2;   // from configstrings - -  qboolean      newHud; - -  int           alienBuildPoints; -  int           alienBuildPointsTotal; -  int           humanBuildPoints; -  int           humanBuildPointsTotal; -  int           humanBuildPointsPowered; - -  int           alienStage; -  int           humanStage; -  int           alienKills; -  int           humanKills; -  int           alienNextStageThreshold; -  int           humanNextStageThreshold; - -  int           numAlienSpawns; -  int           numHumanSpawns; - -  // -  // locally derived information from gamestate -  // -  qhandle_t     gameModels[ MAX_MODELS ]; -  qhandle_t     gameShaders[ MAX_SHADERS ]; -  qhandle_t     gameParticleSystems[ MAX_GAME_PARTICLE_SYSTEMS ]; -  sfxHandle_t   gameSounds[ MAX_SOUNDS ]; - -  int           numInlineModels; -  qhandle_t     inlineDrawModel[ MAX_MODELS ]; -  vec3_t        inlineModelMidpoints[ MAX_MODELS ]; - -  clientInfo_t  clientinfo[ MAX_CLIENTS ]; - -  //TA: corpse info -  clientInfo_t  corpseinfo[ MAX_CLIENTS ]; - -  // teamchat width is *3 because of embedded color codes -  char          teamChatMsgs[ TEAMCHAT_HEIGHT ][ TEAMCHAT_WIDTH * 3 + 1 ]; -  int           teamChatMsgTimes[ TEAMCHAT_HEIGHT ]; -  int           teamChatPos; -  int           teamLastChatPos; - -  int           cursorX; -  int           cursorY; -  qboolean      eventHandling; -  qboolean      mouseCaptured; -  qboolean      sizingHud; -  void          *capturedItem; -  qhandle_t     activeCursor; - -  // media -  cgMedia_t           media; -} cgs_t; - -//============================================================================== - -extern  cgs_t     cgs; -extern  cg_t      cg; -extern  centity_t cg_entities[ MAX_GENTITIES ]; - -//TA: weapon limit expanded: -//extern  weaponInfo_t  cg_weapons[MAX_WEAPONS]; -extern  weaponInfo_t    cg_weapons[ 32 ]; -//TA: upgrade infos: -extern  upgradeInfo_t   cg_upgrades[ 32 ]; - -//TA: buildable infos: -extern  buildableInfo_t cg_buildables[ BA_NUM_BUILDABLES ]; - -extern  markPoly_t      cg_markPolys[ MAX_MARK_POLYS ]; - -extern  vmCvar_t    cg_centertime; -extern  vmCvar_t    cg_runpitch; -extern  vmCvar_t    cg_runroll; -extern  vmCvar_t    cg_bobup; -extern  vmCvar_t    cg_bobpitch; -extern  vmCvar_t    cg_bobroll; -extern  vmCvar_t    cg_swingSpeed; -extern  vmCvar_t    cg_shadows; -extern  vmCvar_t    cg_gibs; -extern  vmCvar_t    cg_drawTimer; -extern  vmCvar_t    cg_drawFPS; -extern  vmCvar_t    cg_drawSnapshot; -extern  vmCvar_t    cg_draw3dIcons; -extern  vmCvar_t    cg_drawIcons; -extern  vmCvar_t    cg_drawAmmoWarning; -extern  vmCvar_t    cg_drawCrosshair; -extern  vmCvar_t    cg_drawCrosshairNames; -extern  vmCvar_t    cg_drawRewards; -extern  vmCvar_t    cg_drawTeamOverlay; -extern  vmCvar_t    cg_teamOverlayUserinfo; -extern  vmCvar_t    cg_crosshairX; -extern  vmCvar_t    cg_crosshairY; -extern  vmCvar_t    cg_drawStatus; -extern  vmCvar_t    cg_draw2D; -extern  vmCvar_t    cg_animSpeed; -extern  vmCvar_t    cg_debugAnim; -extern  vmCvar_t    cg_debugPosition; -extern  vmCvar_t    cg_debugEvents; -extern  vmCvar_t    cg_teslaTrailTime; -extern  vmCvar_t    cg_railTrailTime; -extern  vmCvar_t    cg_errorDecay; -extern  vmCvar_t    cg_nopredict; -extern  vmCvar_t    cg_debugMove; -extern  vmCvar_t    cg_noPlayerAnims; -extern  vmCvar_t    cg_showmiss; -extern  vmCvar_t    cg_footsteps; -extern  vmCvar_t    cg_addMarks; -extern  vmCvar_t    cg_brassTime; -extern  vmCvar_t    cg_gun_frame; -extern  vmCvar_t    cg_gun_x; -extern  vmCvar_t    cg_gun_y; -extern  vmCvar_t    cg_gun_z; -extern  vmCvar_t    cg_drawGun; -extern  vmCvar_t    cg_viewsize; -extern  vmCvar_t    cg_tracerChance; -extern  vmCvar_t    cg_tracerWidth; -extern  vmCvar_t    cg_tracerLength; -extern  vmCvar_t    cg_autoswitch; -extern  vmCvar_t    cg_ignore; -extern  vmCvar_t    cg_simpleItems; -extern  vmCvar_t    cg_fov; -extern  vmCvar_t    cg_zoomFov; -extern  vmCvar_t    cg_thirdPersonRange; -extern  vmCvar_t    cg_thirdPersonAngle; -extern  vmCvar_t    cg_thirdPerson; -extern  vmCvar_t    cg_stereoSeparation; -extern  vmCvar_t    cg_lagometer; -extern  vmCvar_t    cg_drawAttacker; -extern  vmCvar_t    cg_synchronousClients; -extern  vmCvar_t    cg_teamChatTime; -extern  vmCvar_t    cg_teamChatHeight; -extern  vmCvar_t    cg_stats; -extern  vmCvar_t    cg_forceModel; -extern  vmCvar_t    cg_buildScript; -extern  vmCvar_t    cg_paused; -extern  vmCvar_t    cg_blood; -extern  vmCvar_t    cg_predictItems; -extern  vmCvar_t    cg_deferPlayers; -extern  vmCvar_t    cg_drawFriend; -extern  vmCvar_t    cg_teamChatsOnly; -extern  vmCvar_t    cg_noVoiceChats; -extern  vmCvar_t    cg_noVoiceText; -extern  vmCvar_t    cg_scorePlum; -extern  vmCvar_t    cg_smoothClients; -extern  vmCvar_t    pmove_fixed; -extern  vmCvar_t    pmove_msec; -//extern  vmCvar_t    cg_pmove_fixed; -extern  vmCvar_t    cg_cameraOrbit; -extern  vmCvar_t    cg_cameraOrbitDelay; -extern  vmCvar_t    cg_timescaleFadeEnd; -extern  vmCvar_t    cg_timescaleFadeSpeed; -extern  vmCvar_t    cg_timescale; -extern  vmCvar_t    cg_cameraMode; -extern  vmCvar_t    cg_smallFont; -extern  vmCvar_t    cg_bigFont; -extern  vmCvar_t    cg_noTaunt; -extern  vmCvar_t    cg_noProjectileTrail; -extern  vmCvar_t    cg_oldRail; -extern  vmCvar_t    cg_oldRocket; -extern  vmCvar_t    cg_oldPlasma; -extern  vmCvar_t    cg_trueLightning; -extern  vmCvar_t    cg_creepRes; -extern  vmCvar_t    cg_drawSurfNormal; -extern  vmCvar_t    cg_drawBBOX; -extern  vmCvar_t    cg_debugAlloc; -extern  vmCvar_t    cg_wwSmoothTime; -extern  vmCvar_t    cg_wwFollow; -extern  vmCvar_t    cg_wwToggle; -extern  vmCvar_t    cg_depthSortParticles; -extern  vmCvar_t    cg_consoleLatency; -extern  vmCvar_t    cg_lightFlare; -extern  vmCvar_t    cg_debugParticles; -extern  vmCvar_t    cg_debugTrails; -extern  vmCvar_t    cg_debugPVS; -extern  vmCvar_t    cg_disableWarningDialogs; -extern  vmCvar_t    cg_disableScannerPlane; - -extern  vmCvar_t    cg_painBlendUpRate; -extern  vmCvar_t    cg_painBlendDownRate; -extern  vmCvar_t    cg_painBlendMax; -extern  vmCvar_t    cg_painBlendScale; -extern  vmCvar_t    cg_painBlendZoom; - -//TA: hack to get class an carriage through to UI module -extern  vmCvar_t    ui_currentClass; -extern  vmCvar_t    ui_carriage; -extern  vmCvar_t    ui_stages; -extern  vmCvar_t    ui_dialog; -extern  vmCvar_t    ui_loading; -extern  vmCvar_t    ui_voteActive; -extern  vmCvar_t    ui_alienTeamVoteActive; -extern  vmCvar_t    ui_humanTeamVoteActive; - -extern  vmCvar_t    cg_debugRandom; - -// -// cg_main.c -// -const char  *CG_ConfigString( int index ); -const char  *CG_Argv( int arg ); - -void        CG_TAUIConsole( const char *text ); -void QDECL  CG_Printf( const char *msg, ... ); -void QDECL  CG_Error( const char *msg, ... ); - -void        CG_StartMusic( void ); - -void        CG_UpdateCvars( void ); - -int         CG_CrosshairPlayer( void ); -int         CG_LastAttacker( void ); -void        CG_LoadMenus( const char *menuFile ); -void        CG_KeyEvent( int key, qboolean down ); -void        CG_MouseEvent( int x, int y ); -void        CG_EventHandling( int type ); -void        CG_SetScoreSelection( void *menu ); -void        CG_BuildSpectatorString( void ); - -qboolean    CG_FileExists( char *filename ); -void        CG_RemoveConsoleLine( void ); - - -// -// cg_view.c -// -void        CG_addSmoothOp( vec3_t rotAxis, float rotAngle, float timeMod ); //TA -void        CG_TestModel_f( void ); -void        CG_TestGun_f( void ); -void        CG_TestModelNextFrame_f( void ); -void        CG_TestModelPrevFrame_f( void ); -void        CG_TestModelNextSkin_f( void ); -void        CG_TestModelPrevSkin_f( void ); -void        CG_ZoomDown_f( void ); -void        CG_ZoomUp_f( void ); -void        CG_AddBufferedSound( sfxHandle_t sfx ); -void        CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback ); - - -// -// cg_drawtools.c -// -void        CG_DrawPlane( vec3_t origin, vec3_t down, vec3_t right, qhandle_t shader ); -void        CG_AdjustFrom640( float *x, float *y, float *w, float *h ); -void        CG_FillRect( float x, float y, float width, float height, const float *color ); -void        CG_DrawPic( float x, float y, float width, float height, qhandle_t hShader ); -void        CG_DrawFadePic( float x, float y, float width, float height, vec4_t fcolor, -                            vec4_t tcolor, float amount, qhandle_t hShader ); - -int         CG_DrawStrlen( const char *str ); - -float       *CG_FadeColor( int startMsec, int totalMsec ); -void        CG_TileClear( void ); -void        CG_ColorForHealth( vec4_t hcolor ); -void        CG_GetColorForHealth( int health, int armor, vec4_t hcolor ); - -void        CG_DrawRect( float x, float y, float width, float height, float size, const float *color ); -void        CG_DrawSides(float x, float y, float w, float h, float size); -void        CG_DrawTopBottom(float x, float y, float w, float h, float size); - - -// -// cg_draw.c -// -extern  int sortedTeamPlayers[ TEAM_MAXOVERLAY ]; -extern  int numSortedTeamPlayers; -extern  char systemChat[ 256 ]; -extern  char teamChat1[ 256 ]; -extern  char teamChat2[ 256 ]; - -void        CG_AddLagometerFrameInfo( void ); -void        CG_AddLagometerSnapshotInfo( snapshot_t *snap ); -void        CG_CenterPrint( const char *str, int y, int charWidth ); -void        CG_DrawActive( stereoFrame_t stereoView ); -void        CG_OwnerDraw( float x, float y, float w, float h, float text_x, float text_y, -                          int ownerDraw, int ownerDrawFlags, int align, float special, -                          float scale, vec4_t color, qhandle_t shader, int textStyle); -void        CG_Text_Paint( float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style ); -int         CG_Text_Width( const char *text, float scale, int limit ); -int         CG_Text_Height( const char *text, float scale, int limit ); -float       CG_GetValue(int ownerDraw); -void        CG_RunMenuScript(char **args); -void        CG_SetPrintString( int type, const char *p ); -void        CG_InitTeamChat( void ); -void        CG_GetTeamColor( vec4_t *color ); -const char  *CG_GetKillerText(); -void        CG_Text_PaintChar( float x, float y, float width, float height, float scale, -                               float s, float t, float s2, float t2, qhandle_t hShader ); -void        CG_DrawLoadingScreen( void ); -void        CG_UpdateMediaFraction( float newFract ); -void        CG_ResetPainBlend( void ); - -// -// cg_players.c -// -void        CG_Player( centity_t *cent ); -void        CG_Corpse( centity_t *cent ); -void        CG_ResetPlayerEntity( centity_t *cent ); -void        CG_AddRefEntityWithPowerups( refEntity_t *ent, int powerups, int team ); -void        CG_NewClientInfo( int clientNum ); -void        CG_PrecacheClientInfo( pClass_t class, char *model, char *skin ); -sfxHandle_t CG_CustomSound( int clientNum, const char *soundName ); -void        CG_PlayerDisconnect( vec3_t org ); -void        CG_Bleed( vec3_t origin, vec3_t normal, int entityNum ); - -// -// cg_buildable.c -// -void        CG_GhostBuildable( buildable_t buildable ); -void        CG_Buildable( centity_t *cent ); -void        CG_InitBuildables( void ); -void        CG_HumanBuildableExplosion( vec3_t origin, vec3_t dir ); -void        CG_AlienBuildableExplosion( vec3_t origin, vec3_t dir ); - -// -// cg_animation.c -// -void        CG_RunLerpFrame( lerpFrame_t *lf ); - -// -// cg_animmapobj.c -// -void        CG_AnimMapObj( centity_t *cent ); -void        CG_ModelDoor( centity_t *cent ); - -// -// cg_predict.c -// - -#define MAGIC_TRACE_HACK -2 - -void        CG_BuildSolidList( void ); -int         CG_PointContents( const vec3_t point, int passEntityNum ); -void        CG_Trace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, -                      int skipNumber, int mask ); -void        CG_CapTrace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, -                         int skipNumber, int mask ); -void        CG_PredictPlayerState( void ); - - -// -// cg_events.c -// -void        CG_CheckEvents( centity_t *cent ); -void        CG_EntityEvent( centity_t *cent, vec3_t position ); -void        CG_PainEvent( centity_t *cent, int health ); - - -// -// cg_ents.c -// -void        CG_DrawBoundingBox( vec3_t origin, vec3_t mins, vec3_t maxs ); -void        CG_SetEntitySoundPosition( centity_t *cent ); -void        CG_AddPacketEntities( void ); -void        CG_Beam( centity_t *cent ); -void        CG_AdjustPositionForMover( const vec3_t in, int moverNum, int fromTime, int toTime, vec3_t out ); - -void        CG_PositionEntityOnTag( refEntity_t *entity, const refEntity_t *parent, -                                    qhandle_t parentModel, char *tagName ); -void        CG_PositionRotatedEntityOnTag( refEntity_t *entity, const refEntity_t *parent, -                                           qhandle_t parentModel, char *tagName ); - - - - -// -// cg_weapons.c -// -void        CG_NextWeapon_f( void ); -void        CG_PrevWeapon_f( void ); -void        CG_Weapon_f( void ); - -void        CG_InitUpgrades( ); -void        CG_RegisterUpgrade( int upgradeNum ); -void        CG_InitWeapons( ); -void        CG_RegisterWeapon( int weaponNum ); - -void        CG_FireWeapon( centity_t *cent, weaponMode_t weaponMode ); -void        CG_MissileHitWall( weapon_t weapon, weaponMode_t weaponMode, int clientNum, -                               vec3_t origin, vec3_t dir, impactSound_t soundType ); -void        CG_MissileHitPlayer( weapon_t weapon, weaponMode_t weaponMode, vec3_t origin, vec3_t dir, int entityNum ); -void        CG_Bullet( vec3_t origin, int sourceEntityNum, vec3_t normal, qboolean flesh, int fleshEntityNum ); -void        CG_ShotgunFire( entityState_t *es ); - -void        CG_AddViewWeapon (playerState_t *ps); -void        CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent ); -void        CG_DrawItemSelect( rectDef_t *rect, vec4_t color ); -void        CG_DrawItemSelectText( rectDef_t *rect, float scale, int textStyle ); - - -// -// cg_scanner.c -// -void        CG_UpdateEntityPositions( void ); -void        CG_Scanner( rectDef_t *rect, qhandle_t shader, vec4_t color ); -void        CG_AlienSense( rectDef_t *rect ); - -// -// cg_marks.c -// -void        CG_InitMarkPolys( void ); -void        CG_AddMarks( void ); -void        CG_ImpactMark( qhandle_t markShader, -                           const vec3_t origin, const vec3_t dir, -                           float orientation, -                           float r, float g, float b, float a, -                           qboolean alphaFade, -                           float radius, qboolean temporary ); - -// -// cg_snapshot.c -// -void          CG_ProcessSnapshots( void ); - -// -// cg_consolecmds.c -// -qboolean      CG_ConsoleCommand( void ); -void          CG_InitConsoleCommands( void ); - -// -// cg_servercmds.c -// -void          CG_ExecuteNewServerCommands( int latestSequence ); -void          CG_ParseServerinfo( void ); -void          CG_SetConfigValues( void ); -void          CG_ShaderStateChanged(void); - -// -// cg_playerstate.c -// -void          CG_Respawn( void ); -void          CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops ); -void          CG_CheckChangedPredictableEvents( playerState_t *ps ); - -// -// cg_mem.c -// -void          CG_InitMemory( void ); -void          *CG_Alloc( int size ); -void          CG_Free( void *ptr ); -void          CG_DefragmentMemory( void ); - -// -// cg_attachment.c -// -qboolean    CG_AttachmentPoint( attachment_t *a, vec3_t v ); -qboolean    CG_AttachmentDir( attachment_t *a, vec3_t v ); -qboolean    CG_AttachmentAxis( attachment_t *a, vec3_t axis[ 3 ] ); -qboolean    CG_AttachmentVelocity( attachment_t *a, vec3_t v ); -int         CG_AttachmentCentNum( attachment_t *a ); - -qboolean    CG_Attached( attachment_t *a ); - -void        CG_AttachToPoint( attachment_t *a ); -void        CG_AttachToCent( attachment_t *a ); -void        CG_AttachToTag( attachment_t *a ); -void        CG_AttachToParticle( attachment_t *a ); -void        CG_SetAttachmentPoint( attachment_t *a, vec3_t v ); -void        CG_SetAttachmentCent( attachment_t *a, centity_t *cent ); -void        CG_SetAttachmentTag( attachment_t *a, refEntity_t parent, -                qhandle_t model, char *tagName ); -void        CG_SetAttachmentParticle( attachment_t *a, particle_t *p ); - -void        CG_SetAttachmentOffset( attachment_t *a, vec3_t v ); - -// -// cg_particles.c -// -void                CG_LoadParticleSystems( void ); -qhandle_t           CG_RegisterParticleSystem( char *name ); - -particleSystem_t    *CG_SpawnNewParticleSystem( qhandle_t psHandle ); -void                CG_DestroyParticleSystem( particleSystem_t **ps ); - -qboolean            CG_IsParticleSystemInfinite( particleSystem_t *ps ); -qboolean            CG_IsParticleSystemValid( particleSystem_t **ps ); - -void                CG_SetParticleSystemNormal( particleSystem_t *ps, vec3_t normal ); - -void                CG_AddParticles( void ); - -void                CG_ParticleSystemEntity( centity_t *cent ); - -void                CG_TestPS_f( void ); -void                CG_DestroyTestPS_f( void ); - -// -// cg_trails.c -// -void                CG_LoadTrailSystems( void ); -qhandle_t           CG_RegisterTrailSystem( char *name ); - -trailSystem_t       *CG_SpawnNewTrailSystem( qhandle_t psHandle ); -void                CG_DestroyTrailSystem( trailSystem_t **ts ); - -qboolean            CG_IsTrailSystemValid( trailSystem_t **ts ); - -void                CG_AddTrails( void ); - -void                CG_TestTS_f( void ); -void                CG_DestroyTestTS_f( void ); - -// -// cg_ptr.c -// -int   CG_ReadPTRCode( void ); -void  CG_WritePTRCode( int code ); - -// -//=============================================== - -// -// system traps -// These functions are how the cgame communicates with the main game system -// - - -// print message on the local console -void          trap_Print( const char *fmt ); - -// abort the game -void          trap_Error( const char *fmt ); - -// milliseconds should only be used for performance tuning, never -// for anything game related.  Get time from the CG_DrawActiveFrame parameter -int           trap_Milliseconds( void ); - -// console variable interaction -void          trap_Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags ); -void          trap_Cvar_Update( vmCvar_t *vmCvar ); -void          trap_Cvar_Set( const char *var_name, const char *value ); -void          trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ); - -// ServerCommand and ConsoleCommand parameter access -int           trap_Argc( void ); -void          trap_Argv( int n, char *buffer, int bufferLength ); -void          trap_Args( char *buffer, int bufferLength ); - -// filesystem access -// returns length of file -int           trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode ); -void          trap_FS_Read( void *buffer, int len, fileHandle_t f ); -void          trap_FS_Write( const void *buffer, int len, fileHandle_t f ); -void          trap_FS_FCloseFile( fileHandle_t f ); -void          trap_FS_Seek( fileHandle_t f, long offset, fsOrigin_t origin ); // fsOrigin_t - -// add commands to the local console as if they were typed in -// for map changing, etc.  The command is not executed immediately, -// but will be executed in order the next time console commands -// are processed -void          trap_SendConsoleCommand( const char *text ); - -// register a command name so the console can perform command completion. -// FIXME: replace this with a normal console command "defineCommand"? -void          trap_AddCommand( const char *cmdName ); - -// send a string to the server over the network -void          trap_SendClientCommand( const char *s ); - -// force a screen update, only used during gamestate load -void          trap_UpdateScreen( void ); - -// model collision -void          trap_CM_LoadMap( const char *mapname ); -int           trap_CM_NumInlineModels( void ); -clipHandle_t  trap_CM_InlineModel( int index );    // 0 = world, 1+ = bmodels -clipHandle_t  trap_CM_TempBoxModel( const vec3_t mins, const vec3_t maxs ); -int           trap_CM_PointContents( const vec3_t p, clipHandle_t model ); -int           trap_CM_TransformedPointContents( const vec3_t p, clipHandle_t model, const vec3_t origin, const vec3_t angles ); -void          trap_CM_BoxTrace( trace_t *results, const vec3_t start, const vec3_t end, -                                const vec3_t mins, const vec3_t maxs, -                                clipHandle_t model, int brushmask ); -void          trap_CM_TransformedBoxTrace( trace_t *results, const vec3_t start, const vec3_t end, -                                           const vec3_t mins, const vec3_t maxs, -                                           clipHandle_t model, int brushmask, -                                           const vec3_t origin, const vec3_t angles ); -void          trap_CM_CapsuleTrace( trace_t *results, const vec3_t start, const vec3_t end, -                const vec3_t mins, const vec3_t maxs, -                clipHandle_t model, int brushmask ); -void          trap_CM_TransformedCapsuleTrace( trace_t *results, const vec3_t start, const vec3_t end, -                const vec3_t mins, const vec3_t maxs, -                clipHandle_t model, int brushmask, -                const vec3_t origin, const vec3_t angles ); - -// Returns the projection of a polygon onto the solid brushes in the world -int           trap_CM_MarkFragments( int numPoints, const vec3_t *points, -                                     const vec3_t projection, -                                     int maxPoints, vec3_t pointBuffer, -                                     int maxFragments, markFragment_t *fragmentBuffer ); - -// normal sounds will have their volume dynamically changed as their entity -// moves and the listener moves -void          trap_S_StartSound( vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfx ); -void          trap_S_StopLoopingSound( int entnum ); - -// a local sound is always played full volume -void          trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum ); -void          trap_S_ClearLoopingSounds( qboolean killall ); -void          trap_S_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ); -void          trap_S_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ); -void          trap_S_UpdateEntityPosition( int entityNum, const vec3_t origin ); - -// respatialize recalculates the volumes of sound as they should be heard by the -// given entityNum and position -void          trap_S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater ); -sfxHandle_t   trap_S_RegisterSound( const char *sample, qboolean compressed );    // returns buzz if not found -void          trap_S_StartBackgroundTrack( const char *intro, const char *loop ); // empty name stops music -void          trap_S_StopBackgroundTrack( void ); - - -void          trap_R_LoadWorldMap( const char *mapname ); - -// all media should be registered during level startup to prevent -// hitches during gameplay -qhandle_t     trap_R_RegisterModel( const char *name );     // returns rgb axis if not found -qhandle_t     trap_R_RegisterSkin( const char *name );      // returns all white if not found -qhandle_t     trap_R_RegisterShader( const char *name );      // returns all white if not found -qhandle_t     trap_R_RegisterShaderNoMip( const char *name );     // returns all white if not found - -// a scene is built up by calls to R_ClearScene and the various R_Add functions. -// Nothing is drawn until R_RenderScene is called. -void          trap_R_ClearScene( void ); -void          trap_R_AddRefEntityToScene( const refEntity_t *re ); - -// polys are intended for simple wall marks, not really for doing -// significant construction -void          trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts ); -void          trap_R_AddPolysToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts, int numPolys ); -void          trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b ); -void          trap_R_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b ); -int           trap_R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir ); -void          trap_R_RenderScene( const refdef_t *fd ); -void          trap_R_SetColor( const float *rgba ); // NULL = 1,1,1,1 -void          trap_R_DrawStretchPic( float x, float y, float w, float h, -                                     float s1, float t1, float s2, float t2, qhandle_t hShader ); -void          trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs ); -int           trap_R_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, -                              float frac, const char *tagName ); -void          trap_R_RemapShader( const char *oldShader, const char *newShader, const char *timeOffset ); - -// The glconfig_t will not change during the life of a cgame. -// If it needs to change, the entire cgame will be restarted, because -// all the qhandle_t are then invalid. -void          trap_GetGlconfig( glconfig_t *glconfig ); - -// the gamestate should be grabbed at startup, and whenever a -// configstring changes -void          trap_GetGameState( gameState_t *gamestate ); - -// cgame will poll each frame to see if a newer snapshot has arrived -// that it is interested in.  The time is returned seperately so that -// snapshot latency can be calculated. -void          trap_GetCurrentSnapshotNumber( int *snapshotNumber, int *serverTime ); - -// a snapshot get can fail if the snapshot (or the entties it holds) is so -// old that it has fallen out of the client system queue -qboolean      trap_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ); - -// retrieve a text command from the server stream -// the current snapshot will hold the number of the most recent command -// qfalse can be returned if the client system handled the command -// argc() / argv() can be used to examine the parameters of the command -qboolean      trap_GetServerCommand( int serverCommandNumber ); - -// returns the most recent command number that can be passed to GetUserCmd -// this will always be at least one higher than the number in the current -// snapshot, and it may be quite a few higher if it is a fast computer on -// a lagged connection -int           trap_GetCurrentCmdNumber( void ); - -qboolean      trap_GetUserCmd( int cmdNumber, usercmd_t *ucmd ); - -// used for the weapon select and zoom -void          trap_SetUserCmdValue( int stateValue, float sensitivityScale ); - -// aids for VM testing -void          testPrintInt( char *string, int i ); -void          testPrintFloat( char *string, float f ); - -int           trap_MemoryRemaining( void ); -void          trap_R_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font); -qboolean      trap_Key_IsDown( int keynum ); -int           trap_Key_GetCatcher( void ); -void          trap_Key_SetCatcher( int catcher ); -int           trap_Key_GetKey( const char *binding ); - -typedef enum -{ -  SYSTEM_PRINT, -  CHAT_PRINT, -  TEAMCHAT_PRINT -} q3print_t; - - -int           trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits ); -e_status      trap_CIN_StopCinematic( int handle ); -e_status      trap_CIN_RunCinematic( int handle ); -void          trap_CIN_DrawCinematic( int handle ); -void          trap_CIN_SetExtents( int handle, int x, int y, int w, int h ); - -void          trap_SnapVector( float *v ); - -qboolean      trap_loadCamera( const char *name ); -void          trap_startCamera( int time ); -qboolean      trap_getCameraInfo( int time, vec3_t *origin, vec3_t *angles ); - -qboolean      trap_GetEntityToken( char *buffer, int bufferSize ); diff --git a/mod/src/cgame/cg_main.c b/mod/src/cgame/cg_main.c deleted file mode 100644 index 81470e0e..00000000 --- a/mod/src/cgame/cg_main.c +++ /dev/null @@ -1,1801 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_main.c -- initialization and primary entry point for cgame - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -#include "../ui/ui_shared.h" -// display context for new ui stuff -displayContextDef_t cgDC; - -int forceModelModificationCount = -1; - -void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum ); -void CG_Shutdown( void ); - -/* -================ -vmMain - -This is the only way control passes into the module. -This must be the very first function compiled into the .q3vm file -================ -*/ -long vmMain( long command, long arg0, long arg1, long arg2, long arg3, -                           long arg4, long arg5, long arg6, long arg7, -                           long arg8, long arg9, long arg10, long arg11 ) -{ -  switch( command ) -  { -    case CG_INIT: -      CG_Init( arg0, arg1, arg2 ); -      return 0; - -    case CG_SHUTDOWN: -      CG_Shutdown( ); -      return 0; - -    case CG_CONSOLE_COMMAND: -      return CG_ConsoleCommand( ); - -    case CG_DRAW_ACTIVE_FRAME: -      CG_DrawActiveFrame( arg0, arg1, arg2 ); -      return 0; - -    case CG_CROSSHAIR_PLAYER: -      return CG_CrosshairPlayer( ); - -    case CG_LAST_ATTACKER: -      return CG_LastAttacker( ); - -    case CG_KEY_EVENT: -      CG_KeyEvent( arg0, arg1 ); -      return 0; - -    case CG_MOUSE_EVENT: -      cgDC.cursorx = cgs.cursorX; -      cgDC.cursory = cgs.cursorY; -      CG_MouseEvent( arg0, arg1 ); -      return 0; - -    case CG_EVENT_HANDLING: -      CG_EventHandling( arg0 ); -      return 0; - -    default: -      CG_Error( "vmMain: unknown command %i", command ); -      break; -  } - -  return -1; -} - - -cg_t        cg; -cgs_t       cgs; -centity_t   cg_entities[ MAX_GENTITIES ]; - -//TA: weapons limit expanded: -//weaponInfo_t    cg_weapons[MAX_WEAPONS]; -weaponInfo_t    cg_weapons[ 32 ]; -upgradeInfo_t   cg_upgrades[ 32 ]; - -buildableInfo_t cg_buildables[ BA_NUM_BUILDABLES ]; - -vmCvar_t  cg_teslaTrailTime; -vmCvar_t  cg_railTrailTime; -vmCvar_t  cg_centertime; -vmCvar_t  cg_runpitch; -vmCvar_t  cg_runroll; -vmCvar_t  cg_bobup; -vmCvar_t  cg_bobpitch; -vmCvar_t  cg_bobroll; -vmCvar_t  cg_swingSpeed; -vmCvar_t  cg_shadows; -vmCvar_t  cg_gibs; -vmCvar_t  cg_drawTimer; -vmCvar_t  cg_drawFPS; -vmCvar_t  cg_drawSnapshot; -vmCvar_t  cg_draw3dIcons; -vmCvar_t  cg_drawIcons; -vmCvar_t  cg_drawAmmoWarning; -vmCvar_t  cg_drawCrosshair; -vmCvar_t  cg_drawCrosshairNames; -vmCvar_t  cg_drawRewards; -vmCvar_t  cg_crosshairX; -vmCvar_t  cg_crosshairY; -vmCvar_t  cg_draw2D; -vmCvar_t  cg_drawStatus; -vmCvar_t  cg_animSpeed; -vmCvar_t  cg_debugAnim; -vmCvar_t  cg_debugPosition; -vmCvar_t  cg_debugEvents; -vmCvar_t  cg_errorDecay; -vmCvar_t  cg_nopredict; -vmCvar_t  cg_debugMove; -vmCvar_t  cg_noPlayerAnims; -vmCvar_t  cg_showmiss; -vmCvar_t  cg_footsteps; -vmCvar_t  cg_addMarks; -vmCvar_t  cg_brassTime; -vmCvar_t  cg_viewsize; -vmCvar_t  cg_drawGun; -vmCvar_t  cg_gun_frame; -vmCvar_t  cg_gun_x; -vmCvar_t  cg_gun_y; -vmCvar_t  cg_gun_z; -vmCvar_t  cg_tracerChance; -vmCvar_t  cg_tracerWidth; -vmCvar_t  cg_tracerLength; -vmCvar_t  cg_autoswitch; -vmCvar_t  cg_ignore; -vmCvar_t  cg_simpleItems; -vmCvar_t  cg_fov; -vmCvar_t  cg_zoomFov; -vmCvar_t  cg_thirdPerson; -vmCvar_t  cg_thirdPersonRange; -vmCvar_t  cg_thirdPersonAngle; -vmCvar_t  cg_stereoSeparation; -vmCvar_t  cg_lagometer; -vmCvar_t  cg_drawAttacker; -vmCvar_t  cg_synchronousClients; -vmCvar_t  cg_teamChatTime; -vmCvar_t  cg_teamChatHeight; -vmCvar_t  cg_stats; -vmCvar_t  cg_buildScript; -vmCvar_t  cg_forceModel; -vmCvar_t  cg_paused; -vmCvar_t  cg_blood; -vmCvar_t  cg_predictItems; -vmCvar_t  cg_deferPlayers; -vmCvar_t  cg_drawTeamOverlay; -vmCvar_t  cg_teamOverlayUserinfo; -vmCvar_t  cg_drawFriend; -vmCvar_t  cg_teamChatsOnly; -vmCvar_t  cg_noVoiceChats; -vmCvar_t  cg_noVoiceText; -vmCvar_t  cg_hudFiles; -vmCvar_t  cg_scorePlum; -vmCvar_t  cg_smoothClients; -vmCvar_t  pmove_fixed; -//vmCvar_t  cg_pmove_fixed; -vmCvar_t  pmove_msec; -vmCvar_t  cg_pmove_msec; -vmCvar_t  cg_cameraMode; -vmCvar_t  cg_cameraOrbit; -vmCvar_t  cg_cameraOrbitDelay; -vmCvar_t  cg_timescaleFadeEnd; -vmCvar_t  cg_timescaleFadeSpeed; -vmCvar_t  cg_timescale; -vmCvar_t  cg_smallFont; -vmCvar_t  cg_bigFont; -vmCvar_t  cg_noTaunt; -vmCvar_t  cg_noProjectileTrail; -vmCvar_t  cg_oldRail; -vmCvar_t  cg_oldRocket; -vmCvar_t  cg_oldPlasma; -vmCvar_t  cg_trueLightning; -vmCvar_t  cg_creepRes; -vmCvar_t  cg_drawSurfNormal; -vmCvar_t  cg_drawBBOX; -vmCvar_t  cg_debugAlloc; -vmCvar_t  cg_wwSmoothTime; -vmCvar_t  cg_wwFollow; -vmCvar_t  cg_wwToggle; -vmCvar_t  cg_depthSortParticles; -vmCvar_t  cg_consoleLatency; -vmCvar_t  cg_lightFlare; -vmCvar_t  cg_debugParticles; -vmCvar_t  cg_debugTrails; -vmCvar_t  cg_debugPVS; -vmCvar_t  cg_disableWarningDialogs; -vmCvar_t  cg_disableScannerPlane; - -vmCvar_t  cg_painBlendUpRate; -vmCvar_t  cg_painBlendDownRate; -vmCvar_t  cg_painBlendMax; -vmCvar_t  cg_painBlendScale; -vmCvar_t  cg_painBlendZoom; - -//TA: hack to get class and carriage through to UI module -vmCvar_t  ui_currentClass; -vmCvar_t  ui_carriage; -vmCvar_t  ui_stages; -vmCvar_t  ui_dialog; -vmCvar_t  ui_loading; -vmCvar_t  ui_voteActive; -vmCvar_t  ui_alienTeamVoteActive; -vmCvar_t  ui_humanTeamVoteActive; - -vmCvar_t  cg_debugRandom; - - -typedef struct -{ -  vmCvar_t  *vmCvar; -  char      *cvarName; -  char      *defaultString; -  int       cvarFlags; -} cvarTable_t; - -static cvarTable_t cvarTable[ ] = -{ -  { &cg_ignore, "cg_ignore", "0", 0 },  // used for debugging -  { &cg_autoswitch, "cg_autoswitch", "1", CVAR_ARCHIVE }, -  { &cg_drawGun, "cg_drawGun", "1", CVAR_ARCHIVE }, -  { &cg_zoomFov, "cg_zoomfov", "22.5", CVAR_ARCHIVE }, -  { &cg_fov, "cg_fov", "90", CVAR_ARCHIVE }, -  { &cg_viewsize, "cg_viewsize", "100", CVAR_ARCHIVE }, -  { &cg_stereoSeparation, "cg_stereoSeparation", "0.4", CVAR_ARCHIVE  }, -  { &cg_shadows, "cg_shadows", "1", CVAR_ARCHIVE  }, -  { &cg_gibs, "cg_gibs", "1", CVAR_ARCHIVE  }, -  { &cg_draw2D, "cg_draw2D", "1", CVAR_ARCHIVE  }, -  { &cg_drawStatus, "cg_drawStatus", "1", CVAR_ARCHIVE  }, -  { &cg_drawTimer, "cg_drawTimer", "1", CVAR_ARCHIVE  }, -  { &cg_drawFPS, "cg_drawFPS", "1", CVAR_ARCHIVE  }, -  { &cg_drawSnapshot, "cg_drawSnapshot", "0", CVAR_ARCHIVE  }, -  { &cg_draw3dIcons, "cg_draw3dIcons", "1", CVAR_ARCHIVE  }, -  { &cg_drawIcons, "cg_drawIcons", "1", CVAR_ARCHIVE  }, -  { &cg_drawAmmoWarning, "cg_drawAmmoWarning", "1", CVAR_ARCHIVE  }, -  { &cg_drawAttacker, "cg_drawAttacker", "1", CVAR_ARCHIVE  }, -  { &cg_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE }, -  { &cg_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE }, -  { &cg_drawRewards, "cg_drawRewards", "1", CVAR_ARCHIVE }, -  { &cg_crosshairX, "cg_crosshairX", "0", CVAR_ARCHIVE }, -  { &cg_crosshairY, "cg_crosshairY", "0", CVAR_ARCHIVE }, -  { &cg_brassTime, "cg_brassTime", "2500", CVAR_ARCHIVE }, -  { &cg_simpleItems, "cg_simpleItems", "0", CVAR_ARCHIVE }, -  { &cg_addMarks, "cg_marks", "1", CVAR_ARCHIVE }, -  { &cg_lagometer, "cg_lagometer", "0", CVAR_ARCHIVE }, -  { &cg_teslaTrailTime, "cg_teslaTrailTime", "250", CVAR_ARCHIVE  }, -  { &cg_railTrailTime, "cg_railTrailTime", "400", CVAR_ARCHIVE  }, -  { &cg_gun_x, "cg_gunX", "0", CVAR_CHEAT }, -  { &cg_gun_y, "cg_gunY", "0", CVAR_CHEAT }, -  { &cg_gun_z, "cg_gunZ", "0", CVAR_CHEAT }, -  { &cg_centertime, "cg_centertime", "3", CVAR_CHEAT }, -  { &cg_runpitch, "cg_runpitch", "0.002", CVAR_ARCHIVE}, -  { &cg_runroll, "cg_runroll", "0.005", CVAR_ARCHIVE }, -  { &cg_bobup , "cg_bobup", "0.005", CVAR_CHEAT }, -  { &cg_bobpitch, "cg_bobpitch", "0.002", CVAR_ARCHIVE }, -  { &cg_bobroll, "cg_bobroll", "0.002", CVAR_ARCHIVE }, -  { &cg_swingSpeed, "cg_swingSpeed", "0.3", CVAR_CHEAT }, -  { &cg_animSpeed, "cg_animspeed", "1", CVAR_CHEAT }, -  { &cg_debugAnim, "cg_debuganim", "0", CVAR_CHEAT }, -  { &cg_debugPosition, "cg_debugposition", "0", CVAR_CHEAT }, -  { &cg_debugEvents, "cg_debugevents", "0", CVAR_CHEAT }, -  { &cg_errorDecay, "cg_errordecay", "100", 0 }, -  { &cg_nopredict, "cg_nopredict", "0", 0 }, -  { &cg_debugMove, "cg_debugMove", "0", 0 }, -  { &cg_noPlayerAnims, "cg_noplayeranims", "0", CVAR_CHEAT }, -  { &cg_showmiss, "cg_showmiss", "0", 0 }, -  { &cg_footsteps, "cg_footsteps", "1", CVAR_CHEAT }, -  { &cg_tracerChance, "cg_tracerchance", "0.4", CVAR_CHEAT }, -  { &cg_tracerWidth, "cg_tracerwidth", "1", CVAR_CHEAT }, -  { &cg_tracerLength, "cg_tracerlength", "100", CVAR_CHEAT }, -  { &cg_thirdPersonRange, "cg_thirdPersonRange", "40", CVAR_CHEAT }, -  { &cg_thirdPersonAngle, "cg_thirdPersonAngle", "0", CVAR_CHEAT }, -  { &cg_thirdPerson, "cg_thirdPerson", "0", CVAR_CHEAT }, -  { &cg_teamChatTime, "cg_teamChatTime", "3000", CVAR_ARCHIVE  }, -  { &cg_teamChatHeight, "cg_teamChatHeight", "0", CVAR_ARCHIVE  }, -  { &cg_forceModel, "cg_forceModel", "0", CVAR_ARCHIVE  }, -  { &cg_predictItems, "cg_predictItems", "1", CVAR_ARCHIVE }, -  { &cg_deferPlayers, "cg_deferPlayers", "1", CVAR_ARCHIVE }, -  { &cg_drawTeamOverlay, "cg_drawTeamOverlay", "0", CVAR_ARCHIVE }, -  { &cg_teamOverlayUserinfo, "teamoverlay", "0", CVAR_ROM | CVAR_USERINFO }, -  { &cg_stats, "cg_stats", "0", 0 }, -  { &cg_drawFriend, "cg_drawFriend", "1", CVAR_ARCHIVE }, -  { &cg_teamChatsOnly, "cg_teamChatsOnly", "0", CVAR_ARCHIVE }, -  { &cg_noVoiceChats, "cg_noVoiceChats", "0", CVAR_ARCHIVE }, -  { &cg_noVoiceText, "cg_noVoiceText", "0", CVAR_ARCHIVE }, -  { &cg_creepRes, "cg_creepRes", "16", CVAR_ARCHIVE }, -  { &cg_drawSurfNormal, "cg_drawSurfNormal", "0", CVAR_CHEAT }, -  { &cg_drawBBOX, "cg_drawBBOX", "0", CVAR_CHEAT }, -  { &cg_debugAlloc, "cg_debugAlloc", "0", 0 }, -  { &cg_wwSmoothTime, "cg_wwSmoothTime", "300", CVAR_ARCHIVE }, -  { &cg_wwFollow, "cg_wwFollow", "1", CVAR_ARCHIVE|CVAR_USERINFO }, -  { &cg_wwToggle, "cg_wwToggle", "1", CVAR_ARCHIVE|CVAR_USERINFO }, -  { &cg_depthSortParticles, "cg_depthSortParticles", "1", CVAR_ARCHIVE }, -  { &cg_consoleLatency, "cg_consoleLatency", "3000", CVAR_ARCHIVE }, -  { &cg_lightFlare, "cg_lightFlare", "3", CVAR_ARCHIVE }, -  { &cg_debugParticles, "cg_debugParticles", "0", CVAR_CHEAT }, -  { &cg_debugTrails, "cg_debugTrails", "0", CVAR_CHEAT }, -  { &cg_debugPVS, "cg_debugPVS", "0", CVAR_CHEAT }, -  { &cg_disableWarningDialogs, "cg_disableWarningDialogs", "0", CVAR_ARCHIVE }, -  { &cg_disableScannerPlane, "cg_disableScannerPlane", "0", CVAR_ARCHIVE }, -  { &cg_hudFiles, "cg_hudFiles", "ui/hud.txt", CVAR_ARCHIVE}, - -  { &cg_painBlendUpRate, "cg_painBlendUpRate", "10.0", 0 }, -  { &cg_painBlendDownRate, "cg_painBlendDownRate", "0.5", 0 }, -  { &cg_painBlendMax, "cg_painBlendMax", "0.7", 0 }, -  { &cg_painBlendScale, "cg_painBlendScale", "7.0", 0 }, -  { &cg_painBlendZoom, "cg_painBlendZoom", "0.18", 0 }, - -  { &ui_currentClass, "ui_currentClass", "0", 0 }, -  { &ui_carriage, "ui_carriage", "", 0 }, -  { &ui_stages, "ui_stages", "0 0", 0 }, -  { &ui_dialog, "ui_dialog", "Text not set", 0 }, -  { &ui_loading, "ui_loading", "0", 0 }, -  { &ui_voteActive, "ui_voteActive", "0", 0 }, -  { &ui_humanTeamVoteActive, "ui_humanTeamVoteActive", "0", 0 }, -  { &ui_alienTeamVoteActive, "ui_alienTeamVoteActive", "0", 0 }, - -  { &cg_debugRandom, "cg_debugRandom", "0", 0 }, - -  // the following variables are created in other parts of the system, -  // but we also reference them here - -  { &cg_buildScript, "com_buildScript", "0", 0 }, // force loading of all possible data amd error on failures -  { &cg_paused, "cl_paused", "0", CVAR_ROM }, -  { &cg_blood, "com_blood", "1", CVAR_ARCHIVE }, -  { &cg_synchronousClients, "g_synchronousClients", "0", 0 }, // communicated by systeminfo -  { &cg_cameraOrbit, "cg_cameraOrbit", "0", CVAR_CHEAT}, -  { &cg_cameraOrbitDelay, "cg_cameraOrbitDelay", "50", CVAR_ARCHIVE}, -  { &cg_timescaleFadeEnd, "cg_timescaleFadeEnd", "1", 0}, -  { &cg_timescaleFadeSpeed, "cg_timescaleFadeSpeed", "0", 0}, -  { &cg_timescale, "timescale", "1", 0}, -  { &cg_scorePlum, "cg_scorePlums", "1", CVAR_USERINFO | CVAR_ARCHIVE}, -  { &cg_smoothClients, "cg_smoothClients", "0", CVAR_USERINFO | CVAR_ARCHIVE}, -  { &cg_cameraMode, "com_cameraMode", "0", CVAR_CHEAT}, - -  { &pmove_fixed, "pmove_fixed", "0", 0}, -  { &pmove_msec, "pmove_msec", "8", 0}, -  { &cg_noTaunt, "cg_noTaunt", "0", CVAR_ARCHIVE}, -  { &cg_noProjectileTrail, "cg_noProjectileTrail", "0", CVAR_ARCHIVE}, -  { &cg_smallFont, "ui_smallFont", "0.2", CVAR_ARCHIVE}, -  { &cg_bigFont, "ui_bigFont", "0.5", CVAR_ARCHIVE}, -  { &cg_oldRail, "cg_oldRail", "1", CVAR_ARCHIVE}, -  { &cg_oldRocket, "cg_oldRocket", "1", CVAR_ARCHIVE}, -  { &cg_oldPlasma, "cg_oldPlasma", "1", CVAR_ARCHIVE}, -  { &cg_trueLightning, "cg_trueLightning", "0.0", CVAR_ARCHIVE} -//  { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE } -}; - -static int   cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] ); - -/* -================= -CG_RegisterCvars -================= -*/ -void CG_RegisterCvars( void ) -{ -  int         i; -  cvarTable_t *cv; -  char        var[ MAX_TOKEN_CHARS ]; - -  for( i = 0, cv = cvarTable; i < cvarTableSize; i++, cv++ ) -  { -    trap_Cvar_Register( cv->vmCvar, cv->cvarName, -      cv->defaultString, cv->cvarFlags ); -  } - -  //repress standard Q3 console -  trap_Cvar_Set( "con_notifytime", "-2" ); - -  // see if we are also running the server on this machine -  trap_Cvar_VariableStringBuffer( "sv_running", var, sizeof( var ) ); -  cgs.localServer = atoi( var ); -  forceModelModificationCount = cg_forceModel.modificationCount; - -  trap_Cvar_Register( NULL, "model", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE ); -  trap_Cvar_Register( NULL, "headmodel", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE ); -  trap_Cvar_Register( NULL, "team_model", DEFAULT_TEAM_MODEL, CVAR_USERINFO | CVAR_ARCHIVE ); -  trap_Cvar_Register( NULL, "team_headmodel", DEFAULT_TEAM_HEAD, CVAR_USERINFO | CVAR_ARCHIVE ); -} - - -/* -=================== -CG_ForceModelChange -=================== -*/ -static void CG_ForceModelChange( void ) -{ -  int   i; - -  for( i = 0; i < MAX_CLIENTS; i++ ) -  { -    const char    *clientInfo; - -    clientInfo = CG_ConfigString( CS_PLAYERS + i ); - -    if( !clientInfo[ 0 ] ) -      continue; - -    CG_NewClientInfo( i ); -  } -} - - -/* -================= -CG_UpdateCvars -================= -*/ -void CG_UpdateCvars( void ) -{ -  int         i; -  cvarTable_t *cv; - -  for( i = 0, cv = cvarTable; i < cvarTableSize; i++, cv++ ) -    trap_Cvar_Update( cv->vmCvar ); - -  // check for modications here - -  // if force model changed -  if( forceModelModificationCount != cg_forceModel.modificationCount ) -  { -    forceModelModificationCount = cg_forceModel.modificationCount; -    CG_ForceModelChange( ); -  } -} - - -int CG_CrosshairPlayer( void ) -{ -  if( cg.time > ( cg.crosshairClientTime + 1000 ) ) -    return -1; - -  return cg.crosshairClientNum; -} - - -int CG_LastAttacker( void ) -{ -  if( !cg.attackerTime ) -    return -1; - -  return cg.snap->ps.persistant[ PERS_ATTACKER ]; -} - -void CG_RemoveConsoleLine( void ) -{ -  int i, offset, totalLength; - -  if( cg.numConsoleLines == 0 ) -    return; - -  offset = cg.consoleLines[ 0 ].length; -  totalLength = strlen( cg.consoleText ) - offset; - -  //slide up consoleText -  for( i = 0; i <= totalLength; i++ ) -    cg.consoleText[ i ] = cg.consoleText[ i + offset ]; - -  //pop up the first consoleLine -  for( i = 0; i < cg.numConsoleLines; i++ ) -    cg.consoleLines[ i ] = cg.consoleLines[ i + 1 ]; - -  cg.numConsoleLines--; -} - -//TA: team arena UI based console -void CG_TAUIConsole( const char *text ) -{ -  if( cg.numConsoleLines == MAX_CONSOLE_LINES ) -    CG_RemoveConsoleLine( ); - -  if( cg.consoleValid ) -  { -    strcat( cg.consoleText, text ); -    cg.consoleLines[ cg.numConsoleLines ].time = cg.time; -    cg.consoleLines[ cg.numConsoleLines ].length = strlen( text ); -    cg.numConsoleLines++; -  } - -} - -void QDECL CG_Printf( const char *msg, ... ) -{ -  va_list argptr; -  char    text[ 1024 ]; - -  va_start( argptr, msg ); -  vsprintf( text, msg, argptr ); -  va_end( argptr ); - -  CG_TAUIConsole( text ); - -  trap_Print( text ); -} - -void QDECL CG_Error( const char *msg, ... ) -{ -  va_list argptr; -  char    text[ 1024 ]; - -  va_start( argptr, msg ); -  vsprintf( text, msg, argptr ); -  va_end( argptr ); - -  trap_Error( text ); -} - -void QDECL Com_Error( int level, const char *error, ... ) -{ -  va_list argptr; -  char    text[1024]; - -  va_start( argptr, error ); -  vsprintf( text, error, argptr ); -  va_end( argptr ); - -  CG_Error( "%s", text ); -} - -void QDECL Com_Printf( const char *msg, ... ) { -  va_list   argptr; -  char    text[1024]; - -  va_start (argptr, msg); -  vsprintf (text, msg, argptr); -  va_end (argptr); - -  //TA: team arena UI based console -  if( cg.numConsoleLines == MAX_CONSOLE_LINES ) -    CG_RemoveConsoleLine( ); - -  if( cg.consoleValid ) -  { -    strcat( cg.consoleText, text ); -    cg.consoleLines[ cg.numConsoleLines ].time = cg.time; -    cg.consoleLines[ cg.numConsoleLines ].length = strlen( text ); -    cg.numConsoleLines++; -  } - -  CG_Printf ("%s", text); -} - - - -/* -================ -CG_Argv -================ -*/ -const char *CG_Argv( int arg ) -{ -  static char buffer[ MAX_STRING_CHARS ]; - -  trap_Argv( arg, buffer, sizeof( buffer ) ); - -  return buffer; -} - - -//======================================================================== - -/* -================= -CG_FileExists - -Test if a specific file exists or not -================= -*/ -qboolean CG_FileExists( char *filename ) -{ -  fileHandle_t  f; - -  if( trap_FS_FOpenFile( filename, &f, FS_READ ) > 0 ) -  { -    //file exists so close it -    trap_FS_FCloseFile( f ); - -    return qtrue; -  } -  else -    return qfalse; -} - -/* -================= -CG_RegisterSounds - -called during a precache command -================= -*/ -static void CG_RegisterSounds( void ) -{ -  int         i; -  char        name[ MAX_QPATH ]; -  const char  *soundName; - -  cgs.media.alienStageTransition  = trap_S_RegisterSound( "sound/announcements/overmindevolved.wav", qtrue ); -  cgs.media.humanStageTransition  = trap_S_RegisterSound( "sound/announcements/reinforcement.wav", qtrue ); - -  cgs.media.alienOvermindAttack   = trap_S_RegisterSound( "sound/announcements/overmindattack.wav", qtrue ); -  cgs.media.alienOvermindDying    = trap_S_RegisterSound( "sound/announcements/overminddying.wav", qtrue ); -  cgs.media.alienOvermindSpawns   = trap_S_RegisterSound( "sound/announcements/overmindspawns.wav", qtrue ); - -  cgs.media.alienL1Grab           = trap_S_RegisterSound( "sound/player/level1/grab.wav", qtrue ); -  cgs.media.alienL4ChargePrepare  = trap_S_RegisterSound( "sound/player/level4/charge_prepare.wav", qtrue ); -  cgs.media.alienL4ChargeStart    = trap_S_RegisterSound( "sound/player/level4/charge_start.wav", qtrue ); - -  cgs.media.tracerSound           = trap_S_RegisterSound( "sound/weapons/machinegun/buletby1.wav", qfalse ); //FIXME -  cgs.media.selectSound           = trap_S_RegisterSound( "sound/weapons/change.wav", qfalse ); - -  cgs.media.talkSound             = trap_S_RegisterSound( "sound/player/talk.wav", qfalse ); //FIXME -  cgs.media.landSound             = trap_S_RegisterSound( "sound/player/land1.wav", qfalse ); //FIXME - -  cgs.media.watrInSound           = trap_S_RegisterSound( "sound/player/watr_in.wav", qfalse ); //FIXME -  cgs.media.watrOutSound          = trap_S_RegisterSound( "sound/player/watr_out.wav", qfalse ); //FIXME -  cgs.media.watrUnSound           = trap_S_RegisterSound( "sound/player/watr_un.wav", qfalse ); //FIXME - -  cgs.media.disconnectSound       = trap_S_RegisterSound( "sound/world/telein.wav", qfalse ); //FIXME - -  //FIXME -  for( i = 0; i < 4; i++ ) -  { -    Com_sprintf( name, sizeof( name ), "sound/player/footsteps/step%i.wav", i + 1 ); -    cgs.media.footsteps[ FOOTSTEP_NORMAL ][ i ] = trap_S_RegisterSound( name, qfalse ); - -    Com_sprintf( name, sizeof( name ), "sound/player/footsteps/boot%i.wav", i + 1 ); -    cgs.media.footsteps[ FOOTSTEP_BOOT ][ i ] = trap_S_RegisterSound( name, qfalse ); - -    Com_sprintf( name, sizeof( name ), "sound/player/footsteps/flesh%i.wav", i + 1 ); -    cgs.media.footsteps[ FOOTSTEP_FLESH ][ i ] = trap_S_RegisterSound( name, qfalse ); - -    Com_sprintf( name, sizeof( name ), "sound/player/footsteps/mech%i.wav", i + 1 ); -    cgs.media.footsteps[ FOOTSTEP_MECH ][ i ] = trap_S_RegisterSound( name, qfalse ); - -    Com_sprintf( name, sizeof( name ), "sound/player/footsteps/energy%i.wav", i + 1 ); -    cgs.media.footsteps[ FOOTSTEP_ENERGY ][ i ] = trap_S_RegisterSound( name, qfalse ); - -    Com_sprintf( name, sizeof( name ), "sound/player/footsteps/splash%i.wav", i + 1 ); -    cgs.media.footsteps[ FOOTSTEP_SPLASH ][ i ] = trap_S_RegisterSound( name, qfalse ); - -    Com_sprintf( name, sizeof( name ), "sound/player/footsteps/clank%i.wav", i + 1 ); -    cgs.media.footsteps[ FOOTSTEP_METAL ][ i ] = trap_S_RegisterSound( name, qfalse ); -  } - -  for( i = 1 ; i < MAX_SOUNDS ; i++ ) -  { -    soundName = CG_ConfigString( CS_SOUNDS + i ); - -    if( !soundName[ 0 ] ) -      break; - -    if( soundName[ 0 ] == '*' ) -      continue; // custom sound - -    cgs.gameSounds[ i ] = trap_S_RegisterSound( soundName, qfalse ); -  } - -  cgs.media.jetpackDescendSound     = trap_S_RegisterSound( "sound/upgrades/jetpack/low.wav", qfalse ); -  cgs.media.jetpackIdleSound        = trap_S_RegisterSound( "sound/upgrades/jetpack/idle.wav", qfalse ); -  cgs.media.jetpackAscendSound      = trap_S_RegisterSound( "sound/upgrades/jetpack/hi.wav", qfalse ); - -  cgs.media.medkitUseSound          = trap_S_RegisterSound( "sound/upgrades/medkit/medkit.wav", qfalse ); - -  cgs.media.alienEvolveSound        = trap_S_RegisterSound( "sound/player/alienevolve.wav", qfalse ); - -  cgs.media.alienBuildableExplosion = trap_S_RegisterSound( "sound/buildables/alien/explosion.wav", qfalse ); -  cgs.media.alienBuildableDamage    = trap_S_RegisterSound( "sound/buildables/alien/damage.wav", qfalse ); -  cgs.media.alienBuildablePrebuild  = trap_S_RegisterSound( "sound/buildables/alien/prebuild.wav", qfalse ); - -  cgs.media.humanBuildableExplosion = trap_S_RegisterSound( "sound/buildables/human/explosion.wav", qfalse ); -  cgs.media.humanBuildablePrebuild  = trap_S_RegisterSound( "sound/buildables/human/prebuild.wav", qfalse ); - -  for( i = 0; i < 4; i++ ) -    cgs.media.humanBuildableDamage[ i ] = trap_S_RegisterSound( -        va( "sound/buildables/human/damage%d.wav", i ), qfalse ); - -  cgs.media.hgrenb1aSound           = trap_S_RegisterSound( "sound/weapons/grenade/hgrenb1a.wav", qfalse ); //FIXME -  cgs.media.hgrenb2aSound           = trap_S_RegisterSound( "sound/weapons/grenade/hgrenb2a.wav", qfalse ); //FIXME - -  cgs.media.repeaterUseSound        = trap_S_RegisterSound( "sound/buildables/repeater/use.wav", qfalse ); - -  cgs.media.buildableRepairSound    = trap_S_RegisterSound( "sound/buildables/human/repair.wav", qfalse ); -  cgs.media.buildableRepairedSound  = trap_S_RegisterSound( "sound/buildables/human/repaired.wav", qfalse ); - -  cgs.media.lCannonWarningSound     = trap_S_RegisterSound( "models/weapons/lcannon/warning.wav", qfalse ); -} - - -//=================================================================================== - - -/* -================= -CG_RegisterGraphics - -This function may execute for a couple of minutes with a slow disk. -================= -*/ -static void CG_RegisterGraphics( void ) -{ -  int         i; -  static char *sb_nums[ 11 ] = -  { -    "gfx/2d/numbers/zero_32b", -    "gfx/2d/numbers/one_32b", -    "gfx/2d/numbers/two_32b", -    "gfx/2d/numbers/three_32b", -    "gfx/2d/numbers/four_32b", -    "gfx/2d/numbers/five_32b", -    "gfx/2d/numbers/six_32b", -    "gfx/2d/numbers/seven_32b", -    "gfx/2d/numbers/eight_32b", -    "gfx/2d/numbers/nine_32b", -    "gfx/2d/numbers/minus_32b", -  }; -  static char *buildWeaponTimerPieShaders[ 8 ] = -  { -    "ui/assets/neutral/1_5pie", -    "ui/assets/neutral/3_0pie", -    "ui/assets/neutral/4_5pie", -    "ui/assets/neutral/6_0pie", -    "ui/assets/neutral/7_5pie", -    "ui/assets/neutral/9_0pie", -    "ui/assets/neutral/10_5pie", -    "ui/assets/neutral/12_0pie", -  }; - -  // clear any references to old media -  memset( &cg.refdef, 0, sizeof( cg.refdef ) ); -  trap_R_ClearScene( ); - -  trap_R_LoadWorldMap( cgs.mapname ); -  CG_UpdateMediaFraction( 0.66f ); - -  for( i = 0; i < 11; i++ ) -    cgs.media.numberShaders[ i ] = trap_R_RegisterShader( sb_nums[ i ] ); - -  cgs.media.viewBloodShader           = trap_R_RegisterShader( "gfx/damage/fullscreen_painblend" ); //FIXME - -  cgs.media.connectionShader          = trap_R_RegisterShader( "disconnected" ); //FIXME? - -  cgs.media.creepShader               = trap_R_RegisterShader( "creep" ); - -  cgs.media.scannerBlipShader         = trap_R_RegisterShader( "gfx/2d/blip" ); -  cgs.media.scannerLineShader         = trap_R_RegisterShader( "gfx/2d/stalk" ); - -  cgs.media.tracerShader              = trap_R_RegisterShader( "gfx/misc/tracer" ); //FIXME -  cgs.media.selectShader              = trap_R_RegisterShader( "gfx/2d/select" ); - -  cgs.media.backTileShader            = trap_R_RegisterShader( "gfx/2d/backtile" ); //FIXME - - -  //TA: building shaders -  cgs.media.greenBuildShader          = trap_R_RegisterShader("gfx/2d/greenbuild" ); -  cgs.media.redBuildShader            = trap_R_RegisterShader("gfx/2d/redbuild" ); -  cgs.media.noPowerShader             = trap_R_RegisterShader("gfx/2d/nopower" ); -  cgs.media.humanSpawningShader       = trap_R_RegisterShader("models/buildables/telenode/rep_cyl" ); - -  for( i = 0; i < 8; i++ ) -    cgs.media.buildWeaponTimerPie[ i ] = trap_R_RegisterShader( buildWeaponTimerPieShaders[ i ] ); - -  cgs.media.upgradeClassIconShader    = trap_R_RegisterShader( "icons/icona_upgrade.tga" ); - -  cgs.media.balloonShader             = trap_R_RegisterShader( "sprites/balloon3" ); //FIXME? - -  cgs.media.disconnectPS              = CG_RegisterParticleSystem( "disconnectPS" ); - -  CG_UpdateMediaFraction( 0.7f ); - -  memset( cg_weapons, 0, sizeof( cg_weapons ) ); -  memset( cg_upgrades, 0, sizeof( cg_upgrades ) ); - -  cgs.media.shadowMarkShader          = trap_R_RegisterShader( "markShadow" ); //FIXME -  cgs.media.wakeMarkShader            = trap_R_RegisterShader( "wake" ); //FIXME - -  cgs.media.poisonCloudPS             = CG_RegisterParticleSystem( "poisonCloudPS" ); -  cgs.media.alienEvolvePS             = CG_RegisterParticleSystem( "alienEvolvePS" ); -  cgs.media.alienAcidTubePS           = CG_RegisterParticleSystem( "alienAcidTubePS" ); - -  cgs.media.jetPackDescendPS          = CG_RegisterParticleSystem( "jetPackDescendPS" ); -  cgs.media.jetPackHoverPS            = CG_RegisterParticleSystem( "jetPackHoverPS" ); -  cgs.media.jetPackAscendPS           = CG_RegisterParticleSystem( "jetPackAscendPS" ); - -  cgs.media.humanBuildableDamagedPS   = CG_RegisterParticleSystem( "humanBuildableDamagedPS" ); -  cgs.media.alienBuildableDamagedPS   = CG_RegisterParticleSystem( "alienBuildableDamagedPS" ); -  cgs.media.humanBuildableDestroyedPS = CG_RegisterParticleSystem( "humanBuildableDestroyedPS" ); -  cgs.media.alienBuildableDestroyedPS = CG_RegisterParticleSystem( "alienBuildableDestroyedPS" ); - -  cgs.media.alienBleedPS              = CG_RegisterParticleSystem( "alienBleedPS" ); -  cgs.media.humanBleedPS              = CG_RegisterParticleSystem( "humanBleedPS" ); - -  // register the inline models -  cgs.numInlineModels = trap_CM_NumInlineModels( ); - -  for( i = 1; i < cgs.numInlineModels; i++ ) -  { -    char    name[ 10 ]; -    vec3_t  mins, maxs; -    int     j; - -    Com_sprintf( name, sizeof( name ), "*%i", i ); - -    cgs.inlineDrawModel[ i ] = trap_R_RegisterModel( name ); -    trap_R_ModelBounds( cgs.inlineDrawModel[ i ], mins, maxs ); - -    for( j = 0 ; j < 3 ; j++ ) -      cgs.inlineModelMidpoints[ i ][ j ] = mins[ j ] + 0.5 * ( maxs[ j ] - mins[ j ] ); -  } - -  // register all the server specified models -  for( i = 1; i < MAX_MODELS; i++ ) -  { -    const char *modelName; - -    modelName = CG_ConfigString( CS_MODELS + i ); - -    if( !modelName[ 0 ] ) -      break; - -    cgs.gameModels[ i ] = trap_R_RegisterModel( modelName ); -  } - -  CG_UpdateMediaFraction( 0.8f ); - -  // register all the server specified shaders -  for( i = 1; i < MAX_SHADERS; i++ ) -  { -    const char *shaderName; - -    shaderName = CG_ConfigString( CS_SHADERS + i ); - -    if( !shaderName[ 0 ] ) -      break; - -    cgs.gameShaders[ i ] = trap_R_RegisterShader( shaderName ); -  } - -  CG_UpdateMediaFraction( 0.9f ); - -  // register all the server specified particle systems -  for( i = 1; i < MAX_GAME_PARTICLE_SYSTEMS; i++ ) -  { -    const char *psName; - -    psName = CG_ConfigString( CS_PARTICLE_SYSTEMS + i ); - -    if( !psName[ 0 ] ) -      break; - -    cgs.gameParticleSystems[ i ] = CG_RegisterParticleSystem( (char *)psName ); -  } -} - - -/* -======================= -CG_BuildSpectatorString - -======================= -*/ -void CG_BuildSpectatorString( void ) -{ -  int i; - -  cg.spectatorList[ 0 ] = 0; - -  for( i = 0; i < MAX_CLIENTS; i++ ) -  { -    if( cgs.clientinfo[ i ].infoValid && cgs.clientinfo[ i ].team == PTE_NONE ) -      Q_strcat( cg.spectatorList, sizeof( cg.spectatorList ), va( "%s     " S_COLOR_WHITE, cgs.clientinfo[ i ].name ) ); -  } - -  i = strlen( cg.spectatorList ); - -  if( i != cg.spectatorLen ) -  { -    cg.spectatorLen = i; -    cg.spectatorWidth = -1; -  } -} - - - -/* -=================== -CG_RegisterClients - -=================== -*/ -static void CG_RegisterClients( void ) -{ -  int   i; - -  cg.charModelFraction = 0.0f; - -  //precache all the models/sounds/etc -  for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES;  i++ ) -  { -    CG_PrecacheClientInfo( i, BG_FindModelNameForClass( i ), -                              BG_FindSkinNameForClass( i ) ); - -    cg.charModelFraction = (float)i / (float)PCL_NUM_CLASSES; -    trap_UpdateScreen( ); -  } - -  cgs.media.larmourHeadSkin    = trap_R_RegisterSkin( "models/players/human_base/head_light.skin" ); -  cgs.media.larmourLegsSkin    = trap_R_RegisterSkin( "models/players/human_base/lower_light.skin" ); -  cgs.media.larmourTorsoSkin   = trap_R_RegisterSkin( "models/players/human_base/upper_light.skin" ); - -  cgs.media.jetpackModel       = trap_R_RegisterModel( "models/players/human_base/jetpack.md3" ); -  cgs.media.jetpackFlashModel  = trap_R_RegisterModel( "models/players/human_base/jetpack_flash.md3" ); -  cgs.media.battpackModel      = trap_R_RegisterModel( "models/players/human_base/battpack.md3" ); - -  cg.charModelFraction = 1.0f; -  trap_UpdateScreen( ); - -  //load all the clientinfos of clients already connected to the server -  for( i = 0; i < MAX_CLIENTS; i++ ) -  { -    const char  *clientInfo; - -    clientInfo = CG_ConfigString( CS_PLAYERS + i ); -    if( !clientInfo[ 0 ] ) -      continue; - -    CG_NewClientInfo( i ); -  } - -  CG_BuildSpectatorString( ); -} - -//=========================================================================== - -/* -================= -CG_ConfigString -================= -*/ -const char *CG_ConfigString( int index ) -{ -  if( index < 0 || index >= MAX_CONFIGSTRINGS ) -    CG_Error( "CG_ConfigString: bad index: %i", index ); - -  return cgs.gameState.stringData + cgs.gameState.stringOffsets[ index ]; -} - -//================================================================== - -/* -====================== -CG_StartMusic - -====================== -*/ -void CG_StartMusic( void ) -{ -  char  *s; -  char  parm1[ MAX_QPATH ], parm2[ MAX_QPATH ]; - -  // start the background music -  s = (char *)CG_ConfigString( CS_MUSIC ); -  Q_strncpyz( parm1, COM_Parse( &s ), sizeof( parm1 ) ); -  Q_strncpyz( parm2, COM_Parse( &s ), sizeof( parm2 ) ); - -  trap_S_StartBackgroundTrack( parm1, parm2 ); -} - -// -// ============================== -// new hud stuff ( mission pack ) -// ============================== -// -char *CG_GetMenuBuffer( const char *filename ) -{ -  int           len; -  fileHandle_t  f; -  static char   buf[ MAX_MENUFILE ]; - -  len = trap_FS_FOpenFile( filename, &f, FS_READ ); - -  if( !f ) -  { -    trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) ); -    return NULL; -  } - -  if( len >= MAX_MENUFILE ) -  { -    trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", -                    filename, len, MAX_MENUFILE ) ); -    trap_FS_FCloseFile( f ); -    return NULL; -  } - -  trap_FS_Read( buf, len, f ); -  buf[len] = 0; -  trap_FS_FCloseFile( f ); - -  return buf; -} - -qboolean CG_Asset_Parse( int handle ) -{ -  pc_token_t token; -  const char *tempStr; - -  if( !trap_PC_ReadToken( handle, &token ) ) -    return qfalse; - -  if( Q_stricmp( token.string, "{" ) != 0 ) -    return qfalse; - -  while( 1 ) -  { -    if( !trap_PC_ReadToken( handle, &token ) ) -      return qfalse; - -    if( Q_stricmp( token.string, "}" ) == 0 ) -      return qtrue; - -    // font -    if( Q_stricmp( token.string, "font" ) == 0 ) -    { -      int pointSize; - -      if( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) ) -        return qfalse; - -      cgDC.registerFont( tempStr, pointSize, &cgDC.Assets.textFont ); -      continue; -    } - -    // smallFont -    if( Q_stricmp( token.string, "smallFont" ) == 0 ) -    { -      int pointSize; - -      if( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) ) -        return qfalse; - -      cgDC.registerFont( tempStr, pointSize, &cgDC.Assets.smallFont ); -      continue; -    } - -    // font -    if( Q_stricmp( token.string, "bigfont" ) == 0 ) -    { -      int pointSize; - -      if( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) ) -        return qfalse; - -      cgDC.registerFont( tempStr, pointSize, &cgDC.Assets.bigFont ); -      continue; -    } - -    // gradientbar -    if( Q_stricmp( token.string, "gradientbar" ) == 0 ) -    { -      if( !PC_String_Parse( handle, &tempStr ) ) -        return qfalse; - -      cgDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( tempStr ); -      continue; -    } - -    // enterMenuSound -    if( Q_stricmp( token.string, "menuEnterSound" ) == 0 ) -    { -      if( !PC_String_Parse( handle, &tempStr ) ) -        return qfalse; - -      cgDC.Assets.menuEnterSound = trap_S_RegisterSound( tempStr, qfalse ); -      continue; -    } - -    // exitMenuSound -    if( Q_stricmp( token.string, "menuExitSound" ) == 0 ) -    { -      if( !PC_String_Parse( handle, &tempStr ) ) -        return qfalse; - -      cgDC.Assets.menuExitSound = trap_S_RegisterSound( tempStr, qfalse ); -      continue; -    } - -    // itemFocusSound -    if( Q_stricmp( token.string, "itemFocusSound" ) == 0 ) -    { -      if( !PC_String_Parse( handle, &tempStr ) ) -        return qfalse; - -      cgDC.Assets.itemFocusSound = trap_S_RegisterSound( tempStr, qfalse ); -      continue; -    } - -    // menuBuzzSound -    if( Q_stricmp( token.string, "menuBuzzSound" ) == 0 ) -    { -      if( !PC_String_Parse( handle, &tempStr ) ) -        return qfalse; - -      cgDC.Assets.menuBuzzSound = trap_S_RegisterSound( tempStr, qfalse ); -      continue; -    } - -    if( Q_stricmp( token.string, "cursor" ) == 0 ) -    { -      if( !PC_String_Parse( handle, &cgDC.Assets.cursorStr ) ) -        return qfalse; - -      cgDC.Assets.cursor = trap_R_RegisterShaderNoMip( cgDC.Assets.cursorStr ); -      continue; -    } - -    if( Q_stricmp( token.string, "fadeClamp" ) == 0 ) -    { -      if( !PC_Float_Parse( handle, &cgDC.Assets.fadeClamp ) ) -        return qfalse; - -      continue; -    } - -    if( Q_stricmp( token.string, "fadeCycle" ) == 0 ) -    { -      if( !PC_Int_Parse( handle, &cgDC.Assets.fadeCycle ) ) -        return qfalse; - -      continue; -    } - -    if( Q_stricmp( token.string, "fadeAmount" ) == 0 ) -    { -      if( !PC_Float_Parse( handle, &cgDC.Assets.fadeAmount ) ) -        return qfalse; - -      continue; -    } - -    if( Q_stricmp( token.string, "shadowX" ) == 0 ) -    { -      if( !PC_Float_Parse( handle, &cgDC.Assets.shadowX ) ) -        return qfalse; - -      continue; -    } - -    if( Q_stricmp( token.string, "shadowY" ) == 0 ) -    { -      if( !PC_Float_Parse( handle, &cgDC.Assets.shadowY ) ) -        return qfalse; - -      continue; -    } - -    if( Q_stricmp( token.string, "shadowColor" ) == 0 ) -    { -      if( !PC_Color_Parse( handle, &cgDC.Assets.shadowColor ) ) -        return qfalse; - -      cgDC.Assets.shadowFadeClamp = cgDC.Assets.shadowColor[ 3 ]; -      continue; -    } -  } - -  return qfalse; // bk001204 - why not? -} - -void CG_ParseMenu( const char *menuFile ) -{ -  pc_token_t  token; -  int         handle; - -  handle = trap_PC_LoadSource( menuFile ); - -  if( !handle ) -    handle = trap_PC_LoadSource( "ui/testhud.menu" ); - -  if( !handle ) -    return; - -  while( 1 ) -  { -    if( !trap_PC_ReadToken( handle, &token ) ) -      break; - -    //if ( Q_stricmp( token, "{" ) ) { -    //  Com_Printf( "Missing { in menu file\n" ); -    //  break; -    //} - -    //if ( menuCount == MAX_MENUS ) { -    //  Com_Printf( "Too many menus!\n" ); -    //  break; -    //} - -    if( token.string[ 0 ] == '}' ) -      break; - -    if( Q_stricmp( token.string, "assetGlobalDef" ) == 0 ) -    { -      if( CG_Asset_Parse( handle ) ) -        continue; -      else -        break; -    } - - -    if( Q_stricmp( token.string, "menudef" ) == 0 ) -    { -      // start a new menu -      Menu_New( handle ); -    } -  } - -  trap_PC_FreeSource( handle ); -} - -qboolean CG_Load_Menu( char **p ) -{ -  char *token; - -  token = COM_ParseExt( p, qtrue ); - -  if( token[ 0 ] != '{' ) -    return qfalse; - -  while( 1 ) -  { -    token = COM_ParseExt( p, qtrue ); - -    if( Q_stricmp( token, "}" ) == 0 ) -      return qtrue; - -    if( !token || token[ 0 ] == 0 ) -      return qfalse; - -    CG_ParseMenu( token ); -  } -  return qfalse; -} - - - -void CG_LoadMenus( const char *menuFile ) -{ -  char          *token; -  char          *p; -  int           len, start; -  fileHandle_t  f; -  static char   buf[ MAX_MENUDEFFILE ]; - -  start = trap_Milliseconds( ); - -  len = trap_FS_FOpenFile( menuFile, &f, FS_READ ); - -  if( !f ) -  { -    trap_Error( va( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile ) ); -    len = trap_FS_FOpenFile( "ui/hud.txt", &f, FS_READ ); - -    if( !f ) -      trap_Error( va( S_COLOR_RED "default menu file not found: ui/hud.txt, unable to continue!\n", menuFile ) ); -  } - -  if( len >= MAX_MENUDEFFILE ) -  { -    trap_Error( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", -                menuFile, len, MAX_MENUDEFFILE ) ); -    trap_FS_FCloseFile( f ); -    return; -  } - -  trap_FS_Read( buf, len, f ); -  buf[ len ] = 0; -  trap_FS_FCloseFile( f ); - -  COM_Compress( buf ); - -  Menu_Reset( ); - -  p = buf; - -  while( 1 ) -  { -    token = COM_ParseExt( &p, qtrue ); - -    if( !token || token[ 0 ] == 0 || token[ 0 ] == '}' ) -      break; - -    if( Q_stricmp( token, "}" ) == 0 ) -      break; - -    if( Q_stricmp( token, "loadmenu" ) == 0 ) -    { -      if( CG_Load_Menu( &p ) ) -        continue; -      else -        break; -    } -  } - -  Com_Printf( "UI menu load time = %d milli seconds\n", trap_Milliseconds( ) - start ); -} - - - -static qboolean CG_OwnerDrawHandleKey( int ownerDraw, int flags, float *special, int key ) -{ -  return qfalse; -} - - -static int CG_FeederCount( float feederID ) -{ -  int i, count = 0; - -  if( feederID == FEEDER_ALIENTEAM_LIST ) -  { -    for( i = 0; i < cg.numScores; i++ ) -    { -      if( cg.scores[ i ].team == PTE_ALIENS ) -        count++; -    } -  } -  else if( feederID == FEEDER_HUMANTEAM_LIST ) -  { -    for( i = 0; i < cg.numScores; i++ ) -    { -      if( cg.scores[ i ].team == PTE_HUMANS ) -        count++; -    } -  } - -  return count; -} - - -void CG_SetScoreSelection( void *p ) -{ -  menuDef_t     *menu = (menuDef_t*)p; -  playerState_t *ps = &cg.snap->ps; -  int           i, alien, human; -  int           feeder; - -  alien = human = 0; - -  for( i = 0; i < cg.numScores; i++ ) -  { -    if( cg.scores[ i ].team == PTE_ALIENS ) -      alien++; -    else if( cg.scores[ i ].team == PTE_HUMANS ) -      human++; - -    if( ps->clientNum == cg.scores[ i ].client ) -      cg.selectedScore = i; -  } - -  if( menu == NULL ) -    // just interested in setting the selected score -    return; - -  feeder = FEEDER_ALIENTEAM_LIST; -  i = alien; - -  if( cg.scores[ cg.selectedScore ].team == PTE_HUMANS ) -  { -    feeder = FEEDER_HUMANTEAM_LIST; -    i = human; -  } - -  Menu_SetFeederSelection(menu, feeder, i, NULL); -} - -// FIXME: might need to cache this info -static clientInfo_t * CG_InfoFromScoreIndex( int index, int team, int *scoreIndex ) -{ -  int i, count; -  count = 0; - -  for( i = 0; i < cg.numScores; i++ ) -  { -    if( cg.scores[ i ].team == team ) -    { -      if( count == index ) -      { -        *scoreIndex = i; -        return &cgs.clientinfo[ cg.scores[ i ].client ]; -      } -      count++; -    } -  } - -  *scoreIndex = index; -  return &cgs.clientinfo[ cg.scores[ index ].client ]; -} - -static const char *CG_FeederItemText( float feederID, int index, int column, qhandle_t *handle ) -{ -  int           scoreIndex = 0; -  clientInfo_t  *info = NULL; -  int           team = -1; -  score_t       *sp = NULL; -  qboolean      showIcons = qfalse; - -  *handle = -1; - -  if( feederID == FEEDER_ALIENTEAM_LIST ) -    team = PTE_ALIENS; -  else if( feederID == FEEDER_HUMANTEAM_LIST ) -    team = PTE_HUMANS; - -  info = CG_InfoFromScoreIndex( index, team, &scoreIndex ); -  sp = &cg.scores[ scoreIndex ]; - -  if( ( atoi( CG_ConfigString( CS_CLIENTS_READY ) ) & ( 1 << sp->client ) ) && -      cg.intermissionStarted ) -    showIcons = qfalse; -  else if( cg.snap->ps.pm_type == PM_SPECTATOR || cg.snap->ps.pm_flags & PMF_FOLLOW || -    team == cg.snap->ps.stats[ STAT_PTEAM ] || cg.intermissionStarted ) -    showIcons = qtrue; - -  if( info && info->infoValid ) -  { -    switch( column ) -    { -      case 0: -        if( showIcons ) -        { -          if( sp->weapon != WP_NONE ) -            *handle = cg_weapons[ sp->weapon ].weaponIcon; -        } -        break; - -      case 1: -        if( showIcons ) -        { -          if( sp->team == PTE_HUMANS && sp->upgrade != UP_NONE ) -            *handle = cg_upgrades[ sp->upgrade ].upgradeIcon; -          else if( sp->team == PTE_ALIENS ) -          { -            switch( sp->weapon ) -            { -              case WP_ABUILD2: -              case WP_ALEVEL1_UPG: -              case WP_ALEVEL2_UPG: -              case WP_ALEVEL3_UPG: -                *handle = cgs.media.upgradeClassIconShader; -                break; - -              default: -                break; -            } -          } -        } -        break; - -      case 2: -        if( ( atoi( CG_ConfigString( CS_CLIENTS_READY ) ) & ( 1 << sp->client ) ) && -            cg.intermissionStarted ) -          return "Ready"; -        break; - -      case 3: -        return info->name; -        break; - -      case 4: -        return va( "%d", info->score ); -        break; - -      case 5: -        return va( "%4d", sp->time ); -        break; - -      case 6: -        if( sp->ping == -1 ) -          return "connecting"; - -        return va( "%4d", sp->ping ); -        break; -    } -  } - -  return ""; -} - -static qhandle_t CG_FeederItemImage( float feederID, int index ) -{ -  return 0; -} - -static void CG_FeederSelection( float feederID, int index ) -{ -  int i, count; -  int team = ( feederID == FEEDER_ALIENTEAM_LIST ) ? PTE_ALIENS : PTE_HUMANS; -  count = 0; - -  for( i = 0; i < cg.numScores; i++ ) -  { -    if( cg.scores[ i ].team == team ) -    { -      if( index == count ) -        cg.selectedScore = i; - -      count++; -    } -  } -} - -static float CG_Cvar_Get( const char *cvar ) -{ -  char buff[ 128 ]; - -  memset( buff, 0, sizeof( buff ) ); -  trap_Cvar_VariableStringBuffer( cvar, buff, sizeof( buff ) ); -  return atof( buff ); -} - -void CG_Text_PaintWithCursor( float x, float y, float scale, vec4_t color, const char *text, -                              int cursorPos, char cursor, int limit, int style ) -{ -  CG_Text_Paint( x, y, scale, color, text, 0, limit, style ); -} - -static int CG_OwnerDrawWidth( int ownerDraw, float scale ) -{ -  switch( ownerDraw ) -  { -    case CG_KILLER: -      return CG_Text_Width( CG_GetKillerText( ), scale, 0 ); -      break; -  } - -  return 0; -} - -static int CG_PlayCinematic( const char *name, float x, float y, float w, float h ) -{ -  return trap_CIN_PlayCinematic( name, x, y, w, h, CIN_loop ); -} - -static void CG_StopCinematic( int handle ) -{ -  trap_CIN_StopCinematic( handle ); -} - -static void CG_DrawCinematic( int handle, float x, float y, float w, float h ) -{ -  trap_CIN_SetExtents( handle, x, y, w, h ); -  trap_CIN_DrawCinematic( handle ); -} - -static void CG_RunCinematicFrame( int handle ) -{ -  trap_CIN_RunCinematic( handle ); -} - -//TA: hack to prevent warning -static qboolean CG_OwnerDrawVisible( int parameter ) -{ -  return qfalse; -} - -/* -================= -CG_LoadHudMenu -================= -*/ -void CG_LoadHudMenu( void ) -{ -  char        buff[ 1024 ]; -  const char  *hudSet; - -  cgDC.registerShaderNoMip  = &trap_R_RegisterShaderNoMip; -  cgDC.setColor             = &trap_R_SetColor; -  cgDC.drawHandlePic        = &CG_DrawPic; -  cgDC.drawStretchPic       = &trap_R_DrawStretchPic; -  cgDC.drawText             = &CG_Text_Paint; -  cgDC.textWidth            = &CG_Text_Width; -  cgDC.textHeight           = &CG_Text_Height; -  cgDC.registerModel        = &trap_R_RegisterModel; -  cgDC.modelBounds          = &trap_R_ModelBounds; -  cgDC.fillRect             = &CG_FillRect; -  cgDC.drawRect             = &CG_DrawRect; -  cgDC.drawSides            = &CG_DrawSides; -  cgDC.drawTopBottom        = &CG_DrawTopBottom; -  cgDC.clearScene           = &trap_R_ClearScene; -  cgDC.addRefEntityToScene  = &trap_R_AddRefEntityToScene; -  cgDC.renderScene          = &trap_R_RenderScene; -  cgDC.registerFont         = &trap_R_RegisterFont; -  cgDC.ownerDrawItem        = &CG_OwnerDraw; -  cgDC.getValue             = &CG_GetValue; -  cgDC.ownerDrawVisible     = &CG_OwnerDrawVisible; -  cgDC.runScript            = &CG_RunMenuScript; -  cgDC.getTeamColor         = &CG_GetTeamColor; -  cgDC.setCVar              = trap_Cvar_Set; -  cgDC.getCVarString        = trap_Cvar_VariableStringBuffer; -  cgDC.getCVarValue         = CG_Cvar_Get; -  cgDC.drawTextWithCursor   = &CG_Text_PaintWithCursor; -  //cgDC.setOverstrikeMode    = &trap_Key_SetOverstrikeMode; -  //cgDC.getOverstrikeMode    = &trap_Key_GetOverstrikeMode; -  cgDC.startLocalSound      = &trap_S_StartLocalSound; -  cgDC.ownerDrawHandleKey   = &CG_OwnerDrawHandleKey; -  cgDC.feederCount          = &CG_FeederCount; -  cgDC.feederItemImage      = &CG_FeederItemImage; -  cgDC.feederItemText       = &CG_FeederItemText; -  cgDC.feederSelection      = &CG_FeederSelection; -  //cgDC.setBinding           = &trap_Key_SetBinding; -  //cgDC.getBindingBuf        = &trap_Key_GetBindingBuf; -  //cgDC.keynumToStringBuf    = &trap_Key_KeynumToStringBuf; -  //cgDC.executeText          = &trap_Cmd_ExecuteText; -  cgDC.Error                = &Com_Error; -  cgDC.Print                = &Com_Printf; -  cgDC.ownerDrawWidth       = &CG_OwnerDrawWidth; -  //cgDC.Pause                = &CG_Pause; -  cgDC.registerSound        = &trap_S_RegisterSound; -  cgDC.startBackgroundTrack = &trap_S_StartBackgroundTrack; -  cgDC.stopBackgroundTrack  = &trap_S_StopBackgroundTrack; -  cgDC.playCinematic        = &CG_PlayCinematic; -  cgDC.stopCinematic        = &CG_StopCinematic; -  cgDC.drawCinematic        = &CG_DrawCinematic; -  cgDC.runCinematicFrame    = &CG_RunCinematicFrame; - -  Init_Display( &cgDC ); - -  Menu_Reset( ); - -  trap_Cvar_VariableStringBuffer( "cg_hudFiles", buff, sizeof( buff ) ); -  hudSet = buff; - -  if( hudSet[ 0 ] == '\0' ) -    hudSet = "ui/hud.txt"; - -  CG_LoadMenus( hudSet ); -} - -void CG_AssetCache( void ) -{ -  cgDC.Assets.gradientBar         = trap_R_RegisterShaderNoMip( ASSET_GRADIENTBAR ); -  cgDC.Assets.scrollBar           = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR ); -  cgDC.Assets.scrollBarArrowDown  = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWDOWN ); -  cgDC.Assets.scrollBarArrowUp    = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWUP ); -  cgDC.Assets.scrollBarArrowLeft  = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWLEFT ); -  cgDC.Assets.scrollBarArrowRight = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWRIGHT ); -  cgDC.Assets.scrollBarThumb      = trap_R_RegisterShaderNoMip( ASSET_SCROLL_THUMB ); -  cgDC.Assets.sliderBar           = trap_R_RegisterShaderNoMip( ASSET_SLIDER_BAR ); -  cgDC.Assets.sliderThumb         = trap_R_RegisterShaderNoMip( ASSET_SLIDER_THUMB ); -} - -/* -================= -CG_Init - -Called after every level change or subsystem restart -Will perform callbacks to make the loading info screen update. -================= -*/ -void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum ) -{ -  const char  *s; - -  // clear everything -  memset( &cgs, 0, sizeof( cgs ) ); -  memset( &cg, 0, sizeof( cg ) ); -  memset( cg_entities, 0, sizeof( cg_entities ) ); - -  cg.clientNum = clientNum; - -  cgs.processedSnapshotNum = serverMessageNum; -  cgs.serverCommandSequence = serverCommandSequence; - -  // load a few needed things before we do any screen updates -  cgs.media.whiteShader     = trap_R_RegisterShader( "white" ); -  cgs.media.charsetShader   = trap_R_RegisterShader( "gfx/2d/bigchars" ); -  cgs.media.outlineShader   = trap_R_RegisterShader( "outline" ); - -  //inform UI to repress cursor whilst loading -  trap_Cvar_Set( "ui_loading", "1" ); - -  //TA: load overrides -  BG_InitClassOverrides( ); -  BG_InitBuildableOverrides( ); - -  //TA: dyn memory -  CG_InitMemory( ); - -  CG_RegisterCvars( ); - -  CG_InitConsoleCommands( ); - -  //TA: moved up for LoadHudMenu -  String_Init( ); - -  //TA: TA UI -  CG_AssetCache( ); -  CG_LoadHudMenu( );      // load new hud stuff - -  cg.weaponSelect = WP_NONE; - -  // old servers - -  // get the rendering configuration from the client system -  trap_GetGlconfig( &cgs.glconfig ); -  cgs.screenXScale = cgs.glconfig.vidWidth / 640.0; -  cgs.screenYScale = cgs.glconfig.vidHeight / 480.0; - -  // get the gamestate from the client system -  trap_GetGameState( &cgs.gameState ); - -  // check version -  s = CG_ConfigString( CS_GAME_VERSION ); - -  if( strcmp( s, GAME_VERSION ) ) -    CG_Error( "Client/Server game mismatch: %s/%s", GAME_VERSION, s ); - -  s = CG_ConfigString( CS_LEVEL_START_TIME ); -  cgs.levelStartTime = atoi( s ); - -  CG_ParseServerinfo( ); - -  // load the new map -  trap_CM_LoadMap( cgs.mapname ); - -  cg.loading = qtrue;   // force players to load instead of defer - -  CG_LoadTrailSystems( ); -  CG_UpdateMediaFraction( 0.05f ); - -  CG_LoadParticleSystems( ); -  CG_UpdateMediaFraction( 0.05f ); - -  CG_RegisterSounds( ); -  CG_UpdateMediaFraction( 0.60f ); - -  CG_RegisterGraphics( ); -  CG_UpdateMediaFraction( 0.90f ); - -  CG_InitWeapons( ); -  CG_UpdateMediaFraction( 0.95f ); - -  CG_InitUpgrades( ); -  CG_UpdateMediaFraction( 1.0f ); - -  //TA: -  CG_InitBuildables( ); - -  CG_RegisterClients( );   // if low on memory, some clients will be deferred - -  cg.loading = qfalse;  // future players will be deferred - -  CG_InitMarkPolys( ); - -  // remove the last loading update -  cg.infoScreenText[ 0 ] = 0; - -  // Make sure we have update values (scores) -  CG_SetConfigValues( ); - -  CG_StartMusic( ); - -  CG_ShaderStateChanged( ); - -  trap_S_ClearLoopingSounds( qtrue ); - -  cg.consoleValid = qtrue; - -  trap_Cvar_Set( "ui_loading", "0" ); -} - -/* -================= -CG_Shutdown - -Called before every level change or subsystem restart -================= -*/ -void CG_Shutdown( void ) -{ -  // some mods may need to do cleanup work here, -  // like closing files or archiving session data -} diff --git a/mod/src/cgame/cg_marks.c b/mod/src/cgame/cg_marks.c deleted file mode 100644 index cc8979de..00000000 --- a/mod/src/cgame/cg_marks.c +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_marks.c -- wall marks - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -/* -=================================================================== - -MARK POLYS - -=================================================================== -*/ - - -markPoly_t  cg_activeMarkPolys;     // double linked list -markPoly_t  *cg_freeMarkPolys;      // single linked list -markPoly_t  cg_markPolys[ MAX_MARK_POLYS ]; -static int  markTotal; - -/* -=================== -CG_InitMarkPolys - -This is called at startup and for tournement restarts -=================== -*/ -void CG_InitMarkPolys( void ) -{ -  int   i; - -  memset( cg_markPolys, 0, sizeof( cg_markPolys ) ); - -  cg_activeMarkPolys.nextMark = &cg_activeMarkPolys; -  cg_activeMarkPolys.prevMark = &cg_activeMarkPolys; -  cg_freeMarkPolys = cg_markPolys; - -  for( i = 0; i < MAX_MARK_POLYS - 1; i++ ) -    cg_markPolys[ i ].nextMark = &cg_markPolys[ i + 1 ]; -} - - -/* -================== -CG_FreeMarkPoly -================== -*/ -void CG_FreeMarkPoly( markPoly_t *le ) -{ -  if( !le->prevMark ) -    CG_Error( "CG_FreeLocalEntity: not active" ); - -  // remove from the doubly linked active list -  le->prevMark->nextMark = le->nextMark; -  le->nextMark->prevMark = le->prevMark; - -  // the free list is only singly linked -  le->nextMark = cg_freeMarkPolys; -  cg_freeMarkPolys = le; -} - -/* -=================== -CG_AllocMark - -Will allways succeed, even if it requires freeing an old active mark -=================== -*/ -markPoly_t *CG_AllocMark( void ) -{ -  markPoly_t  *le; -  int         time; - -  if( !cg_freeMarkPolys ) -  { -    // no free entities, so free the one at the end of the chain -    // remove the oldest active entity -    time = cg_activeMarkPolys.prevMark->time; - -    while( cg_activeMarkPolys.prevMark && time == cg_activeMarkPolys.prevMark->time ) -      CG_FreeMarkPoly( cg_activeMarkPolys.prevMark ); -  } - -  le = cg_freeMarkPolys; -  cg_freeMarkPolys = cg_freeMarkPolys->nextMark; - -  memset( le, 0, sizeof( *le ) ); - -  // link into the active list -  le->nextMark = cg_activeMarkPolys.nextMark; -  le->prevMark = &cg_activeMarkPolys; -  cg_activeMarkPolys.nextMark->prevMark = le; -  cg_activeMarkPolys.nextMark = le; -  return le; -} - - - -/* -================= -CG_ImpactMark - -origin should be a point within a unit of the plane -dir should be the plane normal - -temporary marks will not be stored or randomly oriented, but immediately -passed to the renderer. -================= -*/ -#define MAX_MARK_FRAGMENTS  128 -#define MAX_MARK_POINTS   384 - -void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir, -                    float orientation, float red, float green, float blue, float alpha, -                    qboolean alphaFade, float radius, qboolean temporary ) -{ -  vec3_t          axis[ 3 ]; -  float           texCoordScale; -  vec3_t          originalPoints[ 4 ]; -  byte            colors[ 4 ]; -  int             i, j; -  int             numFragments; -  markFragment_t  markFragments[ MAX_MARK_FRAGMENTS ], *mf; -  vec3_t          markPoints[ MAX_MARK_POINTS ]; -  vec3_t          projection; - -  if( !cg_addMarks.integer ) -    return; - -  if( radius <= 0 ) -    CG_Error( "CG_ImpactMark called with <= 0 radius" ); - -  //if ( markTotal >= MAX_MARK_POLYS ) { -  //  return; -  //} - -  // create the texture axis -  VectorNormalize2( dir, axis[ 0 ] ); -  PerpendicularVector( axis[ 1 ], axis[ 0 ] ); -  RotatePointAroundVector( axis[ 2 ], axis[ 0 ], axis[ 1 ], orientation ); -  CrossProduct( axis[ 0 ], axis[ 2 ], axis[ 1 ] ); - -  texCoordScale = 0.5 * 1.0 / radius; - -  // create the full polygon -  for( i = 0; i < 3; i++ ) -  { -    originalPoints[ 0 ][ i ] = origin[ i ] - radius * axis[ 1 ][ i ] - radius * axis[ 2 ][ i ]; -    originalPoints[ 1 ][ i ] = origin[ i ] + radius * axis[ 1 ][ i ] - radius * axis[ 2 ][ i ]; -    originalPoints[ 2 ][ i ] = origin[ i ] + radius * axis[ 1 ][ i ] + radius * axis[ 2 ][ i ]; -    originalPoints[ 3 ][ i ] = origin[ i ] - radius * axis[ 1 ][ i ] + radius * axis[ 2 ][ i ]; -  } - -  // get the fragments -  VectorScale( dir, -20, projection ); -  numFragments = trap_CM_MarkFragments( 4, (void *)originalPoints, -          projection, MAX_MARK_POINTS, markPoints[ 0 ], -          MAX_MARK_FRAGMENTS, markFragments ); - -  colors[ 0 ] = red * 255; -  colors[ 1 ] = green * 255; -  colors[ 2 ] = blue * 255; -  colors[ 3 ] = alpha * 255; - -  for( i = 0, mf = markFragments; i < numFragments; i++, mf++ ) -  { -    polyVert_t  *v; -    polyVert_t  verts[ MAX_VERTS_ON_POLY ]; -    markPoly_t  *mark; - -    // we have an upper limit on the complexity of polygons -    // that we store persistantly -    if( mf->numPoints > MAX_VERTS_ON_POLY ) -      mf->numPoints = MAX_VERTS_ON_POLY; - -    for( j = 0, v = verts; j < mf->numPoints; j++, v++ ) -    { -      vec3_t    delta; - -      VectorCopy( markPoints[ mf->firstPoint + j ], v->xyz ); - -      VectorSubtract( v->xyz, origin, delta ); -      v->st[ 0 ] = 0.5 + DotProduct( delta, axis[ 1 ] ) * texCoordScale; -      v->st[ 1 ] = 0.5 + DotProduct( delta, axis[ 2 ] ) * texCoordScale; -      *(int *)v->modulate = *(int *)colors; -    } - -    // if it is a temporary (shadow) mark, add it immediately and forget about it -    if( temporary ) -    { -      trap_R_AddPolyToScene( markShader, mf->numPoints, verts ); -      continue; -    } - -    // otherwise save it persistantly -    mark = CG_AllocMark( ); -    mark->time = cg.time; -    mark->alphaFade = alphaFade; -    mark->markShader = markShader; -    mark->poly.numVerts = mf->numPoints; -    mark->color[ 0 ] = red; -    mark->color[ 1 ] = green; -    mark->color[ 2 ] = blue; -    mark->color[ 3 ] = alpha; -    memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[ 0 ] ) ); -    markTotal++; -  } -} - - -/* -=============== -CG_AddMarks -=============== -*/ -#define MARK_TOTAL_TIME   10000 -#define MARK_FADE_TIME    1000 - -void CG_AddMarks( void ) -{ -  int         j; -  markPoly_t  *mp, *next; -  int         t; -  int         fade; - -  if( !cg_addMarks.integer ) -    return; - -  mp = cg_activeMarkPolys.nextMark; -  for ( ; mp != &cg_activeMarkPolys; mp = next ) -  { -    // grab next now, so if the local entity is freed we -    // still have it -    next = mp->nextMark; - -    // see if it is time to completely remove it -    if( cg.time > mp->time + MARK_TOTAL_TIME ) -    { -      CG_FreeMarkPoly( mp ); -      continue; -    } - -    // fade all marks out with time -    t = mp->time + MARK_TOTAL_TIME - cg.time; -    if( t < MARK_FADE_TIME ) -    { -      fade = 255 * t / MARK_FADE_TIME; -      if( mp->alphaFade ) -      { -        for( j = 0; j < mp->poly.numVerts; j++ ) -          mp->verts[ j ].modulate[ 3 ] = fade; -      } -      else -      { -        for( j = 0; j < mp->poly.numVerts; j++ ) -        { -          mp->verts[ j ].modulate[ 0 ] = mp->color[ 0 ] * fade; -          mp->verts[ j ].modulate[ 1 ] = mp->color[ 1 ] * fade; -          mp->verts[ j ].modulate[ 2 ] = mp->color[ 2 ] * fade; -        } -      } -    } - -    trap_R_AddPolyToScene( mp->markShader, mp->poly.numVerts, mp->verts ); -  } -} - diff --git a/mod/src/cgame/cg_mem.c b/mod/src/cgame/cg_mem.c deleted file mode 100644 index 959bd4b0..00000000 --- a/mod/src/cgame/cg_mem.c +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// -// cg_mem.c -// -// Golliwog: All rewritten to allow deallocation -// -// TA: (very) minor changes for client side operation -// thanks to Golliwog of Quake 3 Fortress ( http://www.q3f.com ) -// for this. - - -#include "cg_local.h" - -#define POOLSIZE      (256 * 1024) -#define FREEMEMCOOKIE ((int)0xDEADBE3F) // Any unlikely to be used value -#define ROUNDBITS     31          // Round to 32 bytes - -struct freememnode -{ -  // Size of ROUNDBITS -  int cookie, size;       // Size includes node (obviously) -  struct freememnode *prev, *next; -}; - -static char   memoryPool[ POOLSIZE ]; -static struct freememnode *freehead; -static int    freemem; - -void *CG_Alloc( int size ) -{ -  // Find a free block and allocate. -  // Does two passes, attempts to fill same-sized free slot first. - -  struct freememnode *fmn, *prev, *next, *smallest; -  int allocsize, smallestsize; -  char *endptr; -  int *ptr; - -  allocsize = ( size + sizeof(int) + ROUNDBITS ) & ~ROUNDBITS;    // Round to 32-byte boundary -  ptr = NULL; - -  smallest = NULL; -  smallestsize = POOLSIZE + 1;    // Guaranteed not to miss any slots :) -  for( fmn = freehead; fmn; fmn = fmn->next ) -  { -    if( fmn->cookie != FREEMEMCOOKIE ) -      CG_Error( "CG_Alloc: Memory corruption detected!\n" ); - -    if( fmn->size >= allocsize ) -    { -      // We've got a block -      if( fmn->size == allocsize ) -      { -        // Same size, just remove - -        prev = fmn->prev; -        next = fmn->next; -        if( prev ) -          prev->next = next;      // Point previous node to next -        if( next ) -          next->prev = prev;      // Point next node to previous -        if( fmn == freehead ) -          freehead = next;      // Set head pointer to next -        ptr = (int *) fmn; -        break;              // Stop the loop, this is fine -      } -      else -      { -        // Keep track of the smallest free slot -        if( fmn->size < smallestsize ) -        { -          smallest = fmn; -          smallestsize = fmn->size; -        } -      } -    } -  } - -  if( !ptr && smallest ) -  { -    // We found a slot big enough -    smallest->size -= allocsize; -    endptr = (char *) smallest + smallest->size; -    ptr = (int *) endptr; -  } - -  if( ptr ) -  { -    freemem -= allocsize; -    if( cg_debugAlloc.integer ) -      CG_Printf( "CG_Alloc of %i bytes (%i left)\n", allocsize, freemem ); -    memset( ptr, 0, allocsize ); -    *ptr++ = allocsize;       // Store a copy of size for deallocation -    return( (void *) ptr ); -  } - -  CG_Error( "CG_Alloc: failed on allocation of %i bytes\n", size ); -  return( NULL ); -} - -void CG_Free( void *ptr ) -{ -  // Release allocated memory, add it to the free list. - -  struct freememnode *fmn; -  char *freeend; -  int *freeptr; - -  freeptr = ptr; -  freeptr--; - -  freemem += *freeptr; -  if( cg_debugAlloc.integer ) -    CG_Printf( "CG_Free of %i bytes (%i left)\n", *freeptr, freemem ); - -  for( fmn = freehead; fmn; fmn = fmn->next ) -  { -    freeend = ((char *) fmn) + fmn->size; -    if( freeend == (char *) freeptr ) -    { -      // Released block can be merged to an existing node - -      fmn->size += *freeptr;    // Add size of node. -      return; -    } -  } -  // No merging, add to head of list - -  fmn = (struct freememnode *) freeptr; -  fmn->size = *freeptr;       // Set this first to avoid corrupting *freeptr -  fmn->cookie = FREEMEMCOOKIE; -  fmn->prev = NULL; -  fmn->next = freehead; -  freehead->prev = fmn; -  freehead = fmn; -} - -void CG_InitMemory( void ) -{ -  // Set up the initial node - -  freehead = (struct freememnode *) memoryPool; -  freehead->cookie = FREEMEMCOOKIE; -  freehead->size = POOLSIZE; -  freehead->next = NULL; -  freehead->prev = NULL; -  freemem = sizeof(memoryPool); -} - -void CG_DefragmentMemory( void ) -{ -  // If there's a frenzy of deallocation and we want to -  // allocate something big, this is useful. Otherwise... -  // not much use. - -  struct freememnode *startfmn, *endfmn, *fmn; - -  for( startfmn = freehead; startfmn; ) -  { -    endfmn = (struct freememnode *)(((char *) startfmn) + startfmn->size); -    for( fmn = freehead; fmn; ) -    { -      if( fmn->cookie != FREEMEMCOOKIE ) -        CG_Error( "CG_DefragmentMemory: Memory corruption detected!\n" ); - -      if( fmn == endfmn ) -      { -        // We can add fmn onto startfmn. - -        if( fmn->prev ) -          fmn->prev->next = fmn->next; -        if( fmn->next ) -        { -          if( !(fmn->next->prev = fmn->prev) ) -            freehead = fmn->next; // We're removing the head node -        } -        startfmn->size += fmn->size; -        memset( fmn, 0, sizeof(struct freememnode) ); // A redundant call, really. - -        startfmn = freehead; -        endfmn = fmn = NULL;        // Break out of current loop -      } -      else -        fmn = fmn->next; -    } - -    if( endfmn ) -      startfmn = startfmn->next;    // endfmn acts as a 'restart' flag here -  } -} diff --git a/mod/src/cgame/cg_particles.c b/mod/src/cgame/cg_particles.c deleted file mode 100644 index 64587360..00000000 --- a/mod/src/cgame/cg_particles.c +++ /dev/null @@ -1,2551 +0,0 @@ -// cg_particles.c -- the particle system - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -static baseParticleSystem_t   baseParticleSystems[ MAX_BASEPARTICLE_SYSTEMS ]; -static baseParticleEjector_t  baseParticleEjectors[ MAX_BASEPARTICLE_EJECTORS ]; -static baseParticle_t         baseParticles[ MAX_BASEPARTICLES ]; -static int                    numBaseParticleSystems = 0; -static int                    numBaseParticleEjectors = 0; -static int                    numBaseParticles = 0; - -static particleSystem_t     particleSystems[ MAX_PARTICLE_SYSTEMS ]; -static particleEjector_t    particleEjectors[ MAX_PARTICLE_EJECTORS ]; -static particle_t           particles[ MAX_PARTICLES ]; -static particle_t           *sortedParticles[ MAX_PARTICLES ]; -static particle_t           *radixBuffer[ MAX_PARTICLES ]; - -/* -=============== -CG_LerpValues - -Lerp between two values -=============== -*/ -static float CG_LerpValues( float a, float b, float f ) -{ -  if( b == PARTICLES_SAME_AS_INITIAL ) -    return a; -  else -    return ( (a) + (f) * ( (b) - (a) ) ); -} - -/* -=============== -CG_RandomiseValue - -Randomise some value by some variance -=============== -*/ -static float CG_RandomiseValue( float value, float variance ) -{ -  if( value != 0.0f ) -    return value * ( 1.0f + ( random( ) * variance ) ); -  else -    return random( ) * variance; -} - -/* -=============== -CG_SpreadVector - -Randomly spread a vector by some amount -=============== -*/ -static void CG_SpreadVector( vec3_t v, float spread ) -{ -  vec3_t  p, r1, r2; -  float   randomSpread = crandom( ) * spread; -  float   randomRotation = random( ) * 360.0f; - -  PerpendicularVector( p, v ); - -  RotatePointAroundVector( r1, p, v, randomSpread ); -  RotatePointAroundVector( r2, v, r1, randomRotation ); - -  VectorCopy( r2, v ); -} - -/* -=============== -CG_DestroyParticle - -Destroy an individual particle -=============== -*/ -static void CG_DestroyParticle( particle_t *p, vec3_t impactNormal ) -{ -  //this particle has an onDeath particle system attached -  if( p->class->onDeathSystemName[ 0 ] != '\0' ) -  { -    particleSystem_t  *ps; - -    ps = CG_SpawnNewParticleSystem( p->class->onDeathSystemHandle ); - -    if( CG_IsParticleSystemValid( &ps ) ) -    { -      if( impactNormal ) -        CG_SetParticleSystemNormal( ps, impactNormal ); - -      CG_SetAttachmentPoint( &ps->attachment, p->origin ); -      CG_AttachToPoint( &ps->attachment ); -    } -  } - -  p->valid = qfalse; - -  //this gives other systems a couple of -  //frames to realise the particle is gone -  p->frameWhenInvalidated = cg.clientFrame; -} - -/* -=============== -CG_SpawnNewParticle - -Introduce a new particle into the world -=============== -*/ -static particle_t *CG_SpawnNewParticle( baseParticle_t *bp, particleEjector_t *parent ) -{ -  int                     i, j; -  particle_t              *p = NULL; -  particleEjector_t       *pe = parent; -  particleSystem_t        *ps = parent->parent; -  vec3_t                  attachmentPoint, attachmentVelocity; -  vec3_t                  transform[ 3 ]; - -  for( i = 0; i < MAX_PARTICLES; i++ ) -  { -    p = &particles[ i ]; - -    //FIXME: the + 1 may be unnecessary -    if( !p->valid && cg.clientFrame > p->frameWhenInvalidated + 1 ) -    { -      memset( p, 0, sizeof( particle_t ) ); - -      //found a free slot -      p->class = bp; -      p->parent = pe; - -      p->birthTime = cg.time; -      p->lifeTime = (int)CG_RandomiseValue( (float)bp->lifeTime, bp->lifeTimeRandFrac ); - -      p->radius.delay = (int)CG_RandomiseValue( (float)bp->radius.delay, bp->radius.delayRandFrac ); -      p->radius.initial = CG_RandomiseValue( bp->radius.initial, bp->radius.initialRandFrac ); -      p->radius.final = CG_RandomiseValue( bp->radius.final, bp->radius.finalRandFrac ); - -      p->alpha.delay = (int)CG_RandomiseValue( (float)bp->alpha.delay, bp->alpha.delayRandFrac ); -      p->alpha.initial = CG_RandomiseValue( bp->alpha.initial, bp->alpha.initialRandFrac ); -      p->alpha.final = CG_RandomiseValue( bp->alpha.final, bp->alpha.finalRandFrac ); - -      p->rotation.delay = (int)CG_RandomiseValue( (float)bp->rotation.delay, bp->rotation.delayRandFrac ); -      p->rotation.initial = CG_RandomiseValue( bp->rotation.initial, bp->rotation.initialRandFrac ); -      p->rotation.final = CG_RandomiseValue( bp->rotation.final, bp->rotation.finalRandFrac ); - -      p->dLightRadius.delay = -        (int)CG_RandomiseValue( (float)bp->dLightRadius.delay, bp->dLightRadius.delayRandFrac ); -      p->dLightRadius.initial = -        CG_RandomiseValue( bp->dLightRadius.initial, bp->dLightRadius.initialRandFrac ); -      p->dLightRadius.final = -        CG_RandomiseValue( bp->dLightRadius.final, bp->dLightRadius.finalRandFrac ); - -      p->colorDelay = CG_RandomiseValue( bp->colorDelay, bp->colorDelayRandFrac ); - -      p->bounceMarkRadius = CG_RandomiseValue( bp->bounceMarkRadius, bp->bounceMarkRadiusRandFrac ); -      p->bounceMarkCount = -        round( CG_RandomiseValue( (float)bp->bounceMarkCount, bp->bounceMarkCountRandFrac ) ); -      p->bounceSoundCount = -        round( CG_RandomiseValue( (float)bp->bounceSoundCount, bp->bounceSoundCountRandFrac ) ); - -      if( bp->numModels ) -      { -        p->model = bp->models[ rand( ) % bp->numModels ]; - -        if( bp->modelAnimation.frameLerp < 0 ) -        { -          bp->modelAnimation.frameLerp = p->lifeTime / bp->modelAnimation.numFrames; -          bp->modelAnimation.initialLerp = p->lifeTime / bp->modelAnimation.numFrames; -        } -      } - -      if( !CG_AttachmentPoint( &ps->attachment, attachmentPoint ) ) -        return NULL; - -      VectorCopy( attachmentPoint, p->origin ); - -      if( CG_AttachmentAxis( &ps->attachment, transform ) ) -      { -        vec3_t  transDisplacement; - -        VectorMatrixMultiply( bp->displacement, transform, transDisplacement ); -        VectorAdd( p->origin, transDisplacement, p->origin ); -      } -      else -        VectorAdd( p->origin, bp->displacement, p->origin ); - -      for( j = 0; j <= 2; j++ ) -        p->origin[ j ] += ( crandom( ) * bp->randDisplacement ); - -      switch( bp->velMoveType ) -      { -        case PMT_STATIC: -          if( bp->velMoveValues.dirType == PMD_POINT ) -            VectorSubtract( bp->velMoveValues.point, p->origin, p->velocity ); -          else if( bp->velMoveValues.dirType == PMD_LINEAR ) -            VectorCopy( bp->velMoveValues.dir, p->velocity ); -          break; - -        case PMT_STATIC_TRANSFORM: -          if( !CG_AttachmentAxis( &ps->attachment, transform ) ) -          { -            CG_Printf( S_COLOR_RED "ERROR: a particle with velocityType " -                "static_transform is not attached to something which can " -                "provide a transformation\n" ); -            return NULL; -          } - -          if( bp->velMoveValues.dirType == PMD_POINT ) -          { -            vec3_t transPoint; - -            VectorMatrixMultiply( bp->velMoveValues.point, transform, transPoint ); -            VectorSubtract( transPoint, p->origin, p->velocity ); -          } -          else if( bp->velMoveValues.dirType == PMD_LINEAR ) -            VectorMatrixMultiply( bp->velMoveValues.dir, transform, p->velocity ); -          break; - -        case PMT_TAG: -        case PMT_CENT_ANGLES: -          if( bp->velMoveValues.dirType == PMD_POINT ) -            VectorSubtract( attachmentPoint, p->origin, p->velocity ); -          else if( bp->velMoveValues.dirType == PMD_LINEAR ) -          { -            if( !CG_AttachmentDir( &ps->attachment, p->velocity ) ) -              return NULL; -          } -          break; - -        case PMT_NORMAL: -          if( !ps->normalValid ) -          { -            CG_Printf( S_COLOR_RED "ERROR: a particle with velocityType " -                "normal has no normal\n" ); -            return NULL; -          } - -          VectorCopy( ps->normal, p->velocity ); - -          //normal displacement -          VectorNormalize( p->velocity ); -          VectorMA( p->origin, bp->normalDisplacement, p->velocity, p->origin ); -          break; -      } - -      VectorNormalize( p->velocity ); -      CG_SpreadVector( p->velocity, bp->velMoveValues.dirRandAngle ); -      VectorScale( p->velocity, -                   CG_RandomiseValue( bp->velMoveValues.mag, bp->velMoveValues.magRandFrac ), -                   p->velocity ); - -      if( CG_AttachmentVelocity( &ps->attachment, attachmentVelocity ) ) -      { -        VectorMA( p->velocity, -            CG_RandomiseValue( bp->velMoveValues.parentVelFrac, -              bp->velMoveValues.parentVelFracRandFrac ), attachmentVelocity, p->velocity ); -      } - -      p->lastEvalTime = cg.time; - -      p->valid = qtrue; - -      //this particle has a child particle system attached -      if( bp->childSystemName[ 0 ] != '\0' ) -      { -        particleSystem_t  *ps = CG_SpawnNewParticleSystem( bp->childSystemHandle ); - -        if( CG_IsParticleSystemValid( &ps ) ) -        { -          CG_SetAttachmentParticle( &ps->attachment, p ); -          CG_AttachToParticle( &ps->attachment ); -        } -      } - -      //this particle has a child trail system attached -      if( bp->childTrailSystemName[ 0 ] != '\0' ) -      { -        trailSystem_t *ts = CG_SpawnNewTrailSystem( bp->childTrailSystemHandle ); - -        if( CG_IsTrailSystemValid( &ts ) ) -        { -          CG_SetAttachmentParticle( &ts->frontAttachment, p ); -          CG_AttachToParticle( &ts->frontAttachment ); -        } -      } - -      break; -    } -  } - -  return p; -} - - -/* -=============== -CG_SpawnNewParticles - -Check if there are any ejectors that should be -introducing new particles -=============== -*/ -static void CG_SpawnNewParticles( void ) -{ -  int                   i, j; -  particle_t            *p; -  particleSystem_t      *ps; -  particleEjector_t     *pe; -  baseParticleEjector_t *bpe; -  float                 lerpFrac; -  int                   count; - -  for( i = 0; i < MAX_PARTICLE_EJECTORS; i++ ) -  { -    pe = &particleEjectors[ i ]; -    ps = pe->parent; - -    if( pe->valid ) -    { -      //a non attached particle system can't make particles -      if( !CG_Attached( &ps->attachment ) ) -        continue; - -      bpe = particleEjectors[ i ].class; - -      //if this system is scheduled for removal don't make any new particles -      if( !ps->lazyRemove ) -      { -        while( pe->nextEjectionTime <= cg.time && -               ( pe->count > 0 || pe->totalParticles == PARTICLES_INFINITE ) ) -        { -          for( j = 0; j < bpe->numParticles; j++ ) -            CG_SpawnNewParticle( bpe->particles[ j ], pe ); - -          if( pe->count > 0 ) -            pe->count--; - -          //calculate next ejection time -          lerpFrac = 1.0 - ( (float)pe->count / (float)pe->totalParticles ); -          pe->nextEjectionTime = cg.time + (int)CG_RandomiseValue( -              CG_LerpValues( pe->ejectPeriod.initial, -                             pe->ejectPeriod.final, -                             lerpFrac ), -              pe->ejectPeriod.randFrac ); -        } -      } - -      if( pe->count == 0 || ps->lazyRemove ) -      { -        count = 0; - -        //wait for child particles to die before declaring this pe invalid -        for( j = 0; j < MAX_PARTICLES; j++ ) -        { -          p = &particles[ j ]; - -          if( p->valid && p->parent == pe ) -            count++; -        } - -        if( !count ) -          pe->valid = qfalse; -      } -    } -  } -} - - -/* -=============== -CG_SpawnNewParticleEjector - -Allocate a new particle ejector -=============== -*/ -static particleEjector_t *CG_SpawnNewParticleEjector( baseParticleEjector_t *bpe, -                                                      particleSystem_t *parent ) -{ -  int                     i; -  particleEjector_t       *pe = NULL; -  particleSystem_t        *ps = parent; - -  for( i = 0; i < MAX_PARTICLE_EJECTORS; i++ ) -  { -    pe = &particleEjectors[ i ]; - -    if( !pe->valid ) -    { -      memset( pe, 0, sizeof( particleEjector_t ) ); - -      //found a free slot -      pe->class = bpe; -      pe->parent = ps; - -      pe->ejectPeriod.initial = bpe->eject.initial; -      pe->ejectPeriod.final = bpe->eject.final; -      pe->ejectPeriod.randFrac = bpe->eject.randFrac; - -      pe->nextEjectionTime = cg.time + -        (int)CG_RandomiseValue( (float)bpe->eject.delay, bpe->eject.delayRandFrac ); -      pe->count = pe->totalParticles = -        (int)round( CG_RandomiseValue( (float)bpe->totalParticles, bpe->totalParticlesRandFrac ) ); - -      pe->valid = qtrue; - -      if( cg_debugParticles.integer >= 1 ) -        CG_Printf( "PE %s created\n", ps->class->name ); - -      break; -    } -  } - -  return pe; -} - - -/* -=============== -CG_SpawnNewParticleSystem - -Allocate a new particle system -=============== -*/ -particleSystem_t *CG_SpawnNewParticleSystem( qhandle_t psHandle ) -{ -  int                   i, j; -  particleSystem_t      *ps = NULL; -  baseParticleSystem_t  *bps = &baseParticleSystems[ psHandle - 1 ]; - -  if( !bps->registered ) -  { -    CG_Printf( S_COLOR_RED "ERROR: a particle system has not been registered yet\n" ); -    return NULL; -  } - -  for( i = 0; i < MAX_PARTICLE_SYSTEMS; i++ ) -  { -    ps = &particleSystems[ i ]; - -    if( !ps->valid ) -    { -      memset( ps, 0, sizeof( particleSystem_t ) ); - -      //found a free slot -      ps->class = bps; - -      ps->valid = qtrue; -      ps->lazyRemove = qfalse; - -      for( j = 0; j < bps->numEjectors; j++ ) -        CG_SpawnNewParticleEjector( bps->ejectors[ j ], ps ); - -      if( cg_debugParticles.integer >= 1 ) -        CG_Printf( "PS %s created\n", bps->name ); - -      break; -    } -  } - -  return ps; -} - -/* -=============== -CG_RegisterParticleSystem - -Load the shaders required for a particle system -=============== -*/ -qhandle_t CG_RegisterParticleSystem( char *name ) -{ -  int                   i, j, k, l; -  baseParticleSystem_t  *bps; -  baseParticleEjector_t *bpe; -  baseParticle_t        *bp; - -  for( i = 0; i < MAX_BASEPARTICLE_SYSTEMS; i++ ) -  { -    bps = &baseParticleSystems[ i ]; - -    if( !Q_stricmpn( bps->name, name, MAX_QPATH ) ) -    { -      //already registered -      if( bps->registered ) -        return i + 1; - -      for( j = 0; j < bps->numEjectors; j++ ) -      { -        bpe = bps->ejectors[ j ]; - -        for( l = 0; l < bpe->numParticles; l++ ) -        { -          bp = bpe->particles[ l ]; - -          for( k = 0; k < bp->numFrames; k++ ) -            bp->shaders[ k ] = trap_R_RegisterShader( bp->shaderNames[ k ] ); - -          for( k = 0; k < bp->numModels; k++ ) -            bp->models[ k ] = trap_R_RegisterModel( bp->modelNames[ k ] ); - -          if( bp->bounceMarkName[ 0 ] != '\0' ) -            bp->bounceMark = trap_R_RegisterShader( bp->bounceMarkName ); - -          if( bp->bounceSoundName[ 0 ] != '\0' ) -            bp->bounceSound = trap_S_RegisterSound( bp->bounceSoundName, qfalse ); - -          //recursively register any children -          if( bp->childSystemName[ 0 ] != '\0' ) -          { -            //don't care about a handle for children since -            //the system deals with it -            CG_RegisterParticleSystem( bp->childSystemName ); -          } - -          if( bp->onDeathSystemName[ 0 ] != '\0' ) -          { -            //don't care about a handle for children since -            //the system deals with it -            CG_RegisterParticleSystem( bp->onDeathSystemName ); -          } - -          if( bp->childTrailSystemName[ 0 ] != '\0' ) -            bp->childTrailSystemHandle = CG_RegisterTrailSystem( bp->childTrailSystemName ); -        } -      } - -      if( cg_debugParticles.integer >= 1 ) -        CG_Printf( "Registered particle system %s\n", name ); - -      bps->registered = qtrue; - -      //avoid returning 0 -      return i + 1; -    } -  } - -  CG_Printf( S_COLOR_RED "ERROR: failed to register particle system %s\n", name ); -  return 0; -} - - -/* -=============== -CG_ParseValueAndVariance - -Parse a value and its random variance -=============== -*/ -static void CG_ParseValueAndVariance( char *token, float *value, float *variance, qboolean allowNegative ) -{ -  char  valueBuffer[ 16 ]; -  char  varianceBuffer[ 16 ]; -  char  *variancePtr = NULL, *varEndPointer = NULL; -  float localValue = 0.0f; -  float localVariance = 0.0f; - -  Q_strncpyz( valueBuffer, token, sizeof( valueBuffer ) ); -  Q_strncpyz( varianceBuffer, token, sizeof( varianceBuffer ) ); - -  variancePtr = strchr( valueBuffer, '~' ); - -  //variance included -  if( variancePtr ) -  { -    variancePtr[ 0 ] = '\0'; -    variancePtr++; - -    localValue = atof_neg( valueBuffer, allowNegative ); - -    varEndPointer = strchr( variancePtr, '%' ); - -    if( varEndPointer ) -    { -      varEndPointer[ 0 ] = '\0'; -      localVariance = atof_neg( variancePtr, qfalse ) / 100.0f; -    } -    else -    { -      if( localValue != 0.0f ) -        localVariance = atof_neg( variancePtr, qfalse ) / localValue; -      else -        localVariance = atof_neg( variancePtr, qfalse ); -    } -  } -  else -    localValue = atof_neg( valueBuffer, allowNegative ); - -  if( value != NULL ) -    *value = localValue; - -  if( variance != NULL ) -    *variance = localVariance; -} - -/* -=============== -CG_ParseColor -=============== -*/ -static qboolean CG_ParseColor( byte *c, char **text_p ) -{ -  char  *token; -  int   i; - -  for( i = 0; i <= 2; i++ ) -  { -    token = COM_Parse( text_p ); - -    if( !Q_stricmp( token, "" ) ) -      return qfalse; - -    c[ i ] = (int)( (float)0xFF * atof_neg( token, qfalse ) ); -  } - -  return qtrue; -} - -/* -=============== -CG_ParseParticle - -Parse a particle section -=============== -*/ -static qboolean CG_ParseParticle( baseParticle_t *bp, char **text_p ) -{ -  char  *token; -  float number, randFrac; -  int   i; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( text_p ); - -    if( !token ) -      break; - -    if( !Q_stricmp( token, "" ) ) -      return qfalse; - -    if( !Q_stricmp( token, "bounce" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      if( !Q_stricmp( token, "cull" ) ) -      { -        bp->bounceCull = qtrue; - -        bp->bounceFrac = -1.0f; -        bp->bounceFracRandFrac = 0.0f; -      } -      else -      { -        CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -        bp->bounceFrac = number; -        bp->bounceFracRandFrac = randFrac; -      } - -      continue; -    } -    else if( !Q_stricmp( token, "bounceMark" ) ) -    { -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->bounceMarkCount = number; -      bp->bounceMarkCountRandFrac = randFrac; - -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->bounceMarkRadius = number; -      bp->bounceMarkRadiusRandFrac = randFrac; - -      token = COM_ParseExt( text_p, qfalse ); -      if( !*token ) -        break; - -      Q_strncpyz( bp->bounceMarkName, token, MAX_QPATH ); - -      continue; -    } -    else if( !Q_stricmp( token, "bounceSound" ) ) -    { -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->bounceSoundCount = number; -      bp->bounceSoundCountRandFrac = randFrac; - -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      Q_strncpyz( bp->bounceSoundName, token, MAX_QPATH ); - -      continue; -    } -    else if( !Q_stricmp( token, "shader" ) ) -    { -      if( bp->numModels > 0 ) -      { -        CG_Printf( S_COLOR_RED "ERROR: 'shader' not allowed in " -            "conjunction with 'model'\n", token ); -        break; -      } - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      if( !Q_stricmp( token, "sync" ) ) -        bp->framerate = 0.0f; -      else -        bp->framerate = atof_neg( token, qfalse ); - -      token = COM_ParseExt( text_p, qfalse ); -      if( !*token ) -        break; - -      while( *token && bp->numFrames < MAX_PS_SHADER_FRAMES ) -      { -        Q_strncpyz( bp->shaderNames[ bp->numFrames++ ], token, MAX_QPATH ); -        token = COM_ParseExt( text_p, qfalse ); -      } - -      continue; -    } -    else if( !Q_stricmp( token, "model" ) ) -    { -      if( bp->numFrames > 0 ) -      { -        CG_Printf( S_COLOR_RED "ERROR: 'model' not allowed in " -            "conjunction with 'shader'\n", token ); -        break; -      } - -      token = COM_ParseExt( text_p, qfalse ); -      if( !*token ) -        break; - -      while( *token && bp->numModels < MAX_PS_MODELS ) -      { -        Q_strncpyz( bp->modelNames[ bp->numModels++ ], token, MAX_QPATH ); -        token = COM_ParseExt( text_p, qfalse ); -      } - -      continue; -    } -    else if( !Q_stricmp( token, "modelAnimation" ) ) -    { -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      bp->modelAnimation.firstFrame = atoi_neg( token, qfalse ); - -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      bp->modelAnimation.numFrames = atoi( token ); -      bp->modelAnimation.reversed = qfalse; -      bp->modelAnimation.flipflop = qfalse; - -      // if numFrames is negative the animation is reversed -      if( bp->modelAnimation.numFrames < 0 ) -      { -        bp->modelAnimation.numFrames = -bp->modelAnimation.numFrames; -        bp->modelAnimation.reversed = qtrue; -      } - -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      bp->modelAnimation.loopFrames = atoi( token ); - -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      if( !Q_stricmp( token, "sync" ) ) -      { -        bp->modelAnimation.frameLerp = -1; -        bp->modelAnimation.initialLerp = -1; -      } -      else -      { -        float fps = atof_neg( token, qfalse ); - -        if( fps == 0.0f ) -          fps = 1.0f; - -        bp->modelAnimation.frameLerp = 1000 / fps; -        bp->modelAnimation.initialLerp = 1000 / fps; -      } - -      continue; -    } -    /// -    else if( !Q_stricmp( token, "velocityType" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      if( !Q_stricmp( token, "static" ) ) -        bp->velMoveType = PMT_STATIC; -      else if( !Q_stricmp( token, "static_transform" ) ) -        bp->velMoveType = PMT_STATIC_TRANSFORM; -      else if( !Q_stricmp( token, "tag" ) ) -        bp->velMoveType = PMT_TAG; -      else if( !Q_stricmp( token, "cent" ) ) -        bp->velMoveType = PMT_CENT_ANGLES; -      else if( !Q_stricmp( token, "normal" ) ) -        bp->velMoveType = PMT_NORMAL; - -      continue; -    } -    else if( !Q_stricmp( token, "velocityDir" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      if( !Q_stricmp( token, "linear" ) ) -        bp->velMoveValues.dirType = PMD_LINEAR; -      else if( !Q_stricmp( token, "point" ) ) -        bp->velMoveValues.dirType = PMD_POINT; - -      continue; -    } -    else if( !Q_stricmp( token, "velocityMagnitude" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->velMoveValues.mag = number; -      bp->velMoveValues.magRandFrac = randFrac; - -      continue; -    } -    else if( !Q_stricmp( token, "parentVelocityFraction" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->velMoveValues.parentVelFrac = number; -      bp->velMoveValues.parentVelFracRandFrac = randFrac; - -      continue; -    } -    else if( !Q_stricmp( token, "velocity" ) ) -    { -      for( i = 0; i <= 2; i++ ) -      { -        token = COM_Parse( text_p ); -        if( !token ) -          break; - -        bp->velMoveValues.dir[ i ] = atof_neg( token, qtrue ); -      } - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, NULL, &randFrac, qfalse ); - -      bp->velMoveValues.dirRandAngle = randFrac; - -      continue; -    } -    else if( !Q_stricmp( token, "velocityPoint" ) ) -    { -      for( i = 0; i <= 2; i++ ) -      { -        token = COM_Parse( text_p ); -        if( !token ) -          break; - -        bp->velMoveValues.point[ i ] = atof_neg( token, qtrue ); -      } - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, NULL, &randFrac, qfalse ); - -      bp->velMoveValues.pointRandAngle = randFrac; - -      continue; -    } -    /// -    else if( !Q_stricmp( token, "accelerationType" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      if( !Q_stricmp( token, "static" ) ) -        bp->accMoveType = PMT_STATIC; -      else if( !Q_stricmp( token, "static_transform" ) ) -        bp->accMoveType = PMT_STATIC_TRANSFORM; -      else if( !Q_stricmp( token, "tag" ) ) -        bp->accMoveType = PMT_TAG; -      else if( !Q_stricmp( token, "cent" ) ) -        bp->accMoveType = PMT_CENT_ANGLES; -      else if( !Q_stricmp( token, "normal" ) ) -        bp->accMoveType = PMT_NORMAL; - -      continue; -    } -    else if( !Q_stricmp( token, "accelerationDir" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      if( !Q_stricmp( token, "linear" ) ) -        bp->accMoveValues.dirType = PMD_LINEAR; -      else if( !Q_stricmp( token, "point" ) ) -        bp->accMoveValues.dirType = PMD_POINT; - -      continue; -    } -    else if( !Q_stricmp( token, "accelerationMagnitude" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->accMoveValues.mag = number; -      bp->accMoveValues.magRandFrac = randFrac; - -      continue; -    } -    else if( !Q_stricmp( token, "acceleration" ) ) -    { -      for( i = 0; i <= 2; i++ ) -      { -        token = COM_Parse( text_p ); -        if( !token ) -          break; - -        bp->accMoveValues.dir[ i ] = atof_neg( token, qtrue ); -      } - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, NULL, &randFrac, qfalse ); - -      bp->accMoveValues.dirRandAngle = randFrac; - -      continue; -    } -    else if( !Q_stricmp( token, "accelerationPoint" ) ) -    { -      for( i = 0; i <= 2; i++ ) -      { -        token = COM_Parse( text_p ); -        if( !token ) -          break; - -        bp->accMoveValues.point[ i ] = atof_neg( token, qtrue ); -      } - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, NULL, &randFrac, qfalse ); - -      bp->accMoveValues.pointRandAngle = randFrac; - -      continue; -    } -    /// -    else if( !Q_stricmp( token, "displacement" ) ) -    { -      for( i = 0; i <= 2; i++ ) -      { -        token = COM_Parse( text_p ); -        if( !token ) -          break; - -        bp->displacement[ i ] = atof_neg( token, qtrue ); -      } - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, NULL, &randFrac, qfalse ); - -      bp->randDisplacement = randFrac; - -      continue; -    } -    else if( !Q_stricmp( token, "normalDisplacement" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      bp->normalDisplacement = atof_neg( token, qtrue ); - -      continue; -    } -    else if( !Q_stricmp( token, "overdrawProtection" ) ) -    { -      bp->overdrawProtection = qtrue; - -      continue; -    } -    else if( !Q_stricmp( token, "realLight" ) ) -    { -      bp->realLight = qtrue; - -      continue; -    } -    else if( !Q_stricmp( token, "dynamicLight" ) ) -    { -      bp->dynamicLight = qtrue; - -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->dLightRadius.delay = (int)number; -      bp->dLightRadius.delayRandFrac = randFrac; - -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->dLightRadius.initial = number; -      bp->dLightRadius.initialRandFrac = randFrac; - -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      if( !Q_stricmp( token, "-" ) ) -      { -        bp->dLightRadius.final = PARTICLES_SAME_AS_INITIAL; -        bp->dLightRadius.finalRandFrac = 0.0f; -      } -      else -      { -        CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -        bp->dLightRadius.final = number; -        bp->dLightRadius.finalRandFrac = randFrac; -      } - -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      if( !Q_stricmp( token, "{" ) ) -      { -        if( !CG_ParseColor( bp->dLightColor, text_p ) ) -          break; - -        token = COM_Parse( text_p ); -        if( Q_stricmp( token, "}" ) ) -        { -          CG_Printf( S_COLOR_RED "ERROR: missing '}'\n" ); -          break; -        } -      } - -      continue; -    } -    else if( !Q_stricmp( token, "cullOnStartSolid" ) ) -    { -      bp->cullOnStartSolid = qtrue; - -      continue; -    } -    else if( !Q_stricmp( token, "radius" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->radius.delay = (int)number; -      bp->radius.delayRandFrac = randFrac; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->radius.initial = number; -      bp->radius.initialRandFrac = randFrac; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      if( !Q_stricmp( token, "-" ) ) -      { -        bp->radius.final = PARTICLES_SAME_AS_INITIAL; -        bp->radius.finalRandFrac = 0.0f; -      } -      else -      { -        CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -        bp->radius.final = number; -        bp->radius.finalRandFrac = randFrac; -      } - -      continue; -    } -    else if( !Q_stricmp( token, "alpha" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->alpha.delay = (int)number; -      bp->alpha.delayRandFrac = randFrac; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->alpha.initial = number; -      bp->alpha.initialRandFrac = randFrac; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      if( !Q_stricmp( token, "-" ) ) -      { -        bp->alpha.final = PARTICLES_SAME_AS_INITIAL; -        bp->alpha.finalRandFrac = 0.0f; -      } -      else -      { -        CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -        bp->alpha.final = number; -        bp->alpha.finalRandFrac = randFrac; -      } - -      continue; -    } -    else if( !Q_stricmp( token, "color" ) ) -    { -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->colorDelay = (int)number; -      bp->colorDelayRandFrac = randFrac; - -      token = COM_Parse( text_p ); -      if( !*token ) -        break; - -      if( !Q_stricmp( token, "{" ) ) -      { -        if( !CG_ParseColor( bp->initialColor, text_p ) ) -          break; - -        token = COM_Parse( text_p ); -        if( Q_stricmp( token, "}" ) ) -        { -          CG_Printf( S_COLOR_RED "ERROR: missing '}'\n" ); -          break; -        } - -        token = COM_Parse( text_p ); -        if( !*token ) -          break; - -        if( !Q_stricmp( token, "-" ) ) -        { -          bp->finalColor[ 0 ] = bp->initialColor[ 0 ]; -          bp->finalColor[ 1 ] = bp->initialColor[ 1 ]; -          bp->finalColor[ 2 ] = bp->initialColor[ 2 ]; -        } -        else if( !Q_stricmp( token, "{" ) ) -        { -          if( !CG_ParseColor( bp->finalColor, text_p ) ) -            break; - -          token = COM_Parse( text_p ); -          if( Q_stricmp( token, "}" ) ) -          { -            CG_Printf( S_COLOR_RED "ERROR: missing '}'\n" ); -            break; -          } -        } -        else -        { -          CG_Printf( S_COLOR_RED "ERROR: missing '{'\n" ); -          break; -        } -      } -      else -      { -        CG_Printf( S_COLOR_RED "ERROR: missing '{'\n" ); -        break; -      } - -      continue; -    } -    else if( !Q_stricmp( token, "rotation" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->rotation.delay = (int)number; -      bp->rotation.delayRandFrac = randFrac; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qtrue ); - -      bp->rotation.initial = number; -      bp->rotation.initialRandFrac = randFrac; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      if( !Q_stricmp( token, "-" ) ) -      { -        bp->rotation.final = PARTICLES_SAME_AS_INITIAL; -        bp->rotation.finalRandFrac = 0.0f; -      } -      else -      { -        CG_ParseValueAndVariance( token, &number, &randFrac, qtrue ); - -        bp->rotation.final = number; -        bp->rotation.finalRandFrac = randFrac; -      } - -      continue; -    } -    else if( !Q_stricmp( token, "lifeTime" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bp->lifeTime = (int)number; -      bp->lifeTimeRandFrac = randFrac; - -      continue; -    } -    else if( !Q_stricmp( token, "childSystem" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      Q_strncpyz( bp->childSystemName, token, MAX_QPATH ); - -      continue; -    } -    else if( !Q_stricmp( token, "onDeathSystem" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      Q_strncpyz( bp->onDeathSystemName, token, MAX_QPATH ); - -      continue; -    } -    else if( !Q_stricmp( token, "childTrailSystem" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      Q_strncpyz( bp->childTrailSystemName, token, MAX_QPATH ); - -      continue; -    } -    else if( !Q_stricmp( token, "}" ) ) -      return qtrue; //reached the end of this particle -    else -    { -      CG_Printf( S_COLOR_RED "ERROR: unknown token '%s' in particle\n", token ); -      return qfalse; -    } -  } - -  return qfalse; -} - -/* -=============== -CG_InitialiseBaseParticle -=============== -*/ -static void CG_InitialiseBaseParticle( baseParticle_t *bp ) -{ -  memset( bp, 0, sizeof( baseParticle_t ) ); - -  memset( bp->initialColor, 0xFF, sizeof( bp->initialColor ) ); -  memset( bp->finalColor, 0xFF, sizeof( bp->finalColor ) ); -} - -/* -=============== -CG_ParseParticleEjector - -Parse a particle ejector section -=============== -*/ -static qboolean CG_ParseParticleEjector( baseParticleEjector_t *bpe, char **text_p ) -{ -  char  *token; -  float number, randFrac; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( text_p ); - -    if( !token ) -      break; - -    if( !Q_stricmp( token, "" ) ) -      return qfalse; - -    if( !Q_stricmp( token, "{" ) ) -    { -      CG_InitialiseBaseParticle( &baseParticles[ numBaseParticles ] ); - -      if( !CG_ParseParticle( &baseParticles[ numBaseParticles ], text_p ) ) -      { -        CG_Printf( S_COLOR_RED "ERROR: failed to parse particle\n" ); -        return qfalse; -      } - -      if( bpe->numParticles == MAX_PARTICLES_PER_EJECTOR ) -      { -        CG_Printf( S_COLOR_RED "ERROR: ejector has > %d particles\n", MAX_PARTICLES_PER_EJECTOR ); -        return qfalse; -      } -      else if( numBaseParticles == MAX_BASEPARTICLES ) -      { -        CG_Printf( S_COLOR_RED "ERROR: maximum number of particles (%d) reached\n", MAX_BASEPARTICLES ); -        return qfalse; -      } -      else -      { -        //start parsing particles again -        bpe->particles[ bpe->numParticles ] = &baseParticles[ numBaseParticles ]; -        bpe->numParticles++; -        numBaseParticles++; -      } -      continue; -    } -    else if( !Q_stricmp( token, "delay" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -      bpe->eject.delay = (int)number; -      bpe->eject.delayRandFrac = randFrac; - -      continue; -    } -    else if( !Q_stricmp( token, "period" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      bpe->eject.initial = atoi_neg( token, qfalse ); - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      if( !Q_stricmp( token, "-" ) ) -        bpe->eject.final = PARTICLES_SAME_AS_INITIAL; -      else -        bpe->eject.final = atoi_neg( token, qfalse ); - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      CG_ParseValueAndVariance( token, NULL, &bpe->eject.randFrac, qfalse ); - -      continue; -    } -    else if( !Q_stricmp( token, "count" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      if( !Q_stricmp( token, "infinite" ) ) -      { -        bpe->totalParticles = PARTICLES_INFINITE; -        bpe->totalParticlesRandFrac = 0.0f; -      } -      else -      { -        CG_ParseValueAndVariance( token, &number, &randFrac, qfalse ); - -        bpe->totalParticles = (int)number; -        bpe->totalParticlesRandFrac = randFrac; -      } - -      continue; -    } -    else if( !Q_stricmp( token, "particle" ) ) //acceptable text -      continue; -    else if( !Q_stricmp( token, "}" ) ) -      return qtrue; //reached the end of this particle ejector -    else -    { -      CG_Printf( S_COLOR_RED "ERROR: unknown token '%s' in particle ejector\n", token ); -      return qfalse; -    } -  } - -  return qfalse; -} - - -/* -=============== -CG_ParseParticleSystem - -Parse a particle system section -=============== -*/ -static qboolean CG_ParseParticleSystem( baseParticleSystem_t *bps, char **text_p, const char *name ) -{ -  char                  *token; -  baseParticleEjector_t *bpe; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( text_p ); - -    if( !token ) -      break; - -    if( !Q_stricmp( token, "" ) ) -      return qfalse; - -    if( !Q_stricmp( token, "{" ) ) -    { -      if( !CG_ParseParticleEjector( &baseParticleEjectors[ numBaseParticleEjectors ], text_p ) ) -      { -        CG_Printf( S_COLOR_RED "ERROR: failed to parse particle ejector\n" ); -        return qfalse; -      } - -      bpe = &baseParticleEjectors[ numBaseParticleEjectors ]; - -      //check for infinite count + zero period -      if( bpe->totalParticles == PARTICLES_INFINITE && -          ( bpe->eject.initial == 0.0f || bpe->eject.final == 0.0f ) ) -      { -        CG_Printf( S_COLOR_RED "ERROR: ejector with 'count infinite' potentially has zero period\n" ); -        return qfalse; -      } - -      if( bps->numEjectors == MAX_EJECTORS_PER_SYSTEM ) -      { -        CG_Printf( S_COLOR_RED "ERROR: particle system has > %d ejectors\n", MAX_EJECTORS_PER_SYSTEM ); -        return qfalse; -      } -      else if( numBaseParticleEjectors == MAX_BASEPARTICLE_EJECTORS ) -      { -        CG_Printf( S_COLOR_RED "ERROR: maximum number of particle ejectors (%d) reached\n", -            MAX_BASEPARTICLE_EJECTORS ); -        return qfalse; -      } -      else -      { -        //start parsing ejectors again -        bps->ejectors[ bps->numEjectors ] = &baseParticleEjectors[ numBaseParticleEjectors ]; -        bps->numEjectors++; -        numBaseParticleEjectors++; -      } -      continue; -    } -    else if( !Q_stricmp( token, "thirdPersonOnly" ) ) -      bps->thirdPersonOnly = qtrue; -    else if( !Q_stricmp( token, "ejector" ) ) //acceptable text -      continue; -    else if( !Q_stricmp( token, "}" ) ) -    { -      if( cg_debugParticles.integer >= 1 ) -        CG_Printf( "Parsed particle system %s\n", name ); - -      return qtrue; //reached the end of this particle system -    } -    else -    { -      CG_Printf( S_COLOR_RED "ERROR: unknown token '%s' in particle system %s\n", token, bps->name ); -      return qfalse; -    } -  } - -  return qfalse; -} - -/* -=============== -CG_ParseParticleFile - -Load the particle systems from a particle file -=============== -*/ -static qboolean CG_ParseParticleFile( const char *fileName ) -{ -  char          *text_p; -  int           i; -  int           len; -  char          *token; -  char          text[ 32000 ]; -  char          psName[ MAX_QPATH ]; -  qboolean      psNameSet = qfalse; -  fileHandle_t  f; - -  // load the file -  len = trap_FS_FOpenFile( fileName, &f, FS_READ ); -  if( len <= 0 ) -    return qfalse; - -  if( len >= sizeof( text ) - 1 ) -  { -    CG_Printf( S_COLOR_RED "ERROR: particle file %s too long\n", fileName ); -    return qfalse; -  } - -  trap_FS_Read( text, len, f ); -  text[ len ] = 0; -  trap_FS_FCloseFile( f ); - -  // parse the text -  text_p = text; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( &text_p ); - -    if( !Q_stricmp( token, "" ) ) -      break; - -    if( !Q_stricmp( token, "{" ) ) -    { -      if( psNameSet ) -      { -        //check for name space clashes -        for( i = 0; i < numBaseParticleSystems; i++ ) -        { -          if( !Q_stricmp( baseParticleSystems[ i ].name, psName ) ) -          { -            CG_Printf( S_COLOR_RED "ERROR: a particle system is already named %s\n", psName ); -            return qfalse; -          } -        } - -        Q_strncpyz( baseParticleSystems[ numBaseParticleSystems ].name, psName, MAX_QPATH ); - -        if( !CG_ParseParticleSystem( &baseParticleSystems[ numBaseParticleSystems ], &text_p, psName ) ) -        { -          CG_Printf( S_COLOR_RED "ERROR: %s: failed to parse particle system %s\n", fileName, psName ); -          return qfalse; -        } - -        //start parsing particle systems again -        psNameSet = qfalse; - -        if( numBaseParticleSystems == MAX_BASEPARTICLE_SYSTEMS ) -        { -          CG_Printf( S_COLOR_RED "ERROR: maximum number of particle systems (%d) reached\n", -              MAX_BASEPARTICLE_SYSTEMS ); -          return qfalse; -        } -        else -          numBaseParticleSystems++; - -        continue; -      } -      else -      { -        CG_Printf( S_COLOR_RED "ERROR: unamed particle system\n" ); -        return qfalse; -      } -    } - -    if( !psNameSet ) -    { -      Q_strncpyz( psName, token, sizeof( psName ) ); -      psNameSet = qtrue; -    } -    else -    { -      CG_Printf( S_COLOR_RED "ERROR: particle system already named\n" ); -      return qfalse; -    } -  } - -  return qtrue; -} - - -/* -=============== -CG_LoadParticleSystems - -Load particle systems from .particle files -=============== -*/ -void CG_LoadParticleSystems( void ) -{ -  int         i, j; -  const char  *s[ MAX_PARTICLE_FILES ]; - -  //clear out the old -  numBaseParticleSystems = 0; -  numBaseParticleEjectors = 0; -  numBaseParticles = 0; - -  for( i = 0; i < MAX_BASEPARTICLE_SYSTEMS; i++ ) -  { -    baseParticleSystem_t  *bps = &baseParticleSystems[ i ]; -    memset( bps, 0, sizeof( baseParticleSystem_t ) ); -  } - -  for( i = 0; i < MAX_BASEPARTICLE_EJECTORS; i++ ) -  { -    baseParticleEjector_t  *bpe = &baseParticleEjectors[ i ]; -    memset( bpe, 0, sizeof( baseParticleEjector_t ) ); -  } - -  for( i = 0; i < MAX_BASEPARTICLES; i++ ) -  { -    baseParticle_t  *bp = &baseParticles[ i ]; -    memset( bp, 0, sizeof( baseParticle_t ) ); -  } - - -  //and bring in the new -  for( i = 0; i < MAX_PARTICLE_FILES; i++ ) -  { -    s[ i ] = CG_ConfigString( CS_PARTICLE_FILES + i ); - -    if( strlen( s[ i ] ) > 0 ) -    { -      CG_Printf( "...loading '%s'\n", s[ i ] ); -      CG_ParseParticleFile( s[ i ] ); -    } -    else -      break; -  } - -  //connect any child systems to their psHandle -  for( i = 0; i < numBaseParticles; i++ ) -  { -    baseParticle_t  *bp = &baseParticles[ i ]; - -    if( bp->childSystemName[ 0 ] ) -    { -      //particle class has a child, resolve the name -      for( j = 0; j < numBaseParticleSystems; j++ ) -      { -        baseParticleSystem_t  *bps = &baseParticleSystems[ j ]; - -        if( !Q_stricmp( bps->name, bp->childSystemName ) ) -        { -          //FIXME: add checks for cycles and infinite children - -          bp->childSystemHandle = j + 1; - -          break; -        } -      } - -      if( j == numBaseParticleSystems ) -      { -        //couldn't find named particle system -        CG_Printf( S_COLOR_YELLOW "WARNING: failed to find child %s\n", bp->childSystemName ); -        bp->childSystemName[ 0 ] = '\0'; -      } -    } - -    if( bp->onDeathSystemName[ 0 ] ) -    { -      //particle class has a child, resolve the name -      for( j = 0; j < numBaseParticleSystems; j++ ) -      { -        baseParticleSystem_t  *bps = &baseParticleSystems[ j ]; - -        if( !Q_stricmp( bps->name, bp->onDeathSystemName ) ) -        { -          //FIXME: add checks for cycles and infinite children - -          bp->onDeathSystemHandle = j + 1; - -          break; -        } -      } - -      if( j == numBaseParticleSystems ) -      { -        //couldn't find named particle system -        CG_Printf( S_COLOR_YELLOW "WARNING: failed to find onDeath system %s\n", bp->onDeathSystemName ); -        bp->onDeathSystemName[ 0 ] = '\0'; -      } -    } -  } -} - -/* -=============== -CG_SetParticleSystemNormal -=============== -*/ -void CG_SetParticleSystemNormal( particleSystem_t *ps, vec3_t normal ) -{ -  if( ps == NULL || !ps->valid ) -  { -    CG_Printf( S_COLOR_YELLOW "WARNING: tried to modify a NULL particle system\n" ); -    return; -  } - -  ps->normalValid = qtrue; -  VectorCopy( normal, ps->normal ); -  VectorNormalize( ps->normal ); -} - - -/* -=============== -CG_DestroyParticleSystem - -Destroy a particle system - -This doesn't actually invalidate anything, it just stops -particle ejectors from producing new particles so the -garbage collector will eventually remove this system. -However is does set the pointer to NULL so the user is -unable to manipulate this particle system any longer. -=============== -*/ -void CG_DestroyParticleSystem( particleSystem_t **ps ) -{ -  int               i; -  particleEjector_t *pe; - -  if( *ps == NULL || !(*ps)->valid ) -  { -    CG_Printf( S_COLOR_YELLOW "WARNING: tried to destroy a NULL particle system\n" ); -    return; -  } - -  if( cg_debugParticles.integer >= 1 ) -    CG_Printf( "PS destroyed\n" ); - -  for( i = 0; i < MAX_PARTICLE_EJECTORS; i++ ) -  { -    pe = &particleEjectors[ i ]; - -    if( pe->valid && pe->parent == *ps ) -      pe->totalParticles = pe->count = 0; -  } - -  *ps = NULL; -} - -/* -=============== -CG_IsParticleSystemInfinite - -Test a particle system for 'count infinite' ejectors -=============== -*/ -qboolean CG_IsParticleSystemInfinite( particleSystem_t *ps ) -{ -  int               i; -  particleEjector_t *pe; - -  if( ps == NULL ) -  { -    CG_Printf( S_COLOR_YELLOW "WARNING: tried to test a NULL particle system\n" ); -    return qfalse; -  } - -  if( !ps->valid ) -  { -    CG_Printf( S_COLOR_YELLOW "WARNING: tried to test an invalid particle system\n" ); -    return qfalse; -  } - -  //don't bother checking already invalid systems -  if( !ps->valid ) -    return qfalse; - -  for( i = 0; i < MAX_PARTICLE_EJECTORS; i++ ) -  { -    pe = &particleEjectors[ i ]; - -    if( pe->valid && pe->parent == ps ) -    { -      if( pe->totalParticles == PARTICLES_INFINITE ) -        return qtrue; -    } -  } - -  return qfalse; -} - -/* -=============== -CG_IsParticleSystemValid - -Test a particle system for validity -=============== -*/ -qboolean CG_IsParticleSystemValid( particleSystem_t **ps ) -{ -  if( *ps == NULL || ( *ps && !(*ps)->valid ) ) -  { -    if( *ps && !(*ps)->valid ) -      *ps = NULL; - -    return qfalse; -  } - -  return qtrue; -} - -/* -=============== -CG_GarbageCollectParticleSystems - -Destroy inactive particle systems -=============== -*/ -static void CG_GarbageCollectParticleSystems( void ) -{ -  int               i, j, count; -  particleSystem_t  *ps; -  particleEjector_t *pe; -  int               centNum; - -  for( i = 0; i < MAX_PARTICLE_SYSTEMS; i++ ) -  { -    ps = &particleSystems[ i ]; -    count = 0; - -    //don't bother checking already invalid systems -    if( !ps->valid ) -      continue; - -    for( j = 0; j < MAX_PARTICLE_EJECTORS; j++ ) -    { -      pe = &particleEjectors[ j ]; - -      if( pe->valid && pe->parent == ps ) -        count++; -    } - -    if( !count ) -      ps->valid = qfalse; - -    //check systems where the parent cent has left the PVS -    //( local player entity is always valid ) -    if( ( centNum = CG_AttachmentCentNum( &ps->attachment ) ) >= 0 && -        centNum != cg.snap->ps.clientNum ) -    { -      if( !cg_entities[ centNum ].valid ) -        ps->lazyRemove = qtrue; -    } - -    if( cg_debugParticles.integer >= 1 && !ps->valid ) -      CG_Printf( "PS %s garbage collected\n", ps->class->name ); -  } -} - - -/* -=============== -CG_CalculateTimeFrac - -Calculate the fraction of time passed -=============== -*/ -static float CG_CalculateTimeFrac( int birth, int life, int delay ) -{ -  float frac; - -  frac = ( (float)cg.time - (float)( birth + delay ) ) / (float)( life - delay ); - -  if( frac < 0.0f ) -    frac = 0.0f; -  else if( frac > 1.0f ) -    frac = 1.0f; - -  return frac; -} - -/* -=============== -CG_EvaluateParticlePhysics - -Compute the physics on a specific particle -=============== -*/ -static void CG_EvaluateParticlePhysics( particle_t *p ) -{ -  particleSystem_t  *ps = p->parent->parent; -  baseParticle_t    *bp = p->class; -  vec3_t            acceleration, newOrigin; -  vec3_t            mins, maxs; -  float             deltaTime, bounce, radius, dot; -  trace_t           trace; -  vec3_t            transform[ 3 ]; - -  if( p->atRest ) -  { -    VectorClear( p->velocity ); -    return; -  } - -  switch( bp->accMoveType ) -  { -    case PMT_STATIC: -      if( bp->accMoveValues.dirType == PMD_POINT ) -        VectorSubtract( bp->accMoveValues.point, p->origin, acceleration ); -      else if( bp->accMoveValues.dirType == PMD_LINEAR ) -        VectorCopy( bp->accMoveValues.dir, acceleration ); - -      break; - -    case PMT_STATIC_TRANSFORM: -      if( !CG_AttachmentAxis( &ps->attachment, transform ) ) -      { -        CG_Printf( S_COLOR_RED "ERROR: a particle with accelerationType " -            "static_transform is not attached to something which can " -            "provide a transformation\n" ); -        return; -      } - -      if( bp->accMoveValues.dirType == PMD_POINT ) -      { -        vec3_t transPoint; - -        VectorMatrixMultiply( bp->accMoveValues.point, transform, transPoint ); -        VectorSubtract( transPoint, p->origin, acceleration ); -      } -      else if( bp->accMoveValues.dirType == PMD_LINEAR ) -        VectorMatrixMultiply( bp->accMoveValues.dir, transform, acceleration ); -      break; - -    case PMT_TAG: -    case PMT_CENT_ANGLES: -      if( bp->accMoveValues.dirType == PMD_POINT ) -      { -        vec3_t point; - -        if( !CG_AttachmentPoint( &ps->attachment, point ) ) -          return; - -        VectorSubtract( point, p->origin, acceleration ); -      } -      else if( bp->accMoveValues.dirType == PMD_LINEAR ) -      { -        if( !CG_AttachmentDir( &ps->attachment, acceleration ) ) -          return; -      } -      break; - -    case PMT_NORMAL: -      if( !ps->normalValid ) -        return; - -      VectorCopy( ps->normal, acceleration ); - -      break; -  } - -#define MAX_ACC_RADIUS 1000.0f - -  if( bp->accMoveValues.dirType == PMD_POINT ) -  { -    //FIXME: so this fall off is a bit... odd -- it works.. -    float r2 = DotProduct( acceleration, acceleration ); // = radius^2 -    float scale = ( MAX_ACC_RADIUS - r2 ) / MAX_ACC_RADIUS; - -    if( scale > 1.0f ) -      scale = 1.0f; -    else if( scale < 0.1f ) -      scale = 0.1f; - -    scale *= CG_RandomiseValue( bp->accMoveValues.mag, bp->accMoveValues.magRandFrac ); - -    VectorNormalize( acceleration ); -    CG_SpreadVector( acceleration, bp->accMoveValues.dirRandAngle ); -    VectorScale( acceleration, scale, acceleration ); -  } -  else if( bp->accMoveValues.dirType == PMD_LINEAR ) -  { -    VectorNormalize( acceleration ); -    CG_SpreadVector( acceleration, bp->accMoveValues.dirRandAngle ); -    VectorScale( acceleration, -                 CG_RandomiseValue( bp->accMoveValues.mag, bp->accMoveValues.magRandFrac ), -                 acceleration ); -  } - -  radius = CG_LerpValues( p->radius.initial, -                 p->radius.final, -                 CG_CalculateTimeFrac( p->birthTime, -                                       p->lifeTime, -                                       p->radius.delay ) ); - -  VectorSet( mins, -radius, -radius, -radius ); -  VectorSet( maxs, radius, radius, radius ); - -  bounce = CG_RandomiseValue( bp->bounceFrac, bp->bounceFracRandFrac ); - -  deltaTime = (float)( cg.time - p->lastEvalTime ) * 0.001; -  VectorMA( p->velocity, deltaTime, acceleration, p->velocity ); -  VectorMA( p->origin, deltaTime, p->velocity, newOrigin ); -  p->lastEvalTime = cg.time; - -  CG_Trace( &trace, p->origin, mins, maxs, newOrigin, -      CG_AttachmentCentNum( &ps->attachment ), CONTENTS_SOLID ); - -  //not hit anything or not a collider -  if( trace.fraction == 1.0f || bounce == 0.0f ) -  { -    VectorCopy( newOrigin, p->origin ); -    return; -  } - -  //remove particles that get into a CONTENTS_NODROP brush -  if( ( trap_CM_PointContents( trace.endpos, 0 ) & CONTENTS_NODROP ) || -      ( bp->cullOnStartSolid && trace.startsolid ) ) -  { -    CG_DestroyParticle( p, NULL ); -    return; -  } -  else if( bp->bounceCull ) -  { -    CG_DestroyParticle( p, trace.plane.normal ); -    return; -  } - -  //reflect the velocity on the trace plane -  dot = DotProduct( p->velocity, trace.plane.normal ); -  VectorMA( p->velocity, -2.0f * dot, trace.plane.normal, p->velocity ); - -  VectorScale( p->velocity, bounce, p->velocity ); - -  if( trace.plane.normal[ 2 ] > 0.5f && -      ( p->velocity[ 2 ] < 40.0f || -        p->velocity[ 2 ] < -cg.frametime * p->velocity[ 2 ] ) ) -    p->atRest = qtrue; - -  if( bp->bounceMarkName[ 0 ] && p->bounceMarkCount > 0 ) -  { -    CG_ImpactMark( bp->bounceMark, trace.endpos, trace.plane.normal, -        random( ) * 360, 1, 1, 1, 1, qtrue, bp->bounceMarkRadius, qfalse ); -    p->bounceMarkCount--; -  } - -  if( bp->bounceSoundName[ 0 ] && p->bounceSoundCount > 0 ) -  { -    trap_S_StartSound( trace.endpos, ENTITYNUM_WORLD, CHAN_AUTO, bp->bounceSound ); -    p->bounceSoundCount--; -  } - -  VectorCopy( trace.endpos, p->origin ); -} - - -#define GETKEY(x,y) (((x)>>y)&0xFF) - -/* -=============== -CG_Radix -=============== -*/ -static void CG_Radix( int bits, int size, particle_t **source, particle_t **dest ) -{ -  int count[ 256 ]; -  int index[ 256 ]; -  int i; - -  memset( count, 0, sizeof( count ) ); - -  for( i = 0; i < size; i++ ) -    count[ GETKEY( source[ i ]->sortKey, bits ) ]++; - -  index[ 0 ] = 0; - -  for( i = 1; i < 256; i++ ) -    index[ i ] = index[ i - 1 ] + count[ i - 1 ]; - -  for( i = 0; i < size; i++ ) -    dest[ index[ GETKEY( source[ i ]->sortKey, bits ) ]++ ] = source[ i ]; -} - -/* -=============== -CG_RadixSort - -Radix sort with 4 byte size buckets -=============== -*/ -static void CG_RadixSort( particle_t **source, particle_t **temp, int size ) -{ -  CG_Radix( 0,   size, source, temp ); -  CG_Radix( 8,   size, temp, source ); -  CG_Radix( 16,  size, source, temp ); -  CG_Radix( 24,  size, temp, source ); -} - -/* -=============== -CG_CompactAndSortParticles - -Depth sort the particles -=============== -*/ -static void CG_CompactAndSortParticles( void ) -{ -  int     i, j = 0; -  int     numParticles; -  vec3_t  delta; - -  for( i = 0; i < MAX_PARTICLES; i++ ) -    sortedParticles[ i ] = &particles[ i ]; - -  for( i = MAX_PARTICLES - 1; i >= 0; i-- ) -  { -    if( sortedParticles[ i ]->valid ) -    { -      //find the first hole -      while( sortedParticles[ j ]->valid ) -        j++; - -      //no more holes -      if( j >= i ) -        break; - -      sortedParticles[ j ] = sortedParticles[ i ]; -    } -  } - -  numParticles = i; - -  //set sort keys -  for( i = 0; i < numParticles; i++ ) -  { -    VectorSubtract( sortedParticles[ i ]->origin, cg.refdef.vieworg, delta ); -    sortedParticles[ i ]->sortKey = (int)DotProduct( delta, delta ); -  } - -  CG_RadixSort( sortedParticles, radixBuffer, numParticles ); - -  //FIXME: wtf? -  //reverse order of particles array -  for( i = 0; i < numParticles; i++ ) -    radixBuffer[ i ] = sortedParticles[ numParticles - i - 1 ]; - -  for( i = 0; i < numParticles; i++ ) -    sortedParticles[ i ] = radixBuffer[ i ]; -} - -/* -=============== -CG_RenderParticle - -Actually render a particle -=============== -*/ -static void CG_RenderParticle( particle_t *p ) -{ -  refEntity_t           re; -  float                 timeFrac, scale; -  int                   index; -  baseParticle_t        *bp = p->class; -  particleSystem_t      *ps = p->parent->parent; -  baseParticleSystem_t  *bps = ps->class; -  vec3_t                alight, dlight, lightdir; -  int                   i; -  vec3_t                up = { 0.0f, 0.0f, 1.0f }; - -  memset( &re, 0, sizeof( refEntity_t ) ); - -  timeFrac = CG_CalculateTimeFrac( p->birthTime, p->lifeTime, 0 ); - -  scale = CG_LerpValues( p->radius.initial, -                    p->radius.final, -                    CG_CalculateTimeFrac( p->birthTime, -                                          p->lifeTime, -                                          p->radius.delay ) ); - -  re.shaderTime = p->birthTime / 1000.0f; - -  if( bp->numFrames )       //shader based -  { -    re.reType = RT_SPRITE; - -    //apply environmental lighting to the particle -    if( bp->realLight ) -    { -      trap_R_LightForPoint( p->origin, alight, dlight, lightdir ); -      for( i = 0; i <= 2; i++ ) -        re.shaderRGBA[ i ] = (byte)alight[ i ]; -    } -    else -    { -      vec3_t  colorRange; - -      VectorSubtract( bp->finalColor, -          bp->initialColor, colorRange ); - -      VectorMA( bp->initialColor, -          CG_CalculateTimeFrac( p->birthTime, -            p->lifeTime, -            p->colorDelay ), -          colorRange, re.shaderRGBA ); -    } - -    re.shaderRGBA[ 3 ] = (byte)( (float)0xFF * -                         CG_LerpValues( p->alpha.initial, -                               p->alpha.final, -                               CG_CalculateTimeFrac( p->birthTime, -                                                     p->lifeTime, -                                                     p->alpha.delay ) ) ); - -    re.radius = scale; - -    re.rotation = CG_LerpValues( p->rotation.initial, -                        p->rotation.final, -                        CG_CalculateTimeFrac( p->birthTime, -                                              p->lifeTime, -                                              p->rotation.delay ) ); - -    // if the view would be "inside" the sprite, kill the sprite -    // so it doesn't add too much overdraw -    if( Distance( p->origin, cg.refdef.vieworg ) < re.radius && bp->overdrawProtection ) -      return; - -    if( bp->framerate == 0.0f ) -    { -      //sync animation time to lifeTime of particle -      index = (int)( timeFrac * ( bp->numFrames + 1 ) ); - -      if( index >= bp->numFrames ) -        index = bp->numFrames - 1; - -      re.customShader = bp->shaders[ index ]; -    } -    else -    { -      //looping animation -      index = (int)( bp->framerate * timeFrac * p->lifeTime * 0.001 ) % bp->numFrames; -      re.customShader = bp->shaders[ index ]; -    } - -  } -  else if( bp->numModels )  //model based -  { -    re.reType = RT_MODEL; - -    re.hModel = p->model; - -    if( p->atRest ) -      AxisCopy( p->lastAxis, re.axis ); -    else -    { -      // convert direction of travel into axis -      VectorNormalize2( p->velocity, re.axis[ 0 ] ); - -      if( re.axis[ 0 ][ 0 ] == 0.0f && re.axis[ 0 ][ 1 ] == 0.0f ) -        AxisCopy( axisDefault, re.axis ); -      else -      { -        ProjectPointOnPlane( re.axis[ 2 ], up, re.axis[ 0 ] ); -        VectorNormalize( re.axis[ 2 ] ); -        CrossProduct( re.axis[ 2 ], re.axis[ 0 ], re.axis[ 1 ] ); -      } - -      AxisCopy( re.axis, p->lastAxis ); -    } - -    if( scale != 1.0f ) -    { -      VectorScale( re.axis[ 0 ], scale, re.axis[ 0 ] ); -      VectorScale( re.axis[ 1 ], scale, re.axis[ 1 ] ); -      VectorScale( re.axis[ 2 ], scale, re.axis[ 2 ] ); -      re.nonNormalizedAxes = qtrue; -    } -    else -      re.nonNormalizedAxes = qfalse; - -    p->lf.animation = &bp->modelAnimation; - -    //run animation -    CG_RunLerpFrame( &p->lf ); - -    re.oldframe = p->lf.oldFrame; -    re.frame    = p->lf.frame; -    re.backlerp = p->lf.backlerp; -  } - -  if( bps->thirdPersonOnly && -      CG_AttachmentCentNum( &ps->attachment ) == cg.snap->ps.clientNum && -      !cg.renderingThirdPerson ) -    re.renderfx |= RF_THIRD_PERSON; - -  if( bp->dynamicLight && !( re.renderfx & RF_THIRD_PERSON ) ) -  { -    trap_R_AddLightToScene( p->origin, -      CG_LerpValues( p->dLightRadius.initial, p->dLightRadius.final, -        CG_CalculateTimeFrac( p->birthTime, p->lifeTime, p->dLightRadius.delay ) ), -        (float)bp->dLightColor[ 0 ] / (float)0xFF, -        (float)bp->dLightColor[ 1 ] / (float)0xFF, -        (float)bp->dLightColor[ 2 ] / (float)0xFF ); -  } - -  VectorCopy( p->origin, re.origin ); - -  trap_R_AddRefEntityToScene( &re ); -} - -/* -=============== -CG_AddParticles - -Add particles to the scene -=============== -*/ -void CG_AddParticles( void ) -{ -  int           i; -  particle_t    *p; -  int           numPS = 0, numPE = 0, numP = 0; - -  //remove expired particle systems -  CG_GarbageCollectParticleSystems( ); - -  //check each ejector and introduce any new particles -  CG_SpawnNewParticles( ); - -  //sorting -  if( cg_depthSortParticles.integer ) -    CG_CompactAndSortParticles( ); - -  for( i = 0; i < MAX_PARTICLES; i++ ) -  { -    p = sortedParticles[ i ]; - -    if( p->valid ) -    { -      if( p->birthTime + p->lifeTime > cg.time ) -      { -        //particle is active -        CG_EvaluateParticlePhysics( p ); -        CG_RenderParticle( p ); -      } -      else -        CG_DestroyParticle( p, NULL ); -    } -  } - -  if( cg_debugParticles.integer >= 2 ) -  { -    for( i = 0; i < MAX_PARTICLE_SYSTEMS; i++ ) -      if( particleSystems[ i ].valid ) -        numPS++; - -    for( i = 0; i < MAX_PARTICLE_EJECTORS; i++ ) -      if( particleEjectors[ i ].valid ) -        numPE++; - -    for( i = 0; i < MAX_PARTICLES; i++ ) -      if( particles[ i ].valid ) -        numP++; - -    CG_Printf( "PS: %d  PE: %d  P: %d\n", numPS, numPE, numP ); -  } -} - -/* -=============== -CG_ParticleSystemEntity - -Particle system entity client code -=============== -*/ -void CG_ParticleSystemEntity( centity_t *cent ) -{ -  entityState_t *es; - -  es = ¢->currentState; - -  if( es->eFlags & EF_NODRAW ) -  { -    if( CG_IsParticleSystemValid( ¢->entityPS ) && CG_IsParticleSystemInfinite( cent->entityPS ) ) -      CG_DestroyParticleSystem( ¢->entityPS ); - -    return; -  } - -  if( !CG_IsParticleSystemValid( ¢->entityPS ) && !cent->entityPSMissing ) -  { -    cent->entityPS = CG_SpawnNewParticleSystem( cgs.gameParticleSystems[ es->modelindex ] ); - -    if( CG_IsParticleSystemValid( ¢->entityPS ) ) -    { -      CG_SetAttachmentPoint( ¢->entityPS->attachment, cent->lerpOrigin ); -      CG_SetAttachmentCent( ¢->entityPS->attachment, cent ); -      CG_AttachToPoint( ¢->entityPS->attachment ); -    } -    else -      cent->entityPSMissing = qtrue; -  } -} - -static particleSystem_t *testPS; -static qhandle_t        testPSHandle; - -/* -=============== -CG_DestroyTestPS_f - -Destroy the test a particle system -=============== -*/ -void CG_DestroyTestPS_f( void ) -{ -  if( CG_IsParticleSystemValid( &testPS ) ) -    CG_DestroyParticleSystem( &testPS ); -} - -/* -=============== -CG_TestPS_f - -Test a particle system -=============== -*/ -void CG_TestPS_f( void ) -{ -  vec3_t  origin; -  vec3_t  up = { 0.0f, 0.0f, 1.0f }; -  char    psName[ MAX_QPATH ]; - -  if( trap_Argc( ) < 2 ) -    return; - -  Q_strncpyz( psName, CG_Argv( 1 ), MAX_QPATH ); -  testPSHandle = CG_RegisterParticleSystem( psName ); - -  if( testPSHandle ) -  { -    CG_DestroyTestPS_f( ); - -    testPS = CG_SpawnNewParticleSystem( testPSHandle ); - -    VectorMA( cg.refdef.vieworg, 100, cg.refdef.viewaxis[ 0 ], origin ); - -    if( CG_IsParticleSystemValid( &testPS ) ) -    { -      CG_SetAttachmentPoint( &testPS->attachment, origin ); -      CG_SetParticleSystemNormal( testPS, up ); -      CG_AttachToPoint( &testPS->attachment ); -    } -  } -} diff --git a/mod/src/cgame/cg_players.c b/mod/src/cgame/cg_players.c deleted file mode 100644 index ac1ec181..00000000 --- a/mod/src/cgame/cg_players.c +++ /dev/null @@ -1,2575 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_players.c -- handle the media and animation for player entities - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -char *cg_customSoundNames[ MAX_CUSTOM_SOUNDS ] = -{ -  "*death1.wav", -  "*death2.wav", -  "*death3.wav", -  "*jump1.wav", -  "*pain25_1.wav", -  "*pain50_1.wav", -  "*pain75_1.wav", -  "*pain100_1.wav", -  "*falling1.wav", -  "*gasp.wav", -  "*drown.wav", -  "*fall1.wav", -  "*taunt.wav" -}; - - -/* -================ -CG_CustomSound - -================ -*/ -sfxHandle_t CG_CustomSound( int clientNum, const char *soundName ) -{ -  clientInfo_t  *ci; -  int           i; - -  if( soundName[ 0 ] != '*' ) -    return trap_S_RegisterSound( soundName, qfalse ); - -  if( clientNum < 0 || clientNum >= MAX_CLIENTS ) -    clientNum = 0; - -  ci = &cgs.clientinfo[ clientNum ]; - -  for( i = 0; i < MAX_CUSTOM_SOUNDS && cg_customSoundNames[ i ]; i++ ) -  { -    if( !strcmp( soundName, cg_customSoundNames[ i ] ) ) -      return ci->sounds[ i ]; -  } - -  CG_Error( "Unknown custom sound: %s", soundName ); -  return 0; -} - - - -/* -============================================================================= - -CLIENT INFO - -============================================================================= -*/ - -/* -====================== -CG_ParseAnimationFile - -Read a configuration file containing animation coutns and rates -models/players/visor/animation.cfg, etc -====================== -*/ -static qboolean CG_ParseAnimationFile( const char *filename, clientInfo_t *ci ) -{ -  char          *text_p, *prev; -  int           len; -  int           i; -  char          *token; -  float         fps; -  int           skip; -  char          text[ 20000 ]; -  fileHandle_t  f; -  animation_t   *animations; - -  animations = ci->animations; - -  // load the file -  len = trap_FS_FOpenFile( filename, &f, FS_READ ); -  if( len <= 0 ) -    return qfalse; - -  if( len >= sizeof( text ) - 1 ) -  { -    CG_Printf( "File %s too long\n", filename ); -    trap_FS_FCloseFile( f ); -    return qfalse; -  } - -  trap_FS_Read( text, len, f ); -  text[ len ] = 0; -  trap_FS_FCloseFile( f ); - -  // parse the text -  text_p = text; -  skip = 0; // quite the compiler warning - -  ci->footsteps = FOOTSTEP_NORMAL; -  VectorClear( ci->headOffset ); -  ci->gender = GENDER_MALE; -  ci->fixedlegs = qfalse; -  ci->fixedtorso = qfalse; -  ci->nonsegmented = qfalse; - -  // read optional parameters -  while( 1 ) -  { -    prev = text_p;  // so we can unget -    token = COM_Parse( &text_p ); - -    if( !token ) -      break; - -    if( !Q_stricmp( token, "footsteps" ) ) -    { -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      if( !Q_stricmp( token, "default" ) || !Q_stricmp( token, "normal" ) ) -        ci->footsteps = FOOTSTEP_NORMAL; -      else if( !Q_stricmp( token, "boot" ) ) -        ci->footsteps = FOOTSTEP_BOOT; -      else if( !Q_stricmp( token, "flesh" ) ) -        ci->footsteps = FOOTSTEP_FLESH; -      else if( !Q_stricmp( token, "mech" ) ) -        ci->footsteps = FOOTSTEP_MECH; -      else if( !Q_stricmp( token, "energy" ) ) -        ci->footsteps = FOOTSTEP_ENERGY; -      else if( !Q_stricmp( token, "none" ) ) -        ci->footsteps = FOOTSTEP_NONE; -      else if( !Q_stricmp( token, "custom" ) ) -        ci->footsteps = FOOTSTEP_CUSTOM; -      else -        CG_Printf( "Bad footsteps parm in %s: %s\n", filename, token ); - -      continue; -    } -    else if( !Q_stricmp( token, "headoffset" ) ) -    { -      for( i = 0 ; i < 3 ; i++ ) -      { -        token = COM_Parse( &text_p ); -        if( !token ) -          break; - -        ci->headOffset[ i ] = atof( token ); -      } - -      continue; -    } -    else if( !Q_stricmp( token, "sex" ) ) -    { -      token = COM_Parse( &text_p ); - -      if( !token ) -        break; - -      if( token[ 0 ] == 'f' || token[ 0 ] == 'F' ) -        ci->gender = GENDER_FEMALE; -      else if( token[ 0 ] == 'n' || token[ 0 ] == 'N' ) -        ci->gender = GENDER_NEUTER; -      else -        ci->gender = GENDER_MALE; - -      continue; -    } -    else if( !Q_stricmp( token, "fixedlegs" ) ) -    { -      ci->fixedlegs = qtrue; -      continue; -    } -    else if( !Q_stricmp( token, "fixedtorso" ) ) -    { -      ci->fixedtorso = qtrue; -      continue; -    } -    else if( !Q_stricmp( token, "nonsegmented" ) ) -    { -      ci->nonsegmented = qtrue; -      continue; -    } - -    // if it is a number, start parsing animations -    if( token[ 0 ] >= '0' && token[ 0 ] <= '9' ) -    { -      text_p = prev;  // unget the token -      break; -    } - -    Com_Printf( "unknown token '%s' is %s\n", token, filename ); -  } - -  if( !ci->nonsegmented ) -  { -    // read information for each frame -    for( i = 0; i < MAX_PLAYER_ANIMATIONS; i++ ) -    { -      token = COM_Parse( &text_p ); - -      if( !*token ) -      { -        if( i >= TORSO_GETFLAG && i <= TORSO_NEGATIVE ) -        { -          animations[ i ].firstFrame = animations[ TORSO_GESTURE ].firstFrame; -          animations[ i ].frameLerp = animations[ TORSO_GESTURE ].frameLerp; -          animations[ i ].initialLerp = animations[ TORSO_GESTURE ].initialLerp; -          animations[ i ].loopFrames = animations[ TORSO_GESTURE ].loopFrames; -          animations[ i ].numFrames = animations[ TORSO_GESTURE ].numFrames; -          animations[ i ].reversed = qfalse; -          animations[ i ].flipflop = qfalse; -          continue; -        } - -        break; -      } - -      animations[ i ].firstFrame = atoi( token ); - -      // leg only frames are adjusted to not count the upper body only frames -      if( i == LEGS_WALKCR ) -        skip = animations[ LEGS_WALKCR ].firstFrame - animations[ TORSO_GESTURE ].firstFrame; - -      if( i >= LEGS_WALKCR && i<TORSO_GETFLAG ) -        animations[ i ].firstFrame -= skip; - -      token = COM_Parse( &text_p ); -      if( !*token ) -        break; - -      animations[ i ].numFrames = atoi( token ); -      animations[ i ].reversed = qfalse; -      animations[ i ].flipflop = qfalse; - -      // if numFrames is negative the animation is reversed -      if( animations[ i ].numFrames < 0 ) -      { -        animations[ i ].numFrames = -animations[ i ].numFrames; -        animations[ i ].reversed = qtrue; -      } - -      token = COM_Parse( &text_p ); - -      if( !*token ) -        break; - -      animations[ i ].loopFrames = atoi( token ); - -      token = COM_Parse( &text_p ); - -      if( !*token ) -        break; - -      fps = atof( token ); -      if( fps == 0 ) -        fps = 1; - -      animations[ i ].frameLerp = 1000 / fps; -      animations[ i ].initialLerp = 1000 / fps; -    } - -    if( i != MAX_PLAYER_ANIMATIONS ) -    { -      CG_Printf( "Error parsing animation file: %s", filename ); -      return qfalse; -    } -    // crouch backward animation -    memcpy( &animations[ LEGS_BACKCR ], &animations[ LEGS_WALKCR ], sizeof( animation_t ) ); -    animations[ LEGS_BACKCR ].reversed = qtrue; -    // walk backward animation -    memcpy( &animations[ LEGS_BACKWALK ], &animations[ LEGS_WALK ], sizeof( animation_t ) ); -    animations[ LEGS_BACKWALK ].reversed = qtrue; -    // flag moving fast -    animations[ FLAG_RUN ].firstFrame = 0; -    animations[ FLAG_RUN ].numFrames = 16; -    animations[ FLAG_RUN ].loopFrames = 16; -    animations[ FLAG_RUN ].frameLerp = 1000 / 15; -    animations[ FLAG_RUN ].initialLerp = 1000 / 15; -    animations[ FLAG_RUN ].reversed = qfalse; -    // flag not moving or moving slowly -    animations[ FLAG_STAND ].firstFrame = 16; -    animations[ FLAG_STAND ].numFrames = 5; -    animations[ FLAG_STAND ].loopFrames = 0; -    animations[ FLAG_STAND ].frameLerp = 1000 / 20; -    animations[ FLAG_STAND ].initialLerp = 1000 / 20; -    animations[ FLAG_STAND ].reversed = qfalse; -    // flag speeding up -    animations[ FLAG_STAND2RUN ].firstFrame = 16; -    animations[ FLAG_STAND2RUN ].numFrames = 5; -    animations[ FLAG_STAND2RUN ].loopFrames = 1; -    animations[ FLAG_STAND2RUN ].frameLerp = 1000 / 15; -    animations[ FLAG_STAND2RUN ].initialLerp = 1000 / 15; -    animations[ FLAG_STAND2RUN ].reversed = qtrue; -  } -  else -  { -    // read information for each frame -    for( i = 0; i < MAX_NONSEG_PLAYER_ANIMATIONS; i++ ) -    { -      token = COM_Parse( &text_p ); - -      if( !*token ) -        break; - -      animations[ i ].firstFrame = atoi( token ); - -      token = COM_Parse( &text_p ); -      if( !*token ) -        break; - -      animations[ i ].numFrames = atoi( token ); -      animations[ i ].reversed = qfalse; -      animations[ i ].flipflop = qfalse; - -      // if numFrames is negative the animation is reversed -      if( animations[ i ].numFrames < 0 ) -      { -        animations[ i ].numFrames = -animations[ i ].numFrames; -        animations[ i ].reversed = qtrue; -      } - -      token = COM_Parse( &text_p ); - -      if( !*token ) -        break; - -      animations[ i ].loopFrames = atoi( token ); - -      token = COM_Parse( &text_p ); - -      if( !*token ) -        break; - -      fps = atof( token ); -      if( fps == 0 ) -        fps = 1; - -      animations[ i ].frameLerp = 1000 / fps; -      animations[ i ].initialLerp = 1000 / fps; -    } - -    if( i != MAX_NONSEG_PLAYER_ANIMATIONS ) -    { -      CG_Printf( "Error parsing animation file: %s", filename ); -      return qfalse; -    } - -    // walk backward animation -    memcpy( &animations[ NSPA_WALKBACK ], &animations[ NSPA_WALK ], sizeof( animation_t ) ); -    animations[ NSPA_WALKBACK ].reversed = qtrue; -  } - -  return qtrue; -} - -/* -========================== -CG_RegisterClientSkin -========================== -*/ -static qboolean CG_RegisterClientSkin( clientInfo_t *ci, const char *modelName, const char *skinName ) -{ -  char filename[ MAX_QPATH ]; - -  if( !ci->nonsegmented ) -  { -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower_%s.skin", modelName, skinName ); -    ci->legsSkin = trap_R_RegisterSkin( filename ); -    if( !ci->legsSkin ) -      Com_Printf( "Leg skin load failure: %s\n", filename ); - -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper_%s.skin", modelName, skinName ); -    ci->torsoSkin = trap_R_RegisterSkin( filename ); -    if( !ci->torsoSkin ) -      Com_Printf( "Torso skin load failure: %s\n", filename ); - -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/head_%s.skin", modelName, skinName ); -    ci->headSkin = trap_R_RegisterSkin( filename ); -    if( !ci->headSkin ) -      Com_Printf( "Head skin load failure: %s\n", filename ); - -    if( !ci->legsSkin || !ci->torsoSkin || !ci->headSkin ) -      return qfalse; -  } -  else -  { -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/nonseg_%s.skin", modelName, skinName ); -    ci->nonSegSkin = trap_R_RegisterSkin( filename ); -    if( !ci->nonSegSkin ) -      Com_Printf( "Non-segmented skin load failure: %s\n", filename ); - -    if( !ci->nonSegSkin ) -      return qfalse; -  } - -  return qtrue; -} - -/* -========================== -CG_RegisterClientModelname -========================== -*/ -static qboolean CG_RegisterClientModelname( clientInfo_t *ci, const char *modelName, const char *skinName ) -{ -  char filename[ MAX_QPATH * 2 ]; - -  //TA: do this first so the nonsegmented property is set -  // load the animations -  Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg", modelName ); -  if( !CG_ParseAnimationFile( filename, ci ) ) -  { -    Com_Printf( "Failed to load animation file %s\n", filename ); -    return qfalse; -  } - -  // load cmodels before models so filecache works - -  if( !ci->nonsegmented ) -  { -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower.md3", modelName ); -    ci->legsModel = trap_R_RegisterModel( filename ); -    if( !ci->legsModel ) -    { -      Com_Printf( "Failed to load model file %s\n", filename ); -      return qfalse; -    } - -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper.md3", modelName ); -    ci->torsoModel = trap_R_RegisterModel( filename ); -    if( !ci->torsoModel ) -    { -      Com_Printf( "Failed to load model file %s\n", filename ); -      return qfalse; -    } - -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/head.md3", modelName ); -    ci->headModel = trap_R_RegisterModel( filename ); -    if( !ci->headModel ) -    { -      Com_Printf( "Failed to load model file %s\n", filename ); -      return qfalse; -    } -  } -  else -  { -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/nonseg.md3", modelName ); -    ci->nonSegModel = trap_R_RegisterModel( filename ); -    if( !ci->nonSegModel ) -    { -      Com_Printf( "Failed to load model file %s\n", filename ); -      return qfalse; -    } -  } - -  // if any skins failed to load, return failure -  if( !CG_RegisterClientSkin( ci, modelName, skinName ) ) -  { -    Com_Printf( "Failed to load skin file: %s : %s\n", modelName, skinName ); -    return qfalse; -  } - -  //FIXME: skins do not load without icon present. do we want icons anyway? -/*  Com_sprintf( filename, sizeof( filename ), "models/players/%s/icon_%s.tga", modelName, skinName ); -  ci->modelIcon = trap_R_RegisterShaderNoMip( filename ); -  if( !ci->modelIcon ) -  { -    Com_Printf( "Failed to load icon file: %s\n", filename ); -    return qfalse; -  }*/ - -  return qtrue; -} - -/* -==================== -CG_ColorFromString -==================== -*/ -static void CG_ColorFromString( const char *v, vec3_t color ) -{ -  int val; - -  VectorClear( color ); - -  val = atoi( v ); - -  if( val < 1 || val > 7 ) -  { -    VectorSet( color, 1, 1, 1 ); -    return; -  } - -  if( val & 1 ) -    color[ 2 ] = 1.0f; - -  if( val & 2 ) -    color[ 1 ] = 1.0f; - -  if( val & 4 ) -    color[ 0 ] = 1.0f; -} - - -/* -=================== -CG_LoadClientInfo - -Load it now, taking the disk hits -=================== -*/ -static void CG_LoadClientInfo( clientInfo_t *ci ) -{ -  const char  *dir, *fallback; -  int         i; -  const char  *s; -  int         clientNum; - -  if( !CG_RegisterClientModelname( ci, ci->modelName, ci->skinName ) ) -  { -    if( cg_buildScript.integer ) -      CG_Error( "CG_RegisterClientModelname( %s, %s ) failed", ci->modelName, ci->skinName ); - -    // fall back -    if( !CG_RegisterClientModelname( ci, DEFAULT_MODEL, "default" ) ) -      CG_Error( "DEFAULT_MODEL (%s) failed to register", DEFAULT_MODEL ); -  } - -  // sounds -  dir = ci->modelName; -  fallback = DEFAULT_MODEL; - -  for( i = 0; i < MAX_CUSTOM_SOUNDS; i++ ) -  { -    s = cg_customSoundNames[ i ]; - -    if( !s ) -      break; - -    // fanny about a bit with sounds that are missing -    if( !CG_FileExists( va( "sound/player/%s/%s", dir, s + 1 ) ) ) -    { -      //file doesn't exist - -      if( i == 11 || i == 8 ) //fall or falling -      { -        ci->sounds[ i ] = trap_S_RegisterSound( "sound/null.wav", qfalse ); -      } -      else -      { -        if( i == 9 ) //gasp -          s = cg_customSoundNames[ 7 ]; //pain100_1 -        else if( i == 10 ) //drown -          s = cg_customSoundNames[ 0 ]; //death1 - -        ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", dir, s + 1 ), qfalse ); -        if( !ci->sounds[ i ] ) -          ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", fallback, s + 1 ), qfalse ); -      } -    } -    else -    { -      ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", dir, s + 1 ), qfalse ); -      if( !ci->sounds[ i ] ) -        ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", fallback, s + 1 ), qfalse ); -    } -  } - -  if( ci->footsteps == FOOTSTEP_CUSTOM ) -  { -    for( i = 0; i < 4; i++ ) -    { -      ci->customFootsteps[ i ] = trap_S_RegisterSound( va( "sound/player/%s/step%d.wav", dir, i + 1 ), qfalse ); -      if( !ci->customFootsteps[ i ] ) -        ci->customFootsteps[ i ] = trap_S_RegisterSound( va( "sound/player/footsteps/step%d.wav", i + 1 ), qfalse ); - -      ci->customMetalFootsteps[ i ] = trap_S_RegisterSound( va( "sound/player/%s/clank%d.wav", dir, i + 1 ), qfalse ); -      if( !ci->customMetalFootsteps[ i ] ) -        ci->customMetalFootsteps[ i ] = trap_S_RegisterSound( va( "sound/player/footsteps/clank%d.wav", i + 1 ), qfalse ); -    } -  } - -  // reset any existing players and bodies, because they might be in bad -  // frames for this new model -  clientNum = ci - cgs.clientinfo; -  for( i = 0; i < MAX_GENTITIES; i++ ) -  { -    if( cg_entities[ i ].currentState.clientNum == clientNum && -        cg_entities[ i ].currentState.eType == ET_PLAYER ) -      CG_ResetPlayerEntity( &cg_entities[ i ] ); -  } -} - -/* -====================== -CG_CopyClientInfoModel -====================== -*/ -static void CG_CopyClientInfoModel( clientInfo_t *from, clientInfo_t *to ) -{ -  VectorCopy( from->headOffset, to->headOffset ); -  to->footsteps = from->footsteps; -  to->gender = from->gender; - -  to->legsModel = from->legsModel; -  to->legsSkin = from->legsSkin; -  to->torsoModel = from->torsoModel; -  to->torsoSkin = from->torsoSkin; -  to->headModel = from->headModel; -  to->headSkin = from->headSkin; -  to->nonSegModel = from->nonSegModel; -  to->nonSegSkin = from->nonSegSkin; -  to->nonsegmented = from->nonsegmented; -  to->modelIcon = from->modelIcon; - -  memcpy( to->animations, from->animations, sizeof( to->animations ) ); -  memcpy( to->sounds, from->sounds, sizeof( to->sounds ) ); -  memcpy( to->customFootsteps, from->customFootsteps, sizeof( to->customFootsteps ) ); -  memcpy( to->customMetalFootsteps, from->customMetalFootsteps, sizeof( to->customMetalFootsteps ) ); -} - - -/* -====================== -CG_GetCorpseNum -====================== -*/ -static int CG_GetCorpseNum( pClass_t class ) -{ -  int           i; -  clientInfo_t  *match; -  char          *modelName; -  char          *skinName; - -  modelName = BG_FindModelNameForClass( class ); -  skinName = BG_FindSkinNameForClass( class ); - -  for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ ) -  { -    match = &cgs.corpseinfo[ i ]; - -    if( !match->infoValid ) -      continue; - -    if( !Q_stricmp( modelName, match->modelName ) -      && !Q_stricmp( skinName, match->skinName ) ) -    { -      // this clientinfo is identical, so use it's handles -      return i; -    } -  } - -  //something has gone horribly wrong -  return -1; -} - - -/* -====================== -CG_ScanForExistingClientInfo -====================== -*/ -static qboolean CG_ScanForExistingClientInfo( clientInfo_t *ci ) -{ -  int   i; -  clientInfo_t  *match; - -  for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ ) -  { -    match = &cgs.corpseinfo[ i ]; - -    if( !match->infoValid ) -      continue; - -    if( !Q_stricmp( ci->modelName, match->modelName ) && -        !Q_stricmp( ci->skinName, match->skinName ) ) -    { -      // this clientinfo is identical, so use it's handles -      CG_CopyClientInfoModel( match, ci ); - -      return qtrue; -    } -  } - -  //TA: shouldn't happen -  return qfalse; -} - - -/* -====================== -CG_PrecacheClientInfo -====================== -*/ -void CG_PrecacheClientInfo( pClass_t class, char *model, char *skin ) -{ -  clientInfo_t  *ci; -  clientInfo_t  newInfo; - -  ci = &cgs.corpseinfo[ class ]; - -  // the old value -  memset( &newInfo, 0, sizeof( newInfo ) ); - -  // model -  Q_strncpyz( newInfo.modelName, model, sizeof( newInfo.modelName ) ); -  Q_strncpyz( newInfo.headModelName, model, sizeof( newInfo.headModelName ) ); - -  // modelName didn not include a skin name -  if( !skin ) -  { -    Q_strncpyz( newInfo.skinName, "default", sizeof( newInfo.skinName ) ); -    Q_strncpyz( newInfo.headSkinName, "default", sizeof( newInfo.headSkinName ) ); -  } -  else -  { -    Q_strncpyz( newInfo.skinName, skin, sizeof( newInfo.skinName ) ); -    Q_strncpyz( newInfo.headSkinName, skin, sizeof( newInfo.headSkinName ) ); -  } - -  newInfo.infoValid = qtrue; - -  //TA: actually register the models -  *ci = newInfo; -  CG_LoadClientInfo( ci ); -} - - -/* -====================== -CG_NewClientInfo -====================== -*/ -void CG_NewClientInfo( int clientNum ) -{ -  clientInfo_t  *ci; -  clientInfo_t  newInfo; -  const char    *configstring; -  const char    *v; -  char          *slash; - -  ci = &cgs.clientinfo[ clientNum ]; - -  configstring = CG_ConfigString( clientNum + CS_PLAYERS ); -  if( !configstring[ 0 ] ) -  { -    memset( ci, 0, sizeof( *ci ) ); -    return;   // player just left -  } - -  // the old value -  memset( &newInfo, 0, sizeof( newInfo ) ); - -  // isolate the player's name -  v = Info_ValueForKey( configstring, "n" ); -  Q_strncpyz( newInfo.name, v, sizeof( newInfo.name ) ); - -  // colors -  v = Info_ValueForKey( configstring, "c1" ); -  CG_ColorFromString( v, newInfo.color1 ); - -  v = Info_ValueForKey( configstring, "c2" ); -  CG_ColorFromString( v, newInfo.color2 ); - -  // bot skill -  v = Info_ValueForKey( configstring, "skill" ); -  newInfo.botSkill = atoi( v ); - -  // handicap -  v = Info_ValueForKey( configstring, "hc" ); -  newInfo.handicap = atoi( v ); - -  // wins -  v = Info_ValueForKey( configstring, "w" ); -  newInfo.wins = atoi( v ); - -  // losses -  v = Info_ValueForKey( configstring, "l" ); -  newInfo.losses = atoi( v ); - -  // team -  v = Info_ValueForKey( configstring, "t" ); -  newInfo.team = atoi( v ); - -  // team task -  v = Info_ValueForKey( configstring, "tt" ); -  newInfo.teamTask = atoi( v ); - -  // team leader -  v = Info_ValueForKey( configstring, "tl" ); -  newInfo.teamLeader = atoi( v ); - -  v = Info_ValueForKey( configstring, "g_redteam" ); -  Q_strncpyz( newInfo.redTeam, v, MAX_TEAMNAME ); - -  v = Info_ValueForKey( configstring, "g_blueteam" ); -  Q_strncpyz( newInfo.blueTeam, v, MAX_TEAMNAME ); - -  // model -  v = Info_ValueForKey( configstring, "model" ); -  Q_strncpyz( newInfo.modelName, v, sizeof( newInfo.modelName ) ); - -  slash = strchr( newInfo.modelName, '/' ); - -  if( !slash ) -  { -    // modelName didn not include a skin name -    Q_strncpyz( newInfo.skinName, "default", sizeof( newInfo.skinName ) ); -  } -  else -  { -    Q_strncpyz( newInfo.skinName, slash + 1, sizeof( newInfo.skinName ) ); -    // truncate modelName -    *slash = 0; -  } - -  //CG_Printf( "NCI: %s\n", v ); - -  // head model -  v = Info_ValueForKey( configstring, "hmodel" ); -  Q_strncpyz( newInfo.headModelName, v, sizeof( newInfo.headModelName ) ); - -  slash = strchr( newInfo.headModelName, '/' ); - -  if( !slash ) -  { -    // modelName didn not include a skin name -    Q_strncpyz( newInfo.headSkinName, "default", sizeof( newInfo.headSkinName ) ); -  } -  else -  { -    Q_strncpyz( newInfo.headSkinName, slash + 1, sizeof( newInfo.headSkinName ) ); -    // truncate modelName -    *slash = 0; -  } - -  // replace whatever was there with the new one -  newInfo.infoValid = qtrue; -  *ci = newInfo; - -  // scan for an existing clientinfo that matches this modelname -  // so we can avoid loading checks if possible -  if( !CG_ScanForExistingClientInfo( ci ) ) -    CG_LoadClientInfo( ci ); -} - - - -/* -============================================================================= - -PLAYER ANIMATION - -============================================================================= -*/ - - -/* -=============== -CG_SetLerpFrameAnimation - -may include ANIM_TOGGLEBIT -=============== -*/ -static void CG_SetLerpFrameAnimation( clientInfo_t *ci, lerpFrame_t *lf, int newAnimation ) -{ -  animation_t *anim; - -  lf->animationNumber = newAnimation; -  newAnimation &= ~ANIM_TOGGLEBIT; - -  if( newAnimation < 0 || newAnimation >= MAX_PLAYER_TOTALANIMATIONS ) -    CG_Error( "Bad animation number: %i", newAnimation ); - -  anim = &ci->animations[ newAnimation ]; - -  lf->animation = anim; -  lf->animationTime = lf->frameTime + anim->initialLerp; - -  if( cg_debugAnim.integer ) -    CG_Printf( "Anim: %i\n", newAnimation ); -} - -/* -=============== -CG_RunPlayerLerpFrame - -Sets cg.snap, cg.oldFrame, and cg.backlerp -cg.time should be between oldFrameTime and frameTime after exit -=============== -*/ -static void CG_RunPlayerLerpFrame( clientInfo_t *ci, lerpFrame_t *lf, int newAnimation, float speedScale ) -{ -  int         f, numFrames; -  animation_t *anim; - -  // debugging tool to get no animations -  if( cg_animSpeed.integer == 0 ) -  { -    lf->oldFrame = lf->frame = lf->backlerp = 0; -    return; -  } - -  // see if the animation sequence is switching -  if( newAnimation != lf->animationNumber || !lf->animation ) -  { -    CG_SetLerpFrameAnimation( ci, lf, newAnimation ); -  } - -  // if we have passed the current frame, move it to -  // oldFrame and calculate a new frame -  if( cg.time >= lf->frameTime ) -  { -    lf->oldFrame = lf->frame; -    lf->oldFrameTime = lf->frameTime; - -    // get the next frame based on the animation -    anim = lf->animation; -    if( !anim->frameLerp ) -      return;   // shouldn't happen - -    if( cg.time < lf->animationTime ) -      lf->frameTime = lf->animationTime;    // initial lerp -    else -      lf->frameTime = lf->oldFrameTime + anim->frameLerp; - -    f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp; -    f *= speedScale;    // adjust for haste, etc -    numFrames = anim->numFrames; - -    if( anim->flipflop ) -      numFrames *= 2; - -    if( f >= numFrames ) -    { -      f -= numFrames; -      if( anim->loopFrames ) -      { -        f %= anim->loopFrames; -        f += anim->numFrames - anim->loopFrames; -      } -      else -      { -        f = numFrames - 1; -        // the animation is stuck at the end, so it -        // can immediately transition to another sequence -        lf->frameTime = cg.time; -      } -    } - -    if( anim->reversed ) -      lf->frame = anim->firstFrame + anim->numFrames - 1 - f; -    else if( anim->flipflop && f>=anim->numFrames ) -      lf->frame = anim->firstFrame + anim->numFrames - 1 - ( f % anim->numFrames ); -    else -      lf->frame = anim->firstFrame + f; - -    if( cg.time > lf->frameTime ) -    { -      lf->frameTime = cg.time; - -      if( cg_debugAnim.integer ) -        CG_Printf( "Clamp lf->frameTime\n" ); -    } -  } - -  if( lf->frameTime > cg.time + 200 ) -    lf->frameTime = cg.time; - -  if( lf->oldFrameTime > cg.time ) -    lf->oldFrameTime = cg.time; - -  // calculate current lerp value -  if( lf->frameTime == lf->oldFrameTime ) -    lf->backlerp = 0; -  else -    lf->backlerp = 1.0 - (float)( cg.time - lf->oldFrameTime ) / ( lf->frameTime - lf->oldFrameTime ); -} - - -/* -=============== -CG_ClearLerpFrame -=============== -*/ -static void CG_ClearLerpFrame( clientInfo_t *ci, lerpFrame_t *lf, int animationNumber ) -{ -  lf->frameTime = lf->oldFrameTime = cg.time; -  CG_SetLerpFrameAnimation( ci, lf, animationNumber ); -  lf->oldFrame = lf->frame = lf->animation->firstFrame; -} - - -/* -=============== -CG_PlayerAnimation -=============== -*/ -static void CG_PlayerAnimation( centity_t *cent, int *legsOld, int *legs, float *legsBackLerp, -                                int *torsoOld, int *torso, float *torsoBackLerp ) -{ -  clientInfo_t  *ci; -  int           clientNum; -  float         speedScale = 1.0f; - -  clientNum = cent->currentState.clientNum; - -  if( cg_noPlayerAnims.integer ) -  { -    *legsOld = *legs = *torsoOld = *torso = 0; -    return; -  } - -  ci = &cgs.clientinfo[ clientNum ]; - -  // do the shuffle turn frames locally -  if( cent->pe.legs.yawing && ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_IDLE ) -    CG_RunPlayerLerpFrame( ci, ¢->pe.legs, LEGS_TURN, speedScale ); -  else -    CG_RunPlayerLerpFrame( ci, ¢->pe.legs, cent->currentState.legsAnim, speedScale ); - -  *legsOld = cent->pe.legs.oldFrame; -  *legs = cent->pe.legs.frame; -  *legsBackLerp = cent->pe.legs.backlerp; - -  CG_RunPlayerLerpFrame( ci, ¢->pe.torso, cent->currentState.torsoAnim, speedScale ); - -  *torsoOld = cent->pe.torso.oldFrame; -  *torso = cent->pe.torso.frame; -  *torsoBackLerp = cent->pe.torso.backlerp; -} - - -/* -=============== -CG_PlayerNonSegAnimation -=============== -*/ -static void CG_PlayerNonSegAnimation( centity_t *cent, int *nonSegOld, -                                      int *nonSeg, float *nonSegBackLerp ) -{ -  clientInfo_t  *ci; -  int           clientNum; -  float         speedScale = 1.0f; - -  clientNum = cent->currentState.clientNum; - -  if( cg_noPlayerAnims.integer ) -  { -    *nonSegOld = *nonSeg = 0; -    return; -  } - -  ci = &cgs.clientinfo[ clientNum ]; - -  // do the shuffle turn frames locally -  if( cent->pe.nonseg.yawing && ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == NSPA_STAND ) -    CG_RunPlayerLerpFrame( ci, ¢->pe.nonseg, NSPA_TURN, speedScale ); -  else -    CG_RunPlayerLerpFrame( ci, ¢->pe.nonseg, cent->currentState.legsAnim, speedScale ); - -  *nonSegOld = cent->pe.nonseg.oldFrame; -  *nonSeg = cent->pe.nonseg.frame; -  *nonSegBackLerp = cent->pe.nonseg.backlerp; -} - -/* -============================================================================= - -PLAYER ANGLES - -============================================================================= -*/ - -/* -================== -CG_SwingAngles -================== -*/ -static void CG_SwingAngles( float destination, float swingTolerance, float clampTolerance, -                            float speed, float *angle, qboolean *swinging ) -{ -  float swing; -  float move; -  float scale; - -  if( !*swinging ) -  { -    // see if a swing should be started -    swing = AngleSubtract( *angle, destination ); - -    if( swing > swingTolerance || swing < -swingTolerance ) -      *swinging = qtrue; -  } - -  if( !*swinging ) -    return; - -  // modify the speed depending on the delta -  // so it doesn't seem so linear -  swing = AngleSubtract( destination, *angle ); -  scale = fabs( swing ); - -  if( scale < swingTolerance * 0.5 ) -    scale = 0.5; -  else if( scale < swingTolerance ) -    scale = 1.0; -  else -    scale = 2.0; - -  // swing towards the destination angle -  if( swing >= 0 ) -  { -    move = cg.frametime * scale * speed; - -    if( move >= swing ) -    { -      move = swing; -      *swinging = qfalse; -    } -    *angle = AngleMod( *angle + move ); -  } -  else if( swing < 0 ) -  { -    move = cg.frametime * scale * -speed; - -    if( move <= swing ) -    { -      move = swing; -      *swinging = qfalse; -    } -    *angle = AngleMod( *angle + move ); -  } - -  // clamp to no more than tolerance -  swing = AngleSubtract( destination, *angle ); -  if( swing > clampTolerance ) -    *angle = AngleMod( destination - ( clampTolerance - 1 ) ); -  else if( swing < -clampTolerance ) -    *angle = AngleMod( destination + ( clampTolerance - 1 ) ); -} - -/* -================= -CG_AddPainTwitch -================= -*/ -static void CG_AddPainTwitch( centity_t *cent, vec3_t torsoAngles ) -{ -  int   t; -  float f; - -  t = cg.time - cent->pe.painTime; - -  if( t >= PAIN_TWITCH_TIME ) -    return; - -  f = 1.0 - (float)t / PAIN_TWITCH_TIME; - -  if( cent->pe.painDirection ) -    torsoAngles[ ROLL ] += 20 * f; -  else -    torsoAngles[ ROLL ] -= 20 * f; -} - - -/* -=============== -CG_PlayerAngles - -Handles seperate torso motion - -  legs pivot based on direction of movement - -  head always looks exactly at cent->lerpAngles - -  if motion < 20 degrees, show in head only -  if < 45 degrees, also show in torso -=============== -*/ -static void CG_PlayerAngles( centity_t *cent, vec3_t srcAngles, -                             vec3_t legs[ 3 ], vec3_t torso[ 3 ], vec3_t head[ 3 ] ) -{ -  vec3_t        legsAngles, torsoAngles, headAngles; -  float         dest; -  static int    movementOffsets[ 8 ] = { 0, 22, 45, -22, 0, 22, -45, -22 }; -  vec3_t        velocity; -  float         speed; -  int           dir, clientNum; -  clientInfo_t  *ci; - -  VectorCopy( srcAngles, headAngles ); -  headAngles[ YAW ] = AngleMod( headAngles[ YAW ] ); -  VectorClear( legsAngles ); -  VectorClear( torsoAngles ); - -  // --------- yaw ------------- - -  // allow yaw to drift a bit -  if( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_IDLE || -      ( cent->currentState.torsoAnim & ~ANIM_TOGGLEBIT ) != TORSO_STAND  ) -  { -    // if not standing still, always point all in the same direction -    cent->pe.torso.yawing = qtrue;  // always center -    cent->pe.torso.pitching = qtrue;  // always center -    cent->pe.legs.yawing = qtrue; // always center -  } - -  // adjust legs for movement dir -  if( cent->currentState.eFlags & EF_DEAD ) -  { -    // don't let dead bodies twitch -    dir = 0; -  } -  else -  { -    //TA: did use angles2.. now uses time2.. looks a bit funny but time2 isn't used othwise -    dir = cent->currentState.time2; -    if( dir < 0 || dir > 7 ) -      CG_Error( "Bad player movement angle" ); -  } - -  legsAngles[ YAW ] = headAngles[ YAW ] + movementOffsets[ dir ]; -  torsoAngles[ YAW ] = headAngles[ YAW ] + 0.25 * movementOffsets[ dir ]; - -  // torso -  if( cent->currentState.eFlags & EF_DEAD ) -  { -    CG_SwingAngles( torsoAngles[ YAW ], 0, 0, cg_swingSpeed.value, -      ¢->pe.torso.yawAngle, ¢->pe.torso.yawing ); -    CG_SwingAngles( legsAngles[ YAW ], 0, 0, cg_swingSpeed.value, -      ¢->pe.legs.yawAngle, ¢->pe.legs.yawing ); -  } -  else -  { -    CG_SwingAngles( torsoAngles[ YAW ], 25, 90, cg_swingSpeed.value, -      ¢->pe.torso.yawAngle, ¢->pe.torso.yawing ); -    CG_SwingAngles( legsAngles[ YAW ], 40, 90, cg_swingSpeed.value, -      ¢->pe.legs.yawAngle, ¢->pe.legs.yawing ); -  } - -  torsoAngles[ YAW ] = cent->pe.torso.yawAngle; -  legsAngles[ YAW ] = cent->pe.legs.yawAngle; - -  // --------- pitch ------------- - -  // only show a fraction of the pitch angle in the torso -  if( headAngles[ PITCH ] > 180 ) -    dest = ( -360 + headAngles[ PITCH ] ) * 0.75f; -  else -    dest = headAngles[ PITCH ] * 0.75f; - -  CG_SwingAngles( dest, 15, 30, 0.1f, ¢->pe.torso.pitchAngle, ¢->pe.torso.pitching ); -  torsoAngles[ PITCH ] = cent->pe.torso.pitchAngle; - -  // -  clientNum = cent->currentState.clientNum; - -  if( clientNum >= 0 && clientNum < MAX_CLIENTS ) -  { -    ci = &cgs.clientinfo[ clientNum ]; -    if( ci->fixedtorso ) -      torsoAngles[ PITCH ] = 0.0f; -  } - -  // --------- roll ------------- - - -  // lean towards the direction of travel -  VectorCopy( cent->currentState.pos.trDelta, velocity ); -  speed = VectorNormalize( velocity ); - -  if( speed ) -  { -    vec3_t  axis[ 3 ]; -    float   side; - -    speed *= 0.05f; - -    AnglesToAxis( legsAngles, axis ); -    side = speed * DotProduct( velocity, axis[ 1 ] ); -    legsAngles[ ROLL ] -= side; - -    side = speed * DotProduct( velocity, axis[ 0 ] ); -    legsAngles[ PITCH ] += side; -  } - -  // -  clientNum = cent->currentState.clientNum; - -  if( clientNum >= 0 && clientNum < MAX_CLIENTS ) -  { -    ci = &cgs.clientinfo[ clientNum ]; - -    if( ci->fixedlegs ) -    { -      legsAngles[ YAW ] = torsoAngles[ YAW ]; -      legsAngles[ PITCH ] = 0.0f; -      legsAngles[ ROLL ] = 0.0f; -    } -  } - -  // pain twitch -  CG_AddPainTwitch( cent, torsoAngles ); - -  // pull the angles back out of the hierarchial chain -  AnglesSubtract( headAngles, torsoAngles, headAngles ); -  AnglesSubtract( torsoAngles, legsAngles, torsoAngles ); -  AnglesToAxis( legsAngles, legs ); -  AnglesToAxis( torsoAngles, torso ); -  AnglesToAxis( headAngles, head ); -} - -#define MODEL_WWSMOOTHTIME 200 - -/* -=============== -CG_PlayerWWSmoothing - -Smooth the angles of transitioning wall walkers -=============== -*/ -static void CG_PlayerWWSmoothing( centity_t *cent, vec3_t in[ 3 ], vec3_t out[ 3 ] ) -{ -  entityState_t *es = ¢->currentState; -  int           i; -  vec3_t        surfNormal, rotAxis, temp; -  vec3_t        refNormal     = { 0.0f, 0.0f,  1.0f }; -  vec3_t        ceilingNormal = { 0.0f, 0.0f, -1.0f }; -  float         stLocal, sFraction, rotAngle; -  vec3_t        inAxis[ 3 ], lastAxis[ 3 ], outAxis[ 3 ]; - -  //set surfNormal -  if( !(es->eFlags & EF_WALLCLIMB ) ) -    VectorCopy( refNormal, surfNormal ); -  else if( !( es->eFlags & EF_WALLCLIMBCEILING ) ) -    VectorCopy( es->angles2, surfNormal ); -  else -    VectorCopy( ceilingNormal, surfNormal ); - -  AxisCopy( in, inAxis ); - -  if( !VectorCompare( surfNormal, cent->pe.lastNormal ) ) -  { -    //if we moving from the ceiling to the floor special case -    //( x product of colinear vectors is undefined) -    if( VectorCompare( ceilingNormal, cent->pe.lastNormal ) && -        VectorCompare( refNormal,     surfNormal ) ) -    { -      VectorCopy( in[ 1 ], rotAxis ); -      rotAngle = 180.0f; -    } -    else -    { -      AxisCopy( cent->pe.lastAxis, lastAxis ); -      rotAngle = DotProduct( inAxis[ 0 ], lastAxis[ 0 ] ) + -                 DotProduct( inAxis[ 1 ], lastAxis[ 1 ] ) + -                 DotProduct( inAxis[ 2 ], lastAxis[ 2 ] ); - -      rotAngle = RAD2DEG( acos( ( rotAngle - 1.0f ) / 2.0f ) ); - -      CrossProduct( lastAxis[ 0 ], inAxis[ 0 ], temp ); -      VectorCopy( temp, rotAxis ); -      CrossProduct( lastAxis[ 1 ], inAxis[ 1 ], temp ); -      VectorAdd( rotAxis, temp, rotAxis ); -      CrossProduct( lastAxis[ 2 ], inAxis[ 2 ], temp ); -      VectorAdd( rotAxis, temp, rotAxis ); - -      VectorNormalize( rotAxis ); -    } - -    //iterate through smooth array -    for( i = 0; i < MAXSMOOTHS; i++ ) -    { -      //found an unused index in the smooth array -      if( cent->pe.sList[ i ].time + MODEL_WWSMOOTHTIME < cg.time ) -      { -        //copy to array and stop -        VectorCopy( rotAxis, cent->pe.sList[ i ].rotAxis ); -        cent->pe.sList[ i ].rotAngle = rotAngle; -        cent->pe.sList[ i ].time = cg.time; -        break; -      } -    } -  } - -  //iterate through ops -  for( i = MAXSMOOTHS - 1; i >= 0; i-- ) -  { -    //if this op has time remaining, perform it -    if( cg.time < cent->pe.sList[ i ].time + MODEL_WWSMOOTHTIME ) -    { -      stLocal = 1.0f - ( ( ( cent->pe.sList[ i ].time + MODEL_WWSMOOTHTIME ) - cg.time ) / MODEL_WWSMOOTHTIME ); -      sFraction = -( cos( stLocal * M_PI ) + 1.0f ) / 2.0f; - -      RotatePointAroundVector( outAxis[ 0 ], cent->pe.sList[ i ].rotAxis, -        inAxis[ 0 ], sFraction * cent->pe.sList[ i ].rotAngle ); -      RotatePointAroundVector( outAxis[ 1 ], cent->pe.sList[ i ].rotAxis, -        inAxis[ 1 ], sFraction * cent->pe.sList[ i ].rotAngle ); -      RotatePointAroundVector( outAxis[ 2 ], cent->pe.sList[ i ].rotAxis, -        inAxis[ 2 ], sFraction * cent->pe.sList[ i ].rotAngle ); - -      AxisCopy( outAxis, inAxis ); -    } -  } - -  //outAxis has been copied to inAxis -  AxisCopy( inAxis, out ); -} - -/* -=============== -CG_PlayerNonSegAngles - -Resolve angles for non-segmented models -=============== -*/ -static void CG_PlayerNonSegAngles( centity_t *cent, vec3_t srcAngles, vec3_t nonSegAxis[ 3 ] ) -{ -  vec3_t        localAngles; -  vec3_t        velocity; -  float         speed; -  int           dir; -  entityState_t *es = ¢->currentState; -  vec3_t        surfNormal; -  vec3_t        ceilingNormal = { 0.0f, 0.0f, -1.0f }; - -  VectorCopy( srcAngles, localAngles ); -  localAngles[ YAW ] = AngleMod( localAngles[ YAW ] ); -  localAngles[ PITCH ] = 0.0f; -  localAngles[ ROLL ] = 0.0f; - -  //set surfNormal -  if( !( es->eFlags & EF_WALLCLIMBCEILING ) ) -    VectorCopy( es->angles2, surfNormal ); -  else -    VectorCopy( ceilingNormal, surfNormal ); - -  //make sure that WW transitions don't cause the swing stuff to go nuts -  if( !VectorCompare( surfNormal, cent->pe.lastNormal ) ) -  { -    //stop CG_SwingAngles having an eppy -    cent->pe.nonseg.yawAngle = localAngles[ YAW ]; -    cent->pe.nonseg.yawing = qfalse; -  } - -  // --------- yaw ------------- - -  // allow yaw to drift a bit -  if( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) != NSPA_STAND ) -  { -    // if not standing still, always point all in the same direction -    cent->pe.nonseg.yawing = qtrue; // always center -  } - -  // adjust legs for movement dir -  if( cent->currentState.eFlags & EF_DEAD ) -  { -    // don't let dead bodies twitch -    dir = 0; -  } -  else -  { -    //TA: did use angles2.. now uses time2.. looks a bit funny but time2 isn't used othwise -    dir = cent->currentState.time2; -    if( dir < 0 || dir > 7 ) -      CG_Error( "Bad player movement angle" ); -  } - -  // torso -  if( cent->currentState.eFlags & EF_DEAD ) -  { -    CG_SwingAngles( localAngles[ YAW ], 0, 0, cg_swingSpeed.value, -      ¢->pe.nonseg.yawAngle, ¢->pe.nonseg.yawing ); -  } -  else -  { -    CG_SwingAngles( localAngles[ YAW ], 40, 90, cg_swingSpeed.value, -      ¢->pe.nonseg.yawAngle, ¢->pe.nonseg.yawing ); -  } - -  localAngles[ YAW ] = cent->pe.nonseg.yawAngle; - -  // --------- pitch ------------- - -  //NO PITCH! - - -  // --------- roll ------------- - - -  // lean towards the direction of travel -  VectorCopy( cent->currentState.pos.trDelta, velocity ); -  speed = VectorNormalize( velocity ); - -  if( speed ) -  { -    vec3_t  axis[ 3 ]; -    float   side; - -    //much less than with the regular model system -    speed *= 0.01f; - -    AnglesToAxis( localAngles, axis ); -    side = speed * DotProduct( velocity, axis[ 1 ] ); -    localAngles[ ROLL ] -= side; - -    side = speed * DotProduct( velocity, axis[ 0 ] ); -    localAngles[ PITCH ] += side; -  } - -  //FIXME: PAIN[123] animations? -  // pain twitch -  //CG_AddPainTwitch( cent, torsoAngles ); - -  AnglesToAxis( localAngles, nonSegAxis ); -} - - -//========================================================================== - -/* -=============== -CG_PlayerUpgrade -=============== -*/ -static void CG_PlayerUpgrades( centity_t *cent, refEntity_t *torso ) -{ -  int           held, active; -  refEntity_t   jetpack; -  refEntity_t   battpack; -  refEntity_t   flash; -  entityState_t *es = ¢->currentState; - -  held = es->modelindex; -  active = es->modelindex2; - -  if( held & ( 1 << UP_JETPACK ) ) -  { -    memset( &jetpack, 0, sizeof( jetpack ) ); -    VectorCopy( torso->lightingOrigin, jetpack.lightingOrigin ); -    jetpack.shadowPlane = torso->shadowPlane; -    jetpack.renderfx = torso->renderfx; - -    jetpack.hModel = cgs.media.jetpackModel; - -    //identity matrix -    AxisCopy( axisDefault, jetpack.axis ); - -    //FIXME: change to tag_back when it exists -    CG_PositionRotatedEntityOnTag( &jetpack, torso, torso->hModel, "tag_head" ); - -    trap_R_AddRefEntityToScene( &jetpack ); - -    if( active & ( 1 << UP_JETPACK ) ) -    { -      if( es->pos.trDelta[ 2 ] > 10.0f ) -      { -        if( cent->jetPackState != JPS_ASCENDING ) -        { -          if( CG_IsParticleSystemValid( ¢->jetPackPS ) ) -            CG_DestroyParticleSystem( ¢->jetPackPS ); - -          cent->jetPackPS = CG_SpawnNewParticleSystem( cgs.media.jetPackAscendPS ); -          cent->jetPackState = JPS_ASCENDING; -        } - -        trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, -                                vec3_origin, cgs.media.jetpackAscendSound ); -      } -      else if( es->pos.trDelta[ 2 ] < -10.0f ) -      { -        if( cent->jetPackState != JPS_DESCENDING ) -        { -          if( CG_IsParticleSystemValid( ¢->jetPackPS ) ) -            CG_DestroyParticleSystem( ¢->jetPackPS ); - -          cent->jetPackPS = CG_SpawnNewParticleSystem( cgs.media.jetPackDescendPS ); -          cent->jetPackState = JPS_DESCENDING; -        } - -        trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, -                                vec3_origin, cgs.media.jetpackDescendSound ); -      } -      else -      { -        if( cent->jetPackState != JPS_HOVERING ) -        { -          if( CG_IsParticleSystemValid( ¢->jetPackPS ) ) -            CG_DestroyParticleSystem( ¢->jetPackPS ); - -          cent->jetPackPS = CG_SpawnNewParticleSystem( cgs.media.jetPackHoverPS ); -          cent->jetPackState = JPS_HOVERING; -        } - -        trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, -                                vec3_origin, cgs.media.jetpackIdleSound ); -      } - -      memset( &flash, 0, sizeof( flash ) ); -      VectorCopy( torso->lightingOrigin, flash.lightingOrigin ); -      flash.shadowPlane = torso->shadowPlane; -      flash.renderfx = torso->renderfx; - -      flash.hModel = cgs.media.jetpackFlashModel; -      if( !flash.hModel ) -        return; - -      AxisCopy( axisDefault, flash.axis ); - -      CG_PositionRotatedEntityOnTag( &flash, &jetpack, jetpack.hModel, "tag_flash" ); -      trap_R_AddRefEntityToScene( &flash ); - -      if( CG_IsParticleSystemValid( ¢->jetPackPS ) ) -      { -        CG_SetAttachmentTag( ¢->jetPackPS->attachment, -            jetpack, jetpack.hModel, "tag_flash" ); -        CG_SetAttachmentCent( ¢->jetPackPS->attachment, cent ); -        CG_AttachToTag( ¢->jetPackPS->attachment ); -      } -    } -    else if( CG_IsParticleSystemValid( ¢->jetPackPS ) ) -    { -      CG_DestroyParticleSystem( ¢->jetPackPS ); -      cent->jetPackState = JPS_OFF; -    } -  } -  else if( CG_IsParticleSystemValid( ¢->jetPackPS ) ) -  { -    CG_DestroyParticleSystem( ¢->jetPackPS ); -    cent->jetPackState = JPS_OFF; -  } - -  if( held & ( 1 << UP_BATTPACK ) ) -  { -    memset( &battpack, 0, sizeof( battpack ) ); -    VectorCopy( torso->lightingOrigin, battpack.lightingOrigin ); -    battpack.shadowPlane = torso->shadowPlane; -    battpack.renderfx = torso->renderfx; - -    battpack.hModel = cgs.media.battpackModel; - -    //identity matrix -    AxisCopy( axisDefault, battpack.axis ); - -    //FIXME: change to tag_back when it exists -    CG_PositionRotatedEntityOnTag( &battpack, torso, torso->hModel, "tag_head" ); - -    trap_R_AddRefEntityToScene( &battpack ); -  } - -  if( es->eFlags & EF_BLOBLOCKED ) -  { -    vec3_t  temp, origin, up = { 0.0f, 0.0f, 1.0f }; -    trace_t tr; -    float   size; - -    VectorCopy( es->pos.trBase, temp ); -    temp[ 2 ] -= 4096.0f; - -    CG_Trace( &tr, es->pos.trBase, NULL, NULL, temp, es->number, MASK_SOLID ); -    VectorCopy( tr.endpos, origin ); - -    size = 32.0f; - -    if( size > 0.0f ) -      CG_ImpactMark( cgs.media.creepShader, origin, up, -                     0.0f, 1.0f, 1.0f, 1.0f, 1.0f, qfalse, size, qtrue ); -  } -} - - -/* -=============== -CG_PlayerFloatSprite - -Float a sprite over the player's head -=============== -*/ -static void CG_PlayerFloatSprite( centity_t *cent, qhandle_t shader ) -{ -  int           rf; -  refEntity_t   ent; - -  if( cent->currentState.number == cg.snap->ps.clientNum && !cg.renderingThirdPerson ) -    rf = RF_THIRD_PERSON;   // only show in mirrors -  else -    rf = 0; - -  memset( &ent, 0, sizeof( ent ) ); -  VectorCopy( cent->lerpOrigin, ent.origin ); -  ent.origin[ 2 ] += 48; -  ent.reType = RT_SPRITE; -  ent.customShader = shader; -  ent.radius = 10; -  ent.renderfx = rf; -  ent.shaderRGBA[ 0 ] = 255; -  ent.shaderRGBA[ 1 ] = 255; -  ent.shaderRGBA[ 2 ] = 255; -  ent.shaderRGBA[ 3 ] = 255; -  trap_R_AddRefEntityToScene( &ent ); -} - - - -/* -=============== -CG_PlayerSprites - -Float sprites over the player's head -=============== -*/ -static void CG_PlayerSprites( centity_t *cent ) -{ -  if( cent->currentState.eFlags & EF_CONNECTION ) -  { -    CG_PlayerFloatSprite( cent, cgs.media.connectionShader ); -    return; -  } - -  if( cent->currentState.eFlags & EF_TALK ) -  { -    //TA: the masses have decreed this to be wrong -/*    CG_PlayerFloatSprite( cent, cgs.media.balloonShader ); -    return;*/ -  } -} - -/* -=============== -CG_PlayerShadow - -Returns the Z component of the surface being shadowed - -  should it return a full plane instead of a Z? -=============== -*/ -#define SHADOW_DISTANCE   128 -static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane, pClass_t class ) -{ -  vec3_t        end, mins, maxs; -  trace_t       trace; -  float         alpha; -  entityState_t *es = ¢->currentState; -  vec3_t        surfNormal = { 0.0f, 0.0f, 1.0f }; - -  BG_FindBBoxForClass( class, mins, maxs, NULL, NULL, NULL ); -  mins[ 2 ] = 0.0f; -  maxs[ 2 ] = 2.0f; - -  if( es->eFlags & EF_WALLCLIMB ) -  { -    if( es->eFlags & EF_WALLCLIMBCEILING ) -      VectorSet( surfNormal, 0.0f, 0.0f, -1.0f ); -    else -      VectorCopy( es->angles2, surfNormal ); -  } - -  *shadowPlane = 0; - -  if( cg_shadows.integer == 0 ) -    return qfalse; - -  // send a trace down from the player to the ground -  VectorCopy( cent->lerpOrigin, end ); -  VectorMA( cent->lerpOrigin, -SHADOW_DISTANCE, surfNormal, end ); - -  trap_CM_BoxTrace( &trace, cent->lerpOrigin, end, mins, maxs, 0, MASK_PLAYERSOLID ); - -  // no shadow if too high -  if( trace.fraction == 1.0 || trace.startsolid || trace.allsolid ) -    return qfalse; - -  //TA: FIXME: stencil shadows will be broken for walls. -  //           Unfortunately there isn't much that can be -  //           done since Q3 references only the Z coord -  //           of the shadowPlane -  if( surfNormal[ 2 ] < 0.0f ) -    *shadowPlane = trace.endpos[ 2 ] - 1.0f; -  else -    *shadowPlane = trace.endpos[ 2 ] + 1.0f; - -  if( cg_shadows.integer != 1 )  // no mark for stencil or projection shadows -    return qtrue; - -  // fade the shadow out with height -  alpha = 1.0 - trace.fraction; - -  // add the mark as a temporary, so it goes directly to the renderer -  // without taking a spot in the cg_marks array -  CG_ImpactMark( cgs.media.shadowMarkShader, trace.endpos, trace.plane.normal, -                 cent->pe.legs.yawAngle, alpha, alpha, alpha, 1, qfalse, -                 24.0f * BG_FindShadowScaleForClass( class ), qtrue ); - -  return qtrue; -} - - -/* -=============== -CG_PlayerSplash - -Draw a mark at the water surface -=============== -*/ -static void CG_PlayerSplash( centity_t *cent ) -{ -  vec3_t      start, end; -  trace_t     trace; -  int         contents; -  polyVert_t  verts[ 4 ]; - -  if( !cg_shadows.integer ) -    return; - -  VectorCopy( cent->lerpOrigin, end ); -  end[ 2 ] -= 24; - -  // if the feet aren't in liquid, don't make a mark -  // this won't handle moving water brushes, but they wouldn't draw right anyway... -  contents = trap_CM_PointContents( end, 0 ); - -  if( !( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) ) -    return; - -  VectorCopy( cent->lerpOrigin, start ); -  start[ 2 ] += 32; - -  // if the head isn't out of liquid, don't make a mark -  contents = trap_CM_PointContents( start, 0 ); - -  if( contents & ( CONTENTS_SOLID | CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) -    return; - -  // trace down to find the surface -  trap_CM_BoxTrace( &trace, start, end, NULL, NULL, 0, ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ); - -  if( trace.fraction == 1.0 ) -    return; - -  // create a mark polygon -  VectorCopy( trace.endpos, verts[ 0 ].xyz ); -  verts[ 0 ].xyz[ 0 ] -= 32; -  verts[ 0 ].xyz[ 1 ] -= 32; -  verts[ 0 ].st[ 0 ] = 0; -  verts[ 0 ].st[ 1 ] = 0; -  verts[ 0 ].modulate[ 0 ] = 255; -  verts[ 0 ].modulate[ 1 ] = 255; -  verts[ 0 ].modulate[ 2 ] = 255; -  verts[ 0 ].modulate[ 3 ] = 255; - -  VectorCopy( trace.endpos, verts[ 1 ].xyz ); -  verts[ 1 ].xyz[ 0 ] -= 32; -  verts[ 1 ].xyz[ 1 ] += 32; -  verts[ 1 ].st[ 0 ] = 0; -  verts[ 1 ].st[ 1 ] = 1; -  verts[ 1 ].modulate[ 0 ] = 255; -  verts[ 1 ].modulate[ 1 ] = 255; -  verts[ 1 ].modulate[ 2 ] = 255; -  verts[ 1 ].modulate[ 3 ] = 255; - -  VectorCopy( trace.endpos, verts[ 2 ].xyz ); -  verts[ 2 ].xyz[ 0 ] += 32; -  verts[ 2 ].xyz[ 1 ] += 32; -  verts[ 2 ].st[ 0 ] = 1; -  verts[ 2 ].st[ 1 ] = 1; -  verts[ 2 ].modulate[ 0 ] = 255; -  verts[ 2 ].modulate[ 1 ] = 255; -  verts[ 2 ].modulate[ 2 ] = 255; -  verts[ 2 ].modulate[ 3 ] = 255; - -  VectorCopy( trace.endpos, verts[ 3 ].xyz ); -  verts[ 3 ].xyz[ 0 ] += 32; -  verts[ 3 ].xyz[ 1 ] -= 32; -  verts[ 3 ].st[ 0 ] = 1; -  verts[ 3 ].st[ 1 ] = 0; -  verts[ 3 ].modulate[ 0 ] = 255; -  verts[ 3 ].modulate[ 1 ] = 255; -  verts[ 3 ].modulate[ 2 ] = 255; -  verts[ 3 ].modulate[ 3 ] = 255; - -  trap_R_AddPolyToScene( cgs.media.wakeMarkShader, 4, verts ); -} - - -/* -================= -CG_LightVerts -================= -*/ -int CG_LightVerts( vec3_t normal, int numVerts, polyVert_t *verts ) -{ -  int       i, j; -  float     incoming; -  vec3_t      ambientLight; -  vec3_t      lightDir; -  vec3_t      directedLight; - -  trap_R_LightForPoint( verts[ 0 ].xyz, ambientLight, directedLight, lightDir ); - -  for( i = 0; i < numVerts; i++ ) -  { -    incoming = DotProduct( normal, lightDir ); - -    if( incoming <= 0 ) -    { -      verts[ i ].modulate[ 0 ] = ambientLight[ 0 ]; -      verts[ i ].modulate[ 1 ] = ambientLight[ 1 ]; -      verts[ i ].modulate[ 2 ] = ambientLight[ 2 ]; -      verts[ i ].modulate[ 3 ] = 255; -      continue; -    } - -    j = ( ambientLight[ 0 ] + incoming * directedLight[ 0 ] ); - -    if( j > 255 ) -      j = 255; - -    verts[ i ].modulate[ 0 ] = j; - -    j = ( ambientLight[ 1 ] + incoming * directedLight[ 1 ] ); - -    if( j > 255 ) -      j = 255; - -    verts[ i ].modulate[ 1 ] = j; - -    j = ( ambientLight[ 2 ] + incoming * directedLight[ 2 ] ); - -    if( j > 255 ) -      j = 255; - -    verts[ i ].modulate[ 2 ] = j; - -    verts[ i ].modulate[ 3 ] = 255; -  } -  return qtrue; -} - - -/* -================= -CG_LightFromDirection -================= -*/ -int CG_LightFromDirection( vec3_t point, vec3_t direction ) -{ -  int       j; -  float     incoming; -  vec3_t    ambientLight; -  vec3_t    lightDir; -  vec3_t    directedLight; -  vec3_t    result; - -  trap_R_LightForPoint( point, ambientLight, directedLight, lightDir ); - -  incoming = DotProduct( direction, lightDir ); - -  if( incoming <= 0 ) -  { -    result[ 0 ] = ambientLight[ 0 ]; -    result[ 1 ] = ambientLight[ 1 ]; -    result[ 2 ] = ambientLight[ 2 ]; -    return (int)( (float)( result[ 0 ] + result[ 1 ] + result[ 2 ] ) / 3.0f ); -  } - -  j = ( ambientLight[ 0 ] + incoming * directedLight[ 0 ] ); - -  if( j > 255 ) -    j = 255; - -  result[ 0 ] = j; - -  j = ( ambientLight[ 1 ] + incoming * directedLight[ 1 ] ); - -  if( j > 255 ) -    j = 255; - -  result[ 1 ] = j; - -  j = ( ambientLight[ 2 ] + incoming * directedLight[ 2 ] ); - -  if( j > 255 ) -    j = 255; - -  result[ 2 ] = j; - -  return (int)((float)( result[ 0 ] + result[ 1 ] + result[ 2 ] ) / 3.0f ); -} - - -/* -================= -CG_AmbientLight -================= -*/ -int CG_AmbientLight( vec3_t point ) -{ -  vec3_t      ambientLight; -  vec3_t      lightDir; -  vec3_t      directedLight; -  vec3_t      result; - -  trap_R_LightForPoint( point, ambientLight, directedLight, lightDir ); - -  result[ 0 ] = ambientLight[ 0 ]; -  result[ 1 ] = ambientLight[ 1 ]; -  result[ 2 ] = ambientLight[ 2 ]; -  return (int)((float)( result[ 0 ] + result[ 1 ] + result[ 2 ] ) / 3.0f ); -} - -#define TRACE_DEPTH 32.0f - -/* -=============== -CG_Player -=============== -*/ -void CG_Player( centity_t *cent ) -{ -  clientInfo_t  *ci; - -  //TA: NOTE: legs is used for nonsegmented models -  //          this helps reduce code to be changed -  refEntity_t   legs; -  refEntity_t   torso; -  refEntity_t   head; -  int           clientNum; -  int           renderfx; -  qboolean      shadow = qfalse; -  float         shadowPlane; -  entityState_t *es = ¢->currentState; -  pClass_t      class = ( es->powerups >> 8 ) & 0xFF; -  float         scale; -  vec3_t        tempAxis[ 3 ], tempAxis2[ 3 ]; -  vec3_t        angles; -  int           held = es->modelindex; -  vec3_t        surfNormal = { 0.0f, 0.0f, 1.0f }; - -  // the client number is stored in clientNum.  It can't be derived -  // from the entity number, because a single client may have -  // multiple corpses on the level using the same clientinfo -  clientNum = es->clientNum; -  if( clientNum < 0 || clientNum >= MAX_CLIENTS ) -    CG_Error( "Bad clientNum on player entity" ); - -  ci = &cgs.clientinfo[ clientNum ]; - -  // it is possible to see corpses from disconnected players that may -  // not have valid clientinfo -  if( !ci->infoValid ) -    return; - -  //don't draw -  if( es->eFlags & EF_NODRAW ) -    return; - -  // get the player model information -  renderfx = 0; -  if( es->number == cg.snap->ps.clientNum ) -  { -    if( !cg.renderingThirdPerson ) -      renderfx = RF_THIRD_PERSON;     // only draw in mirrors -    else if( cg_cameraMode.integer ) -      return; -  } - -  if( cg_drawBBOX.integer ) -  { -    vec3_t  mins, maxs; - -    BG_FindBBoxForClass( class, mins, maxs, NULL, NULL, NULL ); -    CG_DrawBoundingBox( cent->lerpOrigin, mins, maxs ); -  } - -  memset( &legs,    0, sizeof( legs ) ); -  memset( &torso,   0, sizeof( torso ) ); -  memset( &head,    0, sizeof( head ) ); - -  VectorCopy( cent->lerpAngles, angles ); -  AnglesToAxis( cent->lerpAngles, tempAxis ); - -  //rotate lerpAngles to floor -  if( es->eFlags & EF_WALLCLIMB && -      BG_RotateAxis( es->angles2, tempAxis, tempAxis2, qtrue, es->eFlags & EF_WALLCLIMBCEILING ) ) -    AxisToAngles( tempAxis2, angles ); -  else -    VectorCopy( cent->lerpAngles, angles ); - -  //normalise the pitch -  if( angles[ PITCH ] < -180.0f ) -    angles[ PITCH ] += 360.0f; - -  // get the rotation information -  if( !ci->nonsegmented ) -    CG_PlayerAngles( cent, angles, legs.axis, torso.axis, head.axis ); -  else -    CG_PlayerNonSegAngles( cent, angles, legs.axis ); - -  AxisCopy( legs.axis, tempAxis ); - -  //rotate the legs axis to back to the wall -  if( es->eFlags & EF_WALLCLIMB && -      BG_RotateAxis( es->angles2, legs.axis, tempAxis, qfalse, es->eFlags & EF_WALLCLIMBCEILING ) ) -    AxisCopy( tempAxis, legs.axis ); - -  //smooth out WW transitions so the model doesn't hop around -  CG_PlayerWWSmoothing( cent, legs.axis, legs.axis ); - -  AxisCopy( tempAxis, cent->pe.lastAxis ); - -  // get the animation state (after rotation, to allow feet shuffle) -  if( !ci->nonsegmented ) -    CG_PlayerAnimation( cent, &legs.oldframe, &legs.frame, &legs.backlerp, -                        &torso.oldframe, &torso.frame, &torso.backlerp ); -  else -    CG_PlayerNonSegAnimation( cent, &legs.oldframe, &legs.frame, &legs.backlerp ); - -  // add the talk baloon or disconnect icon -  CG_PlayerSprites( cent ); - -  // add the shadow -  if( ( es->number == cg.snap->ps.clientNum && cg.renderingThirdPerson ) || -      es->number != cg.snap->ps.clientNum ) -  shadow = CG_PlayerShadow( cent, &shadowPlane, class ); - -  // add a water splash if partially in and out of water -  CG_PlayerSplash( cent ); - -  if( cg_shadows.integer == 3 && shadow ) -    renderfx |= RF_SHADOW_PLANE; - -  renderfx |= RF_LIGHTING_ORIGIN;     // use the same origin for all - -  // -  // add the legs -  // -  if( !ci->nonsegmented ) -  { -    legs.hModel = ci->legsModel; - -    if( held & ( 1 << UP_LIGHTARMOUR ) ) -      legs.customSkin = cgs.media.larmourLegsSkin; -    else -      legs.customSkin = ci->legsSkin; -  } -  else -  { -    legs.hModel = ci->nonSegModel; -    legs.customSkin = ci->nonSegSkin; -  } - -  VectorCopy( cent->lerpOrigin, legs.origin ); - -  VectorCopy( cent->lerpOrigin, legs.lightingOrigin ); -  legs.shadowPlane = shadowPlane; -  legs.renderfx = renderfx; -  VectorCopy( legs.origin, legs.oldorigin ); // don't positionally lerp at all - -  //move the origin closer into the wall with a CapTrace -  if( es->eFlags & EF_WALLCLIMB && !( es->eFlags & EF_DEAD ) && !( cg.intermissionStarted ) ) -  { -    vec3_t  start, end, mins, maxs; -    trace_t tr; - -    if( es->eFlags & EF_WALLCLIMBCEILING ) -      VectorSet( surfNormal, 0.0f, 0.0f, -1.0f ); -    else -      VectorCopy( es->angles2, surfNormal ); - -    BG_FindBBoxForClass( class, mins, maxs, NULL, NULL, NULL ); - -    VectorMA( legs.origin, -TRACE_DEPTH, surfNormal, end ); -    VectorMA( legs.origin, 1.0f, surfNormal, start ); -    CG_CapTrace( &tr, start, mins, maxs, end, es->number, MASK_PLAYERSOLID ); - -    //if the trace misses completely then just use legs.origin -    //apparently capsule traces are "smaller" than box traces -    if( tr.fraction != 1.0f ) -      VectorMA( legs.origin, tr.fraction * -TRACE_DEPTH, surfNormal, legs.origin ); - -    VectorCopy( legs.origin, legs.lightingOrigin ); -    VectorCopy( legs.origin, legs.oldorigin ); // don't positionally lerp at all -  } - -  //rescale the model -  scale = BG_FindModelScaleForClass( class ); - -  if( scale != 1.0f ) -  { -    VectorScale( legs.axis[ 0 ], scale, legs.axis[ 0 ] ); -    VectorScale( legs.axis[ 1 ], scale, legs.axis[ 1 ] ); -    VectorScale( legs.axis[ 2 ], scale, legs.axis[ 2 ] ); - -    legs.nonNormalizedAxes = qtrue; -  } - -  //offset on the Z axis if required -  VectorMA( legs.origin, BG_FindZOffsetForClass( class ), surfNormal, legs.origin ); -  VectorCopy( legs.origin, legs.lightingOrigin ); -  VectorCopy( legs.origin, legs.oldorigin ); // don't positionally lerp at all - -  trap_R_AddRefEntityToScene( &legs ); - -  // if the model failed, allow the default nullmodel to be displayed -  if( !legs.hModel ) -    return; - -  if( !ci->nonsegmented ) -  { -    // -    // add the torso -    // -    torso.hModel = ci->torsoModel; - -    if( held & ( 1 << UP_LIGHTARMOUR ) ) -      torso.customSkin = cgs.media.larmourTorsoSkin; -    else -      torso.customSkin = ci->torsoSkin; - -    if( !torso.hModel ) -      return; - -    VectorCopy( cent->lerpOrigin, torso.lightingOrigin ); - -    CG_PositionRotatedEntityOnTag( &torso, &legs, ci->legsModel, "tag_torso" ); - -    torso.shadowPlane = shadowPlane; -    torso.renderfx = renderfx; - -    trap_R_AddRefEntityToScene( &torso ); - -    // -    // add the head -    // -    head.hModel = ci->headModel; - -    if( held & ( 1 << UP_HELMET ) ) -      head.customSkin = cgs.media.larmourHeadSkin; -    else -      head.customSkin = ci->headSkin; - -    if( !head.hModel ) -      return; - -    VectorCopy( cent->lerpOrigin, head.lightingOrigin ); - -    CG_PositionRotatedEntityOnTag( &head, &torso, ci->torsoModel, "tag_head" ); - -    head.shadowPlane = shadowPlane; -    head.renderfx = renderfx; - -    trap_R_AddRefEntityToScene( &head ); -  } - -  // -  // add the gun / barrel / flash -  // -  if( es->weapon != WP_NONE ) -  { -    if( !ci->nonsegmented ) -      CG_AddPlayerWeapon( &torso, NULL, cent ); -    else -      CG_AddPlayerWeapon( &legs, NULL, cent ); -  } - -  CG_PlayerUpgrades( cent, &torso ); - -  //sanity check that particle systems are stopped when dead -  if( es->eFlags & EF_DEAD ) -  { -    if( CG_IsParticleSystemValid( ¢->muzzlePS ) ) -      CG_DestroyParticleSystem( ¢->muzzlePS ); - -    if( CG_IsParticleSystemValid( ¢->jetPackPS ) ) -      CG_DestroyParticleSystem( ¢->jetPackPS ); -  } - -  VectorCopy( surfNormal, cent->pe.lastNormal ); -} - -/* -=============== -CG_Corpse -=============== -*/ -void CG_Corpse( centity_t *cent ) -{ -  clientInfo_t  *ci; -  refEntity_t   legs; -  refEntity_t   torso; -  refEntity_t   head; -  entityState_t *es = ¢->currentState; -  int           corpseNum; -  int           renderfx; -  qboolean      shadow = qfalse; -  float         shadowPlane; -  vec3_t        origin, liveZ, deadZ; -  float         scale; - -  corpseNum = CG_GetCorpseNum( es->clientNum ); - -  if( corpseNum < 0 || corpseNum >= MAX_CLIENTS ) -    CG_Error( "Bad corpseNum on corpse entity: %d", corpseNum ); - -  ci = &cgs.corpseinfo[ corpseNum ]; - -  // it is possible to see corpses from disconnected players that may -  // not have valid clientinfo -  if( !ci->infoValid ) -    return; - -  memset( &legs, 0, sizeof( legs ) ); -  memset( &torso, 0, sizeof( torso ) ); -  memset( &head, 0, sizeof( head ) ); - -  VectorCopy( cent->lerpOrigin, origin ); -  BG_FindBBoxForClass( es->clientNum, liveZ, NULL, NULL, deadZ, NULL ); -  origin[ 2 ] -= ( liveZ[ 2 ] - deadZ[ 2 ] ); - -  VectorCopy( es->angles, cent->lerpAngles ); - -  // get the rotation information -  if( !ci->nonsegmented ) -    CG_PlayerAngles( cent, cent->lerpAngles, legs.axis, torso.axis, head.axis ); -  else -    CG_PlayerNonSegAngles( cent, cent->lerpAngles, legs.axis ); - -  //set the correct frame (should always be dead) -  if( cg_noPlayerAnims.integer ) -    legs.oldframe = legs.frame = torso.oldframe = torso.frame = 0; -  else if( !ci->nonsegmented ) -  { -    memset( ¢->pe.legs, 0, sizeof( lerpFrame_t ) ); -    CG_RunPlayerLerpFrame( ci, ¢->pe.legs, es->legsAnim, 1 ); -    legs.oldframe = cent->pe.legs.oldFrame; -    legs.frame = cent->pe.legs.frame; -    legs.backlerp = cent->pe.legs.backlerp; - -    memset( ¢->pe.torso, 0, sizeof( lerpFrame_t ) ); -    CG_RunPlayerLerpFrame( ci, ¢->pe.torso, es->torsoAnim, 1 ); -    torso.oldframe = cent->pe.torso.oldFrame; -    torso.frame = cent->pe.torso.frame; -    torso.backlerp = cent->pe.torso.backlerp; -  } -  else -  { -    memset( ¢->pe.nonseg, 0, sizeof( lerpFrame_t ) ); -    CG_RunPlayerLerpFrame( ci, ¢->pe.nonseg, es->legsAnim, 1 ); -    legs.oldframe = cent->pe.nonseg.oldFrame; -    legs.frame = cent->pe.nonseg.frame; -    legs.backlerp = cent->pe.nonseg.backlerp; -  } - -  // add the shadow -  shadow = CG_PlayerShadow( cent, &shadowPlane, es->clientNum ); - -  // get the player model information -  renderfx = 0; - -  if( cg_shadows.integer == 3 && shadow ) -    renderfx |= RF_SHADOW_PLANE; - -  renderfx |= RF_LIGHTING_ORIGIN;     // use the same origin for all - -  // -  // add the legs -  // -  if( !ci->nonsegmented ) -  { -    legs.hModel = ci->legsModel; -    legs.customSkin = ci->legsSkin; -  } -  else -  { -    legs.hModel = ci->nonSegModel; -    legs.customSkin = ci->nonSegSkin; -  } - -  VectorCopy( origin, legs.origin ); - -  VectorCopy( origin, legs.lightingOrigin ); -  legs.shadowPlane = shadowPlane; -  legs.renderfx = renderfx; -  legs.origin[ 2 ] += BG_FindZOffsetForClass( es->clientNum ); -  VectorCopy( legs.origin, legs.oldorigin ); // don't positionally lerp at all - -  //rescale the model -  scale = BG_FindModelScaleForClass( es->clientNum ); - -  if( scale != 1.0f ) -  { -    VectorScale( legs.axis[ 0 ], scale, legs.axis[ 0 ] ); -    VectorScale( legs.axis[ 1 ], scale, legs.axis[ 1 ] ); -    VectorScale( legs.axis[ 2 ], scale, legs.axis[ 2 ] ); - -    legs.nonNormalizedAxes = qtrue; -  } - -  //CG_AddRefEntityWithPowerups( &legs, es->powerups, ci->team ); -  trap_R_AddRefEntityToScene( &legs ); - -  // if the model failed, allow the default nullmodel to be displayed -  if( !legs.hModel ) -    return; - -  if( !ci->nonsegmented ) -  { -    // -    // add the torso -    // -    torso.hModel = ci->torsoModel; -    if( !torso.hModel ) -      return; - -    torso.customSkin = ci->torsoSkin; - -    VectorCopy( origin, torso.lightingOrigin ); - -    CG_PositionRotatedEntityOnTag( &torso, &legs, ci->legsModel, "tag_torso" ); - -    torso.shadowPlane = shadowPlane; -    torso.renderfx = renderfx; - -    //CG_AddRefEntityWithPowerups( &torso, es->powerups, ci->team ); -    trap_R_AddRefEntityToScene( &torso ); - -    // -    // add the head -    // -    head.hModel = ci->headModel; -    if( !head.hModel ) -      return; - -    head.customSkin = ci->headSkin; - -    VectorCopy( origin, head.lightingOrigin ); - -    CG_PositionRotatedEntityOnTag( &head, &torso, ci->torsoModel, "tag_head"); - -    head.shadowPlane = shadowPlane; -    head.renderfx = renderfx; - -    //CG_AddRefEntityWithPowerups( &head, es->powerups, ci->team ); -    trap_R_AddRefEntityToScene( &head ); -  } -} - - -//===================================================================== - -/* -=============== -CG_ResetPlayerEntity - -A player just came into view or teleported, so reset all animation info -=============== -*/ -void CG_ResetPlayerEntity( centity_t *cent ) -{ -  cent->errorTime = -99999;   // guarantee no error decay added -  cent->extrapolated = qfalse; - -  CG_ClearLerpFrame( &cgs.clientinfo[ cent->currentState.clientNum ], -                     ¢->pe.legs, cent->currentState.legsAnim ); -  CG_ClearLerpFrame( &cgs.clientinfo[ cent->currentState.clientNum ], -                     ¢->pe.torso, cent->currentState.torsoAnim ); -  CG_ClearLerpFrame( &cgs.clientinfo[ cent->currentState.clientNum ], -                     ¢->pe.nonseg, cent->currentState.legsAnim ); - -  BG_EvaluateTrajectory( ¢->currentState.pos, cg.time, cent->lerpOrigin ); -  BG_EvaluateTrajectory( ¢->currentState.apos, cg.time, cent->lerpAngles ); - -  VectorCopy( cent->lerpOrigin, cent->rawOrigin ); -  VectorCopy( cent->lerpAngles, cent->rawAngles ); - -  memset( ¢->pe.legs, 0, sizeof( cent->pe.legs ) ); -  cent->pe.legs.yawAngle = cent->rawAngles[ YAW ]; -  cent->pe.legs.yawing = qfalse; -  cent->pe.legs.pitchAngle = 0; -  cent->pe.legs.pitching = qfalse; - -  memset( ¢->pe.torso, 0, sizeof( cent->pe.legs ) ); -  cent->pe.torso.yawAngle = cent->rawAngles[ YAW ]; -  cent->pe.torso.yawing = qfalse; -  cent->pe.torso.pitchAngle = cent->rawAngles[ PITCH ]; -  cent->pe.torso.pitching = qfalse; - -  memset( ¢->pe.nonseg, 0, sizeof( cent->pe.nonseg ) ); -  cent->pe.nonseg.yawAngle = cent->rawAngles[ YAW ]; -  cent->pe.nonseg.yawing = qfalse; -  cent->pe.nonseg.pitchAngle = cent->rawAngles[ PITCH ]; -  cent->pe.nonseg.pitching = qfalse; - -  if( cg_debugPosition.integer ) -    CG_Printf( "%i ResetPlayerEntity yaw=%i\n", cent->currentState.number, cent->pe.torso.yawAngle ); -} - -/* -================== -CG_PlayerDisconnect - -Player disconnecting -================== -*/ -void CG_PlayerDisconnect( vec3_t org ) -{ -  particleSystem_t  *ps; - -  trap_S_StartSound( org, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.disconnectSound ); - -  ps = CG_SpawnNewParticleSystem( cgs.media.disconnectPS ); - -  if( CG_IsParticleSystemValid( &ps ) ) -  { -    CG_SetAttachmentPoint( &ps->attachment, org ); -    CG_AttachToPoint( &ps->attachment ); -  } -} - -/* -================= -CG_Bleed - -This is the spurt of blood when a character gets hit -================= -*/ -void CG_Bleed( vec3_t origin, vec3_t normal, int entityNum ) -{ -  pTeam_t           team = cgs.clientinfo[ entityNum ].team; -  qhandle_t         bleedPS; -  particleSystem_t  *ps; - -  if( !cg_blood.integer ) -    return; - -  if( team == PTE_ALIENS ) -    bleedPS = cgs.media.alienBleedPS; -  else if( team == PTE_HUMANS ) -    bleedPS = cgs.media.humanBleedPS; -  else -    return; - -  ps = CG_SpawnNewParticleSystem( bleedPS ); - -  if( CG_IsParticleSystemValid( &ps ) ) -  { -    CG_SetAttachmentPoint( &ps->attachment, origin ); -    CG_SetAttachmentCent( &ps->attachment, &cg_entities[ entityNum ] ); -    CG_AttachToPoint( &ps->attachment ); - -    CG_SetParticleSystemNormal( ps, normal ); -  } -} diff --git a/mod/src/cgame/cg_playerstate.c b/mod/src/cgame/cg_playerstate.c deleted file mode 100644 index 489b024d..00000000 --- a/mod/src/cgame/cg_playerstate.c +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_playerstate.c -- this file acts on changes in a new playerState_t -// With normal play, this will be done after local prediction, but when -// following another player or playing back a demo, it will be checked -// when the snapshot transitions like all the other entities - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -/* -============== -CG_DamageFeedback -============== -*/ -void CG_DamageFeedback( int yawByte, int pitchByte, int damage ) -{ -  float   left, front, up; -  float   kick; -  int     health; -  float   scale; -  vec3_t  dir; -  vec3_t  angles; -  float   dist; -  float   yaw, pitch; - -  // show the attacking player's head and name in corner -  cg.attackerTime = cg.time; - -  // the lower on health you are, the greater the view kick will be -  health = cg.snap->ps.stats[STAT_HEALTH]; - -  if( health < 40 ) -    scale = 1; -  else -    scale = 40.0 / health; - -  kick = damage * scale; - -  if( kick < 5 ) -    kick = 5; - -  if( kick > 10 ) -    kick = 10; - -  // if yaw and pitch are both 255, make the damage always centered (falling, etc) -  if( yawByte == 255 && pitchByte == 255 ) -  { -    cg.damageX = 0; -    cg.damageY = 0; -    cg.v_dmg_roll = 0; -    cg.v_dmg_pitch = -kick; -  } -  else -  { -    // positional -    pitch = pitchByte / 255.0 * 360; -    yaw = yawByte / 255.0 * 360; - -    angles[ PITCH ] = pitch; -    angles[ YAW ] = yaw; -    angles[ ROLL ] = 0; - -    AngleVectors( angles, dir, NULL, NULL ); -    VectorSubtract( vec3_origin, dir, dir ); - -    front = DotProduct( dir, cg.refdef.viewaxis[ 0 ] ); -    left = DotProduct( dir, cg.refdef.viewaxis[ 1 ] ); -    up = DotProduct( dir, cg.refdef.viewaxis[ 2 ] ); - -    dir[ 0 ] = front; -    dir[ 1 ] = left; -    dir[ 2 ] = 0; -    dist = VectorLength( dir ); - -    if( dist < 0.1f ) -      dist = 0.1f; - -    cg.v_dmg_roll = kick * left; - -    cg.v_dmg_pitch = -kick * front; - -    if( front <= 0.1 ) -      front = 0.1f; - -    cg.damageX = -left / front; -    cg.damageY = up / dist; -  } - -  // clamp the position -  if( cg.damageX > 1.0 ) -    cg.damageX = 1.0; - -  if( cg.damageX < - 1.0 ) -    cg.damageX = -1.0; - -  if( cg.damageY > 1.0 ) -    cg.damageY = 1.0; - -  if( cg.damageY < - 1.0 ) -    cg.damageY = -1.0; - -  // don't let the screen flashes vary as much -  if( kick > 10 ) -    kick = 10; - -  cg.damageValue = kick; -  cg.v_dmg_time = cg.time + DAMAGE_TIME; -  cg.damageTime = cg.snap->serverTime; -} - - - - -/* -================ -CG_Respawn - -A respawn happened this snapshot -================ -*/ -void CG_Respawn( void ) -{ -  // no error decay on player movement -  cg.thisFrameTeleport = qtrue; - -  // display weapons available -  cg.weaponSelectTime = cg.time; - -  // select the weapon the server says we are using -  cg.weaponSelect = cg.snap->ps.weapon; - -  CG_ResetPainBlend( ); -} - -/* -============== -CG_CheckPlayerstateEvents - -============== -*/ -void CG_CheckPlayerstateEvents( playerState_t *ps, playerState_t *ops ) -{ -  int       i; -  int       event; -  centity_t *cent; - -  if( ps->externalEvent && ps->externalEvent != ops->externalEvent ) -  { -    cent = &cg_entities[ ps->clientNum ]; -    cent->currentState.event = ps->externalEvent; -    cent->currentState.eventParm = ps->externalEventParm; -    CG_EntityEvent( cent, cent->lerpOrigin ); -  } - -  cent = &cg.predictedPlayerEntity; // cg_entities[ ps->clientNum ]; - -  // go through the predictable events buffer -  for( i = ps->eventSequence - MAX_PS_EVENTS; i < ps->eventSequence; i++ ) -  { -    // if we have a new predictable event -    if( i >= ops->eventSequence || -      // or the server told us to play another event instead of a predicted event we already issued -      // or something the server told us changed our prediction causing a different event -      ( i > ops->eventSequence - MAX_PS_EVENTS && ps->events[ i & ( MAX_PS_EVENTS - 1 ) ] != -        ops->events[ i & ( MAX_PS_EVENTS - 1 ) ] ) ) -    { -      event = ps->events[ i & ( MAX_PS_EVENTS - 1 ) ]; - -      cent->currentState.event = event; -      cent->currentState.eventParm = ps->eventParms[ i & ( MAX_PS_EVENTS - 1 ) ]; -      CG_EntityEvent( cent, cent->lerpOrigin ); -      cg.predictableEvents[ i & ( MAX_PREDICTED_EVENTS - 1 ) ] = event; - -      cg.eventSequence++; -    } -  } -} - - -/* -================== -CG_CheckChangedPredictableEvents -================== -*/ -void CG_CheckChangedPredictableEvents( playerState_t *ps ) -{ -  int       i; -  int       event; -  centity_t *cent; - -  cent = &cg.predictedPlayerEntity; - -  for( i = ps->eventSequence - MAX_PS_EVENTS; i < ps->eventSequence; i++ ) -  { -    // -    if( i >= cg.eventSequence ) -      continue; - -    // if this event is not further back in than the maximum predictable events we remember -    if( i > cg.eventSequence - MAX_PREDICTED_EVENTS ) -    { -      // if the new playerstate event is different from a previously predicted one -      if( ps->events[ i & ( MAX_PS_EVENTS - 1 ) ] != cg.predictableEvents[ i & ( MAX_PREDICTED_EVENTS - 1 ) ] ) -      { -        event = ps->events[ i & ( MAX_PS_EVENTS - 1 ) ]; -        cent->currentState.event = event; -        cent->currentState.eventParm = ps->eventParms[ i & ( MAX_PS_EVENTS - 1 ) ]; -        CG_EntityEvent( cent, cent->lerpOrigin ); - -        cg.predictableEvents[ i & ( MAX_PREDICTED_EVENTS - 1 ) ] = event; - -        if( cg_showmiss.integer ) -          CG_Printf( "WARNING: changed predicted event\n" ); -      } -    } -  } -} - -/* -================== -CG_CheckLocalSounds -================== -*/ -void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) -{ -  int reward; - -  // don't play the sounds if the player just changed teams -  if( ps->persistant[ PERS_TEAM ] != ops->persistant[ PERS_TEAM ] ) -    return; - -  // health changes of more than -1 should make pain sounds -  if( ps->stats[ STAT_HEALTH ] < ops->stats[ STAT_HEALTH ] - 1 ) -  { -    if( ps->stats[ STAT_HEALTH ] > 0 ) -      CG_PainEvent( &cg.predictedPlayerEntity, ps->stats[ STAT_HEALTH ] ); -  } - - -  // if we are going into the intermission, don't start any voices -  if( cg.intermissionStarted ) -    return; - -  // reward sounds -  reward = qfalse; -} - - -/* -=============== -CG_TransitionPlayerState - -=============== -*/ -void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops ) -{ -  // check for changing follow mode -  if( ps->clientNum != ops->clientNum ) -  { -    cg.thisFrameTeleport = qtrue; -    // make sure we don't get any unwanted transition effects -    *ops = *ps; - -    CG_ResetPainBlend( ); -  } - -  // damage events (player is getting wounded) -  if( ps->damageEvent != ops->damageEvent && ps->damageCount ) -    CG_DamageFeedback( ps->damageYaw, ps->damagePitch, ps->damageCount ); - -  // respawning -  if( ps->persistant[ PERS_SPAWN_COUNT ] != ops->persistant[ PERS_SPAWN_COUNT ] ) -    CG_Respawn( ); - -  if( cg.mapRestart ) -  { -    CG_Respawn( ); -    cg.mapRestart = qfalse; -  } - -  if( cg.snap->ps.pm_type != PM_INTERMISSION && -      ps->persistant[ PERS_TEAM ] != TEAM_SPECTATOR ) -    CG_CheckLocalSounds( ps, ops ); - -  // run events -  CG_CheckPlayerstateEvents( ps, ops ); - -  // smooth the ducking viewheight change -  if( ps->viewheight != ops->viewheight ) -  { -    cg.duckChange = ps->viewheight - ops->viewheight; -    cg.duckTime = cg.time; -  } -} - diff --git a/mod/src/cgame/cg_predict.c b/mod/src/cgame/cg_predict.c deleted file mode 100644 index dc6c9dd5..00000000 --- a/mod/src/cgame/cg_predict.c +++ /dev/null @@ -1,615 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_predict.c -- this file generates cg.predictedPlayerState by either -// interpolating between snapshots from the server or locally predicting -// ahead the client's movement. -// It also handles local physics interaction, like fragments bouncing off walls - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -static  pmove_t   cg_pmove; - -static  int     cg_numSolidEntities; -static  centity_t *cg_solidEntities[MAX_ENTITIES_IN_SNAPSHOT]; -static  int     cg_numTriggerEntities; -static  centity_t *cg_triggerEntities[MAX_ENTITIES_IN_SNAPSHOT]; - -/* -==================== -CG_BuildSolidList - -When a new cg.snap has been set, this function builds a sublist -of the entities that are actually solid, to make for more -efficient collision detection -==================== -*/ -void CG_BuildSolidList( void ) -{ -  int           i; -  centity_t     *cent; -  snapshot_t    *snap; -  entityState_t *ent; - -  cg_numSolidEntities = 0; -  cg_numTriggerEntities = 0; - -  if( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport ) -    snap = cg.nextSnap; -  else -    snap = cg.snap; - -  for( i = 0; i < snap->numEntities; i++ ) -  { -    cent = &cg_entities[ snap->entities[ i ].number ]; -    ent = ¢->currentState; - -    if( ent->eType == ET_ITEM || ent->eType == ET_PUSH_TRIGGER || ent->eType == ET_TELEPORT_TRIGGER ) -    { -      cg_triggerEntities[ cg_numTriggerEntities ] = cent; -      cg_numTriggerEntities++; -      continue; -    } - -    if( cent->nextState.solid && ent->eType != ET_MISSILE ) -    { -      cg_solidEntities[ cg_numSolidEntities ] = cent; -      cg_numSolidEntities++; -      continue; -    } -  } -} - -/* -==================== -CG_ClipMoveToEntities - -==================== -*/ -static void CG_ClipMoveToEntities ( const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, -                                    int skipNumber, int mask, trace_t *tr, qboolean capsule ) -{ -  int           i, j, x, zd, zu; -  trace_t       trace; -  entityState_t *ent; -  clipHandle_t  cmodel; -  vec3_t        bmins, bmaxs; -  vec3_t        origin, angles; -  centity_t     *cent; - -  //SUPAR HACK -  //this causes a trace to collide with the local player -  if( skipNumber == MAGIC_TRACE_HACK ) -    j = cg_numSolidEntities + 1; -  else -    j = cg_numSolidEntities; - -  for( i = 0; i < j; i++ ) -  { -    if( i < cg_numSolidEntities ) -      cent = cg_solidEntities[ i ]; -    else -      cent = &cg.predictedPlayerEntity; - -    ent = ¢->currentState; - -    if( ent->number == skipNumber ) -      continue; - -    if( ent->solid == SOLID_BMODEL ) -    { -      // special value for bmodel -      cmodel = trap_CM_InlineModel( ent->modelindex ); -      VectorCopy( cent->lerpAngles, angles ); -      BG_EvaluateTrajectory( ¢->currentState.pos, cg.physicsTime, origin ); -    } -    else -    { -      // encoded bbox -      x = ( ent->solid & 255 ); -      zd = ( ( ent->solid >> 8 ) & 255 ); -      zu = ( ( ent->solid >> 16 ) & 255 ) - 32; - -      bmins[ 0 ] = bmins[ 1 ] = -x; -      bmaxs[ 0 ] = bmaxs[ 1 ] = x; -      bmins[ 2 ] = -zd; -      bmaxs[ 2 ] = zu; - -      if( i == cg_numSolidEntities ) -        BG_FindBBoxForClass( ( ent->powerups >> 8 ) & 0xFF, bmins, bmaxs, NULL, NULL, NULL ); - -      cmodel = trap_CM_TempBoxModel( bmins, bmaxs ); -      VectorCopy( vec3_origin, angles ); -      VectorCopy( cent->lerpOrigin, origin ); -    } - - -    if( capsule ) -    { -      trap_CM_TransformedCapsuleTrace ( &trace, start, end, -        mins, maxs, cmodel,  mask, origin, angles ); -    } -    else -    { -      trap_CM_TransformedBoxTrace ( &trace, start, end, -        mins, maxs, cmodel,  mask, origin, angles ); -    } - -    if( trace.allsolid || trace.fraction < tr->fraction ) -    { -      trace.entityNum = ent->number; -      *tr = trace; -    } -    else if( trace.startsolid ) -      tr->startsolid = qtrue; - -    if( tr->allsolid ) -      return; -  } -} - -/* -================ -CG_Trace -================ -*/ -void  CG_Trace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, -                int skipNumber, int mask ) -{ -  trace_t t; - -  trap_CM_BoxTrace( &t, start, end, mins, maxs, 0, mask ); -  t.entityNum = t.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE; -  // check all other solid models -  CG_ClipMoveToEntities( start, mins, maxs, end, skipNumber, mask, &t, qfalse ); - -  *result = t; -} - -/* -================ -CG_CapTrace -================ -*/ -void  CG_CapTrace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, -                   int skipNumber, int mask ) -{ -  trace_t t; - -  trap_CM_CapsuleTrace( &t, start, end, mins, maxs, 0, mask ); -  t.entityNum = t.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE; -  // check all other solid models -  CG_ClipMoveToEntities( start, mins, maxs, end, skipNumber, mask, &t, qtrue ); - -  *result = t; -} - -/* -================ -CG_PointContents -================ -*/ -int   CG_PointContents( const vec3_t point, int passEntityNum ) -{ -  int           i; -  entityState_t *ent; -  centity_t     *cent; -  clipHandle_t  cmodel; -  int           contents; - -  contents = trap_CM_PointContents (point, 0); - -  for( i = 0; i < cg_numSolidEntities; i++ ) -  { -    cent = cg_solidEntities[ i ]; - -    ent = ¢->currentState; - -    if( ent->number == passEntityNum ) -      continue; - -    if( ent->solid != SOLID_BMODEL ) // special value for bmodel -      continue; - -    cmodel = trap_CM_InlineModel( ent->modelindex ); - -    if( !cmodel ) -      continue; - -    contents |= trap_CM_TransformedPointContents( point, cmodel, ent->origin, ent->angles ); -  } - -  return contents; -} - - -/* -======================== -CG_InterpolatePlayerState - -Generates cg.predictedPlayerState by interpolating between -cg.snap->player_state and cg.nextFrame->player_state -======================== -*/ -static void CG_InterpolatePlayerState( qboolean grabAngles ) -{ -  float         f; -  int           i; -  playerState_t *out; -  snapshot_t    *prev, *next; - -  out = &cg.predictedPlayerState; -  prev = cg.snap; -  next = cg.nextSnap; - -  *out = cg.snap->ps; - -  // if we are still allowing local input, short circuit the view angles -  if( grabAngles ) -  { -    usercmd_t cmd; -    int     cmdNum; - -    cmdNum = trap_GetCurrentCmdNumber( ); -    trap_GetUserCmd( cmdNum, &cmd ); - -    PM_UpdateViewAngles( out, &cmd ); -  } - -  // if the next frame is a teleport, we can't lerp to it -  if( cg.nextFrameTeleport ) -    return; - -  if( !next || next->serverTime <= prev->serverTime ) -    return; - -  f = (float)( cg.time - prev->serverTime ) / ( next->serverTime - prev->serverTime ); - -  i = next->ps.bobCycle; -  if( i < prev->ps.bobCycle ) -    i += 256;   // handle wraparound - -  out->bobCycle = prev->ps.bobCycle + f * ( i - prev->ps.bobCycle ); - -  for( i = 0; i < 3; i++ ) -  { -    out->origin[ i ] = prev->ps.origin[ i ] + f * ( next->ps.origin[ i ] - prev->ps.origin[ i ] ); - -    if( !grabAngles ) -      out->viewangles[ i ] = LerpAngle( prev->ps.viewangles[ i ], next->ps.viewangles[ i ], f ); - -    out->velocity[ i ] = prev->ps.velocity[ i ] + -      f * (next->ps.velocity[ i ] - prev->ps.velocity[ i ] ); -  } -} - - -/* -========================= -CG_TouchTriggerPrediction - -Predict push triggers and items -========================= -*/ -static void CG_TouchTriggerPrediction( void ) -{ -  int           i; -  trace_t       trace; -  entityState_t *ent; -  clipHandle_t  cmodel; -  centity_t     *cent; -  qboolean      spectator; - -  // dead clients don't activate triggers -  if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 ) -    return; - -  spectator = ( cg.predictedPlayerState.pm_type == PM_SPECTATOR ); - -  if( cg.predictedPlayerState.pm_type != PM_NORMAL && !spectator ) -    return; - -  for( i = 0; i < cg_numTriggerEntities; i++ ) -  { -    cent = cg_triggerEntities[ i ]; -    ent = ¢->currentState; - -    if( ent->solid != SOLID_BMODEL ) -      continue; - -    cmodel = trap_CM_InlineModel( ent->modelindex ); -    if( !cmodel ) -      continue; - -    trap_CM_BoxTrace( &trace, cg.predictedPlayerState.origin, cg.predictedPlayerState.origin, -                      cg_pmove.mins, cg_pmove.maxs, cmodel, -1 ); - -    if( !trace.startsolid ) -      continue; - -    if( ent->eType == ET_TELEPORT_TRIGGER ) -      cg.hyperspace = qtrue; -  } - -  // if we didn't touch a jump pad this pmove frame -  if( cg.predictedPlayerState.jumppad_frame != cg.predictedPlayerState.pmove_framecount ) -  { -    cg.predictedPlayerState.jumppad_frame = 0; -    cg.predictedPlayerState.jumppad_ent = 0; -  } -} - - - -/* -================= -CG_PredictPlayerState - -Generates cg.predictedPlayerState for the current cg.time -cg.predictedPlayerState is guaranteed to be valid after exiting. - -For demo playback, this will be an interpolation between two valid -playerState_t. - -For normal gameplay, it will be the result of predicted usercmd_t on -top of the most recent playerState_t received from the server. - -Each new snapshot will usually have one or more new usercmd over the last, -but we simulate all unacknowledged commands each time, not just the new ones. -This means that on an internet connection, quite a few pmoves may be issued -each frame. - -OPTIMIZE: don't re-simulate unless the newly arrived snapshot playerState_t -differs from the predicted one.  Would require saving all intermediate -playerState_t during prediction. - -We detect prediction errors and allow them to be decayed off over several frames -to ease the jerk. -================= -*/ -void CG_PredictPlayerState( void ) -{ -  int     cmdNum, current, i; -  playerState_t oldPlayerState; -  qboolean  moved; -  usercmd_t oldestCmd; -  usercmd_t latestCmd; - -  cg.hyperspace = qfalse; // will be set if touching a trigger_teleport - -  // if this is the first frame we must guarantee -  // predictedPlayerState is valid even if there is some -  // other error condition -  if( !cg.validPPS ) -  { -    cg.validPPS = qtrue; -    cg.predictedPlayerState = cg.snap->ps; -  } - - -  // demo playback just copies the moves -  if( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) ) -  { -    CG_InterpolatePlayerState( qfalse ); -    return; -  } - -  // non-predicting local movement will grab the latest angles -  if( cg_nopredict.integer || cg_synchronousClients.integer ) -  { -    CG_InterpolatePlayerState( qtrue ); -    return; -  } - -  // prepare for pmove -  cg_pmove.ps = &cg.predictedPlayerState; -  cg_pmove.trace = CG_Trace; -  cg_pmove.pointcontents = CG_PointContents; -  cg_pmove.debugLevel = cg_debugMove.integer; - -  if( cg_pmove.ps->pm_type == PM_DEAD ) -    cg_pmove.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY; -  else -    cg_pmove.tracemask = MASK_PLAYERSOLID; - -  if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) -    cg_pmove.tracemask &= ~CONTENTS_BODY; // spectators can fly through bodies - -  cg_pmove.noFootsteps = 0; - -  // save the state before the pmove so we can detect transitions -  oldPlayerState = cg.predictedPlayerState; - -  current = trap_GetCurrentCmdNumber( ); - -  // if we don't have the commands right after the snapshot, we -  // can't accurately predict a current position, so just freeze at -  // the last good position we had -  cmdNum = current - CMD_BACKUP + 1; -  trap_GetUserCmd( cmdNum, &oldestCmd ); - -  if( oldestCmd.serverTime > cg.snap->ps.commandTime && -      oldestCmd.serverTime < cg.time ) -  { // special check for map_restart -    if( cg_showmiss.integer ) -      CG_Printf( "exceeded PACKET_BACKUP on commands\n" ); - -    return; -  } - -  // get the latest command so we can know which commands are from previous map_restarts -  trap_GetUserCmd( current, &latestCmd ); - -  // get the most recent information we have, even if -  // the server time is beyond our current cg.time, -  // because predicted player positions are going to -  // be ahead of everything else anyway -  if( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport ) -  { -    cg.predictedPlayerState = cg.nextSnap->ps; -    cg.physicsTime = cg.nextSnap->serverTime; -  } -  else -  { -    cg.predictedPlayerState = cg.snap->ps; -    cg.physicsTime = cg.snap->serverTime; -  } - -  if( pmove_msec.integer < 8 ) -    trap_Cvar_Set( "pmove_msec", "8" ); -  else if( pmove_msec.integer > 33 ) -    trap_Cvar_Set( "pmove_msec", "33" ); - -  cg_pmove.pmove_fixed = pmove_fixed.integer;// | cg_pmove_fixed.integer; -  cg_pmove.pmove_msec = pmove_msec.integer; - -  // run cmds -  moved = qfalse; - -  for( cmdNum = current - CMD_BACKUP + 1; cmdNum <= current; cmdNum++ ) -  { -    // get the command -    trap_GetUserCmd( cmdNum, &cg_pmove.cmd ); - -    if( cg_pmove.pmove_fixed ) -      PM_UpdateViewAngles( cg_pmove.ps, &cg_pmove.cmd ); - -    // don't do anything if the time is before the snapshot player time -    if( cg_pmove.cmd.serverTime <= cg.predictedPlayerState.commandTime ) -      continue; - -    // don't do anything if the command was from a previous map_restart -    if( cg_pmove.cmd.serverTime > latestCmd.serverTime ) -      continue; - -    // check for a prediction error from last frame -    // on a lan, this will often be the exact value -    // from the snapshot, but on a wan we will have -    // to predict several commands to get to the point -    // we want to compare -    if( cg.predictedPlayerState.commandTime == oldPlayerState.commandTime ) -    { -      vec3_t  delta; -      float   len; - -      if( cg.thisFrameTeleport ) -      { -        // a teleport will not cause an error decay -        VectorClear( cg.predictedError ); - -        if( cg_showmiss.integer ) -          CG_Printf( "PredictionTeleport\n" ); - -        cg.thisFrameTeleport = qfalse; -      } -      else -      { -        vec3_t  adjusted; -        CG_AdjustPositionForMover( cg.predictedPlayerState.origin, -          cg.predictedPlayerState.groundEntityNum, cg.physicsTime, cg.oldTime, adjusted ); - -        if( cg_showmiss.integer ) -        { -          if( !VectorCompare( oldPlayerState.origin, adjusted ) ) -            CG_Printf("prediction error\n"); -        } - -        VectorSubtract( oldPlayerState.origin, adjusted, delta ); -        len = VectorLength( delta ); - -        if( len > 0.1 ) -        { -          if( cg_showmiss.integer ) -            CG_Printf( "Prediction miss: %f\n", len ); - -          if( cg_errorDecay.integer ) -          { -            int   t; -            float f; - -            t = cg.time - cg.predictedErrorTime; -            f = ( cg_errorDecay.value - t ) / cg_errorDecay.value; - -            if( f < 0 ) -              f = 0; - -            if( f > 0 && cg_showmiss.integer ) -              CG_Printf( "Double prediction decay: %f\n", f ); - -            VectorScale( cg.predictedError, f, cg.predictedError ); -          } -          else -            VectorClear( cg.predictedError ); - -          VectorAdd( delta, cg.predictedError, cg.predictedError ); -          cg.predictedErrorTime = cg.oldTime; -        } -      } -    } - -    // don't predict gauntlet firing, which is only supposed to happen -    // when it actually inflicts damage -    for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) -      cg_pmove.autoWeaponHit[ i ] = qfalse; - -    if( cg_pmove.pmove_fixed ) -      cg_pmove.cmd.serverTime = ( ( cg_pmove.cmd.serverTime + pmove_msec.integer - 1 ) / -                                  pmove_msec.integer ) * pmove_msec.integer; - -    Pmove( &cg_pmove ); - -    moved = qtrue; - -    // add push trigger movement effects -    CG_TouchTriggerPrediction( ); - -    // check for predictable events that changed from previous predictions -    //CG_CheckChangedPredictableEvents(&cg.predictedPlayerState); -  } - -  if( cg_showmiss.integer > 1 ) -    CG_Printf( "[%i : %i] ", cg_pmove.cmd.serverTime, cg.time ); - -  if( !moved ) -  { -    if( cg_showmiss.integer ) -      CG_Printf( "not moved\n" ); - -    return; -  } - -  // adjust for the movement of the groundentity -  CG_AdjustPositionForMover( cg.predictedPlayerState.origin, -    cg.predictedPlayerState.groundEntityNum, -    cg.physicsTime, cg.time, cg.predictedPlayerState.origin ); - -  if( cg_showmiss.integer ) -  { -    if( cg.predictedPlayerState.eventSequence > oldPlayerState.eventSequence + MAX_PS_EVENTS ) -      CG_Printf( "WARNING: dropped event\n" ); -  } - -  // fire events and other transition triggered things -  CG_TransitionPlayerState( &cg.predictedPlayerState, &oldPlayerState ); - -  if( cg_showmiss.integer ) -  { -    if( cg.eventSequence > cg.predictedPlayerState.eventSequence ) -    { -      CG_Printf( "WARNING: double event\n" ); -      cg.eventSequence = cg.predictedPlayerState.eventSequence; -    } -  } -} diff --git a/mod/src/cgame/cg_ptr.c b/mod/src/cgame/cg_ptr.c deleted file mode 100644 index c31e5e40..00000000 --- a/mod/src/cgame/cg_ptr.c +++ /dev/null @@ -1,71 +0,0 @@ -// cg_ptr.c -- post timeout restoration handling - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -#define PTRC_FILE  "ptrc.cfg" - -/* -=============== -CG_ReadPTRCode - -Read a PTR code from disk -=============== -*/ -int CG_ReadPTRCode( void ) -{ -  int           len; -  char          text[ 16 ]; -  fileHandle_t  f; - -  // load the file -  len = trap_FS_FOpenFile( PTRC_FILE, &f, FS_READ ); -  if( len <= 0 ) -    return 0; - -  // should never happen - malformed write -  if( len >= sizeof( text ) - 1 ) -    return 0; - -  trap_FS_Read( text, len, f ); -  text[ len ] = 0; -  trap_FS_FCloseFile( f ); - -  return atoi( text ); -} - -/* -=============== -CG_WritePTRCode - -Write a PTR code to disk -=============== -*/ -void CG_WritePTRCode( int code ) -{ -  char          text[ 16 ]; -  fileHandle_t  f; - -  Com_sprintf( text, 16, "%d", code ); - -  // open file -  if( trap_FS_FOpenFile( PTRC_FILE, &f, FS_WRITE ) < 0 ) -    return; - -  // write the code -  trap_FS_Write( text, strlen( text ), f ); - -  trap_FS_FCloseFile( f ); -} diff --git a/mod/src/cgame/cg_public.h b/mod/src/cgame/cg_public.h deleted file mode 100644 index 39d1a402..00000000 --- a/mod/src/cgame/cg_public.h +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#define CMD_BACKUP      64 -#define CMD_MASK      (CMD_BACKUP - 1) -// allow a lot of command backups for very fast systems -// multiple commands may be combined into a single packet, so this -// needs to be larger than PACKET_BACKUP - - -#define MAX_ENTITIES_IN_SNAPSHOT  256 - -// snapshots are a view of the server at a given time - -// Snapshots are generated at regular time intervals by the server, -// but they may not be sent if a client's rate level is exceeded, or -// they may be dropped by the network. -typedef struct -{ -  int           snapFlags;                            // SNAPFLAG_RATE_DELAYED, etc -  int           ping; - -  int           serverTime;                           // server time the message is valid for (in msec) - -  byte          areamask[ MAX_MAP_AREA_BYTES ];       // portalarea visibility bits - -  playerState_t ps;                                   // complete information about the current player at this time - -  int           numEntities;                          // all of the entities that need to be presented -  entityState_t entities[ MAX_ENTITIES_IN_SNAPSHOT ]; // at the time of this snapshot - -  int           numServerCommands;                    // text based server commands to execute when this -  int           serverCommandSequence;                // snapshot becomes current -} snapshot_t; - -enum -{ -  CGAME_EVENT_NONE, -  CGAME_EVENT_TEAMMENU, -  CGAME_EVENT_SCOREBOARD, -  CGAME_EVENT_EDITHUD -}; - -/* -================================================================== - -functions imported from the main executable - -================================================================== -*/ - -#define CGAME_IMPORT_API_VERSION  4 - -typedef enum -{ -  CG_PRINT, -  CG_ERROR, -  CG_MILLISECONDS, -  CG_CVAR_REGISTER, -  CG_CVAR_UPDATE, -  CG_CVAR_SET, -  CG_CVAR_VARIABLESTRINGBUFFER, -  CG_ARGC, -  CG_ARGV, -  CG_ARGS, -  CG_FS_FOPENFILE, -  CG_FS_READ, -  CG_FS_WRITE, -  CG_FS_FCLOSEFILE, -  CG_SENDCONSOLECOMMAND, -  CG_ADDCOMMAND, -  CG_SENDCLIENTCOMMAND, -  CG_UPDATESCREEN, -  CG_CM_LOADMAP, -  CG_CM_NUMINLINEMODELS, -  CG_CM_INLINEMODEL, -  CG_CM_LOADMODEL, -  CG_CM_TEMPBOXMODEL, -  CG_CM_POINTCONTENTS, -  CG_CM_TRANSFORMEDPOINTCONTENTS, -  CG_CM_BOXTRACE, -  CG_CM_TRANSFORMEDBOXTRACE, -  CG_CM_MARKFRAGMENTS, -  CG_S_STARTSOUND, -  CG_S_STARTLOCALSOUND, -  CG_S_CLEARLOOPINGSOUNDS, -  CG_S_ADDLOOPINGSOUND, -  CG_S_UPDATEENTITYPOSITION, -  CG_S_RESPATIALIZE, -  CG_S_REGISTERSOUND, -  CG_S_STARTBACKGROUNDTRACK, -  CG_R_LOADWORLDMAP, -  CG_R_REGISTERMODEL, -  CG_R_REGISTERSKIN, -  CG_R_REGISTERSHADER, -  CG_R_CLEARSCENE, -  CG_R_ADDREFENTITYTOSCENE, -  CG_R_ADDPOLYTOSCENE, -  CG_R_ADDLIGHTTOSCENE, -  CG_R_RENDERSCENE, -  CG_R_SETCOLOR, -  CG_R_DRAWSTRETCHPIC, -  CG_R_MODELBOUNDS, -  CG_R_LERPTAG, -  CG_GETGLCONFIG, -  CG_GETGAMESTATE, -  CG_GETCURRENTSNAPSHOTNUMBER, -  CG_GETSNAPSHOT, -  CG_GETSERVERCOMMAND, -  CG_GETCURRENTCMDNUMBER, -  CG_GETUSERCMD, -  CG_SETUSERCMDVALUE, -  CG_R_REGISTERSHADERNOMIP, -  CG_MEMORY_REMAINING, -  CG_R_REGISTERFONT, -  CG_KEY_ISDOWN, -  CG_KEY_GETCATCHER, -  CG_KEY_SETCATCHER, -  CG_KEY_GETKEY, -  CG_PC_ADD_GLOBAL_DEFINE, -  CG_PC_LOAD_SOURCE, -  CG_PC_FREE_SOURCE, -  CG_PC_READ_TOKEN, -  CG_PC_SOURCE_FILE_AND_LINE, -  CG_S_STOPBACKGROUNDTRACK, -  CG_REAL_TIME, -  CG_SNAPVECTOR, -  CG_REMOVECOMMAND, -  CG_R_LIGHTFORPOINT, -  CG_CIN_PLAYCINEMATIC, -  CG_CIN_STOPCINEMATIC, -  CG_CIN_RUNCINEMATIC, -  CG_CIN_DRAWCINEMATIC, -  CG_CIN_SETEXTENTS, -  CG_R_REMAP_SHADER, -  CG_S_ADDREALLOOPINGSOUND, -  CG_S_STOPLOOPINGSOUND, - -  CG_CM_TEMPCAPSULEMODEL, -  CG_CM_CAPSULETRACE, -  CG_CM_TRANSFORMEDCAPSULETRACE, -  CG_R_ADDADDITIVELIGHTTOSCENE, -  CG_GET_ENTITY_TOKEN, -  CG_R_ADDPOLYSTOSCENE, -  CG_R_INPVS, -  CG_FS_SEEK, - -  CG_MEMSET = 100, -  CG_MEMCPY, -  CG_STRNCPY, -  CG_SIN, -  CG_COS, -  CG_ATAN2, -  CG_SQRT, -  CG_FLOOR, -  CG_CEIL, - -  CG_TESTPRINTINT, -  CG_TESTPRINTFLOAT, -  CG_ACOS -} cgameImport_t; - - -/* -================================================================== - -functions exported to the main executable - -================================================================== -*/ - -typedef enum -{ -  CG_INIT, -  // void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum ) -  // called when the level loads or when the renderer is restarted -  // all media should be registered at this time -  // cgame will display loading status by calling SCR_Update, which -  // will call CG_DrawInformation during the loading process -  // reliableCommandSequence will be 0 on fresh loads, but higher for -  // demos, tourney restarts, or vid_restarts - -  CG_SHUTDOWN, -  // void (*CG_Shutdown)( void ); -  // oportunity to flush and close any open files - -  CG_CONSOLE_COMMAND, -  // qboolean (*CG_ConsoleCommand)( void ); -  // a console command has been issued locally that is not recognized by the -  // main game system. -  // use Cmd_Argc() / Cmd_Argv() to read the command, return qfalse if the -  // command is not known to the game - -  CG_DRAW_ACTIVE_FRAME, -  // void (*CG_DrawActiveFrame)( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback ); -  // Generates and draws a game scene and status information at the given time. -  // If demoPlayback is set, local movement prediction will not be enabled - -  CG_CROSSHAIR_PLAYER, -  // int (*CG_CrosshairPlayer)( void ); - -  CG_LAST_ATTACKER, -  // int (*CG_LastAttacker)( void ); - -  CG_KEY_EVENT, -  // void  (*CG_KeyEvent)( int key, qboolean down ); - -  CG_MOUSE_EVENT, -  // void  (*CG_MouseEvent)( int dx, int dy ); -  CG_EVENT_HANDLING -  // void (*CG_EventHandling)(int type); -} cgameExport_t; - -//---------------------------------------------- diff --git a/mod/src/cgame/cg_scanner.c b/mod/src/cgame/cg_scanner.c deleted file mode 100644 index 6c2a9997..00000000 --- a/mod/src/cgame/cg_scanner.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -static entityPos_t   entityPositions; - -#define HUMAN_SCANNER_UPDATE_PERIOD 700 - -/* -============= -CG_UpdateEntityPositions - -Update this client's perception of entity positions -============= -*/ -void CG_UpdateEntityPositions( void ) -{ -  centity_t *cent = NULL; -  int       i; - -  if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS ) -  { -    if( entityPositions.lastUpdateTime + HUMAN_SCANNER_UPDATE_PERIOD > cg.time ) -      return; -  } - -  VectorCopy( cg.refdef.vieworg, entityPositions.origin ); -  VectorCopy( cg.refdefViewAngles, entityPositions.vangles ); -  entityPositions.lastUpdateTime = cg.time; - -  entityPositions.numAlienBuildables = 0; -  entityPositions.numHumanBuildables = 0; -  entityPositions.numAlienClients = 0; -  entityPositions.numHumanClients = 0; - -  for( i = 0; i < cg.snap->numEntities; i++ ) -  { -    cent = &cg_entities[ cg.snap->entities[ i ].number ]; - -    if( cent->currentState.eType == ET_BUILDABLE ) -    { -      //TA: add to list of item positions (for creep) -      if( cent->currentState.modelindex2 == BIT_ALIENS ) -      { -        VectorCopy( cent->lerpOrigin, entityPositions.alienBuildablePos[ -            entityPositions.numAlienBuildables ] ); -        entityPositions.alienBuildableTimes[ -            entityPositions.numAlienBuildables ] = cent->miscTime; - -        if( entityPositions.numAlienBuildables < MAX_GENTITIES ) -          entityPositions.numAlienBuildables++; -      } -      else if( cent->currentState.modelindex2 == BIT_HUMANS ) -      { -        VectorCopy( cent->lerpOrigin, entityPositions.humanBuildablePos[ -            entityPositions.numHumanBuildables ] ); - -        if( entityPositions.numHumanBuildables < MAX_GENTITIES ) -          entityPositions.numHumanBuildables++; -      } -    } -    else if( cent->currentState.eType == ET_PLAYER ) -    { -      int team = cent->currentState.powerups & 0x00FF; - -      if( team == PTE_ALIENS ) -      { -        VectorCopy( cent->lerpOrigin, entityPositions.alienClientPos[ -            entityPositions.numAlienClients ] ); - -        if( entityPositions.numAlienClients < MAX_CLIENTS ) -          entityPositions.numAlienClients++; -      } -      else if( team == PTE_HUMANS ) -      { -        VectorCopy( cent->lerpOrigin, entityPositions.humanClientPos[ -            entityPositions.numHumanClients ] ); - -        if( entityPositions.numHumanClients < MAX_CLIENTS ) -          entityPositions.numHumanClients++; -      } -    } -  } -} - -#define STALKWIDTH  2.0f -#define BLIPX       16.0f -#define BLIPY       8.0f -#define FAR_ALPHA   0.8f -#define NEAR_ALPHA  1.2f - -/* -============= -CG_DrawBlips - -Draw blips and stalks for the human scanner -============= -*/ -static void CG_DrawBlips( rectDef_t *rect, vec3_t origin, vec4_t colour ) -{ -  vec3_t  drawOrigin; -  vec3_t  up = { 0, 0, 1 }; -  float   alphaMod = 1.0f; -  float   timeFractionSinceRefresh = 1.0f - -    ( (float)( cg.time - entityPositions.lastUpdateTime ) / -      (float)HUMAN_SCANNER_UPDATE_PERIOD ); -  vec4_t  localColour; - -  Vector4Copy( colour, localColour ); - -  RotatePointAroundVector( drawOrigin, up, origin, -entityPositions.vangles[ 1 ] - 90 ); -  drawOrigin[ 0 ] /= ( 2 * HELMET_RANGE / rect->w ); -  drawOrigin[ 1 ] /= ( 2 * HELMET_RANGE / rect->h ); -  drawOrigin[ 2 ] /= ( 2 * HELMET_RANGE / rect->w ); - -  alphaMod = FAR_ALPHA + -    ( ( drawOrigin[ 1 ] + ( rect->h / 2.0f ) ) / rect->h ) * ( NEAR_ALPHA - FAR_ALPHA ); - -  localColour[ 3 ] *= alphaMod; -  localColour[ 3 ] *= ( 0.5f + ( timeFractionSinceRefresh * 0.5f ) ); - -  if( localColour[ 3 ] > 1.0f ) -    localColour[ 3 ] = 1.0f; -  else if( localColour[ 3 ] < 0.0f ) -    localColour[ 3 ] = 0.0f; - -  trap_R_SetColor( localColour ); - -  if( drawOrigin[ 2 ] > 0 ) -    CG_DrawPic( rect->x + ( rect->w / 2 ) - ( STALKWIDTH / 2 ) - drawOrigin[ 0 ], -                rect->y + ( rect->h / 2 ) + drawOrigin[ 1 ] - drawOrigin[ 2 ], -                STALKWIDTH, drawOrigin[ 2 ], cgs.media.scannerLineShader ); -  else -    CG_DrawPic( rect->x + ( rect->w / 2 ) - ( STALKWIDTH / 2 ) - drawOrigin[ 0 ], -                rect->y + ( rect->h / 2 ) + drawOrigin[ 1 ], -                STALKWIDTH, -drawOrigin[ 2 ], cgs.media.scannerLineShader ); - -  CG_DrawPic( rect->x + ( rect->w / 2 ) - ( BLIPX / 2 ) - drawOrigin[ 0 ], -              rect->y + ( rect->h / 2 ) - ( BLIPY / 2 ) + drawOrigin[ 1 ] - drawOrigin[ 2 ], -              BLIPX, BLIPY, cgs.media.scannerBlipShader ); -  trap_R_SetColor( NULL ); -} - -#define BLIPX2  24.0f -#define BLIPY2  24.0f - -/* -============= -CG_DrawDir - -Draw dot marking the direction to an enemy -============= -*/ -static void CG_DrawDir( rectDef_t *rect, vec3_t origin, vec4_t colour ) -{ -  vec3_t  drawOrigin; -  vec3_t  noZOrigin; -  vec3_t  normal, antinormal, normalDiff; -  vec3_t  view, noZview; -  vec3_t  up  = { 0.0f, 0.0f,   1.0f }; -  vec3_t  top = { 0.0f, -1.0f,  0.0f }; -  float   angle; -  playerState_t *ps = &cg.snap->ps; - -  if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) -  { -    if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) -      VectorSet( normal, 0.0f, 0.0f, -1.0f ); -    else -      VectorCopy( ps->grapplePoint, normal ); -  } -  else -    VectorSet( normal, 0.0f, 0.0f, 1.0f ); - -  AngleVectors( entityPositions.vangles, view, NULL, NULL ); - -  ProjectPointOnPlane( noZOrigin, origin, normal ); -  ProjectPointOnPlane( noZview, view, normal ); -  VectorNormalize( noZOrigin ); -  VectorNormalize( noZview ); - -  //calculate the angle between the images of the blip and the view -  angle = RAD2DEG( acos( DotProduct( noZOrigin, noZview ) ) ); -  CrossProduct( noZOrigin, noZview, antinormal ); -  VectorNormalize( antinormal ); - -  //decide which way to rotate -  VectorSubtract( normal, antinormal, normalDiff ); -  if( VectorLength( normalDiff ) < 1.0f ) -    angle = 360.0f - angle; - -  RotatePointAroundVector( drawOrigin, up, top, angle ); - -  trap_R_SetColor( colour ); -  CG_DrawPic( rect->x + ( rect->w / 2 ) - ( BLIPX2 / 2 ) - drawOrigin[ 0 ] * ( rect->w / 2 ), -              rect->y + ( rect->h / 2 ) - ( BLIPY2 / 2 ) + drawOrigin[ 1 ] * ( rect->h / 2 ), -              BLIPX2, BLIPY2, cgs.media.scannerBlipShader ); -  trap_R_SetColor( NULL ); -} - -/* -============= -CG_AlienSense -============= -*/ -void CG_AlienSense( rectDef_t *rect ) -{ -  int     i; -  vec3_t  origin; -  vec3_t  relOrigin; -  vec4_t  buildable = { 1.0f, 0.0f, 0.0f, 0.7f }; -  vec4_t  client    = { 0.0f, 0.0f, 1.0f, 0.7f }; - -  VectorCopy( entityPositions.origin, origin ); - -  //draw human buildables -  for( i = 0; i < entityPositions.numHumanBuildables; i++ ) -  { -    VectorClear( relOrigin ); -    VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin ); - -    if( VectorLength( relOrigin ) < ALIENSENSE_RANGE ) -      CG_DrawDir( rect, relOrigin, buildable ); -  } - -  //draw human clients -  for( i = 0; i < entityPositions.numHumanClients; i++ ) -  { -    VectorClear( relOrigin ); -    VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin ); - -    if( VectorLength( relOrigin ) < ALIENSENSE_RANGE ) -      CG_DrawDir( rect, relOrigin, client ); -  } -} - -/* -============= -CG_Scanner -============= -*/ -void CG_Scanner( rectDef_t *rect, qhandle_t shader, vec4_t color ) -{ -  int     i; -  vec3_t  origin; -  vec3_t  relOrigin; -  vec4_t  hIabove; -  vec4_t  hIbelow; -  vec4_t  aIabove = { 1.0f, 0.0f, 0.0f, 0.75f }; -  vec4_t  aIbelow = { 1.0f, 0.0f, 0.0f, 0.5f }; - -  Vector4Copy( color, hIabove ); -  hIabove[ 3 ] *= 1.5f; -  Vector4Copy( color, hIbelow ); - -  VectorCopy( entityPositions.origin, origin ); - -  //draw human buildables below scanner plane -  for( i = 0; i < entityPositions.numHumanBuildables; i++ ) -  { -    VectorClear( relOrigin ); -    VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin ); - -    if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] < 0 ) ) -      CG_DrawBlips( rect, relOrigin, hIbelow ); -  } - -  //draw alien buildables below scanner plane -  for( i = 0; i < entityPositions.numAlienBuildables; i++ ) -  { -    VectorClear( relOrigin ); -    VectorSubtract( entityPositions.alienBuildablePos[ i ], origin, relOrigin ); - -    if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] < 0 ) ) -      CG_DrawBlips( rect, relOrigin, aIbelow ); -  } - -  //draw human clients below scanner plane -  for( i = 0; i < entityPositions.numHumanClients; i++ ) -  { -    VectorClear( relOrigin ); -    VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin ); - -    if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] < 0 ) ) -      CG_DrawBlips( rect, relOrigin, hIbelow ); -  } - -  //draw alien buildables below scanner plane -  for( i = 0; i < entityPositions.numAlienClients; i++ ) -  { -    VectorClear( relOrigin ); -    VectorSubtract( entityPositions.alienClientPos[ i ], origin, relOrigin ); - -    if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] < 0 ) ) -      CG_DrawBlips( rect, relOrigin, aIbelow ); -  } - -  if( !cg_disableScannerPlane.integer ) -  { -    trap_R_SetColor( color ); -    CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); -    trap_R_SetColor( NULL ); -  } - -  //draw human buildables above scanner plane -  for( i = 0; i < entityPositions.numHumanBuildables; i++ ) -  { -    VectorClear( relOrigin ); -    VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin ); - -    if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] > 0 ) ) -      CG_DrawBlips( rect, relOrigin, hIabove ); -  } - -  //draw alien buildables above scanner plane -  for( i = 0; i < entityPositions.numAlienBuildables; i++ ) -  { -    VectorClear( relOrigin ); -    VectorSubtract( entityPositions.alienBuildablePos[ i ], origin, relOrigin ); - -    if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] > 0 ) ) -      CG_DrawBlips( rect, relOrigin, aIabove ); -  } - -  //draw human clients above scanner plane -  for( i = 0; i < entityPositions.numHumanClients; i++ ) -  { -    VectorClear( relOrigin ); -    VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin ); - -    if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] > 0 ) ) -      CG_DrawBlips( rect, relOrigin, hIabove ); -  } - -  //draw alien clients above scanner plane -  for( i = 0; i < entityPositions.numAlienClients; i++ ) -  { -    VectorClear( relOrigin ); -    VectorSubtract( entityPositions.alienClientPos[ i ], origin, relOrigin ); - -    if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] > 0 ) ) -      CG_DrawBlips( rect, relOrigin, aIabove ); -  } -} diff --git a/mod/src/cgame/cg_servercmds.c b/mod/src/cgame/cg_servercmds.c deleted file mode 100644 index 71fbaac9..00000000 --- a/mod/src/cgame/cg_servercmds.c +++ /dev/null @@ -1,1130 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_servercmds.c -- reliably sequenced text commands sent by the server -// these are processed at snapshot transition time, so there will definately -// be a valid snapshot this frame - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -/* -================= -CG_ParseScores - -================= -*/ -static void CG_ParseScores( void ) -{ -  int   i; - -  cg.numScores = atoi( CG_Argv( 1 ) ); - -  if( cg.numScores > MAX_CLIENTS ) -    cg.numScores = MAX_CLIENTS; - -  cg.teamScores[ 0 ] = atoi( CG_Argv( 2 ) ); -  cg.teamScores[ 1 ] = atoi( CG_Argv( 3 ) ); - -  memset( cg.scores, 0, sizeof( cg.scores ) ); - -  if( cg_debugRandom.integer ) -    CG_Printf( "cg.numScores: %d\n", cg.numScores ); - -  for( i = 0; i < cg.numScores; i++ ) -  { -    // -    cg.scores[ i ].client = atoi( CG_Argv( i * 6 + 4 ) ); -    cg.scores[ i ].score = atoi( CG_Argv( i * 6 + 5 ) ); -    cg.scores[ i ].ping = atoi( CG_Argv( i * 6 + 6 ) ); -    cg.scores[ i ].time = atoi( CG_Argv( i * 6 + 7 ) ); -    cg.scores[ i ].weapon = atoi( CG_Argv( i * 6 + 8 ) ); -    cg.scores[ i ].upgrade = atoi( CG_Argv( i * 6 + 9 ) ); - -    if( cg.scores[ i ].client < 0 || cg.scores[ i ].client >= MAX_CLIENTS ) -      cg.scores[ i ].client = 0; - -    cgs.clientinfo[ cg.scores[ i ].client ].score = cg.scores[ i ].score; -    cgs.clientinfo[ cg.scores[ i ].client ].powerups = 0; - -    cg.scores[ i ].team = cgs.clientinfo[ cg.scores[ i ].client ].team; -  } -} - -/* -================= -CG_ParseTeamInfo - -================= -*/ -static void CG_ParseTeamInfo( void ) -{ -  int   i; -  int   client; - -  numSortedTeamPlayers = atoi( CG_Argv( 1 ) ); - -  for( i = 0; i < numSortedTeamPlayers; i++ ) -  { -    client = atoi( CG_Argv( i * 6 + 2 ) ); - -    sortedTeamPlayers[ i ] = client; - -    cgs.clientinfo[ client ].location = atoi( CG_Argv( i * 6 + 3 ) ); -    cgs.clientinfo[ client ].health = atoi( CG_Argv( i * 6 + 4 ) ); -    cgs.clientinfo[ client ].armor = atoi( CG_Argv( i * 6 + 5 ) ); -    cgs.clientinfo[ client ].curWeapon = atoi( CG_Argv( i * 6 + 6 ) ); -    cgs.clientinfo[ client ].powerups = atoi( CG_Argv( i * 6 + 7 ) ); -  } -} - - -/* -================ -CG_ParseServerinfo - -This is called explicitly when the gamestate is first received, -and whenever the server updates any serverinfo flagged cvars -================ -*/ -void CG_ParseServerinfo( void ) -{ -  const char  *info; -  char  *mapname; - -  info = CG_ConfigString( CS_SERVERINFO ); -  cgs.dmflags = atoi( Info_ValueForKey( info, "dmflags" ) ); -  cgs.teamflags = atoi( Info_ValueForKey( info, "teamflags" ) ); -  cgs.timelimit = atoi( Info_ValueForKey( info, "timelimit" ) ); -  cgs.maxclients = atoi( Info_ValueForKey( info, "sv_maxclients" ) ); -  mapname = Info_ValueForKey( info, "mapname" ); -  Com_sprintf( cgs.mapname, sizeof( cgs.mapname ), "maps/%s.bsp", mapname ); -} - -/* -================== -CG_ParseWarmup -================== -*/ -static void CG_ParseWarmup( void ) -{ -  const char  *info; -  int         warmup; - -  info = CG_ConfigString( CS_WARMUP ); - -  warmup = atoi( info ); -  cg.warmupCount = -1; - -  if( warmup == 0 && cg.warmup ) -  { -  } - -  cg.warmup = warmup; -} - -/* -================ -CG_SetConfigValues - -Called on load to set the initial values from configure strings -================ -*/ -void CG_SetConfigValues( void ) -{ -  cgs.scores1 = atoi( CG_ConfigString( CS_SCORES1 ) ); -  cgs.scores2 = atoi( CG_ConfigString( CS_SCORES2 ) ); - -  sscanf( CG_ConfigString( CS_BUILDPOINTS ), -          "%d %d %d %d %d", &cgs.alienBuildPoints, -                            &cgs.alienBuildPointsTotal, -                            &cgs.humanBuildPoints, -                            &cgs.humanBuildPointsTotal, -                            &cgs.humanBuildPointsPowered ); - -  sscanf( CG_ConfigString( CS_STAGES ), "%d %d %d %d %d %d", &cgs.alienStage, &cgs.humanStage, -      &cgs.alienKills, &cgs.humanKills, &cgs.alienNextStageThreshold, &cgs.humanNextStageThreshold ); -  sscanf( CG_ConfigString( CS_SPAWNS ), "%d %d", &cgs.numAlienSpawns, &cgs.numHumanSpawns ); - -  cgs.levelStartTime = atoi( CG_ConfigString( CS_LEVEL_START_TIME ) ); -  cg.warmup = atoi( CG_ConfigString( CS_WARMUP ) ); -} - - -/* -===================== -CG_ShaderStateChanged -===================== -*/ -void CG_ShaderStateChanged( void ) -{ -  char        originalShader[ MAX_QPATH ]; -  char        newShader[ MAX_QPATH ]; -  char        timeOffset[ 16 ]; -  const char  *o; -  char        *n, *t; - -  o = CG_ConfigString( CS_SHADERSTATE ); - -  while( o && *o ) -  { -    n = strstr( o, "=" ); - -    if( n && *n ) -    { -      strncpy( originalShader, o, n - o ); -      originalShader[ n - o ] = 0; -      n++; -      t = strstr( n, ":" ); - -      if( t && *t ) -      { -        strncpy( newShader, n, t - n ); -        newShader[ t - n ] = 0; -      } -      else -        break; - -      t++; -      o = strstr( t, "@" ); - -      if( o ) -      { -        strncpy( timeOffset, t, o - t ); -        timeOffset[ o - t ] = 0; -        o++; -        trap_R_RemapShader( originalShader, newShader, timeOffset ); -      } -    } -    else -      break; -  } -} - -/* -================ -CG_AnnounceAlienStageTransistion -================ -*/ -static void CG_AnnounceAlienStageTransistion( stage_t from, stage_t to ) -{ -  if( cg.predictedPlayerState.stats[ STAT_PTEAM ] != PTE_ALIENS ) -    return; - -  trap_S_StartLocalSound( cgs.media.alienStageTransition, CHAN_ANNOUNCER ); -  CG_CenterPrint( "We have evolved!", 200, GIANTCHAR_WIDTH * 4 ); -} - -/* -================ -CG_AnnounceHumanStageTransistion -================ -*/ -static void CG_AnnounceHumanStageTransistion( stage_t from, stage_t to ) -{ -  if( cg.predictedPlayerState.stats[ STAT_PTEAM ] != PTE_HUMANS ) -    return; - -  trap_S_StartLocalSound( cgs.media.humanStageTransition, CHAN_ANNOUNCER ); -  CG_CenterPrint( "Reinforcements have arrived!", 200, GIANTCHAR_WIDTH * 4 ); -} - -/* -================ -CG_ConfigStringModified - -================ -*/ -static void CG_ConfigStringModified( void ) -{ -  const char  *str; -  int         num; - -  num = atoi( CG_Argv( 1 ) ); - -  // get the gamestate from the client system, which will have the -  // new configstring already integrated -  trap_GetGameState( &cgs.gameState ); - -  // look up the individual string that was modified -  str = CG_ConfigString( num ); - -  // do something with it if necessary -  if( num == CS_MUSIC ) -    CG_StartMusic( ); -  else if( num == CS_SERVERINFO ) -    CG_ParseServerinfo( ); -  else if( num == CS_WARMUP ) -    CG_ParseWarmup( ); -  else if( num == CS_SCORES1 ) -    cgs.scores1 = atoi( str ); -  else if( num == CS_SCORES2 ) -    cgs.scores2 = atoi( str ); -  else if( num == CS_BUILDPOINTS ) -    sscanf( str, "%d %d %d %d %d", &cgs.alienBuildPoints, -                                   &cgs.alienBuildPointsTotal, -                                   &cgs.humanBuildPoints, -                                   &cgs.humanBuildPointsTotal, -                                   &cgs.humanBuildPointsPowered ); -  else if( num == CS_STAGES ) -  { -    stage_t oldAlienStage = cgs.alienStage; -    stage_t oldHumanStage = cgs.humanStage; - -    sscanf( str, "%d %d %d %d %d %d", -        &cgs.alienStage, &cgs.humanStage, -        &cgs.alienKills, &cgs.humanKills, -        &cgs.alienNextStageThreshold, &cgs.humanNextStageThreshold ); - -    if( cgs.alienStage != oldAlienStage ) -      CG_AnnounceAlienStageTransistion( oldAlienStage, cgs.alienStage ); - -    if( cgs.humanStage != oldHumanStage ) -      CG_AnnounceHumanStageTransistion( oldHumanStage, cgs.humanStage ); -  } -  else if( num == CS_SPAWNS ) -    sscanf( str, "%d %d", &cgs.numAlienSpawns, &cgs.numHumanSpawns ); -  else if( num == CS_LEVEL_START_TIME ) -    cgs.levelStartTime = atoi( str ); -  else if( num == CS_VOTE_TIME ) -  { -    cgs.voteTime = atoi( str ); -    cgs.voteModified = qtrue; - -    if( cgs.voteTime ) -      trap_Cvar_Set( "ui_voteActive", "1" ); -    else -      trap_Cvar_Set( "ui_voteActive", "0" ); -  } -  else if( num == CS_VOTE_YES ) -  { -    cgs.voteYes = atoi( str ); -    cgs.voteModified = qtrue; -  } -  else if( num == CS_VOTE_NO ) -  { -    cgs.voteNo = atoi( str ); -    cgs.voteModified = qtrue; -  } -  else if( num == CS_VOTE_STRING ) -    Q_strncpyz( cgs.voteString, str, sizeof( cgs.voteString ) ); -  else if( num >= CS_TEAMVOTE_TIME && num <= CS_TEAMVOTE_TIME + 1 ) -  { -    int cs_offset = num - CS_TEAMVOTE_TIME; - -    cgs.teamVoteTime[ cs_offset ] = atoi( str ); -    cgs.teamVoteModified[ cs_offset ] = qtrue; - -    if( cs_offset == 0 ) -    { -      if( cgs.teamVoteTime[ cs_offset ] ) -        trap_Cvar_Set( "ui_humanTeamVoteActive", "1" ); -      else -        trap_Cvar_Set( "ui_humanTeamVoteActive", "0" ); -    } -    else if( cs_offset == 1 ) -    { -      if( cgs.teamVoteTime[ cs_offset ] ) -        trap_Cvar_Set( "ui_alienTeamVoteActive", "1" ); -      else -        trap_Cvar_Set( "ui_alienTeamVoteActive", "0" ); -    } -  } -  else if( num >= CS_TEAMVOTE_YES && num <= CS_TEAMVOTE_YES + 1 ) -  { -    cgs.teamVoteYes[ num - CS_TEAMVOTE_YES ] = atoi( str ); -    cgs.teamVoteModified[ num - CS_TEAMVOTE_YES ] = qtrue; -  } -  else if( num >= CS_TEAMVOTE_NO && num <= CS_TEAMVOTE_NO + 1 ) -  { -    cgs.teamVoteNo[ num - CS_TEAMVOTE_NO ] = atoi( str ); -    cgs.teamVoteModified[ num - CS_TEAMVOTE_NO ] = qtrue; -  } -  else if( num >= CS_TEAMVOTE_STRING && num <= CS_TEAMVOTE_STRING + 1 ) -    Q_strncpyz( cgs.teamVoteString[ num - CS_TEAMVOTE_STRING ], str, sizeof( cgs.teamVoteString ) ); -  else if( num == CS_INTERMISSION ) -    cg.intermissionStarted = atoi( str ); -  else if( num >= CS_MODELS && num < CS_MODELS+MAX_MODELS ) -    cgs.gameModels[ num - CS_MODELS ] = trap_R_RegisterModel( str ); -  else if( num >= CS_SHADERS && num < CS_SHADERS+MAX_SHADERS ) -    cgs.gameShaders[ num - CS_SHADERS ] = trap_R_RegisterShader( str ); -  else if( num >= CS_PARTICLE_SYSTEMS && num < CS_PARTICLE_SYSTEMS+MAX_GAME_PARTICLE_SYSTEMS ) -    cgs.gameParticleSystems[ num - CS_PARTICLE_SYSTEMS ] = CG_RegisterParticleSystem( (char *)str ); -  else if( num >= CS_SOUNDS && num < CS_SOUNDS+MAX_SOUNDS ) -  { -    if( str[ 0 ] != '*' ) -    {  // player specific sounds don't register here -      cgs.gameSounds[ num - CS_SOUNDS ] = trap_S_RegisterSound( str, qfalse ); -    } -  } -  else if( num >= CS_PLAYERS && num < CS_PLAYERS+MAX_CLIENTS ) -  { -    CG_NewClientInfo( num - CS_PLAYERS ); -    CG_BuildSpectatorString( ); -  } -  else if( num == CS_FLAGSTATUS ) -  { -  } -  else if( num == CS_SHADERSTATE ) -  { -    CG_ShaderStateChanged( ); -  } -} - - -/* -======================= -CG_AddToTeamChat - -======================= -*/ -static void CG_AddToTeamChat( const char *str ) -{ -  int   len; -  char  *p, *ls; -  int   lastcolor; -  int   chatHeight; - -  if( cg_teamChatHeight.integer < TEAMCHAT_HEIGHT ) -    chatHeight = cg_teamChatHeight.integer; -  else -    chatHeight = TEAMCHAT_HEIGHT; - -  if( chatHeight <= 0 || cg_teamChatTime.integer <= 0 ) -  { -    // team chat disabled, dump into normal chat -    cgs.teamChatPos = cgs.teamLastChatPos = 0; -    return; -  } - -  len = 0; - -  p = cgs.teamChatMsgs[cgs.teamChatPos % chatHeight]; -  *p = 0; - -  lastcolor = '7'; - -  ls = NULL; -  while( *str ) -  { -    if( len > TEAMCHAT_WIDTH - 1 ) -    { -      if( ls ) -      { -        str -= ( p - ls ); -        str++; -        p -= ( p - ls ); -      } - -      *p = 0; - -      cgs.teamChatMsgTimes[ cgs.teamChatPos % chatHeight ] = cg.time; - -      cgs.teamChatPos++; -      p = cgs.teamChatMsgs[ cgs.teamChatPos % chatHeight ]; -      *p = 0; -      *p++ = Q_COLOR_ESCAPE; -      *p++ = lastcolor; -      len = 0; -      ls = NULL; -    } - -    if( Q_IsColorString( str ) ) -    { -      *p++ = *str++; -      lastcolor = *str; -      *p++ = *str++; -      continue; -    } - -    if( *str == ' ' ) -      ls = p; - -    *p++ = *str++; -    len++; -  } -  *p = 0; - -  cgs.teamChatMsgTimes[ cgs.teamChatPos % chatHeight ] = cg.time; -  cgs.teamChatPos++; - -  if( cgs.teamChatPos - cgs.teamLastChatPos > chatHeight ) -    cgs.teamLastChatPos = cgs.teamChatPos - chatHeight; -} - - - -/* -=============== -CG_MapRestart - -The server has issued a map_restart, so the next snapshot -is completely new and should not be interpolated to. - -A tournement restart will clear everything, but doesn't -require a reload of all the media -=============== -*/ -static void CG_MapRestart( void ) -{ -  if( cg_showmiss.integer ) -    CG_Printf( "CG_MapRestart\n" ); - -  CG_InitMarkPolys( ); - -  // make sure the "3 frags left" warnings play again -  cg.fraglimitWarnings = 0; - -  cg.timelimitWarnings = 0; - -  cg.intermissionStarted = qfalse; - -  cgs.voteTime = 0; - -  cg.mapRestart = qtrue; - -  CG_StartMusic( ); - -  trap_S_ClearLoopingSounds( qtrue ); - -  // we really should clear more parts of cg here and stop sounds - -  // play the "fight" sound if this is a restart without warmup -  if( cg.warmup == 0 ) -    CG_CenterPrint( "FIGHT!", 120, GIANTCHAR_WIDTH * 2 ); - -  trap_Cvar_Set( "cg_thirdPerson", "0" ); -} - -/* -================= -CG_RemoveChatEscapeChar -================= -*/ -static void CG_RemoveChatEscapeChar( char *text ) -{ -  int i, l; - -  l = 0; -  for( i = 0; text[ i ]; i++ ) -  { -    if( text[ i ] == '\x19' ) -      continue; - -    text[ l++ ] = text[ i ]; -  } - -  text[ l ] = '\0'; -} - -/* -=============== -CG_SetUIVars - -Set some cvars used by the UI -=============== -*/ -static void CG_SetUIVars( void ) -{ -  int   i; -  char  carriageCvar[ MAX_TOKEN_CHARS ]; - -  *carriageCvar = 0; - -  //determine what the player is carrying -  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) -  { -    if( BG_InventoryContainsWeapon( i, cg.snap->ps.stats ) && -        BG_FindPurchasableForWeapon( i ) ) -      strcat( carriageCvar, va( "W%d ", i ) ); -  } -  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -  { -    if( BG_InventoryContainsUpgrade( i, cg.snap->ps.stats ) && -        BG_FindPurchasableForUpgrade( i ) ) -      strcat( carriageCvar, va( "U%d ", i ) ); -  } -  strcat( carriageCvar, "$" ); - -  trap_Cvar_Set( "ui_carriage", carriageCvar ); - -  trap_Cvar_Set( "ui_stages", va( "%d %d", cgs.alienStage, cgs.humanStage ) ); -} - - -/* -============== -CG_Menu -============== -*/ -void CG_Menu( int menu ) -{ -  CG_SetUIVars( ); - -  switch( menu ) -  { -    case MN_TEAM:       trap_SendConsoleCommand( "menu tremulous_teamselect\n" );   break; -    case MN_A_CLASS:    trap_SendConsoleCommand( "menu tremulous_alienclass\n" );   break; -    case MN_H_SPAWN:    trap_SendConsoleCommand( "menu tremulous_humanitem\n" );    break; -    case MN_A_BUILD:    trap_SendConsoleCommand( "menu tremulous_alienbuild\n" );   break; -    case MN_H_BUILD:    trap_SendConsoleCommand( "menu tremulous_humanbuild\n" );   break; -    case MN_H_ARMOURY:  trap_SendConsoleCommand( "menu tremulous_humanarmoury\n" ); break; - -    case MN_A_TEAMFULL: -      trap_Cvar_Set( "ui_dialog", "The alien team has too many players. Please wait until " -                                  "slots become available or join the human team." ); -      trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      break; - -    case MN_H_TEAMFULL: -      trap_Cvar_Set( "ui_dialog", "The human team has too many players. Please wait until " -                                  "slots become available or join the alien team." ); -      trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      break; - -    case MN_H_NOROOM: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "There is no room to build here. Move until the buildable turns " -                                    "translucent green indicating a valid build location." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "There is no room to build here\n" ); - -      break; - -    case MN_H_NOPOWER: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "There is no power remaining. Free up power by destroying existing " -                                    "buildable objects." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "There is no power remaining\n" ); - -      break; - -    case MN_H_NOTPOWERED: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "This buildable is not powered. Build a Reactor and/or Repeater in " -                                    "order to power it." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "This buildable is not powered\n" ); - -      break; - -    case MN_H_NORMAL: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "Cannot build on this surface. The surface is too steep or unsuitable " -                                    "to build on. Please choose another site for this structure." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "Cannot build on this surface\n" ); - -      break; - -    case MN_H_REACTOR: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "There can only be one Reactor. Destroy the existing one if you " -                                    "wish to move it." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "There can only be one Reactor\n" ); - -      break; - -    case MN_H_REPEATER: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "There is no power here. If available, a Repeater may be used to " -                                    "transmit power to this location." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "There is no power here\n" ); - -      break; - -    case MN_H_NODCC: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "There is no Defense Computer. A Defense Computer is needed to build " -                                    "this." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "There is no Defense Computer\n" ); - -      break; - -    case MN_H_TNODEWARN: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "WARNING: This Telenode will not be powered. Build near a power " -                                    "structure to prevent seeing this message again." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "This Telenode will not be powered\n" ); - -      break; - -    case MN_H_RPTWARN: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "WARNING: This Repeater will not be powered as there is no parent " -                                    "Reactor providing power. Build a Reactor." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "This Repeater will not be powered\n" ); - -      break; - -    case MN_H_RPTWARN2: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "This area already has power. A Repeater is not required here." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "This area already has power\n" ); - -      break; - -    case MN_H_NOSLOTS: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "You have no room to carry this. Please sell any conflicting " -                                    "upgrades before purchasing this item." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "You have no room to carry this\n" ); - -      break; - -    case MN_H_NOFUNDS: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "Insufficient funds. You do not have enough credits to perform this " -                                    "action." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "Insufficient funds\n" ); - -      break; - -    case MN_H_ITEMHELD: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "You already hold this item. It is not possible to carry multiple items " -                                    "of the same type." ); -        trap_SendConsoleCommand( "menu tremulous_human_dialog\n" ); -      } -      else -        CG_Printf( "You already hold this item\n" ); - -      break; - - -    //=============================== - - -    case MN_A_NOROOM: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "There is no room to build here. Move until the structure turns " -                                    "translucent green indicating a valid build location." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "There is no room to build here\n" ); - -      break; - -    case MN_A_NOCREEP: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "There is no creep here. You must build near existing Eggs or " -                                    "the Overmind. Alien structures will not support themselves." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "There is no creep here\n" ); - -      break; - -    case MN_A_NOOVMND: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "There is no Overmind. An Overmind must be built to control " -                                    "the structure you tried to place" ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "There is no Overmind\n" ); - -      break; - -    case MN_A_OVERMIND: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "There can only be one Overmind. Destroy the existing one if you " -                                    "wish to move it." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "There can only be one Overmind\n" ); - -      break; - -    case MN_A_HOVEL: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "There can only be one Hovel. Destroy the existing one if you " -                                    "wish to move it." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "There can only be one Hovel\n" ); - -      break; - -    case MN_A_NOASSERT: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "The Overmind cannot control any more structures. Destroy existing " -                                    "structures to build more." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "The Overmind cannot control any more structures\n" ); - -      break; - -    case MN_A_SPWNWARN: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "WARNING: This spawn will not be controlled by an Overmind. " -                                    "Build an Overmind to prevent seeing this message again." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "This spawn will not be controlled by an Overmind\n" ); - -      break; - -    case MN_A_NORMAL: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "Cannot build on this surface. This surface is too steep or unsuitable " -                                    "to build on. Please choose another site for this structure." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "Cannot build on this surface\n" ); - -      break; - -    case MN_A_NOEROOM: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "There is no room to evolve here. Move away from walls or other " -                                    "nearby objects and try again." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "There is no room to evolve here\n" ); - -      break; - -    case MN_A_TOOCLOSE: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "This location is too close to the enemy to evolve. " -                                    "Move away until you are no longer aware of the enemy's " -                                    "presence and try again." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "This location is too close to the enemy to evolve\n" ); - -      break; - -    case MN_A_NOOVMND_EVOLVE: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "There is no Overmind. An Overmind must be built to allow " -                                    "you to upgrade." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "There is no Overmind\n" ); - -      break; - -    case MN_A_HOVEL_OCCUPIED: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "This Hovel is occupied by another builder. Please find or build " -                                    "another." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "This Hovel is occupied by another builder\n" ); - -      break; - -    case MN_A_HOVEL_BLOCKED: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "The exit to this Hovel is currently blocked. Please wait until it " -                                    "becomes clear then try again." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "The exit to this Hovel is currently blocked\n" ); - -      break; - -    case MN_A_HOVEL_EXIT: -      if( !cg_disableWarningDialogs.integer ) -      { -        trap_Cvar_Set( "ui_dialog", "The exit to this Hovel would always be blocked. Please choose " -                                    "a more suitable location." ); -        trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); -      } -      else -        CG_Printf( "The exit to this Hovel would always be blocked\n" ); - -      break; - -    case MN_A_INFEST: -      trap_Cvar_Set( "ui_currentClass", va( "%d %d",  cg.snap->ps.stats[ STAT_PCLASS ], -                                                      cg.snap->ps.persistant[ PERS_CREDIT ] ) ); -      trap_SendConsoleCommand( "menu tremulous_alienupgrade\n" ); -      break; - -    default: -      Com_Printf( "cgame: debug: no such menu %d\n", menu ); -  } -} - -/* -================= -CG_ServerCommand - -The string has been tokenized and can be retrieved with -Cmd_Argc() / Cmd_Argv() -================= -*/ -static void CG_ServerCommand( void ) -{ -  const char  *cmd; -  char        text[ MAX_SAY_TEXT ]; - -  cmd = CG_Argv( 0 ); - -  if( !cmd[ 0 ] ) -  { -    // server claimed the command -    return; -  } - -  if( !strcmp( cmd, "cp" ) ) -  { -    CG_CenterPrint( CG_Argv( 1 ), SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH ); -    return; -  } - -  if( !strcmp( cmd, "cs" ) ) -  { -    CG_ConfigStringModified( ); -    return; -  } - -  if( !strcmp( cmd, "print" ) ) -  { -    CG_Printf( "%s", CG_Argv( 1 ) ); -    return; -  } - -  if( !strcmp( cmd, "chat" ) ) -  { -    if( !cg_teamChatsOnly.integer ) -    { -      trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND ); -      Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT ); -      CG_RemoveChatEscapeChar( text ); -      CG_Printf( "%s\n", text ); -    } - -    return; -  } - -  if( !strcmp( cmd, "tchat" ) ) -  { -    trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND ); -    Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT ); -    CG_RemoveChatEscapeChar( text ); -    CG_AddToTeamChat( text ); -    CG_Printf( "%s\n", text ); -    return; -  } - -  if( !strcmp( cmd, "scores" ) ) -  { -    CG_ParseScores( ); -    return; -  } - -  if( !strcmp( cmd, "tinfo" ) ) -  { -    CG_ParseTeamInfo( ); -    return; -  } - -  if( !strcmp( cmd, "map_restart" ) ) -  { -    CG_MapRestart( ); -    return; -  } - -  if( Q_stricmp( cmd, "remapShader" ) == 0 ) -  { -    if( trap_Argc( ) == 4 ) -      trap_R_RemapShader( CG_Argv( 1 ), CG_Argv( 2 ), CG_Argv( 3 ) ); -  } - -  // clientLevelShot is sent before taking a special screenshot for -  // the menu system during development -  if( !strcmp( cmd, "clientLevelShot" ) ) -  { -    cg.levelShot = qtrue; -    return; -  } - -  //enable G_Printfs from the server to appear in the TA console -  if( !strcmp( cmd, "gprintf" ) ) -  { -    if( trap_Argc( ) == 2 ) -      CG_TAUIConsole( CG_Argv( 1 ) ); - -    return; -  } - -  //the server has triggered a menu -  if( !strcmp( cmd, "servermenu" ) ) -  { -    if( trap_Argc( ) == 2 && !cg.demoPlayback ) -      CG_Menu( atoi( CG_Argv( 1 ) ) ); - -    return; -  } - -  //the server thinks this client should close all menus -  if( !strcmp( cmd, "serverclosemenus" ) ) -  { -    trap_SendConsoleCommand( "closemenus\n" ); -    return; -  } - -  //poison cloud effect needs to be reliable -  if( !strcmp( cmd, "poisoncloud" ) ) -  { -    cg.poisonedTime = cg.time; - -    if( CG_IsParticleSystemValid( &cg.poisonCloudPS ) ) -    { -      cg.poisonCloudPS = CG_SpawnNewParticleSystem( cgs.media.poisonCloudPS ); -      CG_SetAttachmentCent( &cg.poisonCloudPS->attachment, &cg.predictedPlayerEntity ); -      CG_AttachToCent( &cg.poisonCloudPS->attachment ); -    } - -    return; -  } - -  if( !strcmp( cmd, "weaponswitch" ) ) -  { -    CG_Printf( "client weaponswitch\n" ); -    if( trap_Argc( ) == 2 ) -    { -      cg.weaponSelect = atoi( CG_Argv( 1 ) ); -      cg.weaponSelectTime = cg.time; -    } - -    return; -  } - -  // server requests a ptrc -  if( !strcmp( cmd, "ptrcrequest" ) ) -  { -    int   code = CG_ReadPTRCode( ); - -    trap_SendClientCommand( va( "ptrcverify %d", code ) ); -    return; -  } - -  // server issues a ptrc -  if( !strcmp( cmd, "ptrcissue" ) ) -  { -    if( trap_Argc( ) == 2 ) -    { -      int code = atoi( CG_Argv( 1 ) ); - -      CG_WritePTRCode( code ); -    } - -    return; -  } - -  // reply to ptrcverify -  if( !strcmp( cmd, "ptrcconfirm" ) ) -  { -    trap_SendConsoleCommand( "menu ptrc_popmenu\n" ); - -    return; -  } - -  CG_Printf( "Unknown client game command: %s\n", cmd ); -} - - -/* -==================== -CG_ExecuteNewServerCommands - -Execute all of the server commands that were received along -with this this snapshot. -==================== -*/ -void CG_ExecuteNewServerCommands( int latestSequence ) -{ -  while( cgs.serverCommandSequence < latestSequence ) -  { -    if( trap_GetServerCommand( ++cgs.serverCommandSequence ) ) -      CG_ServerCommand( ); -  } -} diff --git a/mod/src/cgame/cg_snapshot.c b/mod/src/cgame/cg_snapshot.c deleted file mode 100644 index 4a5722ae..00000000 --- a/mod/src/cgame/cg_snapshot.c +++ /dev/null @@ -1,402 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_snapshot.c -- things that happen on snapshot transition, -// not necessarily every single rendered frame - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -/* -================== -CG_ResetEntity -================== -*/ -static void CG_ResetEntity( centity_t *cent ) -{ -  // if the previous snapshot this entity was updated in is at least -  // an event window back in time then we can reset the previous event -  if( cent->snapShotTime < cg.time - EVENT_VALID_MSEC ) -    cent->previousEvent = 0; - -  cent->trailTime = cg.snap->serverTime; - -  VectorCopy( cent->currentState.origin, cent->lerpOrigin ); -  VectorCopy( cent->currentState.angles, cent->lerpAngles ); - -  if( cent->currentState.eType == ET_PLAYER ) -    CG_ResetPlayerEntity( cent ); -} - -/* -=============== -CG_TransitionEntity - -cent->nextState is moved to cent->currentState and events are fired -=============== -*/ -static void CG_TransitionEntity( centity_t *cent ) -{ -  cent->currentState = cent->nextState; -  cent->currentValid = qtrue; - -  // reset if the entity wasn't in the last frame or was teleported -  if( !cent->interpolate ) -    CG_ResetEntity( cent ); - -  // clear the next state.  if will be set by the next CG_SetNextSnap -  cent->interpolate = qfalse; - -  // check for events -  CG_CheckEvents( cent ); -} - - -/* -================== -CG_SetInitialSnapshot - -This will only happen on the very first snapshot, or -on tourney restarts.  All other times will use -CG_TransitionSnapshot instead. - -FIXME: Also called by map_restart? -================== -*/ -void CG_SetInitialSnapshot( snapshot_t *snap ) -{ -  int           i; -  centity_t     *cent; -  entityState_t *state; - -  cg.snap = snap; - -  BG_PlayerStateToEntityState( &snap->ps, &cg_entities[ snap->ps.clientNum ].currentState, qfalse ); - -  // sort out solid entities -  CG_BuildSolidList( ); - -  CG_ExecuteNewServerCommands( snap->serverCommandSequence ); - -  // set our local weapon selection pointer to -  // what the server has indicated the current weapon is -  CG_Respawn( ); - -  for( i = 0; i < cg.snap->numEntities; i++ ) -  { -    state = &cg.snap->entities[ i ]; -    cent = &cg_entities[ state->number ]; - -    memcpy( ¢->currentState, state, sizeof( entityState_t ) ); -    //cent->currentState = *state; -    cent->interpolate = qfalse; -    cent->currentValid = qtrue; - -    CG_ResetEntity( cent ); - -    // check for events -    CG_CheckEvents( cent ); -  } -} - - -/* -=================== -CG_TransitionSnapshot - -The transition point from snap to nextSnap has passed -=================== -*/ -static void CG_TransitionSnapshot( void ) -{ -  centity_t   *cent; -  snapshot_t  *oldFrame; -  int         i; - -  if( !cg.snap ) -    CG_Error( "CG_TransitionSnapshot: NULL cg.snap" ); - -  if( !cg.nextSnap ) -    CG_Error( "CG_TransitionSnapshot: NULL cg.nextSnap" ); - -  // execute any server string commands before transitioning entities -  CG_ExecuteNewServerCommands( cg.nextSnap->serverCommandSequence ); - -  // if we had a map_restart, set everthing with initial -  if( !cg.snap ) { } //TA: ? - -  // clear the currentValid flag for all entities in the existing snapshot -  for( i = 0; i < cg.snap->numEntities; i++ ) -  { -    cent = &cg_entities[ cg.snap->entities[ i ].number ]; -    cent->currentValid = qfalse; -  } - -  // move nextSnap to snap and do the transitions -  oldFrame = cg.snap; -  cg.snap = cg.nextSnap; - -  BG_PlayerStateToEntityState( &cg.snap->ps, &cg_entities[ cg.snap->ps.clientNum ].currentState, qfalse ); -  cg_entities[ cg.snap->ps.clientNum ].interpolate = qfalse; - -  for( i = 0; i < cg.snap->numEntities; i++ ) -  { -    cent = &cg_entities[ cg.snap->entities[ i ].number ]; -    CG_TransitionEntity( cent ); - -    // remember time of snapshot this entity was last updated in -    cent->snapShotTime = cg.snap->serverTime; -  } - -  cg.nextSnap = NULL; - -  // check for playerstate transition events -  if( oldFrame ) -  { -    playerState_t *ops, *ps; - -    ops = &oldFrame->ps; -    ps = &cg.snap->ps; -    // teleporting checks are irrespective of prediction -    if( ( ps->eFlags ^ ops->eFlags ) & EF_TELEPORT_BIT ) -      cg.thisFrameTeleport = qtrue; // will be cleared by prediction code - -    // if we are not doing client side movement prediction for any -    // reason, then the client events and view changes will be issued now -    if( cg.demoPlayback || ( cg.snap->ps.pm_flags & PMF_FOLLOW ) || -        cg_nopredict.integer || cg_synchronousClients.integer ) -      CG_TransitionPlayerState( ps, ops ); -  } -} - - -/* -=================== -CG_SetNextSnap - -A new snapshot has just been read in from the client system. -=================== -*/ -static void CG_SetNextSnap( snapshot_t *snap ) -{ -  int           num; -  entityState_t *es; -  centity_t     *cent; - -  cg.nextSnap = snap; - -  BG_PlayerStateToEntityState( &snap->ps, &cg_entities[ snap->ps.clientNum ].nextState, qfalse ); -  cg_entities[ cg.snap->ps.clientNum ].interpolate = qtrue; - -  // check for extrapolation errors -  for( num = 0 ; num < snap->numEntities ; num++ ) -  { -    es = &snap->entities[ num ]; -    cent = &cg_entities[ es->number ]; - -    memcpy( ¢->nextState, es, sizeof( entityState_t ) ); -    //cent->nextState = *es; - -    // if this frame is a teleport, or the entity wasn't in the -    // previous frame, don't interpolate -    if( !cent->currentValid || ( ( cent->currentState.eFlags ^ es->eFlags ) & EF_TELEPORT_BIT ) ) -      cent->interpolate = qfalse; -    else -      cent->interpolate = qtrue; -  } - -  // if the next frame is a teleport for the playerstate, we -  // can't interpolate during demos -  if( cg.snap && ( ( snap->ps.eFlags ^ cg.snap->ps.eFlags ) & EF_TELEPORT_BIT ) ) -    cg.nextFrameTeleport = qtrue; -  else -    cg.nextFrameTeleport = qfalse; - -  // if changing follow mode, don't interpolate -  if( cg.nextSnap->ps.clientNum != cg.snap->ps.clientNum ) -    cg.nextFrameTeleport = qtrue; - -  // if changing server restarts, don't interpolate -  if( ( cg.nextSnap->snapFlags ^ cg.snap->snapFlags ) & SNAPFLAG_SERVERCOUNT ) -    cg.nextFrameTeleport = qtrue; - -  // sort out solid entities -  CG_BuildSolidList( ); -} - - -/* -======================== -CG_ReadNextSnapshot - -This is the only place new snapshots are requested -This may increment cgs.processedSnapshotNum multiple -times if the client system fails to return a -valid snapshot. -======================== -*/ -static snapshot_t *CG_ReadNextSnapshot( void ) -{ -  qboolean    r; -  snapshot_t  *dest; - -  if( cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000 ) -  { -    CG_Printf( "WARNING: CG_ReadNextSnapshot: way out of range, %i > %i", -      cg.latestSnapshotNum, cgs.processedSnapshotNum ); -  } - -  while( cgs.processedSnapshotNum < cg.latestSnapshotNum ) -  { -    // decide which of the two slots to load it into -    if( cg.snap == &cg.activeSnapshots[ 0 ] ) -      dest = &cg.activeSnapshots[ 1 ]; -    else -      dest = &cg.activeSnapshots[ 0 ]; - -    // try to read the snapshot from the client system -    cgs.processedSnapshotNum++; -    r = trap_GetSnapshot( cgs.processedSnapshotNum, dest ); - -    // FIXME: why would trap_GetSnapshot return a snapshot with the same server time -    if( cg.snap && r && dest->serverTime == cg.snap->serverTime ) -    { -      //continue; -    } - -    // if it succeeded, return -    if( r ) -    { -      CG_AddLagometerSnapshotInfo( dest ); -      return dest; -    } - -    // a GetSnapshot will return failure if the snapshot -    // never arrived, or  is so old that its entities -    // have been shoved off the end of the circular -    // buffer in the client system. - -    // record as a dropped packet -    CG_AddLagometerSnapshotInfo( NULL ); - -    // If there are additional snapshots, continue trying to -    // read them. -  } - -  // nothing left to read -  return NULL; -} - - -/* -============ -CG_ProcessSnapshots - -We are trying to set up a renderable view, so determine -what the simulated time is, and try to get snapshots -both before and after that time if available. - -If we don't have a valid cg.snap after exiting this function, -then a 3D game view cannot be rendered.  This should only happen -right after the initial connection.  After cg.snap has been valid -once, it will never turn invalid. - -Even if cg.snap is valid, cg.nextSnap may not be, if the snapshot -hasn't arrived yet (it becomes an extrapolating situation instead -of an interpolating one) - -============ -*/ -void CG_ProcessSnapshots( void ) -{ -  snapshot_t  *snap; -  int         n; - -  // see what the latest snapshot the client system has is -  trap_GetCurrentSnapshotNumber( &n, &cg.latestSnapshotTime ); - -  if( n != cg.latestSnapshotNum ) -  { -    if( n < cg.latestSnapshotNum ) -    { -      // this should never happen -      CG_Error( "CG_ProcessSnapshots: n < cg.latestSnapshotNum" ); -    } - -    cg.latestSnapshotNum = n; -  } - -  // If we have yet to receive a snapshot, check for it. -  // Once we have gotten the first snapshot, cg.snap will -  // always have valid data for the rest of the game -  while( !cg.snap ) -  { -    snap = CG_ReadNextSnapshot( ); - -    if( !snap ) -    { -      // we can't continue until we get a snapshot -      return; -    } - -    // set our weapon selection to what -    // the playerstate is currently using -    if( !( snap->snapFlags & SNAPFLAG_NOT_ACTIVE ) ) -      CG_SetInitialSnapshot( snap ); -  } - -  // loop until we either have a valid nextSnap with a serverTime -  // greater than cg.time to interpolate towards, or we run -  // out of available snapshots -  do -  { -    // if we don't have a nextframe, try and read a new one in -    if( !cg.nextSnap ) -    { -      snap = CG_ReadNextSnapshot( ); - -      // if we still don't have a nextframe, we will just have to -      // extrapolate -      if( !snap ) -        break; - -      CG_SetNextSnap( snap ); - -      // if time went backwards, we have a level restart -      if( cg.nextSnap->serverTime < cg.snap->serverTime ) -        CG_Error( "CG_ProcessSnapshots: Server time went backwards" ); -    } - -    // if our time is < nextFrame's, we have a nice interpolating state -    if( cg.time >= cg.snap->serverTime && cg.time < cg.nextSnap->serverTime ) -      break; - -    // we have passed the transition from nextFrame to frame -    CG_TransitionSnapshot( ); -  } while( 1 ); - -  // assert our valid conditions upon exiting -  if( cg.snap == NULL ) -    CG_Error( "CG_ProcessSnapshots: cg.snap == NULL" ); - -  if( cg.time < cg.snap->serverTime ) -  { -    // this can happen right after a vid_restart -    cg.time = cg.snap->serverTime; -  } - -  if( cg.nextSnap != NULL && cg.nextSnap->serverTime <= cg.time ) -    CG_Error( "CG_ProcessSnapshots: cg.nextSnap->serverTime <= cg.time" ); -} - diff --git a/mod/src/cgame/cg_syscalls.asm b/mod/src/cgame/cg_syscalls.asm deleted file mode 100644 index 9da1dade..00000000 --- a/mod/src/cgame/cg_syscalls.asm +++ /dev/null @@ -1,105 +0,0 @@ -code - -equ trap_Print                        -1 -equ trap_Error                        -2 -equ trap_Milliseconds                 -3 -equ trap_Cvar_Register                -4 -equ trap_Cvar_Update                  -5 -equ trap_Cvar_Set                     -6 -equ trap_Cvar_VariableStringBuffer    -7 -equ trap_Argc                         -8 -equ trap_Argv                         -9 -equ trap_Args                         -10 -equ trap_FS_FOpenFile                 -11 -equ trap_FS_Read                      -12 -equ trap_FS_Write                     -13  -equ trap_FS_FCloseFile                -14 -equ trap_SendConsoleCommand           -15 -equ trap_AddCommand                   -16 -equ trap_SendClientCommand            -17 -equ trap_UpdateScreen                 -18 -equ trap_CM_LoadMap                   -19 -equ trap_CM_NumInlineModels           -20 -equ trap_CM_InlineModel               -21 -equ trap_CM_LoadModel                 -22 -equ trap_CM_TempBoxModel              -23 -equ trap_CM_PointContents             -24 -equ trap_CM_TransformedPointContents  -25 -equ trap_CM_BoxTrace                  -26 -equ trap_CM_TransformedBoxTrace       -27 -equ trap_CM_MarkFragments             -28 -equ trap_S_StartSound                 -29 -equ trap_S_StartLocalSound            -30 -equ trap_S_ClearLoopingSounds         -31 -equ trap_S_AddLoopingSound            -32 -equ trap_S_UpdateEntityPosition       -33 -equ trap_S_Respatialize               -34 -equ trap_S_RegisterSound              -35 -equ trap_S_StartBackgroundTrack       -36 -equ trap_R_LoadWorldMap               -37 -equ trap_R_RegisterModel              -38 -equ trap_R_RegisterSkin               -39 -equ trap_R_RegisterShader             -40 -equ trap_R_ClearScene                 -41 -equ trap_R_AddRefEntityToScene        -42 -equ trap_R_AddPolyToScene             -43 -equ trap_R_AddLightToScene            -44 -equ trap_R_RenderScene                -45 -equ trap_R_SetColor                   -46 -equ trap_R_DrawStretchPic             -47 -equ trap_R_ModelBounds                -48 -equ trap_R_LerpTag                    -49 -equ trap_GetGlconfig                  -50 -equ trap_GetGameState                 -51 -equ trap_GetCurrentSnapshotNumber     -52 -equ trap_GetSnapshot                  -53 -equ trap_GetServerCommand             -54 -equ trap_GetCurrentCmdNumber          -55 -equ trap_GetUserCmd                   -56 -equ trap_SetUserCmdValue              -57 -equ trap_R_RegisterShaderNoMip        -58 -equ trap_MemoryRemaining              -59 -equ trap_R_RegisterFont               -60 -equ trap_Key_IsDown                   -61 -equ trap_Key_GetCatcher               -62 -equ trap_Key_SetCatcher               -63 -equ trap_Key_GetKey                   -64 -equ trap_PC_AddGlobalDefine           -65 -equ trap_PC_LoadSource                -66 -equ trap_PC_FreeSource                -67 -equ trap_PC_ReadToken                 -68 -equ trap_PC_SourceFileAndLine         -69 -equ trap_S_StopBackgroundTrack        -70 -equ trap_RealTime                     -71 -equ trap_SnapVector                   -72 -equ trap_RemoveCommand                -73 -equ trap_R_LightForPoint              -74 -equ trap_CIN_PlayCinematic            -75 -equ trap_CIN_StopCinematic            -76 -equ trap_CIN_RunCinematic             -77 -equ trap_CIN_DrawCinematic            -78 -equ trap_CIN_SetExtents               -79 -equ trap_R_RemapShader                -80 -equ trap_S_AddRealLoopingSound        -81 -equ trap_S_StopLoopingSound           -82 -equ trap_CM_TempCapsuleModel          -83 -equ trap_CM_CapsuleTrace              -84 -equ trap_CM_TransformedCapsuleTrace   -85 -equ trap_R_AddAdditiveLightToScene    -86 -equ trap_GetEntityToken               -87 -equ trap_R_AddPolysToScene            -88 -equ trap_R_inPVS                      -89 -equ trap_FS_Seek                      -90 - -equ memset                            -101 -equ memcpy                            -102 -equ strncpy                           -103 -equ sin                               -104 -equ cos                               -105 -equ atan2                             -106 -equ sqrt                              -107 -equ floor                             -108 -equ ceil                              -109 -equ testPrintInt                      -110 -equ testPrintFloat                    -111 - diff --git a/mod/src/cgame/cg_syscalls.c b/mod/src/cgame/cg_syscalls.c deleted file mode 100644 index 3e8c5849..00000000 --- a/mod/src/cgame/cg_syscalls.c +++ /dev/null @@ -1,507 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_syscalls.c -- this file is only included when building a dll -// cg_syscalls.asm is included instead when building a qvm - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -static long (QDECL *syscall)( long arg, ... ) = (long (QDECL *)( long, ...))-1; - - -void dllEntry( long (QDECL  *syscallptr)( long arg,... ) ) -{ -  syscall = syscallptr; -} - - -int PASSFLOAT( float x ) -{ -  float floatTemp; -  floatTemp = x; -  return *(int *)&floatTemp; -} - -void trap_Print( const char *fmt ) -{ -  syscall( CG_PRINT, fmt ); -} - -void trap_Error( const char *fmt ) -{ -  syscall( CG_ERROR, fmt ); -} - -int trap_Milliseconds( void ) -{ -  return syscall( CG_MILLISECONDS ); -} - -void trap_Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags ) -{ -  syscall( CG_CVAR_REGISTER, vmCvar, varName, defaultValue, flags ); -} - -void trap_Cvar_Update( vmCvar_t *vmCvar ) -{ -  syscall( CG_CVAR_UPDATE, vmCvar ); -} - -void trap_Cvar_Set( const char *var_name, const char *value ) -{ -  syscall( CG_CVAR_SET, var_name, value ); -} - -void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ) -{ -  syscall( CG_CVAR_VARIABLESTRINGBUFFER, var_name, buffer, bufsize ); -} - -int trap_Argc( void ) -{ -  return syscall( CG_ARGC ); -} - -void  trap_Argv( int n, char *buffer, int bufferLength ) -{ -  syscall( CG_ARGV, n, buffer, bufferLength ); -} - -void  trap_Args( char *buffer, int bufferLength ) -{ -  syscall( CG_ARGS, buffer, bufferLength ); -} - -int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode ) -{ -  return syscall( CG_FS_FOPENFILE, qpath, f, mode ); -} - -void  trap_FS_Read( void *buffer, int len, fileHandle_t f ) -{ -  syscall( CG_FS_READ, buffer, len, f ); -} - -void trap_FS_Write( const void *buffer, int len, fileHandle_t f ) -{ -  syscall( CG_FS_WRITE, buffer, len, f ); -} - -void  trap_FS_FCloseFile( fileHandle_t f ) -{ -  syscall( CG_FS_FCLOSEFILE, f ); -} - -void trap_FS_Seek( fileHandle_t f, long offset, fsOrigin_t origin ) -{ -  syscall( CG_FS_SEEK, f, offset, origin ); -} - -void  trap_SendConsoleCommand( const char *text ) -{ -  syscall( CG_SENDCONSOLECOMMAND, text ); -} - -void  trap_AddCommand( const char *cmdName ) -{ -  syscall( CG_ADDCOMMAND, cmdName ); -} - -void  trap_RemoveCommand( const char *cmdName ) -{ -    syscall( CG_REMOVECOMMAND, cmdName ); -} - -void  trap_SendClientCommand( const char *s ) -{ -  syscall( CG_SENDCLIENTCOMMAND, s ); -} - -void  trap_UpdateScreen( void ) -{ -  syscall( CG_UPDATESCREEN ); -} - -void  trap_CM_LoadMap( const char *mapname ) -{ -  syscall( CG_CM_LOADMAP, mapname ); -} - -int   trap_CM_NumInlineModels( void ) -{ -  return syscall( CG_CM_NUMINLINEMODELS ); -} - -clipHandle_t trap_CM_InlineModel( int index ) -{ -  return syscall( CG_CM_INLINEMODEL, index ); -} - -clipHandle_t trap_CM_TempBoxModel( const vec3_t mins, const vec3_t maxs ) -{ -  return syscall( CG_CM_TEMPBOXMODEL, mins, maxs ); -} - -clipHandle_t trap_CM_TempCapsuleModel( const vec3_t mins, const vec3_t maxs ) -{ -  return syscall( CG_CM_TEMPCAPSULEMODEL, mins, maxs ); -} - -int   trap_CM_PointContents( const vec3_t p, clipHandle_t model ) -{ -  return syscall( CG_CM_POINTCONTENTS, p, model ); -} - -int   trap_CM_TransformedPointContents( const vec3_t p, clipHandle_t model, const vec3_t origin, -                                        const vec3_t angles ) -{ -  return syscall( CG_CM_TRANSFORMEDPOINTCONTENTS, p, model, origin, angles ); -} - -void  trap_CM_BoxTrace( trace_t *results, const vec3_t start, const vec3_t end, -              const vec3_t mins, const vec3_t maxs, -              clipHandle_t model, int brushmask ) -{ -  syscall( CG_CM_BOXTRACE, results, start, end, mins, maxs, model, brushmask ); -} - -void  trap_CM_CapsuleTrace( trace_t *results, const vec3_t start, const vec3_t end, -              const vec3_t mins, const vec3_t maxs, -              clipHandle_t model, int brushmask ) -{ -  syscall( CG_CM_CAPSULETRACE, results, start, end, mins, maxs, model, brushmask ); -} - -void  trap_CM_TransformedBoxTrace( trace_t *results, const vec3_t start, const vec3_t end, -              const vec3_t mins, const vec3_t maxs, -              clipHandle_t model, int brushmask, -              const vec3_t origin, const vec3_t angles ) -{ -  syscall( CG_CM_TRANSFORMEDBOXTRACE, results, start, end, mins, maxs, model, brushmask, origin, angles ); -} - -void  trap_CM_TransformedCapsuleTrace( trace_t *results, const vec3_t start, const vec3_t end, -              const vec3_t mins, const vec3_t maxs, -              clipHandle_t model, int brushmask, -              const vec3_t origin, const vec3_t angles ) -{ -  syscall( CG_CM_TRANSFORMEDCAPSULETRACE, results, start, end, mins, maxs, model, brushmask, origin, angles ); -} - -int   trap_CM_MarkFragments( int numPoints, const vec3_t *points, -        const vec3_t projection, -        int maxPoints, vec3_t pointBuffer, -        int maxFragments, markFragment_t *fragmentBuffer ) -{ -  return syscall( CG_CM_MARKFRAGMENTS, numPoints, points, projection, maxPoints, -                  pointBuffer, maxFragments, fragmentBuffer ); -} - -void  trap_S_StartSound( vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfx ) -{ -  syscall( CG_S_STARTSOUND, origin, entityNum, entchannel, sfx ); -} - -void  trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum ) -{ -  syscall( CG_S_STARTLOCALSOUND, sfx, channelNum ); -} - -void  trap_S_ClearLoopingSounds( qboolean killall ) -{ -  syscall( CG_S_CLEARLOOPINGSOUNDS, killall ); -} - -void  trap_S_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ) -{ -  syscall( CG_S_ADDLOOPINGSOUND, entityNum, origin, velocity, sfx ); -} - -void  trap_S_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ) -{ -  syscall( CG_S_ADDREALLOOPINGSOUND, entityNum, origin, velocity, sfx ); -} - -void  trap_S_StopLoopingSound( int entityNum ) -{ -  syscall( CG_S_STOPLOOPINGSOUND, entityNum ); -} - -void  trap_S_UpdateEntityPosition( int entityNum, const vec3_t origin ) -{ -  syscall( CG_S_UPDATEENTITYPOSITION, entityNum, origin ); -} - -void  trap_S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater ) -{ -  syscall( CG_S_RESPATIALIZE, entityNum, origin, axis, inwater ); -} - -sfxHandle_t trap_S_RegisterSound( const char *sample, qboolean compressed ) -{ -  return syscall( CG_S_REGISTERSOUND, sample, compressed ); -} - -void  trap_S_StartBackgroundTrack( const char *intro, const char *loop ) -{ -  syscall( CG_S_STARTBACKGROUNDTRACK, intro, loop ); -} - -void  trap_R_LoadWorldMap( const char *mapname ) -{ -  syscall( CG_R_LOADWORLDMAP, mapname ); -} - -qhandle_t trap_R_RegisterModel( const char *name ) -{ -  return syscall( CG_R_REGISTERMODEL, name ); -} - -qhandle_t trap_R_RegisterSkin( const char *name ) -{ -  return syscall( CG_R_REGISTERSKIN, name ); -} - -qhandle_t trap_R_RegisterShader( const char *name ) -{ -  return syscall( CG_R_REGISTERSHADER, name ); -} - -qhandle_t trap_R_RegisterShaderNoMip( const char *name ) -{ -  return syscall( CG_R_REGISTERSHADERNOMIP, name ); -} - -void trap_R_RegisterFont( const char *fontName, int pointSize, fontInfo_t *font ) -{ -  syscall(CG_R_REGISTERFONT, fontName, pointSize, font ); -} - -void  trap_R_ClearScene( void ) -{ -  syscall( CG_R_CLEARSCENE ); -} - -void  trap_R_AddRefEntityToScene( const refEntity_t *re ) -{ -  syscall( CG_R_ADDREFENTITYTOSCENE, re ); -} - -void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts ) -{ -  syscall( CG_R_ADDPOLYTOSCENE, hShader, numVerts, verts ); -} - -void trap_R_AddPolysToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts, int num ) -{ -  syscall( CG_R_ADDPOLYSTOSCENE, hShader, numVerts, verts, num ); -} - -int trap_R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir ) -{ -  return syscall( CG_R_LIGHTFORPOINT, point, ambientLight, directedLight, lightDir ); -} - -void  trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b ) -{ -  syscall( CG_R_ADDLIGHTTOSCENE, org, PASSFLOAT(intensity), PASSFLOAT(r), PASSFLOAT(g), PASSFLOAT(b) ); -} - -void  trap_R_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b ) -{ -  syscall( CG_R_ADDADDITIVELIGHTTOSCENE, org, PASSFLOAT(intensity), PASSFLOAT(r), PASSFLOAT(g), PASSFLOAT(b) ); -} - -void  trap_R_RenderScene( const refdef_t *fd ) -{ -  syscall( CG_R_RENDERSCENE, fd ); -} - -void  trap_R_SetColor( const float *rgba ) -{ -  syscall( CG_R_SETCOLOR, rgba ); -} - -void  trap_R_DrawStretchPic( float x, float y, float w, float h, -                 float s1, float t1, float s2, float t2, qhandle_t hShader ) -{ -  syscall( CG_R_DRAWSTRETCHPIC, PASSFLOAT(x), PASSFLOAT(y), PASSFLOAT(w), PASSFLOAT(h), -           PASSFLOAT(s1), PASSFLOAT(t1), PASSFLOAT(s2), PASSFLOAT(t2), hShader ); -} - -void  trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs ) { -  syscall( CG_R_MODELBOUNDS, model, mins, maxs ); -} - -int   trap_R_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, -             float frac, const char *tagName ) -{ -  return syscall( CG_R_LERPTAG, tag, mod, startFrame, endFrame, PASSFLOAT(frac), tagName ); -} - -void  trap_R_RemapShader( const char *oldShader, const char *newShader, const char *timeOffset ) -{ -  syscall( CG_R_REMAP_SHADER, oldShader, newShader, timeOffset ); -} - -void trap_GetGlconfig( glconfig_t *glconfig ) -{ -  syscall( CG_GETGLCONFIG, glconfig ); -} - -void trap_GetGameState( gameState_t *gamestate ) -{ -  syscall( CG_GETGAMESTATE, gamestate ); -} - -void trap_GetCurrentSnapshotNumber( int *snapshotNumber, int *serverTime ) -{ -  syscall( CG_GETCURRENTSNAPSHOTNUMBER, snapshotNumber, serverTime ); -} - -qboolean  trap_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) -{ -  return syscall( CG_GETSNAPSHOT, snapshotNumber, snapshot ); -} - -qboolean  trap_GetServerCommand( int serverCommandNumber ) -{ -  return syscall( CG_GETSERVERCOMMAND, serverCommandNumber ); -} - -int trap_GetCurrentCmdNumber( void ) -{ -  return syscall( CG_GETCURRENTCMDNUMBER ); -} - -qboolean  trap_GetUserCmd( int cmdNumber, usercmd_t *ucmd ) -{ -  return syscall( CG_GETUSERCMD, cmdNumber, ucmd ); -} - -void    trap_SetUserCmdValue( int stateValue, float sensitivityScale ) -{ -  syscall( CG_SETUSERCMDVALUE, stateValue, PASSFLOAT( sensitivityScale ) ); -} - -void    testPrintInt( char *string, int i ) -{ -  syscall( CG_TESTPRINTINT, string, i ); -} - -void    testPrintFloat( char *string, float f ) -{ -  syscall( CG_TESTPRINTFLOAT, string, PASSFLOAT(f) ); -} - -int trap_MemoryRemaining( void ) -{ -  return syscall( CG_MEMORY_REMAINING ); -} - -qboolean trap_Key_IsDown( int keynum ) -{ -  return syscall( CG_KEY_ISDOWN, keynum ); -} - -int trap_Key_GetCatcher( void ) -{ -  return syscall( CG_KEY_GETCATCHER ); -} - -void trap_Key_SetCatcher( int catcher ) -{ -  syscall( CG_KEY_SETCATCHER, catcher ); -} - -int trap_Key_GetKey( const char *binding ) -{ -  return syscall( CG_KEY_GETKEY, binding ); -} - -int trap_PC_AddGlobalDefine( char *define ) -{ -  return syscall( CG_PC_ADD_GLOBAL_DEFINE, define ); -} - -int trap_PC_LoadSource( const char *filename ) -{ -  return syscall( CG_PC_LOAD_SOURCE, filename ); -} - -int trap_PC_FreeSource( int handle ) -{ -  return syscall( CG_PC_FREE_SOURCE, handle ); -} - -int trap_PC_ReadToken( int handle, pc_token_t *pc_token ) -{ -  return syscall( CG_PC_READ_TOKEN, handle, pc_token ); -} - -int trap_PC_SourceFileAndLine( int handle, char *filename, int *line ) -{ -  return syscall( CG_PC_SOURCE_FILE_AND_LINE, handle, filename, line ); -} - -void  trap_S_StopBackgroundTrack( void ) -{ -  syscall( CG_S_STOPBACKGROUNDTRACK ); -} - -int trap_RealTime(qtime_t *qtime) -{ -  return syscall( CG_REAL_TIME, qtime ); -} - -void trap_SnapVector( float *v ) -{ -  syscall( CG_SNAPVECTOR, v ); -} - -// this returns a handle.  arg0 is the name in the format "idlogo.roq", set arg1 to NULL, alteredstates to qfalse (do not alter gamestate) -int trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits ) -{ -  return syscall(CG_CIN_PLAYCINEMATIC, arg0, xpos, ypos, width, height, bits); -} - -// stops playing the cinematic and ends it.  should always return FMV_EOF -// cinematics must be stopped in reverse order of when they are started -e_status trap_CIN_StopCinematic( int handle ) -{ -  return syscall(CG_CIN_STOPCINEMATIC, handle); -} - - -// will run a frame of the cinematic but will not draw it.  Will return FMV_EOF if the end of the cinematic has been reached. -e_status trap_CIN_RunCinematic( int handle ) -{ -  return syscall(CG_CIN_RUNCINEMATIC, handle); -} - - -// draws the current frame -void trap_CIN_DrawCinematic( int handle ) -{ -  syscall(CG_CIN_DRAWCINEMATIC, handle); -} - - -// allows you to resize the animation dynamically -void trap_CIN_SetExtents( int handle, int x, int y, int w, int h ) -{ -  syscall(CG_CIN_SETEXTENTS, handle, x, y, w, h); -} - diff --git a/mod/src/cgame/cg_trails.c b/mod/src/cgame/cg_trails.c deleted file mode 100644 index 3ef19f00..00000000 --- a/mod/src/cgame/cg_trails.c +++ /dev/null @@ -1,1489 +0,0 @@ -// cg_trails.c -- the trail system - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -static baseTrailSystem_t  baseTrailSystems[ MAX_BASETRAIL_SYSTEMS ]; -static baseTrailBeam_t    baseTrailBeams[ MAX_BASETRAIL_BEAMS ]; -static int                numBaseTrailSystems = 0; -static int                numBaseTrailBeams = 0; - -static trailSystem_t      trailSystems[ MAX_TRAIL_SYSTEMS ]; -static trailBeam_t        trailBeams[ MAX_TRAIL_BEAMS ]; - -/* -=============== -CG_CalculateBeamNodeProperties - -Fills in trailBeamNode_t.textureCoord -=============== -*/ -static void CG_CalculateBeamNodeProperties( trailBeam_t *tb ) -{ -  trailBeamNode_t *i = NULL; -  trailSystem_t   *ts; -  baseTrailBeam_t *btb; -  float           nodeDistances[ MAX_TRAIL_BEAM_NODES ]; -  float           totalDistance = 0.0f, position = 0.0f; -  int             j, numNodes = 0; -  float           TCRange, widthRange, alphaRange; -  vec3_t          colorRange; -  float           fadeAlpha = 1.0f; - -  if( !tb || !tb->nodes ) -    return; - -  ts = tb->parent; -  btb = tb->class; - -  if( ts->destroyTime > 0 && btb->fadeOutTime ) -  { -    fadeAlpha -= ( cg.time - ts->destroyTime ) / btb->fadeOutTime; - -    if( fadeAlpha < 0.0f ) -      fadeAlpha = 0.0f; -  } - -  TCRange = tb->class->backTextureCoord - -    tb->class->frontTextureCoord; -  widthRange = tb->class->backWidth - -    tb->class->frontWidth; -  alphaRange = tb->class->backAlpha - -    tb->class->frontAlpha; -  VectorSubtract( tb->class->backColor, -      tb->class->frontColor, colorRange ); - -  for( i = tb->nodes; i && i->next; i = i->next ) -  { -    nodeDistances[ numNodes++ ] = -      Distance( i->position, i->next->position ); -  } - -  for( j = 0; j < numNodes; j++ ) -    totalDistance += nodeDistances[ j ]; - -  for( j = 0, i = tb->nodes; i; i = i->next, j++ ) -  { -    if( tb->class->textureType == TBTT_STRETCH ) -    { -      i->textureCoord = tb->class->frontTextureCoord + -        ( ( position / totalDistance ) * TCRange ); -    } -    else if( tb->class->textureType == TBTT_REPEAT ) -    { -      if( tb->class->clampToBack ) -        i->textureCoord = ( totalDistance - position ) / -          tb->class->repeatLength; -      else -        i->textureCoord = position / tb->class->repeatLength; -    } - -    i->halfWidth = ( tb->class->frontWidth + -      ( ( position / totalDistance ) * widthRange ) ) / 2.0f; -    i->alpha = (byte)( (float)0xFF * ( tb->class->frontAlpha + -      ( ( position / totalDistance ) * alphaRange ) ) * fadeAlpha ); -    VectorMA( tb->class->frontColor, ( position / totalDistance ), -        colorRange, i->color ); - -    position += nodeDistances[ j ]; -  } -} - -/* -=============== -CG_LightVertex - -Lights a particular vertex -=============== -*/ -static void CG_LightVertex( vec3_t point, byte alpha, byte *rgba ) -{ -  int     i; -  vec3_t  alight, dlight, lightdir; - -  trap_R_LightForPoint( point, alight, dlight, lightdir ); -  for( i = 0; i <= 2; i++ ) -    rgba[ i ] = (int)alight[ i ]; - -  rgba[ 3 ] = alpha; -} - -/* -=============== -CG_RenderBeam - -Renders a beam -=============== -*/ -static void CG_RenderBeam( trailBeam_t *tb ) -{ -  trailBeamNode_t   *i = NULL; -  trailBeamNode_t   *prev = NULL; -  trailBeamNode_t   *next = NULL; -  vec3_t            up; -  polyVert_t        verts[ ( MAX_TRAIL_BEAM_NODES - 1 ) * 4 ]; -  int               numVerts = 0; -  baseTrailBeam_t   *btb; -  trailSystem_t     *ts; -  baseTrailSystem_t *bts; - -  if( !tb || !tb->nodes ) -    return; - -  btb = tb->class; -  ts = tb->parent; -  bts = ts->class; - -  if( bts->thirdPersonOnly && -      ( CG_AttachmentCentNum( &ts->frontAttachment ) == cg.snap->ps.clientNum || -        CG_AttachmentCentNum( &ts->backAttachment ) == cg.snap->ps.clientNum ) && -      !cg.renderingThirdPerson ) -    return; - -  CG_CalculateBeamNodeProperties( tb ); - -  i = tb->nodes; - -  do -  { -    prev = i->prev; -    next = i->next; - -    if( prev && next ) -    { -      //this node has two neighbours -      GetPerpendicularViewVector( cg.refdef.vieworg, next->position, prev->position, up ); -    } -    else if( !prev && next ) -    { -      //this is the front -      GetPerpendicularViewVector( cg.refdef.vieworg, next->position, i->position, up ); -    } -    else if( prev && !next ) -    { -      //this is the back -      GetPerpendicularViewVector( cg.refdef.vieworg, i->position, prev->position, up ); -    } -    else -      break; - -    if( prev ) -    { -      VectorMA( i->position, i->halfWidth, up, verts[ numVerts ].xyz ); -      verts[ numVerts ].st[ 0 ] = i->textureCoord; -      verts[ numVerts ].st[ 1 ] = 1.0f; - -      if( btb->realLight ) -        CG_LightVertex( verts[ numVerts ].xyz, i->alpha, verts[ numVerts ].modulate ); -      else -      { -        VectorCopy( i->color, verts[ numVerts ].modulate ); -        verts[ numVerts ].modulate[ 3 ] = i->alpha; -      } - -      numVerts++; - -      VectorMA( i->position, -i->halfWidth, up, verts[ numVerts ].xyz ); -      verts[ numVerts ].st[ 0 ] = i->textureCoord; -      verts[ numVerts ].st[ 1 ] = 0.0f; - -      if( btb->realLight ) -        CG_LightVertex( verts[ numVerts ].xyz, i->alpha, verts[ numVerts ].modulate ); -      else -      { -        VectorCopy( i->color, verts[ numVerts ].modulate ); -        verts[ numVerts ].modulate[ 3 ] = i->alpha; -      } - -      numVerts++; -    } - -    if( next ) -    { -      VectorMA( i->position, -i->halfWidth, up, verts[ numVerts ].xyz ); -      verts[ numVerts ].st[ 0 ] = i->textureCoord; -      verts[ numVerts ].st[ 1 ] = 0.0f; - -      if( btb->realLight ) -        CG_LightVertex( verts[ numVerts ].xyz, i->alpha, verts[ numVerts ].modulate ); -      else -      { -        VectorCopy( i->color, verts[ numVerts ].modulate ); -        verts[ numVerts ].modulate[ 3 ] = i->alpha; -      } - -      numVerts++; - -      VectorMA( i->position, i->halfWidth, up, verts[ numVerts ].xyz ); -      verts[ numVerts ].st[ 0 ] = i->textureCoord; -      verts[ numVerts ].st[ 1 ] = 1.0f; - -      if( btb->realLight ) -        CG_LightVertex( verts[ numVerts ].xyz, i->alpha, verts[ numVerts ].modulate ); -      else -      { -        VectorCopy( i->color, verts[ numVerts ].modulate ); -        verts[ numVerts ].modulate[ 3 ] = i->alpha; -      } - -      numVerts++; -    } - -    i = i->next; -  } while( i ); - -  trap_R_AddPolysToScene( tb->class->shader, 4, &verts[ 0 ], numVerts / 4 ); -} - -/* -=============== -CG_AllocateBeamNode - -Allocates a trailBeamNode_t from a trailBeam_t's nodePool -=============== -*/ -static trailBeamNode_t *CG_AllocateBeamNode( trailBeam_t *tb ) -{ -  baseTrailBeam_t *btb = tb->class; -  int             i; -  trailBeamNode_t *tbn; - -  for( i = 0; i < MAX_TRAIL_BEAM_NODES; i++ ) -  { -    tbn = &tb->nodePool[ i ]; -    if( !tbn->used ) -    { -      tbn->timeLeft = btb->segmentTime; -      tbn->prev = NULL; -      tbn->next = NULL; -      tbn->used = qtrue; -      return tbn; -    } -  } - -  // no space left -  return NULL; -} - -/* -=============== -CG_DestroyBeamNode - -Removes a node from a beam -Returns the new head -=============== -*/ -static trailBeamNode_t *CG_DestroyBeamNode( trailBeamNode_t *tbn ) -{ -  trailBeamNode_t *newHead = NULL; - -  if( tbn->prev ) -  { -    if( tbn->next ) -    { -      // node is in the middle -      tbn->prev->next = tbn->next; -      tbn->next->prev = tbn->prev; -    } -    else // node is at the back -      tbn->prev->next = NULL; - -    // find the new head (shouldn't have changed) -    newHead = tbn->prev; - -    while( newHead->prev ) -      newHead = newHead->prev; -  } -  else if( tbn->next ) -  { -    //node is at the front -    tbn->next->prev = NULL; -    newHead = tbn->next; -  } - -  tbn->prev = NULL; -  tbn->next = NULL; -  tbn->used = qfalse; - -  return newHead; -} - -/* -=============== -CG_FindLastBeamNode - -Returns the last beam node in a beam -=============== -*/ -static trailBeamNode_t *CG_FindLastBeamNode( trailBeam_t *tb ) -{ -  trailBeamNode_t *i = tb->nodes; - -  while( i && i->next ) -    i = i->next; - -  return i; -} - -/* -=============== -CG_CountBeamNodes - -Returns the number of nodes in a beam -=============== -*/ -static int CG_CountBeamNodes( trailBeam_t *tb ) -{ -  trailBeamNode_t *i = tb->nodes; -  int             numNodes = 0; - -  while( i ) -  { -    numNodes++; -    i = i->next; -  } - -  return numNodes; -} - -/* -=============== -CG_PrependBeamNode - -Prepend a new beam node to the front of a beam -Returns the new node -=============== -*/ -static trailBeamNode_t *CG_PrependBeamNode( trailBeam_t *tb ) -{ -  trailBeamNode_t *i; - -  if( tb->nodes ) -  { -    // prepend another node -    i = CG_AllocateBeamNode( tb ); - -    if( i ) -    { -      i->next = tb->nodes; -      tb->nodes->prev = i; -      tb->nodes = i; -    } -  } -  else //add first node -  { -    i = CG_AllocateBeamNode( tb ); - -    if( i ) -      tb->nodes = i; -  } - -  return i; -} - -/* -=============== -CG_AppendBeamNode - -Append a new beam node to the back of a beam -Returns the new node -=============== -*/ -static trailBeamNode_t *CG_AppendBeamNode( trailBeam_t *tb ) -{ -  trailBeamNode_t *last, *i; - -  if( tb->nodes ) -  { -    // append another node -    last = CG_FindLastBeamNode( tb ); -    i = CG_AllocateBeamNode( tb ); - -    if( i ) -    { -      last->next = i; -      i->prev = last; -      i->next = NULL; -    } -  } -  else //add first node -  { -    i = CG_AllocateBeamNode( tb ); - -    if( i ) -      tb->nodes = i; -  } - -  return i; -} - -/* -=============== -CG_ApplyJitters -=============== -*/ -static void CG_ApplyJitters( trailBeam_t *tb ) -{ -  trailBeamNode_t *i = NULL; -  int             j; -  baseTrailBeam_t *btb; -  trailSystem_t   *ts; -  trailBeamNode_t *start; -  trailBeamNode_t *end; - -  if( !tb || !tb->nodes ) -    return; - -  btb = tb->class; -  ts = tb->parent; - -  for( j = 0; j < btb->numJitters; j++ ) -  { -    if( tb->nextJitterTimes[ j ] <= cg.time ) -    { -      for( i = tb->nodes; i; i = i->next ) -      { -        i->jitters[ j ][ 0 ] = ( crandom( ) * btb->jitters[ j ].magnitude ); -        i->jitters[ j ][ 1 ] = ( crandom( ) * btb->jitters[ j ].magnitude ); -      } - -      tb->nextJitterTimes[ j ] = cg.time + btb->jitters[ j ].period; -    } -  } - -  start = tb->nodes; -  end = CG_FindLastBeamNode( tb ); - -  if( !btb->jitterAttachments ) -  { -    if( CG_Attached( &ts->frontAttachment ) && start->next ) -      start = start->next; - -    if( CG_Attached( &ts->backAttachment ) && end->prev ) -      end = end->prev; -  } - -  for( i = start; i; i = i->next ) -  { -    vec3_t          forward, right, up; -    trailBeamNode_t *prev; -    trailBeamNode_t *next; -    float           upJitter = 0.0f, rightJitter = 0.0f; - -    prev = i->prev; -    next = i->next; - -    if( prev && next ) -    { -      //this node has two neighbours -      GetPerpendicularViewVector( cg.refdef.vieworg, next->position, prev->position, up ); -      VectorSubtract( next->position, prev->position, forward ); -    } -    else if( !prev && next ) -    { -      //this is the front -      GetPerpendicularViewVector( cg.refdef.vieworg, next->position, i->position, up ); -      VectorSubtract( next->position, i->position, forward ); -    } -    else if( prev && !next ) -    { -      //this is the back -      GetPerpendicularViewVector( cg.refdef.vieworg, i->position, prev->position, up ); -      VectorSubtract( i->position, prev->position, forward ); -    } - -    VectorNormalize( forward ); -    CrossProduct( forward, up, right ); -    VectorNormalize( right ); - -    for( j = 0; j < btb->numJitters; j++ ) -    { -      upJitter += i->jitters[ j ][ 0 ]; -      rightJitter += i->jitters[ j ][ 1 ]; -    } - -    VectorMA( i->position, upJitter, up, i->position ); -    VectorMA( i->position, rightJitter, right, i->position ); - -    if( i == end ) -      break; -  } -} - -/* -=============== -CG_UpdateBeam - -Updates a beam -=============== -*/ -static void CG_UpdateBeam( trailBeam_t *tb ) -{ -  baseTrailBeam_t *btb; -  trailSystem_t   *ts; -  trailBeamNode_t *i; -  int             deltaTime; -  int             nodesToAdd; -  int             j; -  int             numNodes; - -  if( !tb ) -    return; - -  btb = tb->class; -  ts = tb->parent; - -  deltaTime = cg.time - tb->lastEvalTime; -  tb->lastEvalTime = cg.time; - -  // first make sure this beam has enough nodes -  if( ts->destroyTime <= 0 ) -  { -    nodesToAdd = btb->numSegments - CG_CountBeamNodes( tb ) + 1; - -    while( nodesToAdd-- ) -    { -      i = CG_AppendBeamNode( tb ); - -      if( !tb->nodes->next && CG_Attached( &ts->frontAttachment ) ) -      { -        // this is the first node to be added -        if( !CG_AttachmentPoint( &ts->frontAttachment, i->refPosition ) ) -          CG_DestroyTrailSystem( &ts ); -      } -      else -        VectorCopy( i->prev->refPosition, i->refPosition ); -    } -  } - -  numNodes = CG_CountBeamNodes( tb ); - -  for( i = tb->nodes; i; i = i->next ) -    VectorCopy( i->refPosition, i->position ); - -  if( CG_Attached( &ts->frontAttachment ) && CG_Attached( &ts->backAttachment ) ) -  { -    // beam between two attachments -    vec3_t dir, front, back; - -    if( ts->destroyTime > 0 && ( cg.time - ts->destroyTime ) >= btb->fadeOutTime ) -    { -      tb->valid = qfalse; -      return; -    } - -    if( !CG_AttachmentPoint( &ts->frontAttachment, front ) ) -      CG_DestroyTrailSystem( &ts ); - -    if( !CG_AttachmentPoint( &ts->backAttachment, back ) ) -      CG_DestroyTrailSystem( &ts ); - -    VectorSubtract( back, front, dir ); - -    for( j = 0, i = tb->nodes; i; i = i->next, j++ ) -    { -      float scale = (float)j / (float)( numNodes - 1 ); - -      VectorMA( front, scale, dir, i->position ); -    } -  } -  else if( CG_Attached( &ts->frontAttachment ) ) -  { -    // beam from one attachment - -    // cull the trail tail -    i = CG_FindLastBeamNode( tb ); - -    if( i && i->timeLeft >= 0 ) -    { -      i->timeLeft -= deltaTime; - -      if( i->timeLeft < 0 ) -      { -        tb->nodes = CG_DestroyBeamNode( i ); - -        if( !tb->nodes ) -        { -          tb->valid = qfalse; -          return; -        } - -        // if the ts has been destroyed, stop creating new nodes -        if( ts->destroyTime <= 0 ) -          CG_PrependBeamNode( tb ); -      } -      else if( i->timeLeft >= 0 && i->prev ) -      { -        vec3_t  dir; -        float   length; - -        VectorSubtract( i->refPosition, i->prev->refPosition, dir ); -        length = VectorNormalize( dir ) * -          ( (float)i->timeLeft / (float)tb->class->segmentTime ); - -        VectorMA( i->prev->refPosition, length, dir, i->position ); -      } -    } - -    if( tb->nodes ) -    { -      if( !CG_AttachmentPoint( &ts->frontAttachment, tb->nodes->refPosition ) ) -        CG_DestroyTrailSystem( &ts ); - -      VectorCopy( tb->nodes->refPosition, tb->nodes->position ); -    } -  } - -  CG_ApplyJitters( tb ); -} - -/* -=============== -CG_ParseTrailBeamColor -=============== -*/ -static qboolean CG_ParseTrailBeamColor( byte *c, char **text_p ) -{ -  char  *token; -  int   i; - -  for( i = 0; i <= 2; i++ ) -  { -    token = COM_Parse( text_p ); - -    if( !Q_stricmp( token, "" ) ) -      return qfalse; - -    c[ i ] = (int)( (float)0xFF * atof_neg( token, qfalse ) ); -  } - -  return qtrue; -} - -/* -=============== -CG_ParseTrailBeam - -Parse a trail beam -=============== -*/ -static qboolean CG_ParseTrailBeam( baseTrailBeam_t *btb, char **text_p ) -{ -  char  *token; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( text_p ); - -    if( !Q_stricmp( token, "" ) ) -      return qfalse; - -    if( !Q_stricmp( token, "segments" ) ) -    { -      token = COM_Parse( text_p ); -      if( !Q_stricmp( token, "" ) ) -        break; - -      btb->numSegments = atoi_neg( token, qfalse ); - -      if( btb->numSegments >= MAX_TRAIL_BEAM_NODES ) -      { -        btb->numSegments = MAX_TRAIL_BEAM_NODES - 1; -        CG_Printf( S_COLOR_YELLOW "WARNING: too many segments in trail beam\n" ); -      } -      continue; -    } -    else if( !Q_stricmp( token, "width" ) ) -    { -      token = COM_Parse( text_p ); -      if( !Q_stricmp( token, "" ) ) -        break; - -      btb->frontWidth = atof_neg( token, qfalse ); - -      token = COM_Parse( text_p ); -      if( !Q_stricmp( token, "" ) ) -        break; - -      if( !Q_stricmp( token, "-" ) ) -        btb->backWidth = btb->frontWidth; -      else -        btb->backWidth = atof_neg( token, qfalse ); -      continue; -    } -    else if( !Q_stricmp( token, "alpha" ) ) -    { -      token = COM_Parse( text_p ); -      if( !Q_stricmp( token, "" ) ) -        break; - -      btb->frontAlpha = atof_neg( token, qfalse ); - -      token = COM_Parse( text_p ); -      if( !Q_stricmp( token, "" ) ) -        break; - -      if( !Q_stricmp( token, "-" ) ) -        btb->backAlpha = btb->frontAlpha; -      else -        btb->backAlpha = atof_neg( token, qfalse ); -      continue; -    } -    else if( !Q_stricmp( token, "color" ) ) -    { -      token = COM_Parse( text_p ); -      if( !Q_stricmp( token, "" ) ) -        break; - -      if( !Q_stricmp( token, "{" ) ) -      { -        if( !CG_ParseTrailBeamColor( btb->frontColor, text_p ) ) -          break; - -        token = COM_Parse( text_p ); -        if( Q_stricmp( token, "}" ) ) -        { -          CG_Printf( S_COLOR_RED "ERROR: missing '}'\n" ); -          break; -        } - -        token = COM_Parse( text_p ); -        if( !Q_stricmp( token, "" ) ) -          break; - -        if( !Q_stricmp( token, "-" ) ) -        { -          btb->backColor[ 0 ] = btb->frontColor[ 0 ]; -          btb->backColor[ 1 ] = btb->frontColor[ 1 ]; -          btb->backColor[ 2 ] = btb->frontColor[ 2 ]; -        } -        else if( !Q_stricmp( token, "{" ) ) -        { -          if( !CG_ParseTrailBeamColor( btb->backColor, text_p ) ) -            break; - -          token = COM_Parse( text_p ); -          if( Q_stricmp( token, "}" ) ) -          { -            CG_Printf( S_COLOR_RED "ERROR: missing '}'\n" ); -            break; -          } -        } -        else -        { -          CG_Printf( S_COLOR_RED "ERROR: missing '{'\n" ); -          break; -        } -      } -      else -      { -        CG_Printf( S_COLOR_RED "ERROR: missing '{'\n" ); -        break; -      } - -      continue; -    } -    else if( !Q_stricmp( token, "segmentTime" ) ) -    { -      token = COM_Parse( text_p ); -      if( !Q_stricmp( token, "" ) ) -        break; - -      btb->segmentTime = atoi_neg( token, qfalse ); -      continue; -    } -    else if( !Q_stricmp( token, "fadeOutTime" ) ) -    { -      token = COM_Parse( text_p ); -      if( !Q_stricmp( token, "" ) ) -        break; - -      btb->fadeOutTime = atoi_neg( token, qfalse ); -      continue; -    } -    else if( !Q_stricmp( token, "shader" ) ) -    { -      token = COM_Parse( text_p ); -      if( !Q_stricmp( token, "" ) ) -        break; - -      Q_strncpyz( btb->shaderName, token, MAX_QPATH ); - -      continue; -    } -    else if( !Q_stricmp( token, "textureType" ) ) -    { -      token = COM_Parse( text_p ); -      if( !Q_stricmp( token, "" ) ) -        break; - -      if( !Q_stricmp( token, "stretch" ) ) -      { -        btb->textureType = TBTT_STRETCH; - -        token = COM_Parse( text_p ); -        if( !Q_stricmp( token, "" ) ) -          break; - -        btb->frontTextureCoord = atof_neg( token, qfalse ); - -        token = COM_Parse( text_p ); -        if( !Q_stricmp( token, "" ) ) -          break; - -        btb->backTextureCoord = atof_neg( token, qfalse ); -      } -      else if( !Q_stricmp( token, "repeat" ) ) -      { -        btb->textureType = TBTT_REPEAT; - -        token = COM_Parse( text_p ); -        if( !Q_stricmp( token, "" ) ) -          break; - -        if( !Q_stricmp( token, "front" ) ) -          btb->clampToBack = qfalse; -        else if( !Q_stricmp( token, "back" ) ) -          btb->clampToBack = qtrue; -        else -        { -          CG_Printf( S_COLOR_RED "ERROR: unknown textureType clamp \"%s\"\n", token ); -          break; -        } - -        token = COM_Parse( text_p ); -        if( !Q_stricmp( token, "" ) ) -          break; - -        btb->repeatLength = atof_neg( token, qfalse ); -      } -      else -      { -        CG_Printf( S_COLOR_RED "ERROR: unknown textureType \"%s\"\n", token ); -        break; -      } - -      continue; -    } -    else if( !Q_stricmp( token, "realLight" ) ) -    { -      btb->realLight = qtrue; - -      continue; -    } -    else if( !Q_stricmp( token, "jitter" ) ) -    { -      if( btb->numJitters == MAX_TRAIL_BEAM_JITTERS ) -      { -        CG_Printf( S_COLOR_RED "ERROR: too many jitters\n", token ); -        break; -      } - -      token = COM_Parse( text_p ); -      if( !Q_stricmp( token, "" ) ) -        break; - -      btb->jitters[ btb->numJitters ].magnitude = atof_neg( token, qfalse ); - -      token = COM_Parse( text_p ); -      if( !Q_stricmp( token, "" ) ) -        break; - -      btb->jitters[ btb->numJitters ].period = atoi_neg( token, qfalse ); - -      btb->numJitters++; - -      continue; -    } -    else if( !Q_stricmp( token, "jitterAttachments" ) ) -    { -      btb->jitterAttachments = qtrue; - -      continue; -    } -    else if( !Q_stricmp( token, "}" ) ) -      return qtrue; //reached the end of this trail beam -    else -    { -      CG_Printf( S_COLOR_RED "ERROR: unknown token '%s' in trail beam\n", token ); -      return qfalse; -    } -  } - -  return qfalse; -} - -/* -=============== -CG_InitialiseBaseTrailBeam -=============== -*/ -static void CG_InitialiseBaseTrailBeam( baseTrailBeam_t *btb ) -{ -  memset( btb, 0, sizeof( baseTrailBeam_t ) ); - -  btb->numSegments = 1; -  btb->frontWidth = btb->backWidth = 1.0f; -  btb->frontAlpha = btb->backAlpha = 1.0f; -  memset( btb->frontColor, 0xFF, sizeof( btb->frontColor ) ); -  memset( btb->backColor, 0xFF, sizeof( btb->backColor ) ); - -  btb->segmentTime = 100; - -  btb->textureType = TBTT_STRETCH; -  btb->frontTextureCoord = 0.0f; -  btb->backTextureCoord = 1.0f; -} - -/* -=============== -CG_ParseTrailSystem - -Parse a trail system section -=============== -*/ -static qboolean CG_ParseTrailSystem( baseTrailSystem_t *bts, char **text_p, const char *name ) -{ -  char *token; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( text_p ); - -    if( !Q_stricmp( token, "" ) ) -      return qfalse; - -    if( !Q_stricmp( token, "{" ) ) -    { -      CG_InitialiseBaseTrailBeam( &baseTrailBeams[ numBaseTrailBeams ] ); - -      if( !CG_ParseTrailBeam( &baseTrailBeams[ numBaseTrailBeams ], text_p ) ) -      { -        CG_Printf( S_COLOR_RED "ERROR: failed to parse trail beam\n" ); -        return qfalse; -      } - -      if( bts->numBeams == MAX_BEAMS_PER_SYSTEM ) -      { -        CG_Printf( S_COLOR_RED "ERROR: trail system has > %d beams\n", MAX_BEAMS_PER_SYSTEM ); -        return qfalse; -      } -      else if( numBaseTrailBeams == MAX_BASETRAIL_BEAMS ) -      { -        CG_Printf( S_COLOR_RED "ERROR: maximum number of trail beams (%d) reached\n", -            MAX_BASETRAIL_BEAMS ); -        return qfalse; -      } -      else -      { -        //start parsing beams again -        bts->beams[ bts->numBeams ] = &baseTrailBeams[ numBaseTrailBeams ]; -        bts->numBeams++; -        numBaseTrailBeams++; -      } -      continue; -    } -    else if( !Q_stricmp( token, "thirdPersonOnly" ) ) -      bts->thirdPersonOnly = qtrue; -    else if( !Q_stricmp( token, "beam" ) ) //acceptable text -      continue; -    else if( !Q_stricmp( token, "}" ) ) -    { -      if( cg_debugTrails.integer >= 1 ) -        CG_Printf( "Parsed trail system %s\n", name ); - -      return qtrue; //reached the end of this trail system -    } -    else -    { -      CG_Printf( S_COLOR_RED "ERROR: unknown token '%s' in trail system %s\n", token, bts->name ); -      return qfalse; -    } -  } - -  return qfalse; -} - -/* -=============== -CG_ParseTrailFile - -Load the trail systems from a trail file -=============== -*/ -static qboolean CG_ParseTrailFile( const char *fileName ) -{ -  char          *text_p; -  int           i; -  int           len; -  char          *token; -  char          text[ 32000 ]; -  char          tsName[ MAX_QPATH ]; -  qboolean      tsNameSet = qfalse; -  fileHandle_t  f; - -  // load the file -  len = trap_FS_FOpenFile( fileName, &f, FS_READ ); -  if( len <= 0 ) -    return qfalse; - -  if( len >= sizeof( text ) - 1 ) -  { -    CG_Printf( S_COLOR_RED "ERROR: trail file %s too long\n", fileName ); -    return qfalse; -  } - -  trap_FS_Read( text, len, f ); -  text[ len ] = 0; -  trap_FS_FCloseFile( f ); - -  // parse the text -  text_p = text; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( &text_p ); - -    if( !Q_stricmp( token, "" ) ) -      break; - -    if( !Q_stricmp( token, "{" ) ) -    { -      if( tsNameSet ) -      { -        //check for name space clashes -        for( i = 0; i < numBaseTrailSystems; i++ ) -        { -          if( !Q_stricmp( baseTrailSystems[ i ].name, tsName ) ) -          { -            CG_Printf( S_COLOR_RED "ERROR: a trail system is already named %s\n", tsName ); -            return qfalse; -          } -        } - -        Q_strncpyz( baseTrailSystems[ numBaseTrailSystems ].name, tsName, MAX_QPATH ); - -        if( !CG_ParseTrailSystem( &baseTrailSystems[ numBaseTrailSystems ], &text_p, tsName ) ) -        { -          CG_Printf( S_COLOR_RED "ERROR: %s: failed to parse trail system %s\n", fileName, tsName ); -          return qfalse; -        } - -        //start parsing trail systems again -        tsNameSet = qfalse; - -        if( numBaseTrailSystems == MAX_BASETRAIL_SYSTEMS ) -        { -          CG_Printf( S_COLOR_RED "ERROR: maximum number of trail systems (%d) reached\n", -              MAX_BASETRAIL_SYSTEMS ); -          return qfalse; -        } -        else -          numBaseTrailSystems++; - -        continue; -      } -      else -      { -        CG_Printf( S_COLOR_RED "ERROR: unamed trail system\n" ); -        return qfalse; -      } -    } - -    if( !tsNameSet ) -    { -      Q_strncpyz( tsName, token, sizeof( tsName ) ); -      tsNameSet = qtrue; -    } -    else -    { -      CG_Printf( S_COLOR_RED "ERROR: trail system already named\n" ); -      return qfalse; -    } -  } - -  return qtrue; -} - -/* -=============== -CG_LoadTrailSystems - -Load trail system templates -=============== -*/ -void CG_LoadTrailSystems( void ) -{ -  int         i; -  /*const char  *s[ MAX_TRAIL_FILES ];*/ - -  //clear out the old -  numBaseTrailSystems = 0; -  numBaseTrailBeams = 0; - -  for( i = 0; i < MAX_BASETRAIL_SYSTEMS; i++ ) -  { -    baseTrailSystem_t  *bts = &baseTrailSystems[ i ]; -    memset( bts, 0, sizeof( baseTrailSystem_t ) ); -  } - -  for( i = 0; i < MAX_BASETRAIL_BEAMS; i++ ) -  { -    baseTrailBeam_t  *btb = &baseTrailBeams[ i ]; -    memset( btb, 0, sizeof( baseTrailBeam_t ) ); -  } - -  //and bring in the new -/*  for( i = 0; i < MAX_TRAIL_FILES; i++ ) -  { -    s[ i ] = CG_ConfigString( CS_TRAIL_FILES + i ); - -    if( strlen( s[ i ] ) > 0 ) -    { -      CG_Printf( "...loading '%s'\n", s[ i ] ); -      CG_ParseTrailFile( s[ i ] ); -    } -    else -      break; -  }*/ -  CG_Printf( "trail.trail: %d\n", CG_ParseTrailFile( "scripts/trail.trail" ) ); -} - -/* -=============== -CG_RegisterTrailSystem - -Load the media that a trail system needs -=============== -*/ -qhandle_t CG_RegisterTrailSystem( char *name ) -{ -  int               i, j; -  baseTrailSystem_t *bts; -  baseTrailBeam_t   *btb; - -  for( i = 0; i < MAX_BASETRAIL_SYSTEMS; i++ ) -  { -    bts = &baseTrailSystems[ i ]; - -    if( !Q_stricmp( bts->name, name ) ) -    { -      //already registered -      if( bts->registered ) -        return i + 1; - -      for( j = 0; j < bts->numBeams; j++ ) -      { -        btb = bts->beams[ j ]; - -        btb->shader = trap_R_RegisterShader( btb->shaderName ); -      } - -      if( cg_debugTrails.integer >= 1 ) -        CG_Printf( "Registered trail system %s\n", name ); - -      bts->registered = qtrue; - -      //avoid returning 0 -      return i + 1; -    } -  } - -  CG_Printf( S_COLOR_RED "ERROR: failed to register trail system %s\n", name ); -  return 0; -} - - -/* -=============== -CG_SpawnNewTrailBeam - -Allocate a new trail beam -=============== -*/ -static trailBeam_t *CG_SpawnNewTrailBeam( baseTrailBeam_t *btb, -    trailSystem_t *parent ) -{ -  int           i; -  trailBeam_t   *tb = NULL; -  trailSystem_t *ts = parent; - -  for( i = 0; i < MAX_TRAIL_BEAMS; i++ ) -  { -    tb = &trailBeams[ i ]; - -    if( !tb->valid ) -    { -      memset( tb, 0, sizeof( trailBeam_t ) ); - -      //found a free slot -      tb->class = btb; -      tb->parent = ts; - -      tb->valid = qtrue; - -      if( cg_debugTrails.integer >= 1 ) -        CG_Printf( "TB %s created\n", ts->class->name ); - -      break; -    } -  } - -  return tb; -} - - -/* -=============== -CG_SpawnNewTrailSystem - -Spawns a new trail system -=============== -*/ -trailSystem_t *CG_SpawnNewTrailSystem( qhandle_t psHandle ) -{ -  int               i, j; -  trailSystem_t     *ts = NULL; -  baseTrailSystem_t *bts = &baseTrailSystems[ psHandle - 1 ]; - -  if( !bts->registered ) -  { -    CG_Printf( S_COLOR_RED "ERROR: a trail system has not been registered yet\n" ); -    return NULL; -  } - -  for( i = 0; i < MAX_TRAIL_SYSTEMS; i++ ) -  { -    ts = &trailSystems[ i ]; - -    if( !ts->valid ) -    { -      memset( ts, 0, sizeof( trailSystem_t ) ); - -      //found a free slot -      ts->class = bts; - -      ts->valid = qtrue; -      ts->destroyTime = -1; - -      for( j = 0; j < bts->numBeams; j++ ) -        CG_SpawnNewTrailBeam( bts->beams[ j ], ts ); - -      if( cg_debugTrails.integer >= 1 ) -        CG_Printf( "TS %s created\n", bts->name ); - -      break; -    } -  } - -  return ts; -} - -/* -=============== -CG_DestroyTrailSystem - -Destroy a trail system -=============== -*/ -void CG_DestroyTrailSystem( trailSystem_t **ts ) -{ -  (*ts)->destroyTime = cg.time; - -  if( CG_Attached( &(*ts)->frontAttachment ) && -      !CG_Attached( &(*ts)->backAttachment ) ) -  { -    vec3_t v; - -    // attach the trail head to a static point -    CG_AttachmentPoint( &(*ts)->frontAttachment, v ); -    CG_SetAttachmentPoint( &(*ts)->frontAttachment, v ); -    CG_AttachToPoint( &(*ts)->frontAttachment ); - -    (*ts)->frontAttachment.centValid = qfalse; // a bit naughty -  } - -  ts = NULL; -} - -/* -=============== -CG_IsTrailSystemValid - -Test a trail system for validity -=============== -*/ -qboolean CG_IsTrailSystemValid( trailSystem_t **ts ) -{ -  if( *ts == NULL || ( *ts && !(*ts)->valid ) ) -  { -    if( *ts && !(*ts)->valid ) -      *ts = NULL; - -    return qfalse; -  } - -  return qtrue; -} - -/* -=============== -CG_GarbageCollectTrailSystems - -Destroy inactive trail systems -=============== -*/ -static void CG_GarbageCollectTrailSystems( void ) -{ -  int           i, j, count; -  trailSystem_t *ts; -  trailBeam_t   *tb; -  int           centNum; - -  for( i = 0; i < MAX_TRAIL_SYSTEMS; i++ ) -  { -    ts = &trailSystems[ i ]; -    count = 0; - -    //don't bother checking already invalid systems -    if( !ts->valid ) -      continue; - -    for( j = 0; j < MAX_TRAIL_BEAMS; j++ ) -    { -      tb = &trailBeams[ j ]; - -      if( tb->valid && tb->parent == ts ) -        count++; -    } - -    if( !count ) -      ts->valid = qfalse; - -    //check systems where the parent cent has left the PVS -    //( local player entity is always valid ) -    if( ( centNum = CG_AttachmentCentNum( &ts->frontAttachment ) ) >= 0 && -        centNum != cg.snap->ps.clientNum ) -    { -      trailSystem_t *tempTS = ts; - -      if( !cg_entities[ centNum ].valid ) -        CG_DestroyTrailSystem( &tempTS ); -    } - -    if( ( centNum = CG_AttachmentCentNum( &ts->backAttachment ) ) >= 0 && -        centNum != cg.snap->ps.clientNum ) -    { -      trailSystem_t *tempTS = ts; - -      if( !cg_entities[ centNum ].valid ) -        CG_DestroyTrailSystem( &tempTS ); -    } - -    if( cg_debugTrails.integer >= 1 && !ts->valid ) -      CG_Printf( "TS %s garbage collected\n", ts->class->name ); -  } -} - -/* -=============== -CG_AddTrails - -Add trails to the scene -=============== -*/ -void CG_AddTrails( void ) -{ -  int           i; -  trailBeam_t   *tb; -  int           numTS = 0, numTB = 0; - -  //remove expired trail systems -  CG_GarbageCollectTrailSystems( ); - -  for( i = 0; i < MAX_TRAIL_BEAMS; i++ ) -  { -    tb = &trailBeams[ i ]; - -    if( tb->valid ) -    { -      CG_UpdateBeam( tb ); -      CG_RenderBeam( tb ); -    } -  } - -  if( cg_debugTrails.integer >= 2 ) -  { -    for( i = 0; i < MAX_TRAIL_SYSTEMS; i++ ) -      if( trailSystems[ i ].valid ) -        numTS++; - -    for( i = 0; i < MAX_TRAIL_BEAMS; i++ ) -      if( trailBeams[ i ].valid ) -        numTB++; - -    CG_Printf( "TS: %d  TB: %d\n", numTS, numTB ); -  } -} - -static trailSystem_t  *testTS; -static qhandle_t      testTSHandle; - -/* -=============== -CG_DestroyTestTS_f - -Destroy the test a trail system -=============== -*/ -void CG_DestroyTestTS_f( void ) -{ -  if( CG_IsTrailSystemValid( &testTS ) ) -    CG_DestroyTrailSystem( &testTS ); -} - -/* -=============== -CG_TestTS_f - -Test a trail system -=============== -*/ -void CG_TestTS_f( void ) -{ -  char tsName[ MAX_QPATH ]; - -  if( trap_Argc( ) < 2 ) -    return; - -  Q_strncpyz( tsName, CG_Argv( 1 ), MAX_QPATH ); -  testTSHandle = CG_RegisterTrailSystem( tsName ); - -  if( testTSHandle ) -  { -    CG_DestroyTestTS_f( ); - -    testTS = CG_SpawnNewTrailSystem( testTSHandle ); - -    if( CG_IsTrailSystemValid( &testTS ) ) -    { -      CG_SetAttachmentCent( &testTS->frontAttachment, &cg_entities[ 0 ] ); -      CG_AttachToCent( &testTS->frontAttachment ); -    } -  } -} diff --git a/mod/src/cgame/cg_view.c b/mod/src/cgame/cg_view.c deleted file mode 100644 index 324646c9..00000000 --- a/mod/src/cgame/cg_view.c +++ /dev/null @@ -1,1330 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_view.c -- setup all the parameters (position, angle, etc) -// for a 3D rendering - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - - -/* -============================================================================= - -  MODEL TESTING - -The viewthing and gun positioning tools from Q2 have been integrated and -enhanced into a single model testing facility. - -Model viewing can begin with either "testmodel <modelname>" or "testgun <modelname>". - -The names must be the full pathname after the basedir, like -"models/weapons/v_launch/tris.md3" or "players/male/tris.md3" - -Testmodel will create a fake entity 100 units in front of the current view -position, directly facing the viewer.  It will remain immobile, so you can -move around it to view it from different angles. - -Testgun will cause the model to follow the player around and supress the real -view weapon model.  The default frame 0 of most guns is completely off screen, -so you will probably have to cycle a couple frames to see it. - -"nextframe", "prevframe", "nextskin", and "prevskin" commands will change the -frame or skin of the testmodel.  These are bound to F5, F6, F7, and F8 in -q3default.cfg. - -If a gun is being tested, the "gun_x", "gun_y", and "gun_z" variables will let -you adjust the positioning. - -Note that none of the model testing features update while the game is paused, so -it may be convenient to test with deathmatch set to 1 so that bringing down the -console doesn't pause the game. - -============================================================================= -*/ - -/* -================= -CG_TestModel_f - -Creates an entity in front of the current position, which -can then be moved around -================= -*/ -void CG_TestModel_f( void ) -{ -  vec3_t    angles; - -  memset( &cg.testModelEntity, 0, sizeof( cg.testModelEntity ) ); -  memset( &cg.testModelBarrelEntity, 0, sizeof( cg.testModelBarrelEntity ) ); - -  if( trap_Argc( ) < 2 ) -    return; - -  Q_strncpyz( cg.testModelName, CG_Argv( 1 ), MAX_QPATH ); -  cg.testModelEntity.hModel = trap_R_RegisterModel( cg.testModelName ); - -  Q_strncpyz( cg.testModelBarrelName, CG_Argv( 1 ), MAX_QPATH ); -  cg.testModelBarrelName[ strlen( cg.testModelBarrelName ) - 4 ] = '\0'; -  Q_strcat( cg.testModelBarrelName, MAX_QPATH, "_barrel.md3" ); -  cg.testModelBarrelEntity.hModel = trap_R_RegisterModel( cg.testModelBarrelName ); - -  if( trap_Argc( ) == 3 ) -  { -    cg.testModelEntity.backlerp = atof( CG_Argv( 2 ) ); -    cg.testModelEntity.frame = 1; -    cg.testModelEntity.oldframe = 0; -  } - -  if( !cg.testModelEntity.hModel ) -  { -    CG_Printf( "Can't register model\n" ); -    return; -  } - -  VectorMA( cg.refdef.vieworg, 100, cg.refdef.viewaxis[ 0 ], cg.testModelEntity.origin ); - -  angles[ PITCH ] = 0; -  angles[ YAW ] = 180 + cg.refdefViewAngles[ 1 ]; -  angles[ ROLL ] = 0; - -  AnglesToAxis( angles, cg.testModelEntity.axis ); -  cg.testGun = qfalse; - -  if( cg.testModelBarrelEntity.hModel ) -  { -    angles[ YAW ] = 0; -    angles[ PITCH ] = 0; -    angles[ ROLL ] = 0; -    AnglesToAxis( angles, cg.testModelBarrelEntity.axis ); -  } -} - -/* -================= -CG_TestGun_f - -Replaces the current view weapon with the given model -================= -*/ -void CG_TestGun_f( void ) -{ -  CG_TestModel_f( ); -  cg.testGun = qtrue; -  cg.testModelEntity.renderfx = RF_MINLIGHT | RF_DEPTHHACK | RF_FIRST_PERSON; -} - - -void CG_TestModelNextFrame_f( void ) -{ -  cg.testModelEntity.frame++; -  CG_Printf( "frame %i\n", cg.testModelEntity.frame ); -} - -void CG_TestModelPrevFrame_f( void ) -{ -  cg.testModelEntity.frame--; - -  if( cg.testModelEntity.frame < 0 ) -    cg.testModelEntity.frame = 0; - -  CG_Printf( "frame %i\n", cg.testModelEntity.frame ); -} - -void CG_TestModelNextSkin_f( void ) -{ -  cg.testModelEntity.skinNum++; -  CG_Printf( "skin %i\n", cg.testModelEntity.skinNum ); -} - -void CG_TestModelPrevSkin_f( void ) -{ -  cg.testModelEntity.skinNum--; - -  if( cg.testModelEntity.skinNum < 0 ) -    cg.testModelEntity.skinNum = 0; - -  CG_Printf( "skin %i\n", cg.testModelEntity.skinNum ); -} - -static void CG_AddTestModel( void ) -{ -  int   i; - -  // re-register the model, because the level may have changed -  cg.testModelEntity.hModel = trap_R_RegisterModel( cg.testModelName ); -  cg.testModelBarrelEntity.hModel = trap_R_RegisterModel( cg.testModelBarrelName ); - -  if( !cg.testModelEntity.hModel ) -  { -    CG_Printf( "Can't register model\n" ); -    return; -  } - -  // if testing a gun, set the origin reletive to the view origin -  if( cg.testGun ) -  { -    VectorCopy( cg.refdef.vieworg, cg.testModelEntity.origin ); -    VectorCopy( cg.refdef.viewaxis[ 0 ], cg.testModelEntity.axis[ 0 ] ); -    VectorCopy( cg.refdef.viewaxis[ 1 ], cg.testModelEntity.axis[ 1 ] ); -    VectorCopy( cg.refdef.viewaxis[ 2 ], cg.testModelEntity.axis[ 2 ] ); - -    // allow the position to be adjusted -    for( i = 0; i < 3; i++ ) -    { -      cg.testModelEntity.origin[ i ] += cg.refdef.viewaxis[ 0 ][ i ] * cg_gun_x.value; -      cg.testModelEntity.origin[ i ] += cg.refdef.viewaxis[ 1 ][ i ] * cg_gun_y.value; -      cg.testModelEntity.origin[ i ] += cg.refdef.viewaxis[ 2 ][ i ] * cg_gun_z.value; -    } -  } - -  trap_R_AddRefEntityToScene( &cg.testModelEntity ); - -  if( cg.testModelBarrelEntity.hModel ) -  { -    CG_PositionEntityOnTag( &cg.testModelBarrelEntity, &cg.testModelEntity, -        cg.testModelEntity.hModel, "tag_barrel" ); - -    trap_R_AddRefEntityToScene( &cg.testModelBarrelEntity ); -  } -} - - - -//============================================================================ - - -/* -================= -CG_CalcVrect - -Sets the coordinates of the rendered window -================= -*/ -static void CG_CalcVrect( void ) -{ -  int   size; - -  // the intermission should allways be full screen -  if( cg.snap->ps.pm_type == PM_INTERMISSION ) -    size = 100; -  else -  { -    // bound normal viewsize -    if( cg_viewsize.integer < 30 ) -    { -      trap_Cvar_Set( "cg_viewsize", "30" ); -      size = 30; -    } -    else if( cg_viewsize.integer > 100 ) -    { -      trap_Cvar_Set( "cg_viewsize","100" ); -      size = 100; -    } -    else -      size = cg_viewsize.integer; -  } - -  cg.refdef.width = cgs.glconfig.vidWidth * size / 100; -  cg.refdef.width &= ~1; - -  cg.refdef.height = cgs.glconfig.vidHeight * size / 100; -  cg.refdef.height &= ~1; - -  cg.refdef.x = ( cgs.glconfig.vidWidth - cg.refdef.width ) / 2; -  cg.refdef.y = ( cgs.glconfig.vidHeight - cg.refdef.height ) / 2; -} - -//============================================================================== - - -/* -=============== -CG_OffsetThirdPersonView - -=============== -*/ -#define FOCUS_DISTANCE  512 -static void CG_OffsetThirdPersonView( void ) -{ -  vec3_t        forward, right, up; -  vec3_t        view; -  vec3_t        focusAngles; -  trace_t       trace; -  static vec3_t mins = { -8, -8, -8 }; -  static vec3_t maxs = { 8, 8, 8 }; -  vec3_t        focusPoint; -  float         focusDist; -  float         forwardScale, sideScale; -  vec3_t        surfNormal; - -  if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBING ) -  { -    if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) -      VectorSet( surfNormal, 0.0f, 0.0f, -1.0f ); -    else -      VectorCopy( cg.predictedPlayerState.grapplePoint, surfNormal ); -  } -  else -    VectorSet( surfNormal, 0.0f, 0.0f, 1.0f ); - -  VectorMA( cg.refdef.vieworg, cg.predictedPlayerState.viewheight, surfNormal, cg.refdef.vieworg ); - -  VectorCopy( cg.refdefViewAngles, focusAngles ); - -  // if dead, look at killer -  if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 ) -  { -    focusAngles[ YAW ] = cg.predictedPlayerState.stats[ STAT_VIEWLOCK ]; -    cg.refdefViewAngles[ YAW ] = cg.predictedPlayerState.stats[ STAT_VIEWLOCK ]; -  } - -  //if ( focusAngles[PITCH] > 45 ) { -  //  focusAngles[PITCH] = 45;    // don't go too far overhead -  //} -  AngleVectors( focusAngles, forward, NULL, NULL ); - -  VectorMA( cg.refdef.vieworg, FOCUS_DISTANCE, forward, focusPoint ); - -  VectorCopy( cg.refdef.vieworg, view ); - -  VectorMA( view, 12, surfNormal, view ); - -  //cg.refdefViewAngles[PITCH] *= 0.5; - -  AngleVectors( cg.refdefViewAngles, forward, right, up ); - -  forwardScale = cos( cg_thirdPersonAngle.value / 180 * M_PI ); -  sideScale = sin( cg_thirdPersonAngle.value / 180 * M_PI ); -  VectorMA( view, -cg_thirdPersonRange.value * forwardScale, forward, view ); -  VectorMA( view, -cg_thirdPersonRange.value * sideScale, right, view ); - -  // trace a ray from the origin to the viewpoint to make sure the view isn't -  // in a solid block.  Use an 8 by 8 block to prevent the view from near clipping anything - -  if( !cg_cameraMode.integer ) -  { -    CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.predictedPlayerState.clientNum, MASK_SOLID ); - -    if( trace.fraction != 1.0 ) -    { -      VectorCopy( trace.endpos, view ); -      view[ 2 ] += ( 1.0 - trace.fraction ) * 32; -      // try another trace to this position, because a tunnel may have the ceiling -      // close enogh that this is poking out - -      CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.predictedPlayerState.clientNum, MASK_SOLID ); -      VectorCopy( trace.endpos, view ); -    } -  } - -  VectorCopy( view, cg.refdef.vieworg ); - -  // select pitch to look at focus point from vieword -  VectorSubtract( focusPoint, cg.refdef.vieworg, focusPoint ); -  focusDist = sqrt( focusPoint[ 0 ] * focusPoint[ 0 ] + focusPoint[ 1 ] * focusPoint[ 1 ] ); -  if ( focusDist < 1 ) { -    focusDist = 1;  // should never happen -  } -  cg.refdefViewAngles[ PITCH ] = -180 / M_PI * atan2( focusPoint[ 2 ], focusDist ); -  cg.refdefViewAngles[ YAW ] -= cg_thirdPersonAngle.value; -} - - -// this causes a compiler bug on mac MrC compiler -static void CG_StepOffset( void ) -{ -  float         steptime; -  int            timeDelta; -  vec3_t        normal; -  playerState_t *ps = &cg.predictedPlayerState; - -  if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) -  { -    if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) -      VectorSet( normal, 0.0f, 0.0f, -1.0f ); -    else -      VectorCopy( ps->grapplePoint, normal ); -  } -  else -    VectorSet( normal, 0.0f, 0.0f, 1.0f ); - -  steptime = BG_FindSteptimeForClass( ps->stats[ STAT_PCLASS ] ); - -  // smooth out stair climbing -  timeDelta = cg.time - cg.stepTime; -  if( timeDelta < steptime ) -  { -    float stepChange = cg.stepChange -      * (steptime - timeDelta) / steptime; - -    if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) -      VectorMA( cg.refdef.vieworg, -stepChange, normal, cg.refdef.vieworg ); -    else -      cg.refdef.vieworg[ 2 ] -= stepChange; -  } -} - -#define PCLOUD_ROLL_AMPLITUDE   25.0f -#define PCLOUD_ROLL_FREQUENCY   0.4f -#define PCLOUD_ZOOM_AMPLITUDE   15 -#define PCLOUD_ZOOM_FREQUENCY   0.7f - - -/* -=============== -CG_OffsetFirstPersonView - -=============== -*/ -static void CG_OffsetFirstPersonView( void ) -{ -  float         *origin; -  float         *angles; -  float         bob; -  float         ratio; -  float         delta; -  float         speed; -  float         f; -  vec3_t        predictedVelocity; -  int           timeDelta; -  float         bob2; -  vec3_t        normal, baseOrigin; -  playerState_t *ps = &cg.predictedPlayerState; - -  if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) -  { -    if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) -      VectorSet( normal, 0.0f, 0.0f, -1.0f ); -    else -      VectorCopy( ps->grapplePoint, normal ); -  } -  else -    VectorSet( normal, 0.0f, 0.0f, 1.0f ); - - -  if( cg.snap->ps.pm_type == PM_INTERMISSION ) -    return; - -  origin = cg.refdef.vieworg; -  angles = cg.refdefViewAngles; - -  VectorCopy( origin, baseOrigin ); - -  // if dead, fix the angle and don't add any kick -  if( cg.snap->ps.stats[ STAT_HEALTH ] <= 0 ) -  { -    angles[ ROLL ] = 40; -    angles[ PITCH ] = -15; -    angles[ YAW ] = cg.snap->ps.stats[ STAT_VIEWLOCK ]; -    origin[ 2 ] += cg.predictedPlayerState.viewheight; -    return; -  } - -  // add angles based on weapon kick -  VectorAdd( angles, cg.kick_angles, angles ); - -  // add angles based on damage kick -  if( cg.damageTime ) -  { -    ratio = cg.time - cg.damageTime; -    if( ratio < DAMAGE_DEFLECT_TIME ) -    { -      ratio /= DAMAGE_DEFLECT_TIME; -      angles[ PITCH ] += ratio * cg.v_dmg_pitch; -      angles[ ROLL ] += ratio * cg.v_dmg_roll; -    } -    else -    { -      ratio = 1.0 - ( ratio - DAMAGE_DEFLECT_TIME ) / DAMAGE_RETURN_TIME; -      if( ratio > 0 ) -      { -        angles[ PITCH ] += ratio * cg.v_dmg_pitch; -        angles[ ROLL ] += ratio * cg.v_dmg_roll; -      } -    } -  } - -  // add pitch based on fall kick -#if 0 -  ratio = ( cg.time - cg.landTime) / FALL_TIME; -  if (ratio < 0) -    ratio = 0; -  angles[PITCH] += ratio * cg.fall_value; -#endif - -  // add angles based on velocity -  VectorCopy( cg.predictedPlayerState.velocity, predictedVelocity ); - -  delta = DotProduct( predictedVelocity, cg.refdef.viewaxis[ 0 ] ); -  angles[ PITCH ] += delta * cg_runpitch.value; - -  delta = DotProduct( predictedVelocity, cg.refdef.viewaxis[ 1 ] ); -  angles[ ROLL ] -= delta * cg_runroll.value; - -  // add angles based on bob -  //TA: bob amount is class dependant - -  if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) -    bob2 = 0.0f; -  else -    bob2 = BG_FindBobForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] ); - - -#define LEVEL4_FEEDBACK  10.0f - -  //give a charging player some feedback -  if( ps->weapon == WP_ALEVEL4 ) -  { -    if( ps->stats[ STAT_MISC ] > 0 ) -    { -      float fraction = (float)ps->stats[ STAT_MISC ] / (float)LEVEL4_CHARGE_TIME; - -      if( fraction > 1.0f ) -        fraction = 1.0f; - -      bob2 *= ( 1.0f + fraction * LEVEL4_FEEDBACK ); -    } -  } - -  if( bob2 != 0.0f ) -  { -    // make sure the bob is visible even at low speeds -    speed = cg.xyspeed > 200 ? cg.xyspeed : 200; - -    delta = cg.bobfracsin * ( bob2 ) * speed; -    if( cg.predictedPlayerState.pm_flags & PMF_DUCKED ) -      delta *= 3;   // crouching - -    angles[ PITCH ] += delta; -    delta = cg.bobfracsin * ( bob2 ) * speed; -    if( cg.predictedPlayerState.pm_flags & PMF_DUCKED ) -      delta *= 3;   // crouching accentuates roll - -    if( cg.bobcycle & 1 ) -      delta = -delta; - -    angles[ ROLL ] += delta; -  } - -#define LEVEL3_FEEDBACK  20.0f - -  //provide some feedback for pouncing -  if( cg.predictedPlayerState.weapon == WP_ALEVEL3 || -      cg.predictedPlayerState.weapon == WP_ALEVEL3_UPG ) -  { -    if( cg.predictedPlayerState.stats[ STAT_MISC ] > 0 ) -    { -      float   fraction1, fraction2; -      vec3_t  forward; - -      AngleVectors( angles, forward, NULL, NULL ); -      VectorNormalize( forward ); - -      fraction1 = (float)( cg.time - cg.weapon2Time ) / (float)LEVEL3_POUNCE_CHARGE_TIME; - -      if( fraction1 > 1.0f ) -        fraction1 = 1.0f; - -      fraction2 = -sin( fraction1 * M_PI / 2 ); - -      VectorMA( origin, LEVEL3_FEEDBACK * fraction2, forward, origin ); -    } -  } - -#define STRUGGLE_DIST 5.0f -#define STRUGGLE_TIME 250 - -  //allow the player to struggle a little whilst grabbed -  if( cg.predictedPlayerState.pm_type == PM_GRABBED ) -  { -    vec3_t    forward, right, up; -    usercmd_t cmd; -    int       cmdNum; -    float     fFraction, rFraction, uFraction; -    float     fFraction2, rFraction2, uFraction2; - -    cmdNum = trap_GetCurrentCmdNumber(); -    trap_GetUserCmd( cmdNum, &cmd ); - -    AngleVectors( angles, forward, right, up ); - -    fFraction = (float)( cg.time - cg.forwardMoveTime ) / STRUGGLE_TIME; -    rFraction = (float)( cg.time - cg.rightMoveTime ) / STRUGGLE_TIME; -    uFraction = (float)( cg.time - cg.upMoveTime ) / STRUGGLE_TIME; - -    if( fFraction > 1.0f ) -      fFraction = 1.0f; -    if( rFraction > 1.0f ) -      rFraction = 1.0f; -    if( uFraction > 1.0f ) -      uFraction = 1.0f; - -    fFraction2 = -sin( fFraction * M_PI / 2 ); -    rFraction2 = -sin( rFraction * M_PI / 2 ); -    uFraction2 = -sin( uFraction * M_PI / 2 ); - -    if( cmd.forwardmove > 0 ) -      VectorMA( origin, STRUGGLE_DIST * fFraction, forward, origin ); -    else if( cmd.forwardmove < 0 ) -      VectorMA( origin, -STRUGGLE_DIST * fFraction, forward, origin ); -    else -      cg.forwardMoveTime = cg.time; - -    if( cmd.rightmove > 0 ) -      VectorMA( origin, STRUGGLE_DIST * rFraction, right, origin ); -    else if( cmd.rightmove < 0 ) -      VectorMA( origin, -STRUGGLE_DIST * rFraction, right, origin ); -    else -      cg.rightMoveTime = cg.time; - -    if( cmd.upmove > 0 ) -      VectorMA( origin, STRUGGLE_DIST * uFraction, up, origin ); -    else if( cmd.upmove < 0 ) -      VectorMA( origin, -STRUGGLE_DIST * uFraction, up, origin ); -    else -      cg.upMoveTime = cg.time; -  } - -  if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_POISONCLOUDED && -      !( cg.snap->ps.pm_flags & PMF_FOLLOW ) ) -  { -    float fraction = sin( ( (float)cg.time / 1000.0f ) * M_PI * 2 * PCLOUD_ROLL_FREQUENCY ); -    float pitchFraction = sin( ( (float)cg.time / 1000.0f ) * M_PI * 5 * PCLOUD_ROLL_FREQUENCY ); - -    fraction *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)LEVEL1_PCLOUD_TIME ); -    pitchFraction *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)LEVEL1_PCLOUD_TIME ); - -    angles[ ROLL ] += fraction * PCLOUD_ROLL_AMPLITUDE; -    angles[ YAW ] += fraction * PCLOUD_ROLL_AMPLITUDE; -    angles[ PITCH ] += pitchFraction * PCLOUD_ROLL_AMPLITUDE / 2.0f; -  } - -  //TA: this *feels* more realisitic for humans -  if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS ) -  { -    angles[PITCH] += cg.bobfracsin * bob2 * 0.5; - -    //TA: heavy breathing effects //FIXME: sound -    if( cg.predictedPlayerState.stats[ STAT_STAMINA ] < 0 ) -    { -      float deltaBreath = (float)( -        cg.predictedPlayerState.stats[ STAT_STAMINA ] < 0 ? -        -cg.predictedPlayerState.stats[ STAT_STAMINA ] : -        cg.predictedPlayerState.stats[ STAT_STAMINA ] ) / 200.0; -      float deltaAngle = cos( (float)cg.time/150.0 ) * deltaBreath; - -      deltaAngle += ( deltaAngle < 0 ? -deltaAngle : deltaAngle ) * 0.5; - -      angles[ PITCH ] -= deltaAngle; -    } -  } - -//=================================== - -  // add view height -  //TA: when wall climbing the viewheight is not straight up -  if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBING ) -    VectorMA( origin, ps->viewheight, normal, origin ); -  else -    origin[ 2 ] += cg.predictedPlayerState.viewheight; - -  // smooth out duck height changes -  timeDelta = cg.time - cg.duckTime; -  if( timeDelta < DUCK_TIME) -  { -    cg.refdef.vieworg[ 2 ] -= cg.duckChange -      * ( DUCK_TIME - timeDelta ) / DUCK_TIME; -  } - -  // add bob height -  bob = cg.bobfracsin * cg.xyspeed * bob2; - -  if( bob > 6 ) -    bob = 6; - -  //TA: likewise for bob -  if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBING ) -    VectorMA( origin, bob, normal, origin ); -  else -    origin[ 2 ] += bob; - - -  // add fall height -  delta = cg.time - cg.landTime; - -  if( delta < LAND_DEFLECT_TIME ) -  { -    f = delta / LAND_DEFLECT_TIME; -    cg.refdef.vieworg[ 2 ] += cg.landChange * f; -  } -  else if( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME ) -  { -    delta -= LAND_DEFLECT_TIME; -    f = 1.0 - ( delta / LAND_RETURN_TIME ); -    cg.refdef.vieworg[ 2 ] += cg.landChange * f; -  } - -  // add step offset -  CG_StepOffset( ); - -  // add kick offset - -  VectorAdd (origin, cg.kick_origin, origin); -} - -//====================================================================== - -void CG_ZoomDown_f( void ) -{ -  if( cg.zoomed ) -    return; - -  cg.zoomed = qtrue; -  cg.zoomTime = cg.time; -} - -void CG_ZoomUp_f( void ) -{ -  if( !cg.zoomed ) -    return; - -  cg.zoomed = qfalse; -  cg.zoomTime = cg.time; -} - - -/* -==================== -CG_CalcFov - -Fixed fov at intermissions, otherwise account for fov variable and zooms. -==================== -*/ -#define WAVE_AMPLITUDE  1 -#define WAVE_FREQUENCY  0.4 - -#define FOVWARPTIME     400.0 - -static int CG_CalcFov( void ) -{ -  float x; -  float phase; -  float v; -  int   contents; -  float fov_x, fov_y; -  float zoomFov; -  float f; -  int   inwater; -  int   attribFov; - -  if( cg.predictedPlayerState.pm_type == PM_INTERMISSION || -      ( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) ) -  { -    // if in intermission, use a fixed value -    fov_x = 90; -  } -  else -  { -    //TA: don't lock the fov globally - we need to be able to change it -    attribFov = BG_FindFovForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] ); -    fov_x = attribFov; - -    if ( fov_x < 1 ) -      fov_x = 1; -    else if ( fov_x > 160 ) -      fov_x = 160; - -    if( cg.spawnTime > ( cg.time - FOVWARPTIME ) && -        BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_PCLASS ], SCA_FOVWARPS ) ) -    { -      float temp, temp2; - -      temp = (float)( cg.time - cg.spawnTime ) / FOVWARPTIME; -      temp2 = ( 180 - fov_x ) * temp; - -      //Com_Printf( "%f %f\n", temp*100, temp2*100 ); - -      fov_x = 180 - temp2; -    } - -    // account for zooms -    zoomFov = BG_FindZoomFovForWeapon( cg.predictedPlayerState.weapon ); -    if ( zoomFov < 1 ) -      zoomFov = 1; -    else if ( zoomFov > attribFov ) -      zoomFov = attribFov; - -    //TA: only do all the zoom stuff if the client CAN zoom -    if( BG_WeaponCanZoom( cg.predictedPlayerState.weapon ) ) -    { -      if ( cg.zoomed ) -      { -        f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME; - -        if ( f > 1.0 ) -          fov_x = zoomFov; -        else -          fov_x = fov_x + f * ( zoomFov - fov_x ); -      } -      else -      { -        f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME; - -        if ( f > 1.0 ) -          fov_x = fov_x; -        else -          fov_x = zoomFov + f * ( fov_x - zoomFov ); -      } -    } -  } - -  x = cg.refdef.width / tan( fov_x / 360 * M_PI ); -  fov_y = atan2( cg.refdef.height, x ); -  fov_y = fov_y * 360 / M_PI; - -  // warp if underwater -  contents = CG_PointContents( cg.refdef.vieworg, -1 ); - -  if( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) -  { -    phase = cg.time / 1000.0 * WAVE_FREQUENCY * M_PI * 2; -    v = WAVE_AMPLITUDE * sin( phase ); -    fov_x += v; -    fov_y -= v; -    inwater = qtrue; -  } -  else -    inwater = qfalse; - -  if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_POISONCLOUDED && -      cg.predictedPlayerState.stats[ STAT_HEALTH ] > 0 && -      !( cg.snap->ps.pm_flags & PMF_FOLLOW ) ) -  { -    phase = cg.time / 1000.0 * PCLOUD_ZOOM_FREQUENCY * M_PI * 2; -    v = PCLOUD_ZOOM_AMPLITUDE * sin( phase ); -    v *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)LEVEL1_PCLOUD_TIME ); -    fov_x += v; -    fov_y += v; -  } - - -  // set it -  cg.refdef.fov_x = fov_x; -  cg.refdef.fov_y = fov_y; - -  if( !cg.zoomed ) -    cg.zoomSensitivity = 1; -  else -    cg.zoomSensitivity = cg.refdef.fov_y / 75.0; - -  return inwater; -} - - - -#define NORMAL_HEIGHT 64.0f -#define NORMAL_WIDTH  6.0f - -/* -=============== -CG_DrawSurfNormal - -Draws a vector against -the surface player is looking at -=============== -*/ -static void CG_DrawSurfNormal( void ) -{ -  trace_t     tr; -  vec3_t      end, temp; -  polyVert_t  normal[ 4 ]; -  vec4_t      color = { 0.0f, 255.0f, 0.0f, 128.0f }; - -  VectorMA( cg.refdef.vieworg, 8192, cg.refdef.viewaxis[ 0 ], end ); - -  CG_Trace( &tr, cg.refdef.vieworg, NULL, NULL, end, cg.predictedPlayerState.clientNum, MASK_SOLID ); - -  VectorCopy( tr.endpos, normal[ 0 ].xyz ); -  normal[ 0 ].st[ 0 ] = 0; -  normal[ 0 ].st[ 1 ] = 0; -  Vector4Copy( color, normal[ 0 ].modulate ); - -  VectorMA( tr.endpos, NORMAL_WIDTH, cg.refdef.viewaxis[ 1 ], temp ); -  VectorCopy( temp, normal[ 1 ].xyz); -  normal[ 1 ].st[ 0 ] = 0; -  normal[ 1 ].st[ 1 ] = 1; -  Vector4Copy( color, normal[ 1 ].modulate ); - -  VectorMA( tr.endpos, NORMAL_HEIGHT, tr.plane.normal, temp ); -  VectorMA( temp, NORMAL_WIDTH, cg.refdef.viewaxis[ 1 ], temp ); -  VectorCopy( temp, normal[ 2 ].xyz ); -  normal[ 2 ].st[ 0 ] = 1; -  normal[ 2 ].st[ 1 ] = 1; -  Vector4Copy( color, normal[ 2 ].modulate ); - -  VectorMA( tr.endpos, NORMAL_HEIGHT, tr.plane.normal, temp ); -  VectorCopy( temp, normal[ 3 ].xyz ); -  normal[ 3 ].st[ 0 ] = 1; -  normal[ 3 ].st[ 1 ] = 0; -  Vector4Copy( color, normal[ 3 ].modulate ); - -  trap_R_AddPolyToScene( cgs.media.outlineShader, 4, normal ); -} - -/* -=============== -CG_addSmoothOp -=============== -*/ -void CG_addSmoothOp( vec3_t rotAxis, float rotAngle, float timeMod ) -{ -  int i; - -  //iterate through smooth array -  for( i = 0; i < MAXSMOOTHS; i++ ) -  { -    //found an unused index in the smooth array -    if( cg.sList[ i ].time + cg_wwSmoothTime.integer < cg.time ) -    { -      //copy to array and stop -      VectorCopy( rotAxis, cg.sList[ i ].rotAxis ); -      cg.sList[ i ].rotAngle = rotAngle; -      cg.sList[ i ].time = cg.time; -      cg.sList[ i ].timeMod = timeMod; -      return; -    } -  } - -  //no free indices in the smooth array -} - -/* -=============== -CG_smoothWWTransitions -=============== -*/ -static void CG_smoothWWTransitions( playerState_t *ps, const vec3_t in, vec3_t out ) -{ -  vec3_t    surfNormal, rotAxis, temp; -  vec3_t    refNormal     = { 0.0f, 0.0f,  1.0f }; -  vec3_t    ceilingNormal = { 0.0f, 0.0f, -1.0f }; -  int       i; -  float     stLocal, sFraction, rotAngle; -  float     smoothTime, timeMod; -  qboolean  performed = qfalse; -  vec3_t    inAxis[ 3 ], lastAxis[ 3 ], outAxis[ 3 ]; - -  if( cg.snap->ps.pm_flags & PMF_FOLLOW ) -  { -    VectorCopy( in, out ); -    return; -  } - -  //set surfNormal -  if( !( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) ) -    VectorCopy( ps->grapplePoint, surfNormal ); -  else -    VectorCopy( ceilingNormal, surfNormal ); - -  AnglesToAxis( in, inAxis ); - -  //if we are moving from one surface to another smooth the transition -  if( !VectorCompare( surfNormal, cg.lastNormal ) ) -  { -    //if we moving from the ceiling to the floor special case -    //( x product of colinear vectors is undefined) -    if( VectorCompare( ceilingNormal, cg.lastNormal ) && -        VectorCompare( refNormal,     surfNormal ) ) -    { -      AngleVectors( in, temp, NULL, NULL ); -      ProjectPointOnPlane( rotAxis, temp, refNormal ); -      VectorNormalize( rotAxis ); -      rotAngle = 180.0f; -      timeMod = 1.5f; -    } -    else -    { -      AnglesToAxis( cg.lastVangles, lastAxis ); -      rotAngle = DotProduct( inAxis[ 0 ], lastAxis[ 0 ] ) + -                 DotProduct( inAxis[ 1 ], lastAxis[ 1 ] ) + -                 DotProduct( inAxis[ 2 ], lastAxis[ 2 ] ); - -      rotAngle = RAD2DEG( acos( ( rotAngle - 1.0f ) / 2.0f ) ); - -      CrossProduct( lastAxis[ 0 ], inAxis[ 0 ], temp ); -      VectorCopy( temp, rotAxis ); -      CrossProduct( lastAxis[ 1 ], inAxis[ 1 ], temp ); -      VectorAdd( rotAxis, temp, rotAxis ); -      CrossProduct( lastAxis[ 2 ], inAxis[ 2 ], temp ); -      VectorAdd( rotAxis, temp, rotAxis ); - -      VectorNormalize( rotAxis ); - -      timeMod = 1.0f; -    } - -    //add the op -    CG_addSmoothOp( rotAxis, rotAngle, timeMod ); -  } - -  //iterate through ops -  for( i = MAXSMOOTHS - 1; i >= 0; i-- ) -  { -    smoothTime = (int)( cg_wwSmoothTime.integer * cg.sList[ i ].timeMod ); - -    //if this op has time remaining, perform it -    if( cg.time < cg.sList[ i ].time + smoothTime ) -    { -      stLocal = 1.0f - ( ( ( cg.sList[ i ].time + smoothTime ) - cg.time ) / smoothTime ); -      sFraction = -( cos( stLocal * M_PI ) + 1.0f ) / 2.0f; - -      RotatePointAroundVector( outAxis[ 0 ], cg.sList[ i ].rotAxis, -        inAxis[ 0 ], sFraction * cg.sList[ i ].rotAngle ); -      RotatePointAroundVector( outAxis[ 1 ], cg.sList[ i ].rotAxis, -        inAxis[ 1 ], sFraction * cg.sList[ i ].rotAngle ); -      RotatePointAroundVector( outAxis[ 2 ], cg.sList[ i ].rotAxis, -        inAxis[ 2 ], sFraction * cg.sList[ i ].rotAngle ); - -      AxisCopy( outAxis, inAxis ); -      performed = qtrue; -    } -  } - -  //if we performed any ops then return the smoothed angles -  //otherwise simply return the in angles -  if( performed ) -    AxisToAngles( outAxis, out ); -  else -    VectorCopy( in, out ); - -  //copy the current normal to the lastNormal -  VectorCopy( in, cg.lastVangles ); -  VectorCopy( surfNormal, cg.lastNormal ); -} - -/* -=============== -CG_smoothWJTransitions -=============== -*/ -static void CG_smoothWJTransitions( playerState_t *ps, const vec3_t in, vec3_t out ) -{ -  int       i; -  float     stLocal, sFraction; -  qboolean  performed = qfalse; -  vec3_t    inAxis[ 3 ], outAxis[ 3 ]; - -  if( cg.snap->ps.pm_flags & PMF_FOLLOW ) -  { -    VectorCopy( in, out ); -    return; -  } - -  AnglesToAxis( in, inAxis ); - -  //iterate through ops -  for( i = MAXSMOOTHS - 1; i >= 0; i-- ) -  { -    //if this op has time remaining, perform it -    if( cg.time < cg.sList[ i ].time + cg_wwSmoothTime.integer ) -    { -      stLocal = ( ( cg.sList[ i ].time + cg_wwSmoothTime.integer ) - cg.time ) / cg_wwSmoothTime.integer; -      sFraction = 1.0f - ( ( cos( stLocal * M_PI * 2.0f ) + 1.0f ) / 2.0f ); - -      RotatePointAroundVector( outAxis[ 0 ], cg.sList[ i ].rotAxis, -        inAxis[ 0 ], sFraction * cg.sList[ i ].rotAngle ); -      RotatePointAroundVector( outAxis[ 1 ], cg.sList[ i ].rotAxis, -        inAxis[ 1 ], sFraction * cg.sList[ i ].rotAngle ); -      RotatePointAroundVector( outAxis[ 2 ], cg.sList[ i ].rotAxis, -        inAxis[ 2 ], sFraction * cg.sList[ i ].rotAngle ); - -      AxisCopy( outAxis, inAxis ); -      performed = qtrue; -    } -  } - -  //if we performed any ops then return the smoothed angles -  //otherwise simply return the in angles -  if( performed ) -    AxisToAngles( outAxis, out ); -  else -    VectorCopy( in, out ); -} - - -/* -=============== -CG_CalcViewValues - -Sets cg.refdef view values -=============== -*/ -static int CG_CalcViewValues( void ) -{ -  playerState_t *ps; - -  memset( &cg.refdef, 0, sizeof( cg.refdef ) ); - -  // calculate size of 3D view -  CG_CalcVrect( ); - -  ps = &cg.predictedPlayerState; - -  // intermission view -  if( ps->pm_type == PM_INTERMISSION ) -  { -    VectorCopy( ps->origin, cg.refdef.vieworg ); -    VectorCopy( ps->viewangles, cg.refdefViewAngles ); -    AnglesToAxis( cg.refdefViewAngles, cg.refdef.viewaxis ); - -    return CG_CalcFov( ); -  } - -  cg.bobcycle = ( ps->bobCycle & 128 ) >> 7; -  cg.bobfracsin = fabs( sin( ( ps->bobCycle & 127 ) / 127.0 * M_PI ) ); -  cg.xyspeed = sqrt( ps->velocity[ 0 ] * ps->velocity[ 0 ] + -    ps->velocity[ 1 ] * ps->velocity[ 1 ] ); - -  VectorCopy( ps->origin, cg.refdef.vieworg ); - -  if( BG_ClassHasAbility( ps->stats[ STAT_PCLASS ], SCA_WALLCLIMBER ) ) -    CG_smoothWWTransitions( ps, ps->viewangles, cg.refdefViewAngles ); -  else if( BG_ClassHasAbility( ps->stats[ STAT_PCLASS ], SCA_WALLJUMPER ) ) -    CG_smoothWJTransitions( ps, ps->viewangles, cg.refdefViewAngles ); -  else -    VectorCopy( ps->viewangles, cg.refdefViewAngles ); - -  //clumsy logic, but it needs to be this way round because the CS propogation -  //delay screws things up otherwise -  if( !BG_ClassHasAbility( ps->stats[ STAT_PCLASS ], SCA_WALLJUMPER ) ) -  { -    if( !( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) ) -      VectorSet( cg.lastNormal, 0.0f, 0.0f, 1.0f ); -  } - -  // add error decay -  if( cg_errorDecay.value > 0 ) -  { -    int   t; -    float f; - -    t = cg.time - cg.predictedErrorTime; -    f = ( cg_errorDecay.value - t ) / cg_errorDecay.value; - -    if( f > 0 && f < 1 ) -      VectorMA( cg.refdef.vieworg, f, cg.predictedError, cg.refdef.vieworg ); -    else -      cg.predictedErrorTime = 0; -  } - -  //shut off the poison cloud effect if it's still on the go -  if( cg.snap->ps.stats[ STAT_HEALTH ] <= 0 ) -  { -    if( CG_IsParticleSystemValid( &cg.poisonCloudPS ) ) -      CG_DestroyParticleSystem( &cg.poisonCloudPS ); -  } - -  if( cg.renderingThirdPerson ) -  { -    // back away from character -    CG_OffsetThirdPersonView( ); -  } -  else -  { -    // offset for local bobbing and kicks -    CG_OffsetFirstPersonView( ); -  } - -  // position eye reletive to origin -  AnglesToAxis( cg.refdefViewAngles, cg.refdef.viewaxis ); - -  if( cg.hyperspace ) -    cg.refdef.rdflags |= RDF_NOWORLDMODEL | RDF_HYPERSPACE; - -  //draw the surface normal looking at -  if( cg_drawSurfNormal.integer ) -    CG_DrawSurfNormal( ); - -  // field of view -  return CG_CalcFov( ); -} - -/* -===================== -CG_AddBufferedSound -===================== -*/ -void CG_AddBufferedSound( sfxHandle_t sfx ) -{ -  if( !sfx ) -    return; - -  cg.soundBuffer[ cg.soundBufferIn ] = sfx; -  cg.soundBufferIn = ( cg.soundBufferIn + 1 ) % MAX_SOUNDBUFFER; - -  if( cg.soundBufferIn == cg.soundBufferOut ) -    cg.soundBufferOut++; -} - -/* -===================== -CG_PlayBufferedSounds -===================== -*/ -static void CG_PlayBufferedSounds( void ) -{ -  if( cg.soundTime < cg.time ) -  { -    if( cg.soundBufferOut != cg.soundBufferIn && cg.soundBuffer[ cg.soundBufferOut ] ) -    { -      trap_S_StartLocalSound( cg.soundBuffer[ cg.soundBufferOut ], CHAN_ANNOUNCER ); -      cg.soundBuffer[ cg.soundBufferOut ] = 0; -      cg.soundBufferOut = ( cg.soundBufferOut + 1 ) % MAX_SOUNDBUFFER; -      cg.soundTime = cg.time + 750; -    } -  } -} - -//========================================================================= - -/* -================= -CG_DrawActiveFrame - -Generates and draws a game scene and status information at the given time. -================= -*/ -void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback ) -{ -  int   inwater; - -  cg.time = serverTime; -  cg.demoPlayback = demoPlayback; - -  // update cvars -  CG_UpdateCvars( ); - -  // if we are only updating the screen as a loading -  // pacifier, don't even try to read snapshots -  if( cg.infoScreenText[ 0 ] != 0 ) -  { -    CG_DrawLoadingScreen( ); -    return; -  } - -  // any looped sounds will be respecified as entities -  // are added to the render list -  trap_S_ClearLoopingSounds( qfalse ); - -  // clear all the render lists -  trap_R_ClearScene( ); - -  // set up cg.snap and possibly cg.nextSnap -  CG_ProcessSnapshots( ); - -  // if we haven't received any snapshots yet, all -  // we can draw is the information screen -  if( !cg.snap || ( cg.snap->snapFlags & SNAPFLAG_NOT_ACTIVE ) ) -  { -    CG_DrawLoadingScreen( ); -    return; -  } - -  // let the client system know what our weapon and zoom settings are -  trap_SetUserCmdValue( cg.weaponSelect, cg.zoomSensitivity ); - -  // this counter will be bumped for every valid scene we generate -  cg.clientFrame++; - -  // update cg.predictedPlayerState -  CG_PredictPlayerState( ); - -  // decide on third person view -  cg.renderingThirdPerson = cg_thirdPerson.integer || ( cg.snap->ps.stats[ STAT_HEALTH ] <= 0 ); - -  // build cg.refdef -  inwater = CG_CalcViewValues( ); - -  // build the render lists -  if( !cg.hyperspace ) -  { -    CG_AddPacketEntities( );     // after calcViewValues, so predicted player state is correct -    CG_AddMarks( ); -  } - -  CG_AddViewWeapon( &cg.predictedPlayerState ); - -  //after CG_AddViewWeapon -  if( !cg.hyperspace ) -  { -    CG_AddParticles( ); -    CG_AddTrails( ); -  } - -  // add buffered sounds -  CG_PlayBufferedSounds( ); - -  // finish up the rest of the refdef -  if( cg.testModelEntity.hModel ) -    CG_AddTestModel( ); - -  cg.refdef.time = cg.time; -  memcpy( cg.refdef.areamask, cg.snap->areamask, sizeof( cg.refdef.areamask ) ); - -  //remove expired console lines -  if( cg.consoleLines[ 0 ].time + cg_consoleLatency.integer < cg.time && cg_consoleLatency.integer > 0 ) -    CG_RemoveConsoleLine( ); - -  // update audio positions -  trap_S_Respatialize( cg.snap->ps.clientNum, cg.refdef.vieworg, cg.refdef.viewaxis, inwater ); - -  // make sure the lagometerSample and frame timing isn't done twice when in stereo -  if( stereoView != STEREO_RIGHT ) -  { -    cg.frametime = cg.time - cg.oldTime; - -    if( cg.frametime < 0 ) -      cg.frametime = 0; - -    cg.oldTime = cg.time; -    CG_AddLagometerFrameInfo( ); -  } - -  if( cg_timescale.value != cg_timescaleFadeEnd.value ) -  { -    if( cg_timescale.value < cg_timescaleFadeEnd.value ) -    { -      cg_timescale.value += cg_timescaleFadeSpeed.value * ( (float)cg.frametime ) / 1000; -      if( cg_timescale.value > cg_timescaleFadeEnd.value ) -        cg_timescale.value = cg_timescaleFadeEnd.value; -    } -    else -    { -      cg_timescale.value -= cg_timescaleFadeSpeed.value * ( (float)cg.frametime ) / 1000; -      if( cg_timescale.value < cg_timescaleFadeEnd.value ) -        cg_timescale.value = cg_timescaleFadeEnd.value; -    } - -    if( cg_timescaleFadeSpeed.value ) -      trap_Cvar_Set( "timescale", va( "%f", cg_timescale.value ) ); -  } - -  // actually issue the rendering calls -  CG_DrawActive( stereoView ); - -  if( cg_stats.integer ) -    CG_Printf( "cg.clientFrame:%i\n", cg.clientFrame ); -} - diff --git a/mod/src/cgame/cg_weapons.c b/mod/src/cgame/cg_weapons.c deleted file mode 100644 index 7297c518..00000000 --- a/mod/src/cgame/cg_weapons.c +++ /dev/null @@ -1,1810 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// cg_weapons.c -- events and effects dealing with weapons - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "cg_local.h" - -/* -================= -CG_RegisterUpgrade - -The server says this item is used on this level -================= -*/ -void CG_RegisterUpgrade( int upgradeNum ) -{ -  upgradeInfo_t   *upgradeInfo; -  char            *icon; - -  upgradeInfo = &cg_upgrades[ upgradeNum ]; - -  if( upgradeNum == 0 ) -    return; - -  if( upgradeInfo->registered ) -    return; - -  memset( upgradeInfo, 0, sizeof( *upgradeInfo ) ); -  upgradeInfo->registered = qtrue; - -  if( !BG_FindNameForUpgrade( upgradeNum ) ) -    CG_Error( "Couldn't find upgrade %i", upgradeNum ); - -  upgradeInfo->humanName = BG_FindHumanNameForUpgrade( upgradeNum ); - -  //la la la la la, i'm not listening! -  if( upgradeNum == UP_GRENADE ) -    upgradeInfo->upgradeIcon = cg_weapons[ WP_GRENADE ].weaponIcon; -  else if( ( icon = BG_FindIconForUpgrade( upgradeNum ) ) ) -    upgradeInfo->upgradeIcon = trap_R_RegisterShader( icon ); -} - -/* -=============== -CG_InitUpgrades - -Precaches upgrades -=============== -*/ -void CG_InitUpgrades( void ) -{ -  int   i; - -  memset( cg_upgrades, 0, sizeof( cg_upgrades ) ); - -  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -    CG_RegisterUpgrade( i ); -} - - -/* -=============== -CG_ParseWeaponModeSection - -Parse a weapon mode section -=============== -*/ -static qboolean CG_ParseWeaponModeSection( weaponInfoMode_t *wim, char **text_p ) -{ -  char  *token; -  int   i; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( text_p ); - -    if( !token ) -      break; - -    if( !Q_stricmp( token, "" ) ) -      return qfalse; - -    if( !Q_stricmp( token, "missileModel" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->missileModel = trap_R_RegisterModel( token ); - -      if( !wim->missileModel ) -        CG_Printf( S_COLOR_RED "ERROR: missile model not found %s\n", token ); - -      continue; -    } -    else if( !Q_stricmp( token, "missileSprite" ) ) -    { -      int size = 0; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      size = atoi( token ); - -      if( size < 0 ) -        size = 0; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->missileSprite = trap_R_RegisterShader( token ); -      wim->missileSpriteSize = size; -      wim->usesSpriteMissle = qtrue; - -      if( !wim->missileSprite ) -        CG_Printf( S_COLOR_RED "ERROR: missile sprite not found %s\n", token ); - -      continue; -    } -    else if( !Q_stricmp( token, "missileRotates" ) ) -    { -      wim->missileRotates = qtrue; - -      continue; -    } -    else if( !Q_stricmp( token, "missileAnimates" ) ) -    { -      wim->missileAnimates = qtrue; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->missileAnimStartFrame = atoi( token ); - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->missileAnimNumFrames = atoi( token ); - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->missileAnimFrameRate = atoi( token ); - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->missileAnimLooping = atoi( token ); - -      continue; -    } -    else if( !Q_stricmp( token, "missileParticleSystem" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->missileParticleSystem = CG_RegisterParticleSystem( token ); - -      if( !wim->missileParticleSystem ) -        CG_Printf( S_COLOR_RED "ERROR: missile particle system not found %s\n", token ); - -      continue; -    } -    else if( !Q_stricmp( token, "missileTrailSystem" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->missileTrailSystem = CG_RegisterTrailSystem( token ); - -      if( !wim->missileTrailSystem ) -        CG_Printf( S_COLOR_RED "ERROR: missile trail system not found %s\n", token ); - -      continue; -    } -    else if( !Q_stricmp( token, "muzzleParticleSystem" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->muzzleParticleSystem = CG_RegisterParticleSystem( token ); - -      if( !wim->muzzleParticleSystem ) -        CG_Printf( S_COLOR_RED "ERROR: muzzle particle system not found %s\n", token ); - -      continue; -    } -    else if( !Q_stricmp( token, "impactParticleSystem" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->impactParticleSystem = CG_RegisterParticleSystem( token ); - -      if( !wim->impactParticleSystem ) -        CG_Printf( S_COLOR_RED "ERROR: impact particle system not found %s\n", token ); - -      continue; -    } -    else if( !Q_stricmp( token, "impactMark" ) ) -    { -      int size = 0; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      size = atoi( token ); - -      if( size < 0 ) -        size = 0; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->impactMark = trap_R_RegisterShader( token ); -      wim->impactMarkSize = size; - -      if( !wim->impactMark ) -        CG_Printf( S_COLOR_RED "ERROR: impact mark shader not found %s\n", token ); - -      continue; -    } -    else if( !Q_stricmp( token, "impactSound" ) ) -    { -      int index = 0; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      index = atoi( token ); - -      if( index < 0 ) -        index = 0; -      else if( index > 3 ) -        index = 3; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->impactSound[ index ] = trap_S_RegisterSound( token, qfalse ); - -      continue; -    } -    else if( !Q_stricmp( token, "impactFleshSound" ) ) -    { -      int index = 0; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      index = atoi( token ); - -      if( index < 0 ) -        index = 0; -      else if( index > 3 ) -        index = 3; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->impactFleshSound[ index ] = trap_S_RegisterSound( token, qfalse ); - -      continue; -    } -    else if( !Q_stricmp( token, "alwaysImpact" ) ) -    { -      wim->alwaysImpact = qtrue; - -      continue; -    } -    else if( !Q_stricmp( token, "flashDLightColor" ) ) -    { -      for( i = 0 ; i < 3 ; i++ ) -      { -        token = COM_Parse( text_p ); -        if( !token ) -          break; - -        wim->flashDlightColor[ i ] = atof( token ); -      } - -      continue; -    } -    else if( !Q_stricmp( token, "continuousFlash" ) ) -    { -      wim->continuousFlash = qtrue; - -      continue; -    } -    else if( !Q_stricmp( token, "missileDlightColor" ) ) -    { -      for( i = 0 ; i < 3 ; i++ ) -      { -        token = COM_Parse( text_p ); -        if( !token ) -          break; - -        wim->missileDlightColor[ i ] = atof( token ); -      } - -      continue; -    } -    else if( !Q_stricmp( token, "missileDlight" ) ) -    { -      int size = 0; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      size = atoi( token ); - -      if( size < 0 ) -        size = 0; - -      wim->missileDlight = size; - -      continue; -    } -    else if( !Q_stricmp( token, "firingSound" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->firingSound = trap_S_RegisterSound( token, qfalse ); - -      continue; -    } -    else if( !Q_stricmp( token, "missileSound" ) ) -    { -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->missileSound = trap_S_RegisterSound( token, qfalse ); - -      continue; -    } -    else if( !Q_stricmp( token, "flashSound" ) ) -    { -      int index = 0; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      index = atoi( token ); - -      if( index < 0 ) -        index = 0; -      else if( index > 3 ) -        index = 3; - -      token = COM_Parse( text_p ); -      if( !token ) -        break; - -      wim->flashSound[ index ] = trap_S_RegisterSound( token, qfalse ); - -      continue; -    } -    else if( !Q_stricmp( token, "}" ) ) -      return qtrue; //reached the end of this weapon section -    else -    { -      CG_Printf( S_COLOR_RED "ERROR: unknown token '%s' in weapon section\n", token ); -      return qfalse; -    } -  } - -  return qfalse; -} - - -/* -====================== -CG_ParseWeaponFile - -Parses a configuration file describing a weapon -====================== -*/ -static qboolean CG_ParseWeaponFile( const char *filename, weaponInfo_t *wi ) -{ -  char          *text_p; -  int           len; -  char          *token; -  char          text[ 20000 ]; -  fileHandle_t  f; -  weaponMode_t  weaponMode = WPM_NONE; - -  // load the file -  len = trap_FS_FOpenFile( filename, &f, FS_READ ); -  if( len <= 0 ) -    return qfalse; - -  if( len >= sizeof( text ) - 1 ) -  { -    CG_Printf( "File %s too long\n", filename ); -    return qfalse; -  } - -  trap_FS_Read( text, len, f ); -  text[ len ] = 0; -  trap_FS_FCloseFile( f ); - -  // parse the text -  text_p = text; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( &text_p ); - -    if( !token ) -      break; - -    if( !Q_stricmp( token, "" ) ) -      break; - -    if( !Q_stricmp( token, "{" ) ) -    { -      if( weaponMode == WPM_NONE ) -      { -        CG_Printf( S_COLOR_RED "ERROR: weapon mode section started without a declaration\n" ); -        return qfalse; -      } -      else if( !CG_ParseWeaponModeSection( &wi->wim[ weaponMode ], &text_p ) ) -      { -        CG_Printf( S_COLOR_RED "ERROR: failed to parse weapon mode section\n" ); -        return qfalse; -      } - -      //start parsing ejectors again -      weaponMode = WPM_NONE; - -      continue; -    } -    else if( !Q_stricmp( token, "primary" ) ) -    { -      weaponMode = WPM_PRIMARY; -      continue; -    } -    else if( !Q_stricmp( token, "secondary" ) ) -    { -      weaponMode = WPM_SECONDARY; -      continue; -    } -    else if( !Q_stricmp( token, "tertiary" ) ) -    { -      weaponMode = WPM_TERTIARY; -      continue; -    } -    else if( !Q_stricmp( token, "weaponModel" ) ) -    { -      char path[ MAX_QPATH ]; - -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      wi->weaponModel = trap_R_RegisterModel( token ); - -      if( !wi->weaponModel ) -        CG_Printf( S_COLOR_RED "ERROR: weapon model not found %s\n", token ); - -      strcpy( path, token ); -      COM_StripExtension( path, path ); -      strcat( path, "_flash.md3" ); -      wi->flashModel = trap_R_RegisterModel( path ); - -      strcpy( path, token ); -      COM_StripExtension( path, path ); -      strcat( path, "_barrel.md3" ); -      wi->barrelModel = trap_R_RegisterModel( path ); - -      strcpy( path, token ); -      COM_StripExtension( path, path ); -      strcat( path, "_hand.md3" ); -      wi->handsModel = trap_R_RegisterModel( path ); - -      if( !wi->handsModel ) -        wi->handsModel = trap_R_RegisterModel( "models/weapons2/shotgun/shotgun_hand.md3" ); - -      continue; -    } -    else if( !Q_stricmp( token, "idleSound" ) ) -    { -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      wi->readySound = trap_S_RegisterSound( token, qfalse ); - -      continue; -    } -    else if( !Q_stricmp( token, "icon" ) ) -    { -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      wi->weaponIcon = wi->ammoIcon = trap_R_RegisterShader( token ); - -      if( !wi->weaponIcon ) -        CG_Printf( S_COLOR_RED "ERROR: weapon icon not found %s\n", token ); - -      continue; -    } -    else if( !Q_stricmp( token, "crosshair" ) ) -    { -      int size = 0; - -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      size = atoi( token ); - -      if( size < 0 ) -        size = 0; - -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      wi->crossHair = trap_R_RegisterShader( token ); -      wi->crossHairSize = size; - -      if( !wi->crossHair ) -        CG_Printf( S_COLOR_RED "ERROR: weapon crosshair not found %s\n", token ); - -      continue; -    } -    else if( !Q_stricmp( token, "disableIn3rdPerson" ) ) -    { -      wi->disableIn3rdPerson = qtrue; - -      continue; -    } - -    Com_Printf( S_COLOR_RED "ERROR: unknown token '%s'\n", token ); -    return qfalse; -  } - -  return qtrue; -} - -/* -================= -CG_RegisterWeapon -================= -*/ -void CG_RegisterWeapon( int weaponNum ) -{ -  weaponInfo_t  *weaponInfo; -  char          path[ MAX_QPATH ]; -  vec3_t        mins, maxs; -  int           i; - -  weaponInfo = &cg_weapons[ weaponNum ]; - -  if( weaponNum == 0 ) -    return; - -  if( weaponInfo->registered ) -    return; - -  memset( weaponInfo, 0, sizeof( *weaponInfo ) ); -  weaponInfo->registered = qtrue; - -  if( !BG_FindNameForWeapon( weaponNum ) ) -    CG_Error( "Couldn't find weapon %i", weaponNum ); - -  Com_sprintf( path, MAX_QPATH, "models/weapons/%s/weapon.cfg", BG_FindNameForWeapon( weaponNum ) ); - -  weaponInfo->humanName = BG_FindHumanNameForWeapon( weaponNum ); - -  if( !CG_ParseWeaponFile( path, weaponInfo ) ) -    Com_Printf( S_COLOR_RED "ERROR: failed to parse %s\n", path ); - -  // calc midpoint for rotation -  trap_R_ModelBounds( weaponInfo->weaponModel, mins, maxs ); -  for( i = 0 ; i < 3 ; i++ ) -    weaponInfo->weaponMidpoint[ i ] = mins[ i ] + 0.5 * ( maxs[ i ] - mins[ i ] ); - -  //FIXME: -  for( i = WPM_NONE + 1; i < WPM_NUM_WEAPONMODES; i++ ) -    weaponInfo->wim[ i ].loopFireSound = qfalse; -} - -/* -=============== -CG_InitWeapons - -Precaches weapons -=============== -*/ -void CG_InitWeapons( void ) -{ -  int   i; - -  memset( cg_weapons, 0, sizeof( cg_weapons ) ); - -  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) -    CG_RegisterWeapon( i ); - -  cgs.media.level2ZapTS = CG_RegisterTrailSystem( "models/weapons/lev2zap/lightning" ); -} - - -/* -======================================================================================== - -VIEW WEAPON - -======================================================================================== -*/ - -/* -================= -CG_MapTorsoToWeaponFrame - -================= -*/ -static int CG_MapTorsoToWeaponFrame( clientInfo_t *ci, int frame ) -{ - -  // change weapon -  if( frame >= ci->animations[ TORSO_DROP ].firstFrame && -      frame < ci->animations[ TORSO_DROP ].firstFrame + 9 ) -    return frame - ci->animations[ TORSO_DROP ].firstFrame + 6; - -  // stand attack -  if( frame >= ci->animations[ TORSO_ATTACK ].firstFrame && -      frame < ci->animations[ TORSO_ATTACK ].firstFrame + 6 ) -    return 1 + frame - ci->animations[ TORSO_ATTACK ].firstFrame; - -  // stand attack 2 -  if( frame >= ci->animations[ TORSO_ATTACK2 ].firstFrame && -      frame < ci->animations[ TORSO_ATTACK2 ].firstFrame + 6 ) -    return 1 + frame - ci->animations[ TORSO_ATTACK2 ].firstFrame; - -  return 0; -} - - -/* -============== -CG_CalculateWeaponPosition -============== -*/ -static void CG_CalculateWeaponPosition( vec3_t origin, vec3_t angles ) -{ -  float scale; -  int   delta; -  float fracsin; -  float bob; - -  VectorCopy( cg.refdef.vieworg, origin ); -  VectorCopy( cg.refdefViewAngles, angles ); - -  // on odd legs, invert some angles -  if( cg.bobcycle & 1 ) -    scale = -cg.xyspeed; -  else -    scale = cg.xyspeed; - -  // gun angles from bobbing -  //TA: bob amount is class dependant -  bob = BG_FindBobForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] ); - -  if( bob != 0 ) -  { -    angles[ ROLL ] += scale * cg.bobfracsin * 0.005; -    angles[ YAW ] += scale * cg.bobfracsin * 0.01; -    angles[ PITCH ] += cg.xyspeed * cg.bobfracsin * 0.005; -  } - -  // drop the weapon when landing -  if( !BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_PCLASS ], SCA_NOWEAPONDRIFT ) ) -  { -    delta = cg.time - cg.landTime; -    if( delta < LAND_DEFLECT_TIME ) -      origin[ 2 ] += cg.landChange*0.25 * delta / LAND_DEFLECT_TIME; -    else if( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME ) -      origin[ 2 ] += cg.landChange*0.25 * -        ( LAND_DEFLECT_TIME + LAND_RETURN_TIME - delta ) / LAND_RETURN_TIME; - -    // idle drift -    scale = cg.xyspeed + 40; -    fracsin = sin( cg.time * 0.001 ); -    angles[ ROLL ] += scale * fracsin * 0.01; -    angles[ YAW ] += scale * fracsin * 0.01; -    angles[ PITCH ] += scale * fracsin * 0.01; -  } -} - - -/* -====================== -CG_MachinegunSpinAngle -====================== -*/ -#define   SPIN_SPEED  0.9 -#define   COAST_TIME  1000 -static float CG_MachinegunSpinAngle( centity_t *cent ) -{ -  int   delta; -  float angle; -  float speed; - -  delta = cg.time - cent->pe.barrelTime; -  if( cent->pe.barrelSpinning ) -    angle = cent->pe.barrelAngle + delta * SPIN_SPEED; -  else -  { -    if( delta > COAST_TIME ) -      delta = COAST_TIME; - -    speed = 0.5 * ( SPIN_SPEED + (float)( COAST_TIME - delta ) / COAST_TIME ); -    angle = cent->pe.barrelAngle + delta * speed; -  } - -  if( cent->pe.barrelSpinning == !( cent->currentState.eFlags & EF_FIRING ) ) -  { -    cent->pe.barrelTime = cg.time; -    cent->pe.barrelAngle = AngleMod( angle ); -    cent->pe.barrelSpinning = !!( cent->currentState.eFlags & EF_FIRING ); -                          //TA: um? -  } - -  return angle; -} - - -/* -============= -CG_AddPlayerWeapon - -Used for both the view weapon (ps is valid) and the world modelother character models (ps is NULL) -The main player will have this called for BOTH cases, so effects like light and -sound should only be done on the world model case. -============= -*/ -void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent ) -{ -  refEntity_t   gun; -  refEntity_t   barrel; -  refEntity_t   flash; -  vec3_t        angles; -  weapon_t      weaponNum; -  weaponMode_t  weaponMode; -  weaponInfo_t  *weapon; -  qboolean      noGunModel; -  qboolean      firing; - -  weaponNum = cent->currentState.weapon; -  weaponMode = cent->currentState.generic1; - -  if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES ) -    weaponMode = WPM_PRIMARY; - -  if( ( ( cent->currentState.eFlags & EF_FIRING ) && weaponMode == WPM_PRIMARY ) || -      ( ( cent->currentState.eFlags & EF_FIRING2 ) && weaponMode == WPM_SECONDARY ) || -      ( ( cent->currentState.eFlags & EF_FIRING3 ) && weaponMode == WPM_TERTIARY ) ) -    firing = qtrue; -  else -    firing = qfalse; - -  CG_RegisterWeapon( weaponNum ); -  weapon = &cg_weapons[ weaponNum ]; - -  // add the weapon -  memset( &gun, 0, sizeof( gun ) ); -  VectorCopy( parent->lightingOrigin, gun.lightingOrigin ); -  gun.shadowPlane = parent->shadowPlane; -  gun.renderfx = parent->renderfx; - -  // set custom shading for railgun refire rate -  if( ps ) -  { -    gun.shaderRGBA[ 0 ] = 255; -    gun.shaderRGBA[ 1 ] = 255; -    gun.shaderRGBA[ 2 ] = 255; -    gun.shaderRGBA[ 3 ] = 255; - -    //set weapon[1/2]Time when respective buttons change state -    if( cg.weapon1Firing != ( cg.predictedPlayerState.eFlags & EF_FIRING ) ) -    { -      cg.weapon1Time = cg.time; -      cg.weapon1Firing = ( cg.predictedPlayerState.eFlags & EF_FIRING ); -    } - -    if( cg.weapon2Firing != ( cg.predictedPlayerState.eFlags & EF_FIRING2 ) ) -    { -      cg.weapon2Time = cg.time; -      cg.weapon2Firing = ( cg.predictedPlayerState.eFlags & EF_FIRING2 ); -    } - -    if( cg.weapon3Firing != ( cg.predictedPlayerState.eFlags & EF_FIRING3 ) ) -    { -      cg.weapon3Time = cg.time; -      cg.weapon3Firing = ( cg.predictedPlayerState.eFlags & EF_FIRING3 ); -    } -  } - -  gun.hModel = weapon->weaponModel; - -  noGunModel = ( ( !ps || cg.renderingThirdPerson ) && weapon->disableIn3rdPerson ) || !gun.hModel; - -  if( !ps ) -  { -    // add weapon ready sound -    if( firing && weapon->wim[ weaponMode ].firingSound ) -    { -      trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, -                              weapon->wim[ weaponMode ].firingSound ); -    } -    else if( weapon->readySound ) -      trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, weapon->readySound ); -  } - -  if( !noGunModel ) -  { -    CG_PositionEntityOnTag( &gun, parent, parent->hModel, "tag_weapon" ); - -    trap_R_AddRefEntityToScene( &gun ); - -    // add the spinning barrel -    if( weapon->barrelModel ) -    { -      memset( &barrel, 0, sizeof( barrel ) ); -      VectorCopy( parent->lightingOrigin, barrel.lightingOrigin ); -      barrel.shadowPlane = parent->shadowPlane; -      barrel.renderfx = parent->renderfx; - -      barrel.hModel = weapon->barrelModel; -      angles[ YAW ] = 0; -      angles[ PITCH ] = 0; -      angles[ ROLL ] = CG_MachinegunSpinAngle( cent ); -      AnglesToAxis( angles, barrel.axis ); - -      CG_PositionRotatedEntityOnTag( &barrel, &gun, weapon->weaponModel, "tag_barrel" ); - -      trap_R_AddRefEntityToScene( &barrel ); -    } -  } - -  if( CG_IsParticleSystemValid( ¢->muzzlePS ) ) -  { -    if( ps || cg.renderingThirdPerson || -        cent->currentState.number != cg.predictedPlayerState.clientNum ) -    { -      if( noGunModel ) -        CG_SetAttachmentTag( ¢->muzzlePS->attachment, *parent, parent->hModel, "tag_weapon" ); -      else -        CG_SetAttachmentTag( ¢->muzzlePS->attachment, gun, weapon->weaponModel, "tag_flash" ); -    } - -    //if the PS is infinite disable it when not firing -    if( !firing && CG_IsParticleSystemInfinite( cent->muzzlePS ) ) -      CG_DestroyParticleSystem( ¢->muzzlePS ); -  } - -  // add the flash -  if( !weapon->wim[ weaponMode ].continuousFlash || !firing ) -  { -    // impulse flash -    if( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME ) -      return; -  } - -  memset( &flash, 0, sizeof( flash ) ); -  VectorCopy( parent->lightingOrigin, flash.lightingOrigin ); -  flash.shadowPlane = parent->shadowPlane; -  flash.renderfx = parent->renderfx; - -  flash.hModel = weapon->flashModel; -  if( flash.hModel ) -  { -    angles[ YAW ] = 0; -    angles[ PITCH ] = 0; -    angles[ ROLL ] = crandom( ) * 10; -    AnglesToAxis( angles, flash.axis ); - -    if( noGunModel ) -      CG_PositionRotatedEntityOnTag( &flash, parent, parent->hModel, "tag_weapon" ); -    else -      CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash" ); - -    trap_R_AddRefEntityToScene( &flash ); -  } - -  if( ps || cg.renderingThirdPerson || -      cent->currentState.number != cg.predictedPlayerState.clientNum ) -  { -    if( weapon->wim[ weaponMode ].muzzleParticleSystem && cent->muzzlePsTrigger ) -    { -      cent->muzzlePS = CG_SpawnNewParticleSystem( weapon->wim[ weaponMode ].muzzleParticleSystem ); - -      if( CG_IsParticleSystemValid( ¢->muzzlePS ) ) -      { -        if( noGunModel ) -          CG_SetAttachmentTag( ¢->muzzlePS->attachment, *parent, parent->hModel, "tag_weapon" ); -        else -          CG_SetAttachmentTag( ¢->muzzlePS->attachment, gun, weapon->weaponModel, "tag_flash" ); - -        CG_SetAttachmentCent( ¢->muzzlePS->attachment, cent ); -        CG_AttachToTag( ¢->muzzlePS->attachment ); -      } - -      cent->muzzlePsTrigger = qfalse; -    } - -    // make a dlight for the flash -    if( weapon->wim[ weaponMode ].flashDlightColor[ 0 ] || -        weapon->wim[ weaponMode ].flashDlightColor[ 1 ] || -        weapon->wim[ weaponMode ].flashDlightColor[ 2 ] ) -    { -      trap_R_AddLightToScene( flash.origin, 300 + ( rand( ) & 31 ), -          weapon->wim[ weaponMode ].flashDlightColor[ 0 ], -          weapon->wim[ weaponMode ].flashDlightColor[ 1 ], -          weapon->wim[ weaponMode ].flashDlightColor[ 2 ] ); -    } -  } -} - -/* -============== -CG_AddViewWeapon - -Add the weapon, and flash for the player's view -============== -*/ -void CG_AddViewWeapon( playerState_t *ps ) -{ -  refEntity_t   hand; -  centity_t     *cent; -  clientInfo_t  *ci; -  float         fovOffset; -  vec3_t        angles; -  weaponInfo_t  *wi; -  weapon_t      weapon = ps->weapon; -  weaponMode_t  weaponMode = ps->generic1; - -  if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES ) -    weaponMode = WPM_PRIMARY; - -  CG_RegisterWeapon( weapon ); -  wi = &cg_weapons[ weapon ]; -  cent = &cg.predictedPlayerEntity; // &cg_entities[cg.snap->ps.clientNum]; - -  if( ( ps->persistant[PERS_TEAM] == TEAM_SPECTATOR ) || -      ( ps->stats[ STAT_STATE ] & SS_INFESTING ) || -      ( ps->stats[ STAT_STATE ] & SS_HOVELING ) ) -    return; - -  //TA: no weapon carried - can't draw it -  if( weapon == WP_NONE ) -    return; - -  if( ps->pm_type == PM_INTERMISSION ) -    return; - -  //TA: draw a prospective buildable infront of the player -  if( ( ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) > BA_NONE ) -    CG_GhostBuildable( ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ); - -  if( weapon == WP_LUCIFER_CANNON && ps->stats[ STAT_MISC ] > 0 ) -  { -    if( ps->stats[ STAT_MISC ] > ( LCANNON_TOTAL_CHARGE - ( LCANNON_TOTAL_CHARGE / 3 ) ) ) -      trap_S_AddLoopingSound( ps->clientNum, ps->origin, vec3_origin, cgs.media.lCannonWarningSound ); -  } - -  // no gun if in third person view -  if( cg.renderingThirdPerson ) -    return; - -  // allow the gun to be completely removed -  if( !cg_drawGun.integer ) -  { -    vec3_t origin; - -    VectorCopy( cg.refdef.vieworg, origin ); -    VectorMA( origin, -8, cg.refdef.viewaxis[ 2 ], origin ); - -    if( cent->muzzlePS ) -      CG_SetAttachmentPoint( ¢->muzzlePS->attachment, origin ); - -    //check for particle systems -    if( wi->wim[ weaponMode ].muzzleParticleSystem && cent->muzzlePsTrigger ) -    { -      cent->muzzlePS = CG_SpawnNewParticleSystem( wi->wim[ weaponMode ].muzzleParticleSystem ); - -      if( CG_IsParticleSystemValid( ¢->muzzlePS ) ) -      { -        CG_SetAttachmentPoint( ¢->muzzlePS->attachment, origin ); -        CG_SetAttachmentCent( ¢->muzzlePS->attachment, cent ); -        CG_AttachToPoint( ¢->muzzlePS->attachment ); -      } -      cent->muzzlePsTrigger = qfalse; -    } - -    return; -  } - -  // don't draw if testing a gun model -  if( cg.testGun ) -    return; - -  // drop gun lower at higher fov -  //if ( cg_fov.integer > 90 ) { -  //TA: the client side variable isn't used ( shouldn't iD have done this anyway? ) -  if( cg.refdef.fov_y > 90 ) -    fovOffset = -0.4 * ( cg.refdef.fov_y - 90 ); -  else -    fovOffset = 0; - -  memset( &hand, 0, sizeof( hand ) ); - -  // set up gun position -  CG_CalculateWeaponPosition( hand.origin, angles ); - -  VectorMA( hand.origin, cg_gun_x.value, cg.refdef.viewaxis[ 0 ], hand.origin ); -  VectorMA( hand.origin, cg_gun_y.value, cg.refdef.viewaxis[ 1 ], hand.origin ); -  VectorMA( hand.origin, ( cg_gun_z.value + fovOffset ), cg.refdef.viewaxis[ 2 ], hand.origin ); - -  if( weapon == WP_LUCIFER_CANNON && ps->stats[ STAT_MISC ] > 0 ) -  { -    float fraction = (float)ps->stats[ STAT_MISC ] / (float)LCANNON_TOTAL_CHARGE; - -    VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 0 ], hand.origin ); -    VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 1 ], hand.origin ); -  } - -  AnglesToAxis( angles, hand.axis ); - -  // map torso animations to weapon animations -  if( cg_gun_frame.integer ) -  { -    // development tool -    hand.frame = hand.oldframe = cg_gun_frame.integer; -    hand.backlerp = 0; -  } -  else -  { -    // get clientinfo for animation map -    ci = &cgs.clientinfo[ cent->currentState.clientNum ]; -    hand.frame = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.frame ); -    hand.oldframe = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.oldFrame ); -    hand.backlerp = cent->pe.torso.backlerp; -  } - -  hand.hModel = wi->handsModel; -  hand.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT; - -  // add everything onto the hand -  CG_AddPlayerWeapon( &hand, ps, &cg.predictedPlayerEntity ); -} - -/* -============================================================================== - -WEAPON SELECTION - -============================================================================== -*/ - -/* -=============== -CG_WeaponSelectable -=============== -*/ -static qboolean CG_WeaponSelectable( weapon_t weapon ) -{ -  //int ammo, clips; -  // -  //BG_UnpackAmmoArray( i, cg.snap->ps.ammo, cg.snap->ps.powerups, &ammo, &clips ); -  // -  //TA: this is a pain in the ass -  //if( !ammo && !clips && !BG_FindInfinteAmmoForWeapon( i ) ) -  //  return qfalse; - -  if( !BG_InventoryContainsWeapon( weapon, cg.snap->ps.stats ) ) -    return qfalse; - -  return qtrue; -} - - -/* -=============== -CG_UpgradeSelectable -=============== -*/ -static qboolean CG_UpgradeSelectable( upgrade_t upgrade ) -{ -  if( !BG_InventoryContainsUpgrade( upgrade, cg.snap->ps.stats ) ) -    return qfalse; - -  return qtrue; -} - - -#define ICON_BORDER 4 - -/* -=================== -CG_DrawItemSelect -=================== -*/ -void CG_DrawItemSelect( rectDef_t *rect, vec4_t color ) -{ -  int           i; -  int           x = rect->x; -  int           y = rect->y; -  int           width = rect->w; -  int           height = rect->h; -  int           iconsize; -  int           items[ 64 ]; -  int           numItems = 0, selectedItem = 0; -  int           length; -  int           selectWindow; -  qboolean      vertical; -  centity_t     *cent; -  playerState_t *ps; - -  cent = &cg_entities[ cg.snap->ps.clientNum ]; -  ps = &cg.snap->ps; - -  // don't display if dead -  if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 ) -    return; - -  if( !( cg.snap->ps.pm_flags & PMF_FOLLOW ) ) -  { -    // first make sure that whatever it selected is actually selectable -    if( cg.weaponSelect <= 32 && !CG_WeaponSelectable( cg.weaponSelect ) ) -      CG_NextWeapon_f( ); -    else if( cg.weaponSelect > 32 && !CG_UpgradeSelectable( cg.weaponSelect ) ) -      CG_NextWeapon_f( ); -  } - -  // showing weapon select clears pickup item display, but not the blend blob -  cg.itemPickupTime = 0; - -  if( height > width ) -  { -    vertical = qtrue; -    iconsize = width; -    length = height / width; -  } -  else if( height <= width ) -  { -    vertical = qfalse; -    iconsize = height; -    length = width / height; -  } - -  selectWindow = length / 2; - -  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) -  { -    if( !BG_InventoryContainsWeapon( i, cg.snap->ps.stats ) ) -      continue; - -    if( i == cg.weaponSelect ) -      selectedItem = numItems; - -    CG_RegisterWeapon( i ); -    items[ numItems ] = i; -    numItems++; -  } - -  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -  { -    if( !BG_InventoryContainsUpgrade( i, cg.snap->ps.stats ) ) -      continue; - -    if( i == cg.weaponSelect - 32 ) -      selectedItem = numItems; - -    CG_RegisterUpgrade( i ); -    items[ numItems ] = i + 32; -    numItems++; -  } - -  for( i = 0; i < length; i++ ) -  { -    int displacement = i - selectWindow; -    int item = displacement + selectedItem; - -    if( ( item >= 0 ) && ( item < numItems ) ) -    { -      trap_R_SetColor( color ); - -      if( items[ item ] <= 32 ) -        CG_DrawPic( x, y, iconsize, iconsize, cg_weapons[ items[ item ] ].weaponIcon ); -      else if( items[ item ] > 32 ) -        CG_DrawPic( x, y, iconsize, iconsize, cg_upgrades[ items[ item ] - 32 ].upgradeIcon ); - -      trap_R_SetColor( NULL ); - -/*      if( displacement == 0 ) -        CG_DrawPic( x, y, iconsize, iconsize, cgs.media.selectShader );*/ -    } - -    if( vertical ) -      y += iconsize; -    else -      x += iconsize; -  } -} - - -/* -=================== -CG_DrawItemSelectText -=================== -*/ -void CG_DrawItemSelectText( rectDef_t *rect, float scale, int textStyle ) -{ -  int x, w; -  char  *name; -  float *color; - -  color = CG_FadeColor( cg.weaponSelectTime, WEAPON_SELECT_TIME ); -  if( !color ) -    return; - -  trap_R_SetColor( color ); - -  // draw the selected name -  if( cg.weaponSelect <= 32 ) -  { -    if( cg_weapons[ cg.weaponSelect ].registered && -        BG_InventoryContainsWeapon( cg.weaponSelect, cg.snap->ps.stats ) ) -    { -      if( ( name = cg_weapons[ cg.weaponSelect ].humanName ) ) -      { -        w = CG_Text_Width( name, scale, 0 ); -        x = rect->x + rect->w / 2; -        CG_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle ); -      } -    } -  } -  else if( cg.weaponSelect > 32 ) -  { -    if( cg_upgrades[ cg.weaponSelect - 32 ].registered && -        BG_InventoryContainsUpgrade( cg.weaponSelect - 32, cg.snap->ps.stats ) ) -    { -      if( ( name = cg_upgrades[ cg.weaponSelect - 32 ].humanName ) ) -      { -        w = CG_Text_Width( name, scale, 0 ); -        x = rect->x + rect->w / 2; -        CG_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle ); -      } -    } -  } - -  trap_R_SetColor( NULL ); -} - - -/* -=============== -CG_NextWeapon_f -=============== -*/ -void CG_NextWeapon_f( void ) -{ -  int   i; -  int   original; - -  if( !cg.snap ) -    return; - -  if( cg.snap->ps.pm_flags & PMF_FOLLOW ) -  { -    trap_SendClientCommand( "followprev\n" ); -    return; -  } - -  cg.weaponSelectTime = cg.time; -  original = cg.weaponSelect; - -  for( i = 0; i < 64; i++ ) -  { -    cg.weaponSelect++; -    if( cg.weaponSelect == 64 ) -      cg.weaponSelect = 0; - -    if( cg.weaponSelect <= 32 ) -    { -      if( CG_WeaponSelectable( cg.weaponSelect ) ) -        break; -    } -    else if( cg.weaponSelect > 32 ) -    { -      if( CG_UpgradeSelectable( cg.weaponSelect - 32 ) ) -        break; -    } -  } - -  if( i == 64 ) -    cg.weaponSelect = original; -} - -/* -=============== -CG_PrevWeapon_f -=============== -*/ -void CG_PrevWeapon_f( void ) -{ -  int   i; -  int   original; - -  if( !cg.snap ) -    return; - -  if( cg.snap->ps.pm_flags & PMF_FOLLOW ) -  { -    trap_SendClientCommand( "follownext\n" ); -    return; -  } - -  cg.weaponSelectTime = cg.time; -  original = cg.weaponSelect; - -  for( i = 0; i < 64; i++ ) -  { -    cg.weaponSelect--; -    if( cg.weaponSelect == -1 ) -      cg.weaponSelect = 63; - -    if( cg.weaponSelect <= 32 ) -    { -      if( CG_WeaponSelectable( cg.weaponSelect ) ) -        break; -    } -    else if( cg.weaponSelect > 32 ) -    { -      if( CG_UpgradeSelectable( cg.weaponSelect - 32 ) ) -        break; -    } -  } - -  if( i == 64 ) -    cg.weaponSelect = original; -} - -/* -=============== -CG_Weapon_f -=============== -*/ -void CG_Weapon_f( void ) -{ -  int   num; - -  if( !cg.snap ) -    return; - -  if( cg.snap->ps.pm_flags & PMF_FOLLOW ) -    return; - -  num = atoi( CG_Argv( 1 ) ); - -  if( num < 1 || num > 31 ) -    return; - -  cg.weaponSelectTime = cg.time; - -  if( !BG_InventoryContainsWeapon( num, cg.snap->ps.stats ) ) -    return;   // don't have the weapon - -  cg.weaponSelect = num; -} - - -/* -=================================================================================================== - -WEAPON EVENTS - -=================================================================================================== -*/ - -/* -================ -CG_FireWeapon - -Caused by an EV_FIRE_WEAPON event -================ -*/ -void CG_FireWeapon( centity_t *cent, weaponMode_t weaponMode ) -{ -  entityState_t     *es; -  int               c; -  weaponInfo_t      *wi; -  weapon_t          weaponNum; - -  es = ¢->currentState; - -  weaponNum = es->weapon; - -  if( weaponNum == WP_NONE ) -    return; - -  if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES ) -    weaponMode = WPM_PRIMARY; - -  if( weaponNum >= WP_NUM_WEAPONS ) -  { -    CG_Error( "CG_FireWeapon: ent->weapon >= WP_NUM_WEAPONS" ); -    return; -  } - -  wi = &cg_weapons[ weaponNum ]; - -  // mark the entity as muzzle flashing, so when it is added it will -  // append the flash to the weapon model -  cent->muzzleFlashTime = cg.time; - -  if( wi->wim[ weaponMode ].muzzleParticleSystem ) -  { -    if( !CG_IsParticleSystemValid( ¢->muzzlePS ) || -        !CG_IsParticleSystemInfinite( cent->muzzlePS ) ) -      cent->muzzlePsTrigger = qtrue; -  } - -  // play a sound -  for( c = 0; c < 4; c++ ) -  { -    if( !wi->wim[ weaponMode ].flashSound[ c ] ) -      break; -  } - -  if( c > 0 ) -  { -    c = rand( ) % c; -    if( wi->wim[ weaponMode ].flashSound[ c ] ) -      trap_S_StartSound( NULL, es->number, CHAN_WEAPON, wi->wim[ weaponMode ].flashSound[ c ] ); -  } -} - - -/* -================= -CG_MissileHitWall - -Caused by an EV_MISSILE_MISS event, or directly by local bullet tracing -================= -*/ -void CG_MissileHitWall( weapon_t weaponNum, weaponMode_t weaponMode, int clientNum, -                        vec3_t origin, vec3_t dir, impactSound_t soundType ) -{ -  qhandle_t           mark = 0; -  qhandle_t           ps = 0; -  int                 c; -  float               radius = 1.0f; -  weaponInfo_t        *weapon = &cg_weapons[ weaponNum ]; - -  if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES ) -    weaponMode = WPM_PRIMARY; - -  mark = weapon->wim[ weaponMode ].impactMark; -  radius = weapon->wim[ weaponMode ].impactMarkSize; -  ps = weapon->wim[ weaponMode ].impactParticleSystem; - -  if( soundType == IMPACTSOUND_FLESH ) -  { -    //flesh sound -    for( c = 0; c < 4; c++ ) -    { -      if( !weapon->wim[ weaponMode ].impactFleshSound[ c ] ) -        break; -    } - -    if( c > 0 ) -    { -      c = rand( ) % c; -      if( weapon->wim[ weaponMode ].impactFleshSound[ c ] ) -        trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weapon->wim[ weaponMode ].impactFleshSound[ c ] ); -    } -  } -  else -  { -    //normal sound -    for( c = 0; c < 4; c++ ) -    { -      if( !weapon->wim[ weaponMode ].impactSound[ c ] ) -        break; -    } - -    if( c > 0 ) -    { -      c = rand( ) % c; -      if( weapon->wim[ weaponMode ].impactSound[ c ] ) -        trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weapon->wim[ weaponMode ].impactSound[ c ] ); -    } -  } - -  //create impact particle system -  if( ps ) -  { -    particleSystem_t *partSystem = CG_SpawnNewParticleSystem( ps ); - -    if( CG_IsParticleSystemValid( &partSystem ) ) -    { -      CG_SetAttachmentPoint( &partSystem->attachment, origin ); -      CG_SetParticleSystemNormal( partSystem, dir ); -      CG_AttachToPoint( &partSystem->attachment ); -    } -  } - -  // -  // impact mark -  // -  if( radius > 0.0f ) -    CG_ImpactMark( mark, origin, dir, random( ) * 360, 1, 1, 1, 1, qfalse, radius, qfalse ); -} - - -/* -================= -CG_MissileHitPlayer -================= -*/ -void CG_MissileHitPlayer( weapon_t weaponNum, weaponMode_t weaponMode, -    vec3_t origin, vec3_t dir, int entityNum ) -{ -  vec3_t        normal; -  weaponInfo_t  *weapon = &cg_weapons[ weaponNum ]; - -  VectorCopy( dir, normal ); -  VectorInverse( normal ); - -  CG_Bleed( origin, normal, entityNum ); - -  if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES ) -    weaponMode = WPM_PRIMARY; - -  if( weapon->wim[ weaponMode ].alwaysImpact ) -    CG_MissileHitWall( weaponNum, weaponMode, 0, origin, dir, IMPACTSOUND_FLESH ); -} - - -/* -============================================================================ - -BULLETS - -============================================================================ -*/ - - -/* -=============== -CG_Tracer -=============== -*/ -void CG_Tracer( vec3_t source, vec3_t dest ) -{ -  vec3_t      forward, right; -  polyVert_t  verts[ 4 ]; -  vec3_t      line; -  float       len, begin, end; -  vec3_t      start, finish; -  vec3_t      midpoint; - -  // tracer -  VectorSubtract( dest, source, forward ); -  len = VectorNormalize( forward ); - -  // start at least a little ways from the muzzle -  if( len < 100 ) -    return; - -  begin = 50 + random( ) * ( len - 60 ); -  end = begin + cg_tracerLength.value; -  if( end > len ) -    end = len; - -  VectorMA( source, begin, forward, start ); -  VectorMA( source, end, forward, finish ); - -  line[ 0 ] = DotProduct( forward, cg.refdef.viewaxis[ 1 ] ); -  line[ 1 ] = DotProduct( forward, cg.refdef.viewaxis[ 2 ] ); - -  VectorScale( cg.refdef.viewaxis[ 1 ], line[ 1 ], right ); -  VectorMA( right, -line[ 0 ], cg.refdef.viewaxis[ 2 ], right ); -  VectorNormalize( right ); - -  VectorMA( finish, cg_tracerWidth.value, right, verts[ 0 ].xyz ); -  verts[ 0 ].st[ 0 ] = 0; -  verts[ 0 ].st[ 1 ] = 1; -  verts[ 0 ].modulate[ 0 ] = 255; -  verts[ 0 ].modulate[ 1 ] = 255; -  verts[ 0 ].modulate[ 2 ] = 255; -  verts[ 0 ].modulate[ 3 ] = 255; - -  VectorMA( finish, -cg_tracerWidth.value, right, verts[ 1 ].xyz ); -  verts[ 1 ].st[ 0 ] = 1; -  verts[ 1 ].st[ 1 ] = 0; -  verts[ 1 ].modulate[ 0 ] = 255; -  verts[ 1 ].modulate[ 1 ] = 255; -  verts[ 1 ].modulate[ 2 ] = 255; -  verts[ 1 ].modulate[ 3 ] = 255; - -  VectorMA( start, -cg_tracerWidth.value, right, verts[ 2 ].xyz ); -  verts[ 2 ].st[ 0 ] = 1; -  verts[ 2 ].st[ 1 ] = 1; -  verts[ 2 ].modulate[ 0 ] = 255; -  verts[ 2 ].modulate[ 1 ] = 255; -  verts[ 2 ].modulate[ 2 ] = 255; -  verts[ 2 ].modulate[ 3 ] = 255; - -  VectorMA( start, cg_tracerWidth.value, right, verts[ 3 ].xyz ); -  verts[ 3 ].st[ 0 ] = 0; -  verts[ 3 ].st[ 1 ] = 0; -  verts[ 3 ].modulate[ 0 ] = 255; -  verts[ 3 ].modulate[ 1 ] = 255; -  verts[ 3 ].modulate[ 2 ] = 255; -  verts[ 3 ].modulate[ 3 ] = 255; - -  trap_R_AddPolyToScene( cgs.media.tracerShader, 4, verts ); - -  midpoint[ 0 ] = ( start[ 0 ] + finish[ 0 ] ) * 0.5; -  midpoint[ 1 ] = ( start[ 1 ] + finish[ 1 ] ) * 0.5; -  midpoint[ 2 ] = ( start[ 2 ] + finish[ 2 ] ) * 0.5; - -  // add the tracer sound -  trap_S_StartSound( midpoint, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.tracerSound ); -} - - -/* -====================== -CG_CalcMuzzlePoint -====================== -*/ -static qboolean CG_CalcMuzzlePoint( int entityNum, vec3_t muzzle ) -{ -  vec3_t    forward; -  centity_t *cent; -  int       anim; - -  if( entityNum == cg.snap->ps.clientNum ) -  { -    VectorCopy( cg.snap->ps.origin, muzzle ); -    muzzle[ 2 ] += cg.snap->ps.viewheight; -    AngleVectors( cg.snap->ps.viewangles, forward, NULL, NULL ); -    VectorMA( muzzle, 14, forward, muzzle ); -    return qtrue; -  } - -  cent = &cg_entities[entityNum]; - -  if( !cent->currentValid ) -    return qfalse; - -  VectorCopy( cent->currentState.pos.trBase, muzzle ); - -  AngleVectors( cent->currentState.apos.trBase, forward, NULL, NULL ); -  anim = cent->currentState.legsAnim & ~ANIM_TOGGLEBIT; - -  if( anim == LEGS_WALKCR || anim == LEGS_IDLECR ) -    muzzle[ 2 ] += CROUCH_VIEWHEIGHT; -  else -    muzzle[ 2 ] += DEFAULT_VIEWHEIGHT; - -  VectorMA( muzzle, 14, forward, muzzle ); - -  return qtrue; - -} - - -/* -====================== -CG_Bullet - -Renders bullet effects. -====================== -*/ -void CG_Bullet( vec3_t end, int sourceEntityNum, vec3_t normal, qboolean flesh, int fleshEntityNum ) -{ -  vec3_t  start; - -  // if the shooter is currently valid, calc a source point and possibly -  // do trail effects -  if( sourceEntityNum >= 0 && cg_tracerChance.value > 0 ) -  { -    if( CG_CalcMuzzlePoint( sourceEntityNum, start ) ) -    { -      // draw a tracer -      if( random( ) < cg_tracerChance.value ) -        CG_Tracer( start, end ); -    } -  } - -  // impact splash and mark -  if( flesh ) -    CG_Bleed( end, normal, fleshEntityNum ); -  else -    CG_MissileHitWall( WP_MACHINEGUN, WPM_PRIMARY, 0, end, normal, IMPACTSOUND_DEFAULT ); -} - -/* -============================================================================ - -SHOTGUN TRACING - -============================================================================ -*/ - -/* -================ -CG_ShotgunPattern - -Perform the same traces the server did to locate the -hit splashes -================ -*/ -static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, int otherEntNum ) -{ -  int       i; -  float     r, u; -  vec3_t    end; -  vec3_t    forward, right, up; -  trace_t   tr; - -  // derive the right and up vectors from the forward vector, because -  // the client won't have any other information -  VectorNormalize2( origin2, forward ); -  PerpendicularVector( right, forward ); -  CrossProduct( forward, right, up ); - -  // generate the "random" spread pattern -  for( i = 0; i < SHOTGUN_PELLETS; i++ ) -  { -    r = Q_crandom( &seed ) * SHOTGUN_SPREAD * 16; -    u = Q_crandom( &seed ) * SHOTGUN_SPREAD * 16; -    VectorMA( origin, 8192 * 16, forward, end ); -    VectorMA( end, r, right, end ); -    VectorMA( end, u, up, end ); - -    CG_Trace( &tr, origin, NULL, NULL, end, otherEntNum, MASK_SHOT ); - -    if( !( tr.surfaceFlags & SURF_NOIMPACT ) ) -    { -      if( cg_entities[ tr.entityNum ].currentState.eType == ET_PLAYER ) -        CG_MissileHitPlayer( WP_SHOTGUN, WPM_PRIMARY, tr.endpos, tr.plane.normal, tr.entityNum ); -      else if( tr.surfaceFlags & SURF_METALSTEPS ) -        CG_MissileHitWall( WP_SHOTGUN, WPM_PRIMARY, 0, tr.endpos, tr.plane.normal, IMPACTSOUND_METAL ); -      else -        CG_MissileHitWall( WP_SHOTGUN, WPM_PRIMARY, 0, tr.endpos, tr.plane.normal, IMPACTSOUND_DEFAULT ); -    } -  } -} - -/* -============== -CG_ShotgunFire -============== -*/ -void CG_ShotgunFire( entityState_t *es ) -{ -  vec3_t  v; - -  VectorSubtract( es->origin2, es->pos.trBase, v ); -  VectorNormalize( v ); -  VectorScale( v, 32, v ); -  VectorAdd( es->pos.trBase, v, v ); - -  CG_ShotgunPattern( es->pos.trBase, es->origin2, es->eventParm, es->otherEntityNum ); -} - diff --git a/mod/src/cgame/tr_types.h b/mod/src/cgame/tr_types.h deleted file mode 100644 index 26240a2f..00000000 --- a/mod/src/cgame/tr_types.h +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#ifndef __TR_TYPES_H -#define __TR_TYPES_H - - -#define MAX_DLIGHTS         32      // can't be increased, because bit flags are used on surfaces -#define MAX_ENTITIES        1023    // can't be increased without changing drawsurf bit packing - -// renderfx flags -#define RF_MINLIGHT         1       // allways have some light (viewmodel, some items) -#define RF_THIRD_PERSON     2       // don't draw through eyes, only mirrors (player bodies, chat sprites) -#define RF_FIRST_PERSON     4       // only draw through eyes (view weapon, damage blood blob) -#define RF_DEPTHHACK        8       // for view weapon Z crunching -#define RF_NOSHADOW         64      // don't add stencil shadows - -#define RF_LIGHTING_ORIGIN  128     // use refEntity->lightingOrigin instead of refEntity->origin -                                    // for lighting.  This allows entities to sink into the floor -                                    // with their origin going solid, and allows all parts of a -                                    // player to get the same lighting -#define RF_SHADOW_PLANE     256     // use refEntity->shadowPlane -#define RF_WRAP_FRAMES      512     // mod the model frames by the maxframes to allow continuous -                                    // animation without needing to know the frame count - -// refdef flags -#define RDF_NOWORLDMODEL    1       // used for player configuration screen -#define RDF_HYPERSPACE      4       // teleportation effect - -typedef struct -{ -  vec3_t  xyz; -  float   st[ 2 ]; -  byte    modulate[ 4 ]; -} polyVert_t; - -typedef struct poly_s -{ -  qhandle_t   hShader; -  int         numVerts; -  polyVert_t  *verts; -} poly_t; - -typedef enum -{ -  RT_MODEL, -  RT_POLY, -  RT_SPRITE, -  RT_BEAM, -  RT_RAIL_CORE, -  RT_RAIL_RINGS, -  RT_LIGHTNING, -  RT_PORTALSURFACE,   // doesn't draw anything, just info for portals - -  RT_MAX_REF_ENTITY_TYPE -} refEntityType_t; - -typedef struct -{ -  refEntityType_t reType; -  int             renderfx; - -  qhandle_t       hModel;       // opaque type outside refresh - -  // most recent data -  vec3_t          lightingOrigin;     // so multi-part models can be lit identically (RF_LIGHTING_ORIGIN) -  float           shadowPlane;        // projection shadows go here, stencils go slightly lower - -  vec3_t          axis[ 3 ];          // rotation vectors -  qboolean        nonNormalizedAxes;  // axis are not normalized, i.e. they have scale -  float           origin[ 3 ];        // also used as MODEL_BEAM's "from" -  int             frame;              // also used as MODEL_BEAM's diameter - -  // previous data for frame interpolation -  float           oldorigin[ 3 ];     // also used as MODEL_BEAM's "to" -  int             oldframe; -  float           backlerp;           // 0.0 = current, 1.0 = old - -  // texturing -  int             skinNum;            // inline skin index -  qhandle_t       customSkin;         // NULL for default skin -  qhandle_t       customShader;       // use one image for the entire thing - -  // misc -  byte            shaderRGBA[ 4 ];    // colors used by rgbgen entity shaders -  float           shaderTexCoord[ 2 ];// texture coordinates used by tcMod entity modifiers -  float           shaderTime;         // subtracted from refdef time to control effect start times - -  // extra sprite information -  float           radius; -  float           rotation; -} refEntity_t; - - -#define MAX_RENDER_STRINGS      8 -#define MAX_RENDER_STRING_LENGTH  32 - -typedef struct -{ -  int     x, y, width, height; -  float   fov_x, fov_y; -  vec3_t  vieworg; -  vec3_t  viewaxis[ 3 ];    // transformation matrix - -  // time in milliseconds for shader effects and other time dependent rendering issues -  int     time; - -  int     rdflags;          // RDF_NOWORLDMODEL, etc - -  // 1 bits will prevent the associated area from rendering at all -  byte    areamask[ MAX_MAP_AREA_BYTES ]; - -  // text messages for deform text shaders -  char    text[ MAX_RENDER_STRINGS ][ MAX_RENDER_STRING_LENGTH ]; -} refdef_t; - - -typedef enum -{ -  STEREO_CENTER, -  STEREO_LEFT, -  STEREO_RIGHT -} stereoFrame_t; - - -/* -** glconfig_t -** -** Contains variables specific to the OpenGL configuration -** being run right now.  These are constant once the OpenGL -** subsystem is initialized. -*/ -typedef enum -{ -  TC_NONE, -  TC_S3TC -} textureCompression_t; - -typedef enum -{ -  GLDRV_ICD,          // driver is integrated with window system -                      // WARNING: there are tests that check for -                      // > GLDRV_ICD for minidriverness, so this -                      // should always be the lowest value in this -                      // enum set -  GLDRV_STANDALONE,   // driver is a non-3Dfx standalone driver -  GLDRV_VOODOO        // driver is a 3Dfx standalone driver -} glDriverType_t; - -typedef enum -{ -  GLHW_GENERIC,     // where everthing works the way it should -  GLHW_3DFX_2D3D,   // Voodoo Banshee or Voodoo3, relevant since if this is -                    // the hardware type then there can NOT exist a secondary -                    // display adapter -  GLHW_RIVA128,     // where you can't interpolate alpha -  GLHW_RAGEPRO,     // where you can't modulate alpha on alpha textures -  GLHW_PERMEDIA2    // where you don't have src*dst -} glHardwareType_t; - -typedef struct -{ -  char                  renderer_string[ MAX_STRING_CHARS ]; -  char                  vendor_string[ MAX_STRING_CHARS ]; -  char                  version_string[ MAX_STRING_CHARS ]; -  char                  extensions_string[ BIG_INFO_STRING ]; - -  int                   maxTextureSize;     // queried from GL -  int                   maxActiveTextures;    // multitexture ability - -  int                   colorBits, depthBits, stencilBits; - -  glDriverType_t        driverType; -  glHardwareType_t      hardwareType; - -  qboolean              deviceSupportsGamma; -  textureCompression_t  textureCompression; -  qboolean              textureEnvAddAvailable; - -  int                   vidWidth, vidHeight; - -  // aspect is the screen's physical width / height, which may be different -  // than scrWidth / scrHeight if the pixels are non-square -  // normal screens should be 4/3, but wide aspect monitors may be 16/9 -  float                 windowAspect; - -  int                   displayFrequency; - -  // synonymous with "does rendering consume the entire screen?", therefore -  // a Voodoo or Voodoo2 will have this set to TRUE, as will a Win32 ICD that -  // used CDS. -  qboolean              isFullscreen; -  qboolean              stereoEnabled; -  qboolean              smpActive;    // dual processor -} glconfig_t; - - -#if !defined _WIN32 - -#define _3DFX_DRIVER_NAME   "libMesaVoodooGL.so" -// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=524 -#define OPENGL_DRIVER_NAME  "libGL.so.1" - -#else - -#define _3DFX_DRIVER_NAME   "3dfxvgl" -#define OPENGL_DRIVER_NAME  "opengl32" - -#endif  // !defined _WIN32 - - -#endif  // __TR_TYPES_H diff --git a/mod/src/game/bg_lib.c b/mod/src/game/bg_lib.c deleted file mode 100644 index d940c6d8..00000000 --- a/mod/src/game/bg_lib.c +++ /dev/null @@ -1,1940 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// bg_lib,c -- standard C library replacement routines used by code -// compiled for the virtual machine - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "q_shared.h" - -/*- - * Copyright (c) 1992, 1993 - *  The Regents of the University of California.  All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - *    notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - *    notice, this list of conditions and the following disclaimer in the - *    documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - *    must display the following acknowledgement: - *  This product includes software developed by the University of - *  California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - *    may be used to endorse or promote products derived from this software - *    without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "bg_lib.h" - -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93"; -#endif -static const char rcsid[] = -  "$Id$"; -#endif /* LIBC_SCCS and not lint */ - -// bk001127 - needed for DLL's -#if !defined( Q3_VM ) -typedef int    cmp_t(const void *, const void *); -#endif - -static char* med3(char *, char *, char *, cmp_t *); -static void  swapfunc(char *, char *, int, int); - -#ifndef min -#define min(a, b) (a) < (b) ? a : b -#endif - -/* - * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". - */ -#define swapcode(TYPE, parmi, parmj, n) {     \ -  long i = (n) / sizeof (TYPE);       \ -  register TYPE *pi = (TYPE *) (parmi);     \ -  register TYPE *pj = (TYPE *) (parmj);     \ -  do {            \ -    register TYPE t = *pi;    \ -    *pi++ = *pj;        \ -    *pj++ = t;        \ -        } while (--i > 0);        \ -} - -#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ -  es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; - -static void -swapfunc(a, b, n, swaptype) -  char *a, *b; -  int n, swaptype; -{ -  if(swaptype <= 1) -    swapcode(long, a, b, n) -  else -    swapcode(char, a, b, n) -} - -#define swap(a, b)          \ -  if (swaptype == 0) {        \ -    long t = *(long *)(a);      \ -    *(long *)(a) = *(long *)(b);    \ -    *(long *)(b) = t;     \ -  } else            \ -    swapfunc(a, b, es, swaptype) - -#define vecswap(a, b, n)  if ((n) > 0) swapfunc(a, b, n, swaptype) - -static char * -med3(a, b, c, cmp) -  char *a, *b, *c; -  cmp_t *cmp; -{ -  return cmp(a, b) < 0 ? -         (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a )) -              :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c )); -} - -void -qsort(a, n, es, cmp) -  void *a; -  size_t n, es; -  cmp_t *cmp; -{ -  char *pa, *pb, *pc, *pd, *pl, *pm, *pn; -  int d, r, swaptype, swap_cnt; - -loop: SWAPINIT(a, es); -  swap_cnt = 0; -  if (n < 7) { -    for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) -      for (pl = pm; pl > (char *)a && cmp(pl - es, pl) > 0; -           pl -= es) -        swap(pl, pl - es); -    return; -  } -  pm = (char *)a + (n / 2) * es; -  if (n > 7) { -    pl = a; -    pn = (char *)a + (n - 1) * es; -    if (n > 40) { -      d = (n / 8) * es; -      pl = med3(pl, pl + d, pl + 2 * d, cmp); -      pm = med3(pm - d, pm, pm + d, cmp); -      pn = med3(pn - 2 * d, pn - d, pn, cmp); -    } -    pm = med3(pl, pm, pn, cmp); -  } -  swap(a, pm); -  pa = pb = (char *)a + es; - -  pc = pd = (char *)a + (n - 1) * es; -  for (;;) { -    while (pb <= pc && (r = cmp(pb, a)) <= 0) { -      if (r == 0) { -        swap_cnt = 1; -        swap(pa, pb); -        pa += es; -      } -      pb += es; -    } -    while (pb <= pc && (r = cmp(pc, a)) >= 0) { -      if (r == 0) { -        swap_cnt = 1; -        swap(pc, pd); -        pd -= es; -      } -      pc -= es; -    } -    if (pb > pc) -      break; -    swap(pb, pc); -    swap_cnt = 1; -    pb += es; -    pc -= es; -  } -  if (swap_cnt == 0) {  /* Switch to insertion sort */ -    for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) -      for (pl = pm; pl > (char *)a && cmp(pl - es, pl) > 0; -           pl -= es) -        swap(pl, pl - es); -    return; -  } - -  pn = (char *)a + n * es; -  r = min(pa - (char *)a, pb - pa); -  vecswap(a, pb - r, r); -  r = min(pd - pc, pn - pd - es); -  vecswap(pb, pn - r, r); -  if ((r = pb - pa) > es) -    qsort(a, r / es, es, cmp); -  if ((r = pd - pc) > es) { -    /* Iterate rather than recurse to save stack space */ -    a = pn - r; -    n = r / es; -    goto loop; -  } -/*    qsort(pn - r, r / es, es, cmp);*/ -} - -//================================================================================== - - -// this file is excluded from release builds because of intrinsics - -// bk001211 - gcc errors on compiling strcpy:  parse error before `__extension__' -#if defined ( Q3_VM ) - -size_t strlen( const char *string ) -{ -  const char  *s; - -  s = string; -  while( *s ) -    s++; - -  return s - string; -} - - -char *strcat( char *strDestination, const char *strSource ) -{ -  char  *s; - -  s = strDestination; -  while( *s ) -    s++; - -  while( *strSource ) -    *s++ = *strSource++; - -  *s = 0; -  return strDestination; -} - -char *strcpy( char *strDestination, const char *strSource ) -{ -  char *s; - -  s = strDestination; - -  while( *strSource ) -    *s++ = *strSource++; - -  *s = 0; -  return strDestination; -} - - -int strcmp( const char *string1, const char *string2 ) -{ -  while( *string1 == *string2 && *string1 && *string2 ) -  { -    string1++; -    string2++; -  } - -  return *string1 - *string2; -} - -//TA: -char *strrchr( const char *string, int c ) -{ -  int   i, length = strlen( string ); -  char  *p; - -  for( i = length - 1; i >= 0; i-- ) -  { -    p = (char *)&string[ i ]; - -    if( *p == c ) -      return (char *)p; -  } - -  return (char *)0; -} - -char *strchr( const char *string, int c ) -{ -  while( *string ) -  { -    if( *string == c ) -      return ( char * )string; - -    string++; -  } -  return (char *)0; -} - -char *strstr( const char *string, const char *strCharSet ) -{ -  while( *string ) -  { -    int   i; - -    for( i = 0; strCharSet[ i ]; i++ ) -    { -      if( string[ i ] != strCharSet[ i ] ) -        break; -    } - -    if( !strCharSet[ i ] ) -      return (char *)string; - -    string++; -  } -  return (char *)0; -} - -#endif // bk001211 - -#if defined ( Q3_VM ) - -int tolower( int c ) -{ -  if( c >= 'A' && c <= 'Z' ) -    c += 'a' - 'A'; - -  return c; -} - - -int toupper( int c ) -{ -  if( c >= 'a' && c <= 'z' ) -    c += 'A' - 'a'; - -  return c; -} - -#endif - -void *memmove( void *dest, const void *src, size_t count ) -{ -  int   i; - -  if( dest > src ) -  { -    for( i = count - 1; i >= 0; i-- ) -      ( (char *)dest )[ i ] = ( (char *)src )[ i ]; -  } -  else -  { -    for( i = 0; i < count; i++ ) -      ( (char *)dest )[ i ] = ( (char *)src )[ i ]; -  } - -  return dest; -} - - -#if 0 - -double floor( double x ) { -  return (int)(x + 0x40000000) - 0x40000000; -} - -void *memset( void *dest, int c, size_t count ) { -  while ( count-- ) { -    ((char *)dest)[count] = c; -  } -  return dest; -} - -void *memcpy( void *dest, const void *src, size_t count ) { -  while ( count-- ) { -    ((char *)dest)[count] = ((char *)src)[count]; -  } -  return dest; -} - -char *strncpy( char *strDest, const char *strSource, size_t count ) { -  char  *s; - -  s = strDest; -  while ( *strSource && count ) { -    *s++ = *strSource++; -    count--; -  } -  while ( count-- ) { -    *s++ = 0; -  } -  return strDest; -} - -double sqrt( double x ) { -  float y; -  float delta; -  float maxError; - -  if ( x <= 0 ) { -    return 0; -  } - -  // initial guess -  y = x / 2; - -  // refine -  maxError = x * 0.001; - -  do { -    delta = ( y * y ) - x; -    y -= delta / ( 2 * y ); -  } while ( delta > maxError || delta < -maxError ); - -  return y; -} - - -float sintable[1024] = { -0.000000,0.001534,0.003068,0.004602,0.006136,0.007670,0.009204,0.010738, -0.012272,0.013805,0.015339,0.016873,0.018407,0.019940,0.021474,0.023008, -0.024541,0.026075,0.027608,0.029142,0.030675,0.032208,0.033741,0.035274, -0.036807,0.038340,0.039873,0.041406,0.042938,0.044471,0.046003,0.047535, -0.049068,0.050600,0.052132,0.053664,0.055195,0.056727,0.058258,0.059790, -0.061321,0.062852,0.064383,0.065913,0.067444,0.068974,0.070505,0.072035, -0.073565,0.075094,0.076624,0.078153,0.079682,0.081211,0.082740,0.084269, -0.085797,0.087326,0.088854,0.090381,0.091909,0.093436,0.094963,0.096490, -0.098017,0.099544,0.101070,0.102596,0.104122,0.105647,0.107172,0.108697, -0.110222,0.111747,0.113271,0.114795,0.116319,0.117842,0.119365,0.120888, -0.122411,0.123933,0.125455,0.126977,0.128498,0.130019,0.131540,0.133061, -0.134581,0.136101,0.137620,0.139139,0.140658,0.142177,0.143695,0.145213, -0.146730,0.148248,0.149765,0.151281,0.152797,0.154313,0.155828,0.157343, -0.158858,0.160372,0.161886,0.163400,0.164913,0.166426,0.167938,0.169450, -0.170962,0.172473,0.173984,0.175494,0.177004,0.178514,0.180023,0.181532, -0.183040,0.184548,0.186055,0.187562,0.189069,0.190575,0.192080,0.193586, -0.195090,0.196595,0.198098,0.199602,0.201105,0.202607,0.204109,0.205610, -0.207111,0.208612,0.210112,0.211611,0.213110,0.214609,0.216107,0.217604, -0.219101,0.220598,0.222094,0.223589,0.225084,0.226578,0.228072,0.229565, -0.231058,0.232550,0.234042,0.235533,0.237024,0.238514,0.240003,0.241492, -0.242980,0.244468,0.245955,0.247442,0.248928,0.250413,0.251898,0.253382, -0.254866,0.256349,0.257831,0.259313,0.260794,0.262275,0.263755,0.265234, -0.266713,0.268191,0.269668,0.271145,0.272621,0.274097,0.275572,0.277046, -0.278520,0.279993,0.281465,0.282937,0.284408,0.285878,0.287347,0.288816, -0.290285,0.291752,0.293219,0.294685,0.296151,0.297616,0.299080,0.300543, -0.302006,0.303468,0.304929,0.306390,0.307850,0.309309,0.310767,0.312225, -0.313682,0.315138,0.316593,0.318048,0.319502,0.320955,0.322408,0.323859, -0.325310,0.326760,0.328210,0.329658,0.331106,0.332553,0.334000,0.335445, -0.336890,0.338334,0.339777,0.341219,0.342661,0.344101,0.345541,0.346980, -0.348419,0.349856,0.351293,0.352729,0.354164,0.355598,0.357031,0.358463, -0.359895,0.361326,0.362756,0.364185,0.365613,0.367040,0.368467,0.369892, -0.371317,0.372741,0.374164,0.375586,0.377007,0.378428,0.379847,0.381266, -0.382683,0.384100,0.385516,0.386931,0.388345,0.389758,0.391170,0.392582, -0.393992,0.395401,0.396810,0.398218,0.399624,0.401030,0.402435,0.403838, -0.405241,0.406643,0.408044,0.409444,0.410843,0.412241,0.413638,0.415034, -0.416430,0.417824,0.419217,0.420609,0.422000,0.423390,0.424780,0.426168, -0.427555,0.428941,0.430326,0.431711,0.433094,0.434476,0.435857,0.437237, -0.438616,0.439994,0.441371,0.442747,0.444122,0.445496,0.446869,0.448241, -0.449611,0.450981,0.452350,0.453717,0.455084,0.456449,0.457813,0.459177, -0.460539,0.461900,0.463260,0.464619,0.465976,0.467333,0.468689,0.470043, -0.471397,0.472749,0.474100,0.475450,0.476799,0.478147,0.479494,0.480839, -0.482184,0.483527,0.484869,0.486210,0.487550,0.488889,0.490226,0.491563, -0.492898,0.494232,0.495565,0.496897,0.498228,0.499557,0.500885,0.502212, -0.503538,0.504863,0.506187,0.507509,0.508830,0.510150,0.511469,0.512786, -0.514103,0.515418,0.516732,0.518045,0.519356,0.520666,0.521975,0.523283, -0.524590,0.525895,0.527199,0.528502,0.529804,0.531104,0.532403,0.533701, -0.534998,0.536293,0.537587,0.538880,0.540171,0.541462,0.542751,0.544039, -0.545325,0.546610,0.547894,0.549177,0.550458,0.551738,0.553017,0.554294, -0.555570,0.556845,0.558119,0.559391,0.560662,0.561931,0.563199,0.564466, -0.565732,0.566996,0.568259,0.569521,0.570781,0.572040,0.573297,0.574553, -0.575808,0.577062,0.578314,0.579565,0.580814,0.582062,0.583309,0.584554, -0.585798,0.587040,0.588282,0.589521,0.590760,0.591997,0.593232,0.594466, -0.595699,0.596931,0.598161,0.599389,0.600616,0.601842,0.603067,0.604290, -0.605511,0.606731,0.607950,0.609167,0.610383,0.611597,0.612810,0.614022, -0.615232,0.616440,0.617647,0.618853,0.620057,0.621260,0.622461,0.623661, -0.624859,0.626056,0.627252,0.628446,0.629638,0.630829,0.632019,0.633207, -0.634393,0.635578,0.636762,0.637944,0.639124,0.640303,0.641481,0.642657, -0.643832,0.645005,0.646176,0.647346,0.648514,0.649681,0.650847,0.652011, -0.653173,0.654334,0.655493,0.656651,0.657807,0.658961,0.660114,0.661266, -0.662416,0.663564,0.664711,0.665856,0.667000,0.668142,0.669283,0.670422, -0.671559,0.672695,0.673829,0.674962,0.676093,0.677222,0.678350,0.679476, -0.680601,0.681724,0.682846,0.683965,0.685084,0.686200,0.687315,0.688429, -0.689541,0.690651,0.691759,0.692866,0.693971,0.695075,0.696177,0.697278, -0.698376,0.699473,0.700569,0.701663,0.702755,0.703845,0.704934,0.706021, -0.707107,0.708191,0.709273,0.710353,0.711432,0.712509,0.713585,0.714659, -0.715731,0.716801,0.717870,0.718937,0.720003,0.721066,0.722128,0.723188, -0.724247,0.725304,0.726359,0.727413,0.728464,0.729514,0.730563,0.731609, -0.732654,0.733697,0.734739,0.735779,0.736817,0.737853,0.738887,0.739920, -0.740951,0.741980,0.743008,0.744034,0.745058,0.746080,0.747101,0.748119, -0.749136,0.750152,0.751165,0.752177,0.753187,0.754195,0.755201,0.756206, -0.757209,0.758210,0.759209,0.760207,0.761202,0.762196,0.763188,0.764179, -0.765167,0.766154,0.767139,0.768122,0.769103,0.770083,0.771061,0.772036, -0.773010,0.773983,0.774953,0.775922,0.776888,0.777853,0.778817,0.779778, -0.780737,0.781695,0.782651,0.783605,0.784557,0.785507,0.786455,0.787402, -0.788346,0.789289,0.790230,0.791169,0.792107,0.793042,0.793975,0.794907, -0.795837,0.796765,0.797691,0.798615,0.799537,0.800458,0.801376,0.802293, -0.803208,0.804120,0.805031,0.805940,0.806848,0.807753,0.808656,0.809558, -0.810457,0.811355,0.812251,0.813144,0.814036,0.814926,0.815814,0.816701, -0.817585,0.818467,0.819348,0.820226,0.821103,0.821977,0.822850,0.823721, -0.824589,0.825456,0.826321,0.827184,0.828045,0.828904,0.829761,0.830616, -0.831470,0.832321,0.833170,0.834018,0.834863,0.835706,0.836548,0.837387, -0.838225,0.839060,0.839894,0.840725,0.841555,0.842383,0.843208,0.844032, -0.844854,0.845673,0.846491,0.847307,0.848120,0.848932,0.849742,0.850549, -0.851355,0.852159,0.852961,0.853760,0.854558,0.855354,0.856147,0.856939, -0.857729,0.858516,0.859302,0.860085,0.860867,0.861646,0.862424,0.863199, -0.863973,0.864744,0.865514,0.866281,0.867046,0.867809,0.868571,0.869330, -0.870087,0.870842,0.871595,0.872346,0.873095,0.873842,0.874587,0.875329, -0.876070,0.876809,0.877545,0.878280,0.879012,0.879743,0.880471,0.881197, -0.881921,0.882643,0.883363,0.884081,0.884797,0.885511,0.886223,0.886932, -0.887640,0.888345,0.889048,0.889750,0.890449,0.891146,0.891841,0.892534, -0.893224,0.893913,0.894599,0.895284,0.895966,0.896646,0.897325,0.898001, -0.898674,0.899346,0.900016,0.900683,0.901349,0.902012,0.902673,0.903332, -0.903989,0.904644,0.905297,0.905947,0.906596,0.907242,0.907886,0.908528, -0.909168,0.909806,0.910441,0.911075,0.911706,0.912335,0.912962,0.913587, -0.914210,0.914830,0.915449,0.916065,0.916679,0.917291,0.917901,0.918508, -0.919114,0.919717,0.920318,0.920917,0.921514,0.922109,0.922701,0.923291, -0.923880,0.924465,0.925049,0.925631,0.926210,0.926787,0.927363,0.927935, -0.928506,0.929075,0.929641,0.930205,0.930767,0.931327,0.931884,0.932440, -0.932993,0.933544,0.934093,0.934639,0.935184,0.935726,0.936266,0.936803, -0.937339,0.937872,0.938404,0.938932,0.939459,0.939984,0.940506,0.941026, -0.941544,0.942060,0.942573,0.943084,0.943593,0.944100,0.944605,0.945107, -0.945607,0.946105,0.946601,0.947094,0.947586,0.948075,0.948561,0.949046, -0.949528,0.950008,0.950486,0.950962,0.951435,0.951906,0.952375,0.952842, -0.953306,0.953768,0.954228,0.954686,0.955141,0.955594,0.956045,0.956494, -0.956940,0.957385,0.957826,0.958266,0.958703,0.959139,0.959572,0.960002, -0.960431,0.960857,0.961280,0.961702,0.962121,0.962538,0.962953,0.963366, -0.963776,0.964184,0.964590,0.964993,0.965394,0.965793,0.966190,0.966584, -0.966976,0.967366,0.967754,0.968139,0.968522,0.968903,0.969281,0.969657, -0.970031,0.970403,0.970772,0.971139,0.971504,0.971866,0.972226,0.972584, -0.972940,0.973293,0.973644,0.973993,0.974339,0.974684,0.975025,0.975365, -0.975702,0.976037,0.976370,0.976700,0.977028,0.977354,0.977677,0.977999, -0.978317,0.978634,0.978948,0.979260,0.979570,0.979877,0.980182,0.980485, -0.980785,0.981083,0.981379,0.981673,0.981964,0.982253,0.982539,0.982824, -0.983105,0.983385,0.983662,0.983937,0.984210,0.984480,0.984749,0.985014, -0.985278,0.985539,0.985798,0.986054,0.986308,0.986560,0.986809,0.987057, -0.987301,0.987544,0.987784,0.988022,0.988258,0.988491,0.988722,0.988950, -0.989177,0.989400,0.989622,0.989841,0.990058,0.990273,0.990485,0.990695, -0.990903,0.991108,0.991311,0.991511,0.991710,0.991906,0.992099,0.992291, -0.992480,0.992666,0.992850,0.993032,0.993212,0.993389,0.993564,0.993737, -0.993907,0.994075,0.994240,0.994404,0.994565,0.994723,0.994879,0.995033, -0.995185,0.995334,0.995481,0.995625,0.995767,0.995907,0.996045,0.996180, -0.996313,0.996443,0.996571,0.996697,0.996820,0.996941,0.997060,0.997176, -0.997290,0.997402,0.997511,0.997618,0.997723,0.997825,0.997925,0.998023, -0.998118,0.998211,0.998302,0.998390,0.998476,0.998559,0.998640,0.998719, -0.998795,0.998870,0.998941,0.999011,0.999078,0.999142,0.999205,0.999265, -0.999322,0.999378,0.999431,0.999481,0.999529,0.999575,0.999619,0.999660, -0.999699,0.999735,0.999769,0.999801,0.999831,0.999858,0.999882,0.999905, -0.999925,0.999942,0.999958,0.999971,0.999981,0.999989,0.999995,0.999999 -}; - -double sin( double x ) { -  int index; -  int quad; - -  index = 1024 * x / (M_PI * 0.5); -  quad = ( index >> 10 ) & 3; -  index &= 1023; -  switch ( quad ) { -  case 0: -    return sintable[index]; -  case 1: -    return sintable[1023-index]; -  case 2: -    return -sintable[index]; -  case 3: -    return -sintable[1023-index]; -  } -  return 0; -} - - -double cos( double x ) { -  int index; -  int quad; - -  index = 1024 * x / (M_PI * 0.5); -  quad = ( index >> 10 ) & 3; -  index &= 1023; -  switch ( quad ) { -  case 3: -    return sintable[index]; -  case 0: -    return sintable[1023-index]; -  case 1: -    return -sintable[index]; -  case 2: -    return -sintable[1023-index]; -  } -  return 0; -} - - -/* -void create_acostable( void ) { -  int i; -  FILE *fp; -  float a; - -  fp = fopen("c:\\acostable.txt", "w"); -  fprintf(fp, "float acostable[] = {"); -  for (i = 0; i < 1024; i++) { -    if (!(i & 7)) -      fprintf(fp, "\n"); -    a = acos( (float) -1 + i / 512 ); -    fprintf(fp, "%1.8f,", a); -  } -  fprintf(fp, "\n}\n"); -  fclose(fp); -} -*/ - - -float acostable[] = { -3.14159265,3.07908248,3.05317551,3.03328655,3.01651113,3.00172442,2.98834964,2.97604422, -2.96458497,2.95381690,2.94362719,2.93393068,2.92466119,2.91576615,2.90720289,2.89893629, -2.89093699,2.88318015,2.87564455,2.86831188,2.86116621,2.85419358,2.84738169,2.84071962, -2.83419760,2.82780691,2.82153967,2.81538876,2.80934770,2.80341062,2.79757211,2.79182724, -2.78617145,2.78060056,2.77511069,2.76969824,2.76435988,2.75909250,2.75389319,2.74875926, -2.74368816,2.73867752,2.73372510,2.72882880,2.72398665,2.71919677,2.71445741,2.70976688, -2.70512362,2.70052613,2.69597298,2.69146283,2.68699438,2.68256642,2.67817778,2.67382735, -2.66951407,2.66523692,2.66099493,2.65678719,2.65261279,2.64847088,2.64436066,2.64028133, -2.63623214,2.63221238,2.62822133,2.62425835,2.62032277,2.61641398,2.61253138,2.60867440, -2.60484248,2.60103507,2.59725167,2.59349176,2.58975488,2.58604053,2.58234828,2.57867769, -2.57502832,2.57139977,2.56779164,2.56420354,2.56063509,2.55708594,2.55355572,2.55004409, -2.54655073,2.54307530,2.53961750,2.53617701,2.53275354,2.52934680,2.52595650,2.52258238, -2.51922417,2.51588159,2.51255441,2.50924238,2.50594525,2.50266278,2.49939476,2.49614096, -2.49290115,2.48967513,2.48646269,2.48326362,2.48007773,2.47690482,2.47374472,2.47059722, -2.46746215,2.46433933,2.46122860,2.45812977,2.45504269,2.45196720,2.44890314,2.44585034, -2.44280867,2.43977797,2.43675809,2.43374890,2.43075025,2.42776201,2.42478404,2.42181622, -2.41885841,2.41591048,2.41297232,2.41004380,2.40712480,2.40421521,2.40131491,2.39842379, -2.39554173,2.39266863,2.38980439,2.38694889,2.38410204,2.38126374,2.37843388,2.37561237, -2.37279910,2.36999400,2.36719697,2.36440790,2.36162673,2.35885335,2.35608768,2.35332964, -2.35057914,2.34783610,2.34510044,2.34237208,2.33965094,2.33693695,2.33423003,2.33153010, -2.32883709,2.32615093,2.32347155,2.32079888,2.31813284,2.31547337,2.31282041,2.31017388, -2.30753373,2.30489988,2.30227228,2.29965086,2.29703556,2.29442632,2.29182309,2.28922580, -2.28663439,2.28404881,2.28146900,2.27889490,2.27632647,2.27376364,2.27120637,2.26865460, -2.26610827,2.26356735,2.26103177,2.25850149,2.25597646,2.25345663,2.25094195,2.24843238, -2.24592786,2.24342836,2.24093382,2.23844420,2.23595946,2.23347956,2.23100444,2.22853408, -2.22606842,2.22360742,2.22115104,2.21869925,2.21625199,2.21380924,2.21137096,2.20893709, -2.20650761,2.20408248,2.20166166,2.19924511,2.19683280,2.19442469,2.19202074,2.18962092, -2.18722520,2.18483354,2.18244590,2.18006225,2.17768257,2.17530680,2.17293493,2.17056692, -2.16820274,2.16584236,2.16348574,2.16113285,2.15878367,2.15643816,2.15409630,2.15175805, -2.14942338,2.14709226,2.14476468,2.14244059,2.14011997,2.13780279,2.13548903,2.13317865, -2.13087163,2.12856795,2.12626757,2.12397047,2.12167662,2.11938600,2.11709859,2.11481435, -2.11253326,2.11025530,2.10798044,2.10570867,2.10343994,2.10117424,2.09891156,2.09665185, -2.09439510,2.09214129,2.08989040,2.08764239,2.08539725,2.08315496,2.08091550,2.07867884, -2.07644495,2.07421383,2.07198545,2.06975978,2.06753681,2.06531651,2.06309887,2.06088387, -2.05867147,2.05646168,2.05425445,2.05204979,2.04984765,2.04764804,2.04545092,2.04325628, -2.04106409,2.03887435,2.03668703,2.03450211,2.03231957,2.03013941,2.02796159,2.02578610, -2.02361292,2.02144204,2.01927344,2.01710710,2.01494300,2.01278113,2.01062146,2.00846399, -2.00630870,2.00415556,2.00200457,1.99985570,1.99770895,1.99556429,1.99342171,1.99128119, -1.98914271,1.98700627,1.98487185,1.98273942,1.98060898,1.97848051,1.97635399,1.97422942, -1.97210676,1.96998602,1.96786718,1.96575021,1.96363511,1.96152187,1.95941046,1.95730088, -1.95519310,1.95308712,1.95098292,1.94888050,1.94677982,1.94468089,1.94258368,1.94048818, -1.93839439,1.93630228,1.93421185,1.93212308,1.93003595,1.92795046,1.92586659,1.92378433, -1.92170367,1.91962459,1.91754708,1.91547113,1.91339673,1.91132385,1.90925250,1.90718266, -1.90511432,1.90304746,1.90098208,1.89891815,1.89685568,1.89479464,1.89273503,1.89067683, -1.88862003,1.88656463,1.88451060,1.88245794,1.88040664,1.87835668,1.87630806,1.87426076, -1.87221477,1.87017008,1.86812668,1.86608457,1.86404371,1.86200412,1.85996577,1.85792866, -1.85589277,1.85385809,1.85182462,1.84979234,1.84776125,1.84573132,1.84370256,1.84167495, -1.83964848,1.83762314,1.83559892,1.83357582,1.83155381,1.82953289,1.82751305,1.82549429, -1.82347658,1.82145993,1.81944431,1.81742973,1.81541617,1.81340362,1.81139207,1.80938151, -1.80737194,1.80536334,1.80335570,1.80134902,1.79934328,1.79733848,1.79533460,1.79333164, -1.79132959,1.78932843,1.78732817,1.78532878,1.78333027,1.78133261,1.77933581,1.77733985, -1.77534473,1.77335043,1.77135695,1.76936428,1.76737240,1.76538132,1.76339101,1.76140148, -1.75941271,1.75742470,1.75543743,1.75345090,1.75146510,1.74948002,1.74749565,1.74551198, -1.74352900,1.74154672,1.73956511,1.73758417,1.73560389,1.73362426,1.73164527,1.72966692, -1.72768920,1.72571209,1.72373560,1.72175971,1.71978441,1.71780969,1.71583556,1.71386199, -1.71188899,1.70991653,1.70794462,1.70597325,1.70400241,1.70203209,1.70006228,1.69809297, -1.69612416,1.69415584,1.69218799,1.69022062,1.68825372,1.68628727,1.68432127,1.68235571, -1.68039058,1.67842588,1.67646160,1.67449772,1.67253424,1.67057116,1.66860847,1.66664615, -1.66468420,1.66272262,1.66076139,1.65880050,1.65683996,1.65487975,1.65291986,1.65096028, -1.64900102,1.64704205,1.64508338,1.64312500,1.64116689,1.63920905,1.63725148,1.63529416, -1.63333709,1.63138026,1.62942366,1.62746728,1.62551112,1.62355517,1.62159943,1.61964388, -1.61768851,1.61573332,1.61377831,1.61182346,1.60986877,1.60791422,1.60595982,1.60400556, -1.60205142,1.60009739,1.59814349,1.59618968,1.59423597,1.59228235,1.59032882,1.58837536, -1.58642196,1.58446863,1.58251535,1.58056211,1.57860891,1.57665574,1.57470259,1.57274945, -1.57079633,1.56884320,1.56689007,1.56493692,1.56298375,1.56103055,1.55907731,1.55712403, -1.55517069,1.55321730,1.55126383,1.54931030,1.54735668,1.54540297,1.54344917,1.54149526, -1.53954124,1.53758710,1.53563283,1.53367843,1.53172389,1.52976919,1.52781434,1.52585933, -1.52390414,1.52194878,1.51999323,1.51803748,1.51608153,1.51412537,1.51216900,1.51021240, -1.50825556,1.50629849,1.50434117,1.50238360,1.50042576,1.49846765,1.49650927,1.49455060, -1.49259163,1.49063237,1.48867280,1.48671291,1.48475270,1.48279215,1.48083127,1.47887004, -1.47690845,1.47494650,1.47298419,1.47102149,1.46905841,1.46709493,1.46513106,1.46316677, -1.46120207,1.45923694,1.45727138,1.45530538,1.45333893,1.45137203,1.44940466,1.44743682, -1.44546850,1.44349969,1.44153038,1.43956057,1.43759024,1.43561940,1.43364803,1.43167612, -1.42970367,1.42773066,1.42575709,1.42378296,1.42180825,1.41983295,1.41785705,1.41588056, -1.41390346,1.41192573,1.40994738,1.40796840,1.40598877,1.40400849,1.40202755,1.40004594, -1.39806365,1.39608068,1.39409701,1.39211264,1.39012756,1.38814175,1.38615522,1.38416795, -1.38217994,1.38019117,1.37820164,1.37621134,1.37422025,1.37222837,1.37023570,1.36824222, -1.36624792,1.36425280,1.36225684,1.36026004,1.35826239,1.35626387,1.35426449,1.35226422, -1.35026307,1.34826101,1.34625805,1.34425418,1.34224937,1.34024364,1.33823695,1.33622932, -1.33422072,1.33221114,1.33020059,1.32818904,1.32617649,1.32416292,1.32214834,1.32013273, -1.31811607,1.31609837,1.31407960,1.31205976,1.31003885,1.30801684,1.30599373,1.30396951, -1.30194417,1.29991770,1.29789009,1.29586133,1.29383141,1.29180031,1.28976803,1.28773456, -1.28569989,1.28366400,1.28162688,1.27958854,1.27754894,1.27550809,1.27346597,1.27142257, -1.26937788,1.26733189,1.26528459,1.26323597,1.26118602,1.25913471,1.25708205,1.25502803, -1.25297262,1.25091583,1.24885763,1.24679802,1.24473698,1.24267450,1.24061058,1.23854519, -1.23647833,1.23440999,1.23234015,1.23026880,1.22819593,1.22612152,1.22404557,1.22196806, -1.21988898,1.21780832,1.21572606,1.21364219,1.21155670,1.20946958,1.20738080,1.20529037, -1.20319826,1.20110447,1.19900898,1.19691177,1.19481283,1.19271216,1.19060973,1.18850553, -1.18639955,1.18429178,1.18218219,1.18007079,1.17795754,1.17584244,1.17372548,1.17160663, -1.16948589,1.16736324,1.16523866,1.16311215,1.16098368,1.15885323,1.15672081,1.15458638, -1.15244994,1.15031147,1.14817095,1.14602836,1.14388370,1.14173695,1.13958808,1.13743709, -1.13528396,1.13312866,1.13097119,1.12881153,1.12664966,1.12448556,1.12231921,1.12015061, -1.11797973,1.11580656,1.11363107,1.11145325,1.10927308,1.10709055,1.10490563,1.10271831, -1.10052856,1.09833638,1.09614174,1.09394462,1.09174500,1.08954287,1.08733820,1.08513098, -1.08292118,1.08070879,1.07849378,1.07627614,1.07405585,1.07183287,1.06960721,1.06737882, -1.06514770,1.06291382,1.06067715,1.05843769,1.05619540,1.05395026,1.05170226,1.04945136, -1.04719755,1.04494080,1.04268110,1.04041841,1.03815271,1.03588399,1.03361221,1.03133735, -1.02905939,1.02677830,1.02449407,1.02220665,1.01991603,1.01762219,1.01532509,1.01302471, -1.01072102,1.00841400,1.00610363,1.00378986,1.00147268,0.99915206,0.99682798,0.99450039, -0.99216928,0.98983461,0.98749636,0.98515449,0.98280898,0.98045980,0.97810691,0.97575030, -0.97338991,0.97102573,0.96865772,0.96628585,0.96391009,0.96153040,0.95914675,0.95675912, -0.95436745,0.95197173,0.94957191,0.94716796,0.94475985,0.94234754,0.93993099,0.93751017, -0.93508504,0.93265556,0.93022170,0.92778341,0.92534066,0.92289341,0.92044161,0.91798524, -0.91552424,0.91305858,0.91058821,0.90811309,0.90563319,0.90314845,0.90065884,0.89816430, -0.89566479,0.89316028,0.89065070,0.88813602,0.88561619,0.88309116,0.88056088,0.87802531, -0.87548438,0.87293806,0.87038629,0.86782901,0.86526619,0.86269775,0.86012366,0.85754385, -0.85495827,0.85236686,0.84976956,0.84716633,0.84455709,0.84194179,0.83932037,0.83669277, -0.83405893,0.83141877,0.82877225,0.82611928,0.82345981,0.82079378,0.81812110,0.81544172, -0.81275556,0.81006255,0.80736262,0.80465570,0.80194171,0.79922057,0.79649221,0.79375655, -0.79101352,0.78826302,0.78550497,0.78273931,0.77996593,0.77718475,0.77439569,0.77159865, -0.76879355,0.76598029,0.76315878,0.76032891,0.75749061,0.75464376,0.75178826,0.74892402, -0.74605092,0.74316887,0.74027775,0.73737744,0.73446785,0.73154885,0.72862033,0.72568217, -0.72273425,0.71977644,0.71680861,0.71383064,0.71084240,0.70784376,0.70483456,0.70181469, -0.69878398,0.69574231,0.69268952,0.68962545,0.68654996,0.68346288,0.68036406,0.67725332, -0.67413051,0.67099544,0.66784794,0.66468783,0.66151492,0.65832903,0.65512997,0.65191753, -0.64869151,0.64545170,0.64219789,0.63892987,0.63564741,0.63235028,0.62903824,0.62571106, -0.62236849,0.61901027,0.61563615,0.61224585,0.60883911,0.60541564,0.60197515,0.59851735, -0.59504192,0.59154856,0.58803694,0.58450672,0.58095756,0.57738911,0.57380101,0.57019288, -0.56656433,0.56291496,0.55924437,0.55555212,0.55183778,0.54810089,0.54434099,0.54055758, -0.53675018,0.53291825,0.52906127,0.52517867,0.52126988,0.51733431,0.51337132,0.50938028, -0.50536051,0.50131132,0.49723200,0.49312177,0.48897987,0.48480547,0.48059772,0.47635573, -0.47207859,0.46776530,0.46341487,0.45902623,0.45459827,0.45012983,0.44561967,0.44106652, -0.43646903,0.43182577,0.42713525,0.42239588,0.41760600,0.41276385,0.40786755,0.40291513, -0.39790449,0.39283339,0.38769946,0.38250016,0.37723277,0.37189441,0.36648196,0.36099209, -0.35542120,0.34976542,0.34402054,0.33818204,0.33224495,0.32620390,0.32005298,0.31378574, -0.30739505,0.30087304,0.29421096,0.28739907,0.28042645,0.27328078,0.26594810,0.25841250, -0.25065566,0.24265636,0.23438976,0.22582651,0.21693146,0.20766198,0.19796546,0.18777575, -0.17700769,0.16554844,0.15324301,0.13986823,0.12508152,0.10830610,0.08841715,0.06251018, -}; - -double acos( double x ) { -  int index; - -  if (x < -1) -    x = -1; -  if (x > 1) -    x = 1; -  index = (float) (1.0 + x) * 511.9; -  return acostable[index]; -} - - -double atan2( double y, double x ) { -  float base; -  float temp; -  float dir; -  float test; -  int   i; - -  if ( x < 0 ) { -    if ( y >= 0 ) { -      // quad 1 -      base = M_PI / 2; -      temp = x; -      x = y; -      y = -temp; -    } else { -      // quad 2 -      base = M_PI; -      x = -x; -      y = -y; -    } -  } else { -    if ( y < 0 ) { -      // quad 3 -      base = 3 * M_PI / 2; -      temp = x; -      x = -y; -      y = temp; -    } -  } - -  if ( y > x ) { -    base += M_PI/2; -    temp = x; -    x = y; -    y = temp; -    dir = -1; -  } else { -    dir = 1; -  } - -  // calcualte angle in octant 0 -  if ( x == 0 ) { -    return base; -  } -  y /= x; - -  for ( i = 0 ; i < 512 ; i++ ) { -    test = sintable[i] / sintable[1023-i]; -    if ( test > y ) { -      break; -    } -  } - -  return base + dir * i * ( M_PI/2048); -} - - -#endif - -#ifdef Q3_VM -// bk001127 - guarded this tan replacement -// ld: undefined versioned symbol name tan@@GLIBC_2.0 -double tan( double x ) -{ -  return sin( x ) / cos( x ); -} - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -typedef union -{ -  float value; -  unsigned int word; -} ieee_float_shape_type; - -/* Get a 32 bit int from a float.  */ - -#define GET_FLOAT_WORD(i,d)   \ -do {                          \ -  ieee_float_shape_type gf_u; \ -  gf_u.value = (d);           \ -  (i) = gf_u.word;            \ -} while (0) - -/* Set a float from a 32 bit int.  */ - -#define SET_FLOAT_WORD(d,i)   \ -do {                          \ -  ieee_float_shape_type sf_u; \ -  sf_u.word = (i);            \ -  (d) = sf_u.value;           \ -} while (0) - -/* A union which permits us to convert between a float and a 32 bit -   int.  */ - -//acos -static const float -pi      =  3.1415925026e+00, /* 0x40490fda */ -pio2_hi =  1.5707962513e+00, /* 0x3fc90fda */ -pio2_lo =  7.5497894159e-08, /* 0x33a22168 */ -pS0     =  1.6666667163e-01, /* 0x3e2aaaab */ -pS1     = -3.2556581497e-01, /* 0xbea6b090 */ -pS2     =  2.0121252537e-01, /* 0x3e4e0aa8 */ -pS3     = -4.0055535734e-02, /* 0xbd241146 */ -pS4     =  7.9153501429e-04, /* 0x3a4f7f04 */ -pS5     =  3.4793309169e-05, /* 0x3811ef08 */ -qS1     = -2.4033949375e+00, /* 0xc019d139 */ -qS2     =  2.0209457874e+00, /* 0x4001572d */ -qS3     = -6.8828397989e-01, /* 0xbf303361 */ -qS4     =  7.7038154006e-02; /* 0x3d9dc62e */ - -/* -================== -acos -================== -*/ -double acos( double x ) -{ -  float z, subp, p, q, r, w, s, c, df; -  int hx, ix; - -  GET_FLOAT_WORD( hx, x ); -  ix = hx & 0x7fffffff; - -  if( ix == 0x3f800000 ) -  {   // |x|==1 -    if( hx > 0 ) -      return 0.0; // acos(1) = 0 -    else -      return pi + (float)2.0 * pio2_lo; // acos(-1)= pi -  } -  else if( ix > 0x3f800000 ) -  { // |x| >= 1 -    return (x-x)/(x-x);   // acos(|x|>1) is NaN -  } - -  if( ix < 0x3f000000 ) -  { // |x| < 0.5 -    if( ix <= 0x23000000 ) -      return pio2_hi + pio2_lo;//if|x|<2**-57 - -    z = x * x; -    subp = pS3 + z * ( pS4 + z * pS5 ); -    // chop up expression to keep mac register based stack happy -    p = z * ( pS0 + z * ( pS1 + z * ( pS2 + z * subp ) ) ); -    q = 1.0 + z * ( qS1 + z * ( qS2 + z * ( qS3 + z * qS4 ) ) ); -    r = p / q; -    return pio2_hi - ( x - ( pio2_lo - x * r ) ); -  } -  else if( hx < 0 ) -  {   // x < -0.5 -    z = ( 1.0 + x ) * (float)0.5; -    subp = pS3 + z * ( pS4 + z * pS5 ); -    // chop up expression to keep mac register based stack happy -    p = z * ( pS0 + z * ( pS1 + z * ( pS2 + z * subp ) ) ); -    q = 1.0 + z * ( qS1 + z * ( qS2 + z * ( qS3 + z * qS4 ) ) ); -    s = sqrt( z ); -    r = p / q; -    w = r * s - pio2_lo; -    return pi - (float)2.0 * ( s + w ); -  } -  else -  {     // x > 0.5 -    int idf; -    z = ( 1.0 - x ) * (float)0.5; -    s = sqrt( z ); -    df = s; -    GET_FLOAT_WORD( idf, df ); -    SET_FLOAT_WORD( df, idf & 0xfffff000 ); -    c  = ( z - df * df ) / ( s + df ); -    subp = pS3 + z * ( pS4 + z * pS5 ); -    // chop up expression to keep mac register based stack happy -    p = z * ( pS0 + z * ( pS1 + z * ( pS2 + z * subp ) ) ); -    q = 1.0 + z * ( qS1 + z * ( qS2 + z * ( qS3 + z * qS4 ) ) ); -    r = p / q; -    w = r * s + c; -    return (double)( 2.0 * ( df + w ) ); -  } -} - -//pow -static const float -bp[ ]   = { 1.0, 1.5, }, -dp_h[ ] = { 0.0, 5.84960938e-01, }, /* 0x3f15c000 */ -dp_l[ ] = { 0.0, 1.56322085e-06, }, /* 0x35d1cfdc */ -huge    =  1.0e+30, -tiny    =  1.0e-30, -zero    =  0.0, -one     =  1.0, -two     =  2.0, -two24   =  16777216.0,  /* 0x4b800000 */ -two25   =  3.355443200e+07, /* 0x4c000000 */ -twom25  =  2.9802322388e-08,  /* 0x33000000 */ -  /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ -L1      =  6.0000002384e-01, /* 0x3f19999a */ -L2      =  4.2857143283e-01, /* 0x3edb6db7 */ -L3      =  3.3333334327e-01, /* 0x3eaaaaab */ -L4      =  2.7272811532e-01, /* 0x3e8ba305 */ -L5      =  2.3066075146e-01, /* 0x3e6c3255 */ -L6      =  2.0697501302e-01, /* 0x3e53f142 */ -P1      =  1.6666667163e-01, /* 0x3e2aaaab */ -P2      = -2.7777778450e-03, /* 0xbb360b61 */ -P3      =  6.6137559770e-05, /* 0x388ab355 */ -P4      = -1.6533901999e-06, /* 0xb5ddea0e */ -P5      =  4.1381369442e-08, /* 0x3331bb4c */ -lg2     =  6.9314718246e-01, /* 0x3f317218 */ -lg2_h   =  6.93145752e-01, /* 0x3f317200 */ -lg2_l   =  1.42860654e-06, /* 0x35bfbe8c */ -ovt     =  4.2995665694e-08, /* -(128-log2(ovfl+.5ulp)) */ -cp      =  9.6179670095e-01, /* 0x3f76384f =2/(3ln2) */ -cp_h    =  9.6179199219e-01, /* 0x3f763800 =head of cp */ -cp_l    =  4.7017383622e-06, /* 0x369dc3a0 =tail of cp_h */ -ivln2   =  1.4426950216e+00, /* 0x3fb8aa3b =1/ln2 */ -ivln2_h =  1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/ -ivln2_l =  7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/ - -/* -================== -copysignf -================== -*/ -static float copysignf( float x, float y ) -{ -  unsigned int ix, iy; - -  GET_FLOAT_WORD( ix, x ); -  GET_FLOAT_WORD( iy, y ); -  SET_FLOAT_WORD( x, ( ix & 0x7fffffff ) | ( iy & 0x80000000 ) ); -  return x; -} - -/* -================== -__scalbnf -================== -*/ -static float __scalbnf( float x, int n ) -{ -  int k, ix; - -  GET_FLOAT_WORD( ix, x ); - -  k = ( ix & 0x7f800000 ) >> 23;    /* extract exponent */ - -  if( k == 0 ) -  {       /* 0 or subnormal x */ -    if( ( ix & 0x7fffffff ) == 0 ) -      return x; /* +-0 */ - -    x *= two25; -    GET_FLOAT_WORD( ix, x ); -    k = ( ( ix & 0x7f800000 ) >> 23 ) - 25; -  } -  if( k == 0xff ) -    return x+x;    /* NaN or Inf */ - -  k = k + n; - -  if( n > 50000 || k > 0xfe ) -    return huge * copysignf( huge, x ); /* overflow  */ -  if ( n < -50000 ) -    return tiny * copysignf( tiny, x );  /*underflow*/ -  if( k > 0 )        /* normal result */ -  { -    SET_FLOAT_WORD( x, ( ix & 0x807fffff ) | ( k << 23 ) ); -    return x; -  } -  if( k <= -25 ) -    return tiny * copysignf( tiny, x );  /*underflow*/ - -  k += 25;        /* subnormal result */ -  SET_FLOAT_WORD( x, ( ix & 0x807fffff ) | ( k << 23 ) ); -  return x * twom25; -} - -/* -================== -pow -================== -*/ -float pow( float x, float y ) -{ -  float z, ax, z_h, z_l, p_h, p_l; -  float y1, subt1, t1, t2, subr, r, s, t, u, v, w; -  int i, j, k, yisint, n; -  int hx, hy, ix, iy, is; - -  /*TA: for some reason the Q3 VM goes apeshit when x = 1.0 -        and y > 1.0. Curiously this doesn't happen with gcc -        hence this hack*/ -  if( x == 1.0 ) -    return x; - -  GET_FLOAT_WORD( hx, x ); -  GET_FLOAT_WORD( hy, y ); -  ix = hx & 0x7fffffff; -  iy = hy & 0x7fffffff; - -  /* y==zero: x**0 = 1 */ -  if( iy == 0 ) -    return one; - -  /* +-NaN return x+y */ -  if( ix > 0x7f800000 || iy > 0x7f800000 ) -    return x + y; - -  /* determine if y is an odd int when x < 0 -   * yisint = 0 ... y is not an integer -   * yisint = 1 ... y is an odd int -   * yisint = 2 ... y is an even int -   */ -  yisint = 0; -  if( hx < 0 ) -  { -    if( iy >= 0x4b800000 ) -      yisint = 2; /* even integer y */ -    else if( iy >= 0x3f800000 ) -    { -      k = ( iy >> 23 ) - 0x7f;     /* exponent */ -      j = iy >> ( 23 - k ); -      if( ( j << ( 23 - k ) ) == iy ) -        yisint = 2 - ( j & 1 ); -    } -  } - -  /* special value of y */ -  if( iy == 0x7f800000 ) -  { /* y is +-inf */ -    if( ix == 0x3f800000 ) -      return  y - y;  /* inf**+-1 is NaN */ -    else if( ix > 0x3f800000 )/* (|x|>1)**+-inf = inf,0 */ -      return ( hy >= 0 ) ? y : zero; -    else      /* (|x|<1)**-,+inf = inf,0 */ -      return ( hy < 0 ) ? -y : zero; -  } - -  if( iy == 0x3f800000 ) -  {  /* y is  +-1 */ -    if( hy < 0 ) -      return one / x; -    else -      return x; -  } - -  if( hy == 0x40000000 ) -    return x * x; /* y is  2 */ - -  if( hy == 0x3f000000 ) -  {  /* y is  0.5 */ -    if( hx >= 0 ) /* x >= +0 */ -      return sqrt( x ); -  } - -  ax = fabs( x ); - -  /* special value of x */ -  if( ix == 0x7f800000 || ix == 0 || ix == 0x3f800000 ) -  { -    z = ax;     /*x is +-0,+-inf,+-1*/ -    if( hy < 0 ) -      z = one / z; /* z = (1/|x|) */ -    if( hx < 0 ) -    { -      if( ( ( ix - 0x3f800000 ) | yisint ) == 0 ) -        z = ( z - z ) / ( z - z ); /* (-1)**non-int is NaN */ -      else if( yisint == 1 ) -        z = -z;   /* (x<0)**odd = -(|x|**odd) */ -    } - -    return z; -  } - -  /* (x<0)**(non-int) is NaN */ -  if( ( ( ( (unsigned int)hx >> 31 ) - 1 ) | yisint ) == 0 ) -    return ( x - x ) / ( x - x ); - -  /* |y| is huge */ -  if( iy > 0x4d000000 ) -  { /* if |y| > 2**27 */ -    /* over/underflow if x is not close to one */ -    if( ix < 0x3f7ffff8 ) -      return ( hy < 0 ) ? huge * huge : tiny * tiny; - -    if( ix > 0x3f800007 ) -      return ( hy > 0 ) ? huge * huge : tiny * tiny; -  /* now |1-x| is tiny <= 2**-20, suffice to compute -     log(x) by x-x^2/2+x^3/3-x^4/4 */ -    t = x - 1;    /* t has 20 trailing zeros */ -    w = ( t * t ) * ( (float)0.5 - t * ( (float)0.333333333333 - t * (float)0.25 ) ); -    u = ivln2_h * t;  /* ivln2_h has 16 sig. bits */ -    v = t * ivln2_l - w * ivln2; -    t1 = u + v; -    GET_FLOAT_WORD( is, t1 ); -    SET_FLOAT_WORD( t1, is & 0xfffff000 ); -    t2 = v - ( t1 - u ); -  } -  else -  { -    float s2, s_h, s_l, t_h, t_l; -    n = 0; -    /* take care subnormal number */ -    if( ix < 0x00800000 ) -    { -      ax *= two24; -      n -= 24; -      GET_FLOAT_WORD( ix, ax ); -    } - -    n  += ( ( ix ) >> 23 ) - 0x7f; -    j  = ix & 0x007fffff; - -    /* determine interval */ -    ix = j | 0x3f800000;    /* normalize ix */ -    if( j <= 0x1cc471 ) -      k = 0;  /* |x|<sqrt(3/2) */ -    else if( j < 0x5db3d7 ) -      k = 1;  /* |x|<sqrt(3)   */ -    else -    { -      k = 0; -      n += 1; -      ix -= 0x00800000; -    } -    SET_FLOAT_WORD( ax, ix ); - -    /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */ -    u = ax - bp[ k ];   /* bp[0]=1.0, bp[1]=1.5 */ -    v = one / ( ax + bp[ k ] ); -    s = u * v; -    s_h = s; -    GET_FLOAT_WORD( is, s_h ); -    SET_FLOAT_WORD( s_h, is & 0xfffff000 ); -    /* t_h=ax+bp[k] High */ -    SET_FLOAT_WORD( t_h, ( ( ix >> 1 ) | 0x20000000 ) + 0x0040000 + ( k << 21 ) ); -    t_l = ax - ( t_h - bp[ k ] ); -    s_l = v * ( ( u - s_h * t_h ) - s_h * t_l ); -    /* compute log(ax) */ -    s2 = s * s; -    subr = L3 + s2 * ( L4 + s2 * ( L5 + s2 * L6 ) ); -    // chop up expression to keep mac register based stack happy -    r = s2 * s2 * ( L1 + s2 * ( L2 + s2 * subr ) ); -    r += s_l * ( s_h + s ); -    s2  = s_h * s_h; -    t_h = (float)3.0 + s2 + r; -    GET_FLOAT_WORD( is, t_h ); -    SET_FLOAT_WORD( t_h, is & 0xfffff000 ); -    t_l = r - ( ( t_h - (float)3.0 ) - s2 ); -    /* u+v = s*(1+...) */ -    u = s_h * t_h; -    v = s_l * t_h + t_l * s; -    /* 2/(3log2)*(s+...) */ -    p_h = u + v; -    GET_FLOAT_WORD( is, p_h ); -    SET_FLOAT_WORD( p_h, is & 0xfffff000 ); -    p_l = v - ( p_h - u ); -    z_h = cp_h * p_h;   /* cp_h+cp_l = 2/(3*log2) */ -    z_l = cp_l * p_h + p_l * cp + dp_l[ k ]; -    /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ -    t = (float)n; -    t1 = ( ( ( z_h + z_l ) + dp_h[ k ] ) + t ); -    GET_FLOAT_WORD( is, t1 ); -    SET_FLOAT_WORD( t1, is & 0xfffff000 ); -    t2 = z_l - ( ( ( t1 - t ) - dp_h[ k ] ) - z_h ); -  } - -  s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ -  if( ( ( ( (unsigned int)hx >> 31 ) - 1 ) | ( yisint - 1 ) ) == 0 ) -    s = -one; /* (-ve)**(odd int) */ - -  /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ -  GET_FLOAT_WORD( is, y ); -  SET_FLOAT_WORD( y1, is & 0xfffff000 ); -  p_l = ( y - y1 ) * t1 + y * t2; -  p_h = y1 * t1; -  z = p_l + p_h; -  GET_FLOAT_WORD( j, z ); - -  if( j > 0x43000000 )       /* if z > 128 */ -    return s * huge * huge;       /* overflow */ -  else if( j == 0x43000000 ) -  {     /* if z == 128 */ -    if( p_l + ovt > z - p_h ) -      return s * huge * huge; /* overflow */ -  } -  else if( ( j & 0x7fffffff ) > 0x43160000 )   /* z <= -150 */ -    return s * tiny * tiny;       /* underflow */ -  else if( (unsigned int)j == 0xc3160000 ) -  { /* z == -150 */ -    if( p_l <= z - p_h ) -      return s * tiny * tiny;    /* underflow */ -  } - -  /* -   * compute 2**(p_h+p_l) -   */ -  i = j & 0x7fffffff; -  k = ( i >> 23 ) - 0x7f; -  n = 0; - -  if( i > 0x3f000000 ) -  {    /* if |z| > 0.5, set n = [z+0.5] */ -    n = j + ( 0x00800000 >> ( k + 1 ) ); -    k = ( ( n & 0x7fffffff ) >> 23 ) - 0x7f;  /* new k for n */ -    SET_FLOAT_WORD( t, n & ~( 0x007fffff >> k ) ); -    n = ( ( n & 0x007fffff ) | 0x00800000 ) >> ( 23 - k ); - -    if( j < 0 ) -      n = -n; - -    p_h -= t; -  } - -  t = p_l + p_h; -  GET_FLOAT_WORD( is, t ); -  SET_FLOAT_WORD( t, is & 0xfffff000 ); -  u = t * lg2_h; -  v = ( p_l - ( t - p_h ) ) * lg2 + t * lg2_l; -  z = u + v; -  w = v - ( z - u ); -  t = z * z; -  subt1 = P3 + t * ( P4 + t * P5 ); -  // chop up expression to keep mac register based stack happy -  t1 = z - t * ( P1 + t * ( P2 + t * subt1 ) ); -  r = ( z * t1 ) / ( t1 - two ) - ( w + z * w ); -  z = one - ( r - z ); -  GET_FLOAT_WORD( j, z ); -  j += (n << 23 ); - -  if( ( j >> 23 ) <= 0 ) -    z = __scalbnf( z, n );  /* subnormal output */ -  else -    SET_FLOAT_WORD( z, j ); - -  return s * z; -} - -#endif - - - -static int randSeed = 0; - -void srand( unsigned seed ) -{ -  randSeed = seed; -} - -int rand( void ) -{ -  randSeed = ( 69069 * randSeed + 1 ); -  return randSeed & 0x7fff; -} - -double atof( const char *string ) -{ -  float sign; -  float value; -  int   c; - -  // skip whitespace -  while( *string <= ' ' ) -  { -    if( !*string ) -      return 0; - -    string++; -  } - -  // check sign -  switch( *string ) -  { -    case '+': -      string++; -      sign = 1; -      break; - -    case '-': -      string++; -      sign = -1; -      break; - -    default: -      sign = 1; -      break; -  } - -  // read digits -  value = 0; -  c = string[ 0 ]; - -  if( c != '.' ) -  { -    do -    { -      c = *string++; -      if( c < '0' || c > '9' ) -        break; - -      c -= '0'; -      value = value * 10 + c; -    } while( 1 ); -  } -  else -    string++; - -  // check for decimal point -  if( c == '.' ) -  { -    double fraction; - -    fraction = 0.1; -    do -    { -      c = *string++; -      if( c < '0' || c > '9' ) -        break; - -      c -= '0'; -      value += c * fraction; -      fraction *= 0.1; -    } while( 1 ); - -  } - -  // not handling 10e10 notation... - -  return value * sign; -} - -double _atof( const char **stringPtr ) -{ -  const char  *string; -  float sign; -  float value; -  int   c = '0'; // bk001211 - uninitialized use possible - -  string = *stringPtr; - -  // skip whitespace -  while( *string <= ' ' ) -  { -    if( !*string ) -    { -      *stringPtr = string; -      return 0; -    } - -    string++; -  } - -  // check sign -  switch( *string ) -  { -    case '+': -      string++; -      sign = 1; -      break; - -    case '-': -      string++; -      sign = -1; -      break; - -    default: -      sign = 1; -      break; -  } - -  // read digits -  value = 0; -  if( string[ 0 ] != '.' ) -  { -    do -    { -      c = *string++; -      if( c < '0' || c > '9' ) -        break; - -      c -= '0'; -      value = value * 10 + c; -    } while( 1 ); -  } - -  // check for decimal point -  if( c == '.' ) -  { -    double fraction; - -    fraction = 0.1; -    do -    { -      c = *string++; -      if( c < '0' || c > '9' ) -        break; - -      c -= '0'; -      value += c * fraction; -      fraction *= 0.1; -    } while( 1 ); - -  } - -  // not handling 10e10 notation... -  *stringPtr = string; - -  return value * sign; -} - - -#if defined ( Q3_VM ) - -int atoi( const char *string ) -{ -  int   sign; -  int   value; -  int   c; - -  // skip whitespace -  while( *string <= ' ' ) -  { -    if( !*string ) -      return 0; - -    string++; -  } - -  // check sign -  switch( *string ) -  { -    case '+': -      string++; -      sign = 1; -      break; - -    case '-': -      string++; -      sign = -1; -      break; - -    default: -      sign = 1; -      break; -  } - -  // read digits -  value = 0; -  do -  { -    c = *string++; -    if( c < '0' || c > '9' ) -      break; - -    c -= '0'; -    value = value * 10 + c; -  } while( 1 ); - -  // not handling 10e10 notation... - -  return value * sign; -} - - -int _atoi( const char **stringPtr ) -{ -  int   sign; -  int   value; -  int   c; -  const char  *string; - -  string = *stringPtr; - -  // skip whitespace -  while( *string <= ' ' ) -  { -    if( !*string ) -      return 0; - -    string++; -  } - -  // check sign -  switch( *string ) -  { -    case '+': -      string++; -      sign = 1; -      break; - -    case '-': -      string++; -      sign = -1; -      break; - -    default: -      sign = 1; -      break; -  } - -  // read digits -  value = 0; -  do -  { -    c = *string++; -    if( c < '0' || c > '9' ) -      break; - -    c -= '0'; -    value = value * 10 + c; -  } while( 1 ); - -  // not handling 10e10 notation... - -  *stringPtr = string; - -  return value * sign; -} - -int abs( int n ) -{ -  return n < 0 ? -n : n; -} - -double fabs( double x ) -{ -  return x < 0 ? -x : x; -} - - - -//========================================================= - - -#define ALT       0x00000001    /* alternate form */ -#define HEXPREFIX 0x00000002    /* add 0x or 0X prefix */ -#define LADJUST   0x00000004    /* left adjustment */ -#define LONGDBL   0x00000008    /* long double */ -#define LONGINT   0x00000010    /* long integer */ -#define QUADINT   0x00000020    /* quad integer */ -#define SHORTINT  0x00000040    /* short integer */ -#define ZEROPAD   0x00000080    /* zero (as opposed to blank) pad */ -#define FPT       0x00000100    /* floating point number */ - -#define to_digit(c)   ((c) - '0') -#define is_digit(c)   ((unsigned)to_digit(c) <= 9) -#define to_char(n)    ((n) + '0') - -void AddInt( char **buf_p, int val, int width, int flags ) -{ -  char  text[ 32 ]; -  int   digits; -  int   signedVal; -  char  *buf; - -  digits = 0; -  signedVal = val; -  if( val < 0 ) -    val = -val; - -  do -  { -    text[ digits++ ] = '0' + val % 10; -    val /= 10; -  } while( val ); - -  if( signedVal < 0 ) -    text[ digits++ ] = '-'; - -  buf = *buf_p; - -  if( !( flags & LADJUST ) ) -  { -    while( digits < width ) -    { -      *buf++ = ( flags & ZEROPAD ) ? '0' : ' '; -      width--; -    } -  } - -  while( digits-- ) -  { -    *buf++ = text[ digits ]; -    width--; -  } - -  if( flags & LADJUST ) -  { -    while( width-- ) -      *buf++ = ( flags & ZEROPAD ) ? '0' : ' '; -  } - -  *buf_p = buf; -} - -void AddFloat( char **buf_p, float fval, int width, int prec ) -{ -  char  text[ 32 ]; -  int   digits; -  float signedVal; -  char  *buf; -  int   val; - -  // get the sign -  signedVal = fval; -  if( fval < 0 ) -    fval = -fval; - -  // write the float number -  digits = 0; -  val = (int)fval; - -  do -  { -    text[ digits++ ] = '0' + val % 10; -    val /= 10; -  } while( val ); - -  if( signedVal < 0 ) -    text[digits++] = '-'; - -  buf = *buf_p; - -  while( digits < width ) -    *buf++ = ' '; -    width--; - -  while( digits-- ) -    *buf++ = text[ digits ]; - -  *buf_p = buf; - -  if( prec < 0 ) -    prec = 6; - -  // write the fraction -  digits = 0; - -  while( digits < prec ) -  { -    fval -= (int)fval; -    fval *= 10.0; -    val = (int)fval; -    text[ digits++ ] = '0' + val % 10; -  } - -  if( digits > 0 ) -  { -    buf = *buf_p; -    *buf++ = '.'; -    for( prec = 0; prec < digits; prec++ ) -      *buf++ = text[ prec ]; - -    *buf_p = buf; -  } -} - -void AddVec3_t( char **buf_p, vec3_t v, int width, int prec ) -{ -  char *buf; - -  buf = *buf_p; - -  *buf++ = '['; - -  AddFloat( &buf, v[ 0 ], width, prec ); -  buf += width; -  *buf++ = ' '; - -  AddFloat( &buf, v[ 1 ], width, prec ); -  buf += width; -  *buf++ = ' '; - -  AddFloat( &buf, v[ 2 ], width, prec ); -  buf += width; -  *buf++ = ']'; - -  *buf_p = buf; -} - -void AddString( char **buf_p, char *string, int width, int prec ) -{ -  int   size; -  char  *buf; - -  buf = *buf_p; - -  if( string == NULL ) -  { -    string = "(null)"; -    prec = -1; -  } - -  if( prec >= 0 ) -  { -    for( size = 0; size < prec; size++ ) -    { -      if( string[ size ] == '\0' ) -        break; -    } -  } -  else -    size = strlen( string ); - -  width -= size; - -  while( size-- ) -    *buf++ = *string++; - -  while( width-- > 0 ) -    *buf++ = ' '; - -  *buf_p = buf; -} - -/* -vsprintf - -I'm not going to support a bunch of the more arcane stuff in here -just to keep it simpler.  For example, the '*' and '$' are not -currently supported.  I've tried to make it so that it will just -parse and ignore formats we don't support. -*/ -int vsprintf( char *buffer, const char *fmt, va_list argptr ) -{ -  int   *arg; -  char  *buf_p; -  char  ch; -  int   flags; -  int   width; -  int   prec; -  int   n; -  char  sign; - -  buf_p = buffer; -  arg = (int *)argptr; - -  while( qtrue ) -  { -    // run through the format string until we hit a '%' or '\0' -    for( ch = *fmt; ( ch = *fmt ) != '\0' && ch != '%'; fmt++ ) -      *buf_p++ = ch; - -    if( ch == '\0' ) -      goto done; - -    // skip over the '%' -    fmt++; - -    // reset formatting state -    flags = 0; -    width = 0; -    prec = -1; -    sign = '\0'; - -rflag: -    ch = *fmt++; -reswitch: -    switch( ch ) -    { -      case '-': -        flags |= LADJUST; -        goto rflag; - -      case '.': -        n = 0; -        while( is_digit( ( ch = *fmt++ ) ) ) -          n = 10 * n + ( ch - '0' ); - -        prec = n < 0 ? -1 : n; -        goto reswitch; - -      case '0': -        flags |= ZEROPAD; -        goto rflag; - -      case '1': -      case '2': -      case '3': -      case '4': -      case '5': -      case '6': -      case '7': -      case '8': -      case '9': -        n = 0; -        do -        { -          n = 10 * n + ( ch - '0' ); -          ch = *fmt++; -        } while( is_digit( ch ) ); - -        width = n; -        goto reswitch; - -      case 'c': -        *buf_p++ = (char)*arg; -        arg++; -        break; - -      case 'd': -      case 'i': -        AddInt( &buf_p, *arg, width, flags ); -        arg++; -        break; - -      case 'f': -        AddFloat( &buf_p, *(double *)arg, width, prec ); -#ifdef Q3_VM -        arg += 1; // everything is 32 bit in my compiler -#else -        arg += 2; -#endif -        break; - -      case 's': -        AddString( &buf_p, (char *)*arg, width, prec ); -        arg++; -        break; - -      case 'v': -        AddVec3_t( &buf_p, (vec_t *)*arg, width, prec ); -        arg++; -        break; - -      case '%': -        *buf_p++ = ch; -        break; - -      default: -        *buf_p++ = (char)*arg; -        arg++; -        break; -    } -  } - -done: -  *buf_p = 0; -  return buf_p - buffer; -} - - -/* this is really crappy */ -int sscanf( const char *buffer, const char *fmt, ... ) -{ -  int cmd; -  int **arg; -  int count; - -  arg = (int **)&fmt + 1; -  count = 0; - -  while( *fmt ) -  { -    if( fmt[ 0 ] != '%' ) -    { -      fmt++; -      continue; -    } - -    cmd = fmt[ 1 ]; -    fmt += 2; - -    switch( cmd ) -    { -      case 'i': -      case 'd': -      case 'u': -        **arg = _atoi( &buffer ); -        break; -      case 'f': -        *(float *)*arg = _atof( &buffer ); -        break; -    } - -    arg++; -  } - -  return count; -} - -#endif diff --git a/mod/src/game/bg_lib.h b/mod/src/game/bg_lib.h deleted file mode 100644 index 61d64025..00000000 --- a/mod/src/game/bg_lib.h +++ /dev/null @@ -1,92 +0,0 @@ -// bg_lib.h -- standard C library replacement routines used by code -// compiled for the virtual machine - -// This file is NOT included on native builds -#ifndef BG_LIB_H -#define BG_LIB_H - -#ifndef NULL -#define NULL ((void *)0) -#endif - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -typedef int size_t; - -typedef char *  va_list; -#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) -#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) ) -#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) -#define va_end(ap)      ( ap = (va_list)0 ) - -#define CHAR_BIT      8         /* number of bits in a char */ -#define SCHAR_MIN   (-128)      /* minimum signed char value */ -#define SCHAR_MAX     127       /* maximum signed char value */ -#define UCHAR_MAX     0xff      /* maximum unsigned char value */ - -#define SHRT_MIN    (-32768)        /* minimum (signed) short value */ -#define SHRT_MAX      32767         /* maximum (signed) short value */ -#define USHRT_MAX     0xffff        /* maximum unsigned short value */ -#define INT_MIN     (-2147483647 - 1) /* minimum (signed) int value */ -#define INT_MAX       2147483647    /* maximum (signed) int value */ -#define UINT_MAX      0xffffffff    /* maximum unsigned int value */ -#define LONG_MIN    (-2147483647L - 1) /* minimum (signed) long value */ -#define LONG_MAX      2147483647L   /* maximum (signed) long value */ -#define ULONG_MAX     0xffffffffUL  /* maximum unsigned long value */ - -// Misc functions -typedef int cmp_t( const void *, const void * ); -void        qsort( void *a, size_t n, size_t es, cmp_t *cmp ); -void        srand( unsigned seed ); -int         rand( void ); - -// String functions -size_t  strlen( const char *string ); -char    *strcat( char *strDestination, const char *strSource ); -char    *strcpy( char *strDestination, const char *strSource ); -int     strcmp( const char *string1, const char *string2 ); -char    *strchr( const char *string, int c ); -char    *strrchr( const char *string, int c ); -char    *strstr( const char *string, const char *strCharSet ); -char    *strncpy( char *strDest, const char *strSource, size_t count ); -int     tolower( int c ); -int     toupper( int c ); - -double  atof( const char *string ); -double  _atof( const char **stringPtr ); -int     atoi( const char *string ); -int     _atoi( const char **stringPtr ); - -int     vsprintf( char *buffer, const char *fmt, va_list argptr ); -int     sscanf( const char *buffer, const char *fmt, ... ); - -// Memory functions -void    *memmove( void *dest, const void *src, size_t count ); -void    *memset( void *dest, int c, size_t count ); -void    *memcpy( void *dest, const void *src, size_t count ); - -// Math functions -double  ceil( double x ); -double  floor( double x ); -double  sqrt( double x ); -double  sin( double x ); -double  cos( double x ); -double  atan2( double y, double x ); -double  tan( double x ); -int     abs( int n ); -double  fabs( double x ); -double  acos( double x ); -float   pow( float x, float y ); - -#endif // BG_LIB_H diff --git a/mod/src/game/bg_local.h b/mod/src/game/bg_local.h deleted file mode 100644 index 7e5ea46f..00000000 --- a/mod/src/game/bg_local.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// bg_local.h -- local definitions for the bg (both games) files - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#define MIN_WALK_NORMAL 0.7f   // can't walk on very steep slopes - -#define STEPSIZE    18 - -#define TIMER_LAND        130 -#define TIMER_GESTURE     (34*66+50) -#define TIMER_ATTACK      500 //nonsegmented models - -#define OVERCLIP    1.001f - -#define FALLING_THRESHOLD -900.0f //what vertical speed to start falling sound at - - -// all of the locals will be zeroed before each -// pmove, just to make damn sure we don't have -// any differences when running on client or server -typedef struct -{ -  vec3_t    forward, right, up; -  float     frametime; - -  int       msec; - -  qboolean  walking; -  qboolean  groundPlane; -  qboolean  ladder; -  trace_t   groundTrace; - -  float     impactSpeed; - -  vec3_t    previous_origin; -  vec3_t    previous_velocity; -  int       previous_waterlevel; -} pml_t; - -extern  pmove_t       *pm; -extern  pml_t         pml; - -// movement parameters -extern  float pm_stopspeed; -extern  float pm_duckScale; -extern  float pm_swimScale; -extern  float pm_wadeScale; - -extern  float pm_accelerate; -extern  float pm_airaccelerate; -extern  float pm_wateraccelerate; -extern  float pm_flyaccelerate; - -extern  float pm_friction; -extern  float pm_waterfriction; -extern  float pm_flightfriction; - -extern  int   c_pmove; - -void PM_ClipVelocity( vec3_t in, vec3_t normal, vec3_t out, float overbounce ); -void PM_AddTouchEnt( int entityNum ); -void PM_AddEvent( int newEvent ); - -qboolean  PM_SlideMove( qboolean gravity ); -void      PM_StepEvent( vec3_t from, vec3_t to, vec3_t normal ); -qboolean  PM_StepSlideMove( qboolean gravity, qboolean predictive ); -qboolean  PM_PredictStepMove( void ); diff --git a/mod/src/game/bg_misc.c b/mod/src/game/bg_misc.c deleted file mode 100644 index 727190af..00000000 --- a/mod/src/game/bg_misc.c +++ /dev/null @@ -1,5248 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// bg_misc.c -- both games misc functions, all completely stateless - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "q_shared.h" -#include "bg_public.h" - -int  trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode ); -void trap_FS_Read( void *buffer, int len, fileHandle_t f ); -void trap_FS_Write( const void *buffer, int len, fileHandle_t f ); -void trap_FS_FCloseFile( fileHandle_t f ); -void trap_FS_Seek( fileHandle_t f, long offset, fsOrigin_t origin ); // fsOrigin_t - -buildableAttributes_t bg_buildableList[ ] = -{ -  { -    BA_A_SPAWN,            //int       buildNum; -    "eggpod",              //char      *buildName; -    "Egg",                 //char      *humanName; -    "team_alien_spawn",    //char      *entityName; -    { "models/buildables/eggpod/eggpod.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -15, -15, -15 },     //vec3_t    mins; -    { 15, 15, 15 },        //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    ASPAWN_BP,             //int       buildPoints; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    ASPAWN_HEALTH,         //int       health; -    ASPAWN_REGEN,          //int       regenRate; -    ASPAWN_SPLASHDAMAGE,   //int       splashDamage; -    ASPAWN_SPLASHRADIUS,   //int       splashRadius; -    MOD_ASPAWN,            //int       meansOfDeath; -    BIT_ALIENS,            //int       team; -    ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    100,                   //int       nextthink; -    ASPAWN_BT,             //int       buildTime; -    qfalse,                //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_NONE,               //weapon_t  turretProjType; -    0.5f,                  //float     minNormal; -    qtrue,                 //qboolean  invertNormal; -    qfalse,                //qboolean  creepTest; -    ASPAWN_CREEPSIZE,      //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  }, -  { -    BA_A_BARRICADE,        //int       buildNum; -    "barricade",           //char      *buildName; -    "Barricade",           //char      *humanName; -    "team_alien_barricade",//char      *entityName; -    { "models/buildables/barricade/barricade.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -35, -35, -15 },     //vec3_t    mins; -    { 35, 35, 60 },        //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    BARRICADE_BP,          //int       buildPoints; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    BARRICADE_HEALTH,      //int       health; -    BARRICADE_REGEN,       //int       regenRate; -    BARRICADE_SPLASHDAMAGE,//int       splashDamage; -    BARRICADE_SPLASHRADIUS,//int       splashRadius; -    MOD_ASPAWN,            //int       meansOfDeath; -    BIT_ALIENS,            //int       team; -    ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    100,                   //int       nextthink; -    BARRICADE_BT,          //int       buildTime; -    qfalse,                //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_NONE,               //weapon_t  turretProjType; -    0.707f,                //float     minNormal; -    qfalse,                //qboolean  invertNormal; -    qtrue,                 //qboolean  creepTest; -    BARRICADE_CREEPSIZE,   //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  }, -  { -    BA_A_BOOSTER,          //int       buildNum; -    "booster",             //char      *buildName; -    "Booster",             //char      *humanName; -    "team_alien_booster",  //char      *entityName; -    { "models/buildables/booster/booster.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -26, -26, -9 },     //vec3_t     mins; -    { 26, 26, 9 },        //vec3_t     maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    BOOSTER_BP,            //int       buildPoints; -    ( 1 << S2 )|( 1 << S3 ), //int  stages -    BOOSTER_HEALTH,        //int       health; -    BOOSTER_REGEN,         //int       regenRate; -    BOOSTER_SPLASHDAMAGE,  //int       splashDamage; -    BOOSTER_SPLASHRADIUS,  //int       splashRadius; -    MOD_ASPAWN,            //int       meansOfDeath; -    BIT_ALIENS,            //int       team; -    ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    100,                   //int       nextthink; -    BOOSTER_BT,            //int       buildTime; -    qfalse,                //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_NONE,               //weapon_t  turretProjType; -    0.707f,                //float     minNormal; -    qfalse,                //qboolean  invertNormal; -    qtrue,                 //qboolean  creepTest; -    BOOSTER_CREEPSIZE,     //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  }, -  { -    BA_A_ACIDTUBE,         //int       buildNum; -    "acid_tube",           //char      *buildName; -    "Acid Tube",           //char      *humanName; -    "team_alien_acid_tube",//char      *entityName; -    { "models/buildables/acid_tube/acid_tube.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -25, -25, -25 },     //vec3_t    mins; -    { 25, 25, 25 },        //vec3_t    maxs; -    -15.0f,                //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    ACIDTUBE_BP,           //int       buildPoints; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    ACIDTUBE_HEALTH,       //int       health; -    ACIDTUBE_REGEN,        //int       regenRate; -    ACIDTUBE_SPLASHDAMAGE, //int       splashDamage; -    ACIDTUBE_SPLASHRADIUS, //int       splashRadius; -    MOD_ATUBE,             //int       meansOfDeath; -    BIT_ALIENS,            //int       team; -    ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    200,                   //int       nextthink; -    ACIDTUBE_BT,           //int       buildTime; -    qfalse,                //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_NONE,               //weapon_t  turretProjType; -    0.0f,                  //float     minNormal; -    qtrue,                 //qboolean  invertNormal; -    qtrue,                 //qboolean  creepTest; -    ACIDTUBE_CREEPSIZE,    //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  }, -  { -    BA_A_HIVE,             //int       buildNum; -    "hive",                //char      *buildName; -    "Hive",                //char      *humanName; -    "team_alien_hive",     //char      *entityName; -    { "models/buildables/acid_tube/acid_tube.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -35, -35, -25 },     //vec3_t    mins; -    { 35, 35, 25 },        //vec3_t    maxs; -    -15.0f,                //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    HIVE_BP,               //int       buildPoints; -    ( 1 << S3 ),           //int  stages -    HIVE_HEALTH,           //int       health; -    HIVE_REGEN,            //int       regenRate; -    HIVE_SPLASHDAMAGE,     //int       splashDamage; -    HIVE_SPLASHRADIUS,     //int       splashRadius; -    MOD_ASPAWN,            //int       meansOfDeath; -    BIT_ALIENS,            //int       team; -    ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    500,                   //int       nextthink; -    HIVE_BT,               //int       buildTime; -    qfalse,                //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_HIVE,               //weapon_t  turretProjType; -    0.0f,                  //float     minNormal; -    qtrue,                 //qboolean  invertNormal; -    qtrue,                 //qboolean  creepTest; -    HIVE_CREEPSIZE,        //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  }, -  { -    BA_A_TRAPPER,          //int       buildNum; -    "trapper",             //char      *buildName; -    "Trapper",             //char      *humanName; -    "team_alien_trapper",  //char      *entityName; -    { "models/buildables/trapper/trapper.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -15, -15, -15 },     //vec3_t    mins; -    { 15, 15, 15 },        //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    TRAPPER_BP,            //int       buildPoints; -    ( 1 << S2 )|( 1 << S3 ), //int  stages //NEEDS ADV BUILDER SO S2 AND UP -    TRAPPER_HEALTH,        //int       health; -    TRAPPER_REGEN,         //int       regenRate; -    TRAPPER_SPLASHDAMAGE,  //int       splashDamage; -    TRAPPER_SPLASHRADIUS,  //int       splashRadius; -    MOD_ASPAWN,            //int       meansOfDeath; -    BIT_ALIENS,            //int       team; -    ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    100,                   //int       nextthink; -    TRAPPER_BT,            //int       buildTime; -    qfalse,                //qboolean  usable; -    TRAPPER_RANGE,         //int       turretRange; -    TRAPPER_REPEAT,        //int       turretFireSpeed; -    WP_LOCKBLOB_LAUNCHER,  //weapon_t  turretProjType; -    0.0f,                  //float     minNormal; -    qtrue,                 //qboolean  invertNormal; -    qtrue,                 //qboolean  creepTest; -    TRAPPER_CREEPSIZE,     //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  }, -  { -    BA_A_OVERMIND,         //int       buildNum; -    "overmind",            //char      *buildName; -    "Overmind",            //char      *humanName; -    "team_alien_overmind", //char      *entityName; -    { "models/buildables/overmind/overmind.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -45, -45, -15 },     //vec3_t    mins; -    { 45, 45, 95 },        //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    OVERMIND_BP,           //int       buildPoints; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    OVERMIND_HEALTH,       //int       health; -    OVERMIND_REGEN,        //int       regenRate; -    OVERMIND_SPLASHDAMAGE, //int       splashDamage; -    OVERMIND_SPLASHRADIUS, //int       splashRadius; -    MOD_ASPAWN,            //int       meansOfDeath; -    BIT_ALIENS,            //int       team; -    ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    OVERMIND_ATTACK_REPEAT,//int       nextthink; -    OVERMIND_BT,           //int       buildTime; -    qfalse,                //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_NONE,               //weapon_t  turretProjType; -    0.95f,                 //float     minNormal; -    qfalse,                //qboolean  invertNormal; -    qfalse,                //qboolean  creepTest; -    OVERMIND_CREEPSIZE,    //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qtrue                  //qboolean  reactorTest; -  }, -  { -    BA_A_HOVEL,            //int       buildNum; -    "hovel",               //char      *buildName; -    "Hovel",               //char      *humanName; -    "team_alien_hovel",    //char      *entityName; -    { "models/buildables/hovel/hovel.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -50, -50, -20 },     //vec3_t    mins; -    { 50, 50, 20 },        //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    HOVEL_BP,              //int       buildPoints; -    ( 1 << S3 ),           //int  stages -    HOVEL_HEALTH,          //int       health; -    HOVEL_REGEN,           //int       regenRate; -    HOVEL_SPLASHDAMAGE,    //int       splashDamage; -    HOVEL_SPLASHRADIUS,    //int       splashRadius; -    MOD_ASPAWN,            //int       meansOfDeath; -    BIT_ALIENS,            //int       team; -    ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    150,                   //int       nextthink; -    HOVEL_BT,              //int       buildTime; -    qtrue,                 //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_NONE,               //weapon_t  turretProjType; -    0.95f,                 //float     minNormal; -    qfalse,                //qboolean  invertNormal; -    qtrue,                 //qboolean  creepTest; -    HOVEL_CREEPSIZE,       //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qtrue                  //qboolean  reactorTest; -  }, -  { -    BA_H_SPAWN,            //int       buildNum; -    "telenode",            //char      *buildName; -    "Telenode",            //char      *humanName; -    "team_human_spawn",    //char      *entityName; -    { "models/buildables/telenode/telenode.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -40, -40, -4 },      //vec3_t    mins; -    { 40, 40, 4 },         //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    HSPAWN_BP,             //int       buildPoints; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    HSPAWN_HEALTH,         //int       health; -    0,                     //int       regenRate; -    HSPAWN_SPLASHDAMAGE,   //int       splashDamage; -    HSPAWN_SPLASHRADIUS,   //int       splashRadius; -    MOD_HSPAWN,            //int       meansOfDeath; -    BIT_HUMANS,            //int       team; -    ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    100,                   //int       nextthink; -    HSPAWN_BT,             //int       buildTime; -    qfalse,                //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_NONE,               //weapon_t  turretProjType; -    0.95f,                 //float     minNormal; -    qfalse,                //qboolean  invertNormal; -    qfalse,                //qboolean  creepTest; -    0,                     //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  }, -  { -    BA_H_MEDISTAT,         //int       buildNum; -    "medistat",            //char      *buildName; -    "Medistation",         //char      *humanName; -    "team_human_medistat", //char      *entityName; -    { "models/buildables/medistat/medistat.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -35, -35, -7 },      //vec3_t    mins; -    { 35, 35, 7 },         //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    MEDISTAT_BP,           //int       buildPoints; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    MEDISTAT_HEALTH,       //int       health; -    0,                     //int       regenRate; -    MEDISTAT_SPLASHDAMAGE, //int       splashDamage; -    MEDISTAT_SPLASHRADIUS, //int       splashRadius; -    MOD_HSPAWN,            //int       meansOfDeath; -    BIT_HUMANS,            //int       team; -    ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    100,                   //int       nextthink; -    MEDISTAT_BT,           //int       buildTime; -    qfalse,                //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_NONE,               //weapon_t  turretProjType; -    0.95f,                 //float     minNormal; -    qfalse,                //qboolean  invertNormal; -    qfalse,                //qboolean  creepTest; -    0,                     //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  }, -  { -    BA_H_MGTURRET,         //int       buildNum; -    "mgturret",            //char      *buildName; -    "Machinegun Turret",   //char      *humanName; -    "team_human_mgturret", //char      *entityName; -    { "models/buildables/mgturret/turret_base.md3", -      "models/buildables/mgturret/turret_barrel.md3", -      "models/buildables/mgturret/turret_top.md3", 0 }, -    1.0f,                  //float     modelScale; -    { -25, -25, -20 },     //vec3_t    mins; -    { 25, 25, 20 },        //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    MGTURRET_BP,           //int       buildPoints; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    MGTURRET_HEALTH,       //int       health; -    0,                     //int       regenRate; -    MGTURRET_SPLASHDAMAGE, //int       splashDamage; -    MGTURRET_SPLASHRADIUS, //int       splashRadius; -    MOD_HSPAWN,            //int       meansOfDeath; -    BIT_HUMANS,            //int       team; -    ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ),   //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    50,                    //int       nextthink; -    MGTURRET_BT,           //int       buildTime; -    qfalse,                //qboolean  usable; -    MGTURRET_RANGE,        //int       turretRange; -    MGTURRET_REPEAT,       //int       turretFireSpeed; -    WP_MGTURRET,           //weapon_t  turretProjType; -    0.95f,                 //float     minNormal; -    qfalse,                //qboolean  invertNormal; -    qfalse,                //qboolean  creepTest; -    0,                     //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  }, -  { -    BA_H_TESLAGEN,         //int       buildNum; -    "tesla",               //char      *buildName; -    "Tesla Generator",     //char      *humanName; -    "team_human_tesla",    //char      *entityName; -    { "models/buildables/tesla/tesla.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -22, -22, -40 },     //vec3_t    mins; -    { 22, 22, 40 },        //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    TESLAGEN_BP,           //int       buildPoints; -    ( 1 << S3 ),           //int       stages -    TESLAGEN_HEALTH,       //int       health; -    0,                     //int       regenRate; -    TESLAGEN_SPLASHDAMAGE, //int       splashDamage; -    TESLAGEN_SPLASHRADIUS, //int       splashRadius; -    MOD_HSPAWN,            //int       meansOfDeath; -    BIT_HUMANS,            //int       team; -    ( 1 << WP_HBUILD2 ),   //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    150,                   //int       nextthink; -    TESLAGEN_BT,           //int       buildTime; -    qfalse,                //qboolean  usable; -    TESLAGEN_RANGE,        //int       turretRange; -    TESLAGEN_REPEAT,       //int       turretFireSpeed; -    WP_TESLAGEN,           //weapon_t  turretProjType; -    0.95f,                 //float     minNormal; -    qfalse,                //qboolean  invertNormal; -    qfalse,                //qboolean  creepTest; -    0,                     //int       creepSize; -    qtrue,                 //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  }, -  { -    BA_H_DCC,              //int       buildNum; -    "dcc",                 //char      *buildName; -    "Defence Computer",    //char      *humanName; -    "team_human_dcc",      //char      *entityName; -    { "models/buildables/dcc/dcc.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -35, -35, -13 },     //vec3_t    mins; -    { 35, 35, 47 },        //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    DC_BP,                 //int       buildPoints; -    ( 1 << S2 )|( 1 << S3 ), //int       stages -    DC_HEALTH,             //int       health; -    0,                     //int       regenRate; -    DC_SPLASHDAMAGE,       //int       splashDamage; -    DC_SPLASHRADIUS,       //int       splashRadius; -    MOD_HSPAWN,            //int       meansOfDeath; -    BIT_HUMANS,            //int       team; -    ( 1 << WP_HBUILD2 ),   //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    100,                   //int       nextthink; -    DC_BT,                 //int       buildTime; -    qfalse,                //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_NONE,               //weapon_t  turretProjType; -    0.95f,                 //float     minNormal; -    qfalse,                //qboolean  invertNormal; -    qfalse,                //qboolean  creepTest; -    0,                     //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  }, -  { -    BA_H_ARMOURY,          //int       buildNum; -    "arm",                 //char      *buildName; -    "Armoury",             //char      *humanName; -    "team_human_armoury",  //char      *entityName; -    { "models/buildables/arm/arm.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -40, -40, -13 },     //vec3_t    mins; -    { 40, 40, 50 },        //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    ARMOURY_BP,            //int       buildPoints; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    ARMOURY_HEALTH,        //int       health; -    0,                     //int       regenRate; -    ARMOURY_SPLASHDAMAGE,  //int       splashDamage; -    ARMOURY_SPLASHRADIUS,  //int       splashRadius; -    MOD_HSPAWN,            //int       meansOfDeath; -    BIT_HUMANS,            //int       team; -    ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    100,                   //int       nextthink; -    ARMOURY_BT,            //int       buildTime; -    qtrue,                 //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_NONE,               //weapon_t  turretProjType; -    0.95f,                 //float     minNormal; -    qfalse,                //qboolean  invertNormal; -    qfalse,                //qboolean  creepTest; -    0,                     //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  }, -  { -    BA_H_REACTOR,          //int       buildNum; -    "reactor",             //char      *buildName; -    "Reactor",             //char      *humanName; -    "team_human_reactor",  //char      *entityName; -    { "models/buildables/reactor/reactor.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -50, -50, -15 },     //vec3_t    mins; -    { 50, 50, 95 },        //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    REACTOR_BP,            //int       buildPoints; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    REACTOR_HEALTH,        //int       health; -    0,                     //int       regenRate; -    REACTOR_SPLASHDAMAGE,  //int       splashDamage; -    REACTOR_SPLASHRADIUS,  //int       splashRadius; -    MOD_HSPAWN,            //int       meansOfDeath; -    BIT_HUMANS,            //int       team; -    ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    REACTOR_ATTACK_REPEAT, //int       nextthink; -    REACTOR_BT,            //int       buildTime; -    qtrue,                 //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_NONE,               //weapon_t  turretProjType; -    0.95f,                 //float     minNormal; -    qfalse,                //qboolean  invertNormal; -    qfalse,                //qboolean  creepTest; -    0,                     //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qtrue                  //qboolean  reactorTest; -  }, -  { -    BA_H_REPEATER,         //int       buildNum; -    "repeater",            //char      *buildName; -    "Repeater",            //char      *humanName; -    "team_human_repeater", //char      *entityName; -    { "models/buildables/repeater/repeater.md3", 0, 0, 0 }, -    1.0f,                  //float     modelScale; -    { -15, -15, -15 },     //vec3_t    mins; -    { 15, 15, 25 },        //vec3_t    maxs; -    0.0f,                  //float     zOffset; -    TR_GRAVITY,            //trType_t  traj; -    0.0,                   //float     bounce; -    REPEATER_BP,           //int       buildPoints; -    ( 1 << S2 )|( 1 << S3 ), //int  stages -    REPEATER_HEALTH,       //int       health; -    0,                     //int       regenRate; -    REPEATER_SPLASHDAMAGE, //int       splashDamage; -    REPEATER_SPLASHRADIUS, //int       splashRadius; -    MOD_HSPAWN,            //int       meansOfDeath; -    BIT_HUMANS,            //int       team; -    ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ),    //weapon_t  buildWeapon; -    BANIM_IDLE1,           //int       idleAnim; -    100,                   //int       nextthink; -    REPEATER_BT,           //int       buildTime; -    qtrue,                 //qboolean  usable; -    0,                     //int       turretRange; -    0,                     //int       turretFireSpeed; -    WP_NONE,               //weapon_t  turretProjType; -    0.95f,                 //float     minNormal; -    qfalse,                //qboolean  invertNormal; -    qfalse,                //qboolean  creepTest; -    0,                     //int       creepSize; -    qfalse,                //qboolean  dccTest; -    qfalse                 //qboolean  reactorTest; -  } -}; - -int   bg_numBuildables = sizeof( bg_buildableList ) / sizeof( bg_buildableList[ 0 ] ); - -//separate from bg_buildableList to work around char struct init bug -buildableAttributeOverrides_t bg_buildableOverrideList[ BA_NUM_BUILDABLES ]; - -/* -============== -BG_FindBuildNumForName -============== -*/ -int BG_FindBuildNumForName( char *name ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( !Q_stricmp( bg_buildableList[ i ].buildName, name ) ) -      return bg_buildableList[ i ].buildNum; -  } - -  //wimp out -  return BA_NONE; -} - -/* -============== -BG_FindBuildNumForEntityName -============== -*/ -int BG_FindBuildNumForEntityName( char *name ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( !Q_stricmp( bg_buildableList[ i ].entityName, name ) ) -      return bg_buildableList[ i ].buildNum; -  } - -  //wimp out -  return BA_NONE; -} - -/* -============== -BG_FindNameForBuildNum -============== -*/ -char *BG_FindNameForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -      return bg_buildableList[ i ].buildName; -  } - -  //wimp out -  return 0; -} - -/* -============== -BG_FindHumanNameForBuildNum -============== -*/ -char *BG_FindHumanNameForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -      return bg_buildableList[ i ].humanName; -  } - -  //wimp out -  return 0; -} - -/* -============== -BG_FindEntityNameForBuildNum -============== -*/ -char *BG_FindEntityNameForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -      return bg_buildableList[ i ].entityName; -  } - -  //wimp out -  return 0; -} - -/* -============== -BG_FindModelsForBuildNum -============== -*/ -char *BG_FindModelsForBuildable( int bclass, int modelNum ) -{ -  int i; - -  if( bg_buildableOverrideList[ bclass ].models[ modelNum ][ 0 ] != 0 ) -    return bg_buildableOverrideList[ bclass ].models[ modelNum ]; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -      return bg_buildableList[ i ].models[ modelNum ]; -  } - -  //wimp out -  return 0; -} - -/* -============== -BG_FindModelScaleForBuildable -============== -*/ -float BG_FindModelScaleForBuildable( int bclass ) -{ -  int i; - -  if( bg_buildableOverrideList[ bclass ].modelScale != 0.0f ) -    return bg_buildableOverrideList[ bclass ].modelScale; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -      return bg_buildableList[ i ].modelScale; -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindModelScaleForBuildable( %d )\n", bclass ); -  return 1.0f; -} - -/* -============== -BG_FindBBoxForBuildable -============== -*/ -void BG_FindBBoxForBuildable( int bclass, vec3_t mins, vec3_t maxs ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      if( mins != NULL ) -      { -        VectorCopy( bg_buildableList[ i ].mins, mins ); - -        if( VectorLength( bg_buildableOverrideList[ bclass ].mins ) ) -          VectorCopy( bg_buildableOverrideList[ bclass ].mins, mins ); -      } - -      if( maxs != NULL ) -      { -        VectorCopy( bg_buildableList[ i ].maxs, maxs ); - -        if( VectorLength( bg_buildableOverrideList[ bclass ].maxs ) ) -          VectorCopy( bg_buildableOverrideList[ bclass ].maxs, maxs ); -      } - -      return; -    } -  } - -  if( mins != NULL ) -    VectorCopy( bg_buildableList[ 0 ].mins, mins ); - -  if( maxs != NULL ) -    VectorCopy( bg_buildableList[ 0 ].maxs, maxs ); -} - -/* -============== -BG_FindZOffsetForBuildable -============== -*/ -float BG_FindZOffsetForBuildable( int bclass ) -{ -  int i; - -  if( bg_buildableOverrideList[ bclass ].zOffset != 0.0f ) -    return bg_buildableOverrideList[ bclass ].zOffset; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].zOffset; -    } -  } - -  return 0.0f; -} - -/* -============== -BG_FindTrajectoryForBuildable -============== -*/ -trType_t BG_FindTrajectoryForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].traj; -    } -  } - -  return TR_GRAVITY; -} - -/* -============== -BG_FindBounceForBuildable -============== -*/ -float BG_FindBounceForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].bounce; -    } -  } - -  return 0.0; -} - -/* -============== -BG_FindBuildPointsForBuildable -============== -*/ -int BG_FindBuildPointsForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].buildPoints; -    } -  } - -  return 1000; -} - -/* -============== -BG_FindStagesForBuildable -============== -*/ -qboolean BG_FindStagesForBuildable( int bclass, stage_t stage ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      if( bg_buildableList[ i ].stages & ( 1 << stage ) ) -        return qtrue; -      else -        return qfalse; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindHealthForBuildable -============== -*/ -int BG_FindHealthForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].health; -    } -  } - -  return 1000; -} - -/* -============== -BG_FindRegenRateForBuildable -============== -*/ -int BG_FindRegenRateForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].regenRate; -    } -  } - -  return 0; -} - -/* -============== -BG_FindSplashDamageForBuildable -============== -*/ -int BG_FindSplashDamageForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].splashDamage; -    } -  } - -  return 50; -} - -/* -============== -BG_FindSplashRadiusForBuildable -============== -*/ -int BG_FindSplashRadiusForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].splashRadius; -    } -  } - -  return 200; -} - -/* -============== -BG_FindMODForBuildable -============== -*/ -int BG_FindMODForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].meansOfDeath; -    } -  } - -  return MOD_UNKNOWN; -} - -/* -============== -BG_FindTeamForBuildable -============== -*/ -int BG_FindTeamForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].team; -    } -  } - -  return BIT_NONE; -} - -/* -============== -BG_FindBuildWeaponForBuildable -============== -*/ -weapon_t BG_FindBuildWeaponForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].buildWeapon; -    } -  } - -  return BA_NONE; -} - -/* -============== -BG_FindAnimForBuildable -============== -*/ -int BG_FindAnimForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].idleAnim; -    } -  } - -  return BANIM_IDLE1; -} - -/* -============== -BG_FindNextThinkForBuildable -============== -*/ -int BG_FindNextThinkForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].nextthink; -    } -  } - -  return 100; -} - -/* -============== -BG_FindBuildTimeForBuildable -============== -*/ -int BG_FindBuildTimeForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].buildTime; -    } -  } - -  return 10000; -} - -/* -============== -BG_FindUsableForBuildable -============== -*/ -qboolean BG_FindUsableForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].usable; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindFireSpeedForBuildable -============== -*/ -int BG_FindFireSpeedForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].turretFireSpeed; -    } -  } - -  return 1000; -} - -/* -============== -BG_FindRangeForBuildable -============== -*/ -int BG_FindRangeForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].turretRange; -    } -  } - -  return 1000; -} - -/* -============== -BG_FindProjTypeForBuildable -============== -*/ -weapon_t BG_FindProjTypeForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].turretProjType; -    } -  } - -  return WP_NONE; -} - -/* -============== -BG_FindMinNormalForBuildable -============== -*/ -float BG_FindMinNormalForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].minNormal; -    } -  } - -  return 0.707f; -} - -/* -============== -BG_FindInvertNormalForBuildable -============== -*/ -qboolean BG_FindInvertNormalForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].invertNormal; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindCreepTestForBuildable -============== -*/ -int BG_FindCreepTestForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].creepTest; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindCreepSizeForBuildable -============== -*/ -int BG_FindCreepSizeForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].creepSize; -    } -  } - -  return CREEP_BASESIZE; -} - -/* -============== -BG_FindDCCTestForBuildable -============== -*/ -int BG_FindDCCTestForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].dccTest; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindUniqueTestForBuildable -============== -*/ -int BG_FindUniqueTestForBuildable( int bclass ) -{ -  int i; - -  for( i = 0; i < bg_numBuildables; i++ ) -  { -    if( bg_buildableList[ i ].buildNum == bclass ) -    { -      return bg_buildableList[ i ].reactorTest; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindOverrideForBuildable -============== -*/ -static buildableAttributeOverrides_t *BG_FindOverrideForBuildable( int bclass ) -{ -  return &bg_buildableOverrideList[ bclass ]; -} - -/* -====================== -BG_ParseBuildableFile - -Parses a configuration file describing a builable -====================== -*/ -static qboolean BG_ParseBuildableFile( const char *filename, buildableAttributeOverrides_t *bao ) -{ -  char          *text_p; -  int           i; -  int           len; -  char          *token; -  char          text[ 20000 ]; -  fileHandle_t  f; -  float         scale; - - -  // load the file -  len = trap_FS_FOpenFile( filename, &f, FS_READ ); -  if( len <= 0 ) -    return qfalse; - -  if( len >= sizeof( text ) - 1 ) -  { -    Com_Printf( S_COLOR_RED "ERROR: Buildable file %s too long\n", filename ); -    return qfalse; -  } - -  trap_FS_Read( text, len, f ); -  text[ len ] = 0; -  trap_FS_FCloseFile( f ); - -  // parse the text -  text_p = text; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( &text_p ); - -    if( !token ) -      break; - -    if( !Q_stricmp( token, "" ) ) -      break; - -    if( !Q_stricmp( token, "model" ) ) -    { -      int index = 0; - -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      index = atoi( token ); - -      if( index < 0 ) -        index = 0; -      else if( index > 3 ) -        index = 3; - -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      Q_strncpyz( bao->models[ index ], token, sizeof( bao->models[ 0 ] ) ); - -      continue; -    } -    else if( !Q_stricmp( token, "modelScale" ) ) -    { -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      scale = atof( token ); - -      if( scale < 0.0f ) -        scale = 0.0f; - -      bao->modelScale = scale; - -      continue; -    } -    else if( !Q_stricmp( token, "mins" ) ) -    { -      for( i = 0; i <= 2; i++ ) -      { -        token = COM_Parse( &text_p ); -        if( !token ) -          break; - -        bao->mins[ i ] = atof( token ); -      } - -      continue; -    } -    else if( !Q_stricmp( token, "maxs" ) ) -    { -      for( i = 0; i <= 2; i++ ) -      { -        token = COM_Parse( &text_p ); -        if( !token ) -          break; - -        bao->maxs[ i ] = atof( token ); -      } - -      continue; -    } -    else if( !Q_stricmp( token, "zOffset" ) ) -    { -      float offset; - -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      offset = atof( token ); - -      bao->zOffset = offset; - -      continue; -    } - - -    Com_Printf( S_COLOR_RED "ERROR: unknown token '%s'\n", token ); -    return qfalse; -  } - -  return qtrue; -} - -/* -=============== -BG_InitBuildableOverrides - -Set any overrides specfied by file -=============== -*/ -void BG_InitBuildableOverrides( void ) -{ -  int                           i; -  buildableAttributeOverrides_t *bao; - -  for( i = BA_NONE + 1; i < BA_NUM_BUILDABLES; i++ ) -  { -    bao = BG_FindOverrideForBuildable( i ); - -    BG_ParseBuildableFile( va( "overrides/buildables/%s.cfg", BG_FindNameForBuildable( i ) ), bao ); -  } -} - -//////////////////////////////////////////////////////////////////////////////// - -classAttributes_t bg_classList[ ] = -{ -  { -    PCL_NONE,                                       //int     classnum; -    "spectator",                                    //char    *className; -    "Spectator",                                    //char    *humanName; -    "",                                             //char    *modelname; -    1.0f,                                           //float   modelScale; -    "",                                             //char    *skinname; -    1.0f,                                           //float   shadowScale; -    "",                                             //char    *hudname; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ),            //int  stages -    { -15, -15, -15 },                              //vec3_t  mins; -    { 15, 15, 15 },                                 //vec3_t  maxs; -    { 15, 15, 15 },                                 //vec3_t  crouchmaxs; -    { -15, -15, -15 },                              //vec3_t  deadmins; -    { 15, 15, 15 },                                 //vec3_t  deadmaxs; -    0.0f,                                           //float   zOffset -    0, 0,                                           //int     viewheight, crouchviewheight; -    0,                                              //int     health; -    0.0f,                                           //float   fallDamage; -    0,                                              //int     regenRate; -    0,                                              //int     abilities; -    WP_NONE,                                        //weapon_t  startWeapon -    0.0f,                                           //float   buildDist; -    90,                                             //int     fov; -    0.000f,                                         //float   bob; -    1.0f,                                           //float   bobCycle; -    0,                                              //int     steptime; -    600,                                            //float   speed; -    10.0f,                                          //float   acceleration; -    1.0f,                                           //float   airAcceleration; -    6.0f,                                           //float   friction; -    100.0f,                                         //float   stopSpeed; -    270.0f,                                         //float   jumpMagnitude; -    1.0f,                                           //float   knockbackScale; -    { PCL_NONE, PCL_NONE, PCL_NONE },               //int     children[ 3 ]; -    0,                                              //int     cost; -    0                                               //int     value; -  }, -  { -    PCL_ALIEN_BUILDER0,                             //int     classnum; -    "builder",                                      //char    *className; -    "Builder",                                      //char    *humanName; -    "builder",                                      //char    *modelname; -    1.0f,                                           //float   modelScale; -    "default",                                      //char    *skinname; -    1.0f,                                           //float   shadowScale; -    "alien_builder_hud",                            //char    *hudname; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ),            //int  stages -    { -15, -15, -20 },                              //vec3_t  mins; -    { 15, 15, 20 },                                 //vec3_t  maxs; -    { 15, 15, 20 },                                 //vec3_t  crouchmaxs; -    { -15, -15, -4 },                               //vec3_t  deadmins; -    { 15, 15, 4 },                                  //vec3_t  deadmaxs; -    0.0f,                                           //float   zOffset -    0, 0,                                           //int     viewheight, crouchviewheight; -    ABUILDER_HEALTH,                                //int     health; -    0.2f,                                           //float   fallDamage; -    ABUILDER_REGEN,                                 //int     regenRate; -    SCA_TAKESFALLDAMAGE|SCA_FOVWARPS|SCA_ALIENSENSE,//int     abilities; -    WP_ABUILD,                                      //weapon_t  startWeapon -    95.0f,                                          //float   buildDist; -    80,                                             //int     fov; -    0.001f,                                         //float   bob; -    2.0f,                                           //float   bobCycle; -    150,                                            //int     steptime; -    ABUILDER_SPEED,                                 //float   speed; -    10.0f,                                          //float   acceleration; -    1.0f,                                           //float   airAcceleration; -    6.0f,                                           //float   friction; -    100.0f,                                         //float   stopSpeed; -    195.0f,                                         //float   jumpMagnitude; -    1.0f,                                           //float   knockbackScale; -    { PCL_ALIEN_BUILDER0_UPG, PCL_ALIEN_LEVEL0, PCL_NONE },       //int     children[ 3 ]; -    ABUILDER_COST,                                  //int     cost; -    ABUILDER_VALUE                                  //int     value; -  }, -  { -    PCL_ALIEN_BUILDER0_UPG,                         //int     classnum; -    "builderupg",                                   //char    *classname; -    "Advanced Builder",                             //char    *humanname; -    "builder",                                      //char    *modelname; -    1.0f,                                           //float   modelScale; -    "advanced",                                     //char    *skinname; -    1.0f,                                           //float   shadowScale; -    "alien_builder_hud",                            //char    *hudname; -    ( 1 << S2 )|( 1 << S3 ),                        //int  stages -    { -20, -20, -20 },                              //vec3_t  mins; -    { 20, 20, 20 },                                 //vec3_t  maxs; -    { 20, 20, 20 },                                 //vec3_t  crouchmaxs; -    { -20, -20, -4 },                               //vec3_t  deadmins; -    { 20, 20, 4 },                                  //vec3_t  deadmaxs; -    0.0f,                                           //float   zOffset -    0, 0,                                           //int     viewheight, crouchviewheight; -    ABUILDER_UPG_HEALTH,                            //int     health; -    0.0f,                                           //float   fallDamage; -    ABUILDER_UPG_REGEN,                             //int     regenRate; -    SCA_FOVWARPS|SCA_WALLCLIMBER|SCA_ALIENSENSE,    //int     abilities; -    WP_ABUILD2,                                     //weapon_t  startWeapon -    105.0f,                                         //float   buildDist; -    110,                                            //int     fov; -    0.001f,                                         //float   bob; -    2.0f,                                           //float   bobCycle; -    100,                                            //int     steptime; -    ABUILDER_UPG_SPEED,                             //float   speed; -    10.0f,                                          //float   acceleration; -    1.0f,                                           //float   airAcceleration; -    6.0f,                                           //float   friction; -    100.0f,                                         //float   stopSpeed; -    270.0f,                                         //float   jumpMagnitude; -    1.0f,                                           //float   knockbackScale; -    { PCL_ALIEN_LEVEL0, PCL_NONE, PCL_NONE },       //int     children[ 3 ]; -    ABUILDER_UPG_COST,                              //int     cost; -    ABUILDER_UPG_VALUE                              //int     value; -  }, -  { -    PCL_ALIEN_LEVEL0,                               //int     classnum; -    "level0",                                       //char    *classname; -    "Soldier",                                      //char    *humanname; -    "jumper",                                       //char    *modelname; -    0.2f,                                           //float   modelScale; -    "default",                                      //char    *skinname; -    0.3f,                                           //float   shadowScale; -    "alien_general_hud",                            //char    *hudname; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ),            //int  stages -    { -15, -15, -15 },                              //vec3_t  mins; -    { 15, 15, 15 },                                 //vec3_t  maxs; -    { 15, 15, 15 },                                 //vec3_t  crouchmaxs; -    { -15, -15, -4 },                               //vec3_t  deadmins; -    { 15, 15, 4 },                                  //vec3_t  deadmaxs; -    -8.0f,                                          //float   zOffset -    0, 0,                                           //int     viewheight, crouchviewheight; -    LEVEL0_HEALTH,                                  //int     health; -    0.0f,                                           //float   fallDamage; -    LEVEL0_REGEN,                                   //int     regenRate; -    SCA_WALLCLIMBER|SCA_NOWEAPONDRIFT| -      SCA_FOVWARPS|SCA_ALIENSENSE,                  //int     abilities; -    WP_ALEVEL0,                                     //weapon_t  startWeapon -    0.0f,                                           //float   buildDist; -    140,                                            //int     fov; -    0.0f,                                           //float   bob; -    2.5f,                                           //float   bobCycle; -    25,                                             //int     steptime; -    LEVEL0_SPEED,                                   //float   speed; -    10.0f,                                          //float   acceleration; -    1.0f,                                           //float   airAcceleration; -    6.0f,                                           //float   friction; -    400.0f,                                         //float   stopSpeed; -    250.0f,                                         //float   jumpMagnitude; -    2.0f,                                           //float   knockbackScale; -    { PCL_ALIEN_LEVEL1, PCL_NONE, PCL_NONE },       //int     children[ 3 ]; -    LEVEL0_COST,                                    //int     cost; -    LEVEL0_VALUE                                    //int     value; -  }, -  { -    PCL_ALIEN_LEVEL1,                               //int     classnum; -    "level1",                                       //char    *classname; -    "Hydra",                                        //char    *humanname; -    "spitter",                                      //char    *modelname; -    0.6f,                                           //float   modelScale; -    "default",                                      //char    *skinname; -    1.0f,                                           //float   shadowScale; -    "alien_general_hud",                            //char    *hudname; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ),            //int  stages -    { -18, -18, -18 },                              //vec3_t  mins; -    { 18, 18, 18 },                                 //vec3_t  maxs; -    { 18, 18, 18 },                                 //vec3_t  crouchmaxs; -    { -18, -18, -4 },                               //vec3_t  deadmins; -    { 18, 18, 4 },                                  //vec3_t  deadmaxs; -    0.0f,                                           //float   zOffset -    0, 0,                                           //int     viewheight, crouchviewheight; -    LEVEL1_HEALTH,                                  //int     health; -    0.0f,                                           //float   fallDamage; -    LEVEL1_REGEN,                                   //int     regenRate; -    SCA_NOWEAPONDRIFT| -      SCA_FOVWARPS|SCA_WALLCLIMBER|SCA_ALIENSENSE,  //int     abilities; -    WP_ALEVEL1,                                     //weapon_t  startWeapon -    0.0f,                                           //float   buildDist; -    120,                                            //int     fov; -    0.001f,                                         //float   bob; -    1.8f,                                           //float   bobCycle; -    60,                                             //int     steptime; -    LEVEL1_SPEED,                                   //float   speed; -    10.0f,                                          //float   acceleration; -    1.0f,                                           //float   airAcceleration; -    6.0f,                                           //float   friction; -    300.0f,                                         //float   stopSpeed; -    270.0f,                                         //float   jumpMagnitude; -    1.2f,                                           //float   knockbackScale; -    { PCL_ALIEN_LEVEL2, PCL_ALIEN_LEVEL1_UPG, PCL_NONE },   //int     children[ 3 ]; -    LEVEL1_COST,                                     //int     cost; -    LEVEL1_VALUE                                     //int     value; -  }, -  { -    PCL_ALIEN_LEVEL1_UPG,                           //int     classnum; -    "level1upg",                                    //char    *classname; -    "Hydra Upgrade",                                //char    *humanname; -    "spitter",                                      //char    *modelname; -    0.7f,                                           //float   modelScale; -    "blue",                                         //char    *skinname; -    1.0f,                                           //float   shadowScale; -    "alien_general_hud",                            //char    *hudname; -    ( 1 << S2 )|( 1 << S3 ),                        //int  stages -    { -20, -20, -20 },                              //vec3_t  mins; -    { 20, 20, 20 },                                 //vec3_t  maxs; -    { 20, 20, 20 },                                 //vec3_t  crouchmaxs; -    { -20, -20, -4 },                               //vec3_t  deadmins; -    { 20, 20, 4 },                                  //vec3_t  deadmaxs; -    0.0f,                                           //float   zOffset -    0, 0,                                           //int     viewheight, crouchviewheight; -    LEVEL1_UPG_HEALTH,                              //int     health; -    0.0f,                                           //float   fallDamage; -    LEVEL1_UPG_REGEN,                               //int     regenRate; -    SCA_NOWEAPONDRIFT|SCA_FOVWARPS| -      SCA_WALLCLIMBER|SCA_ALIENSENSE,               //int     abilities; -    WP_ALEVEL1_UPG,                                 //weapon_t  startWeapon -    0.0f,                                           //float   buildDist; -    120,                                            //int     fov; -    0.001f,                                         //float   bob; -    1.8f,                                           //float   bobCycle; -    60,                                             //int     steptime; -    LEVEL1_UPG_SPEED,                               //float   speed; -    10.0f,                                          //float   acceleration; -    1.0f,                                           //float   airAcceleration; -    6.0f,                                           //float   friction; -    300.0f,                                         //float   stopSpeed; -    270.0f,                                         //float   jumpMagnitude; -    1.1f,                                           //float   knockbackScale; -    { PCL_ALIEN_LEVEL2, PCL_NONE, PCL_NONE },       //int     children[ 3 ]; -    LEVEL1_UPG_COST,                                //int     cost; -    LEVEL1_UPG_VALUE                                //int     value; -  }, -  { -    PCL_ALIEN_LEVEL2,                               //int     classnum; -    "level2",                                       //char    *classname; -    "Chimera",                                      //char    *humanname; -    "tarantula",                                    //char    *modelname; -    0.75f,                                          //float   modelScale; -    "default",                                      //char    *skinname; -    1.0f,                                           //float   shadowScale; -    "alien_general_hud",                            //char    *hudname; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ),            //int  stages -    { -22, -22, -22 },                              //vec3_t  mins; -    { 22, 22, 22 },                                 //vec3_t  maxs; -    { 22, 22, 22 },                                 //vec3_t  crouchmaxs; -    { -22, -22, -4 },                               //vec3_t  deadmins; -    { 22, 22, 4 },                                  //vec3_t  deadmaxs; -    0.0f,                                           //float   zOffset -    10, 10,                                         //int     viewheight, crouchviewheight; -    LEVEL2_HEALTH,                                  //int     health; -    0.0f,                                           //float   fallDamage; -    LEVEL2_REGEN,                                   //int     regenRate; -    SCA_NOWEAPONDRIFT|SCA_WALLJUMPER| -      SCA_FOVWARPS|SCA_ALIENSENSE,                  //int     abilities; -    WP_ALEVEL2,                                     //weapon_t  startWeapon -    0.0f,                                           //float   buildDist; -    90,                                             //int     fov; -    0.001f,                                         //float   bob; -    1.5f,                                           //float   bobCycle; -    80,                                             //int     steptime; -    LEVEL2_SPEED,                                   //float   speed; -    10.0f,                                          //float   acceleration; -    2.0f,                                           //float   airAcceleration; -    6.0f,                                           //float   friction; -    100.0f,                                         //float   stopSpeed; -    400.0f,                                         //float   jumpMagnitude; -    0.8f,                                           //float   knockbackScale; -    { PCL_ALIEN_LEVEL3, PCL_ALIEN_LEVEL2_UPG, PCL_NONE },   //int     children[ 3 ]; -    LEVEL2_COST,                                    //int     cost; -    LEVEL2_VALUE                                    //int     value; -  }, -  { -    PCL_ALIEN_LEVEL2_UPG,                           //int     classnum; -    "level2upg",                                    //char    *classname; -    "Chimera Upgrade",                              //char    *humanname; -    "tarantula",                                    //char    *modelname; -    0.9f,                                           //float   modelScale; -    "red",                                          //char    *skinname; -    1.0f,                                           //float   shadowScale; -    "alien_general_hud",                            //char    *hudname; -    ( 1 << S2 )|( 1 << S3 ),                        //int  stages -    { -24, -24, -24 },                              //vec3_t  mins; -    { 24, 24, 24 },                                 //vec3_t  maxs; -    { 24, 24, 24 },                                 //vec3_t  crouchmaxs; -    { -24, -24, -4 },                               //vec3_t  deadmins; -    { 24, 24, 4 },                                  //vec3_t  deadmaxs; -    0.0f,                                           //float   zOffset -    12, 12,                                         //int     viewheight, crouchviewheight; -    LEVEL2_UPG_HEALTH,                              //int     health; -    0.0f,                                           //float   fallDamage; -    LEVEL2_UPG_REGEN,                               //int     regenRate; -    SCA_NOWEAPONDRIFT|SCA_WALLJUMPER| -      SCA_FOVWARPS|SCA_ALIENSENSE,                  //int     abilities; -    WP_ALEVEL2_UPG,                                 //weapon_t  startWeapon -    0.0f,                                           //float   buildDist; -    90,                                             //int     fov; -    0.001f,                                         //float   bob; -    1.5f,                                           //float   bobCycle; -    80,                                             //int     steptime; -    LEVEL2_UPG_SPEED,                               //float   speed; -    10.0f,                                          //float   acceleration; -    2.0f,                                           //float   airAcceleration; -    6.0f,                                           //float   friction; -    100.0f,                                         //float   stopSpeed; -    400.0f,                                         //float   jumpMagnitude; -    0.7f,                                           //float   knockbackScale; -    { PCL_ALIEN_LEVEL3, PCL_NONE, PCL_NONE },       //int     children[ 3 ]; -    LEVEL2_UPG_COST,                                //int     cost; -    LEVEL2_UPG_VALUE                                //int     value; -  }, -  { -    PCL_ALIEN_LEVEL3,                               //int     classnum; -    "level3",                                       //char    *classname; -    "Dragoon",                                      //char    *humanname; -    "prowl",                                        //char    *modelname; -    1.0f,                                           //float   modelScale; -    "default",                                      //char    *skinname; -    1.0f,                                           //float   shadowScale; -    "alien_general_hud",                            //char    *hudname; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ),            //int  stages -    { -32, -32, -21 },                              //vec3_t  mins; -    { 32, 32, 21 },                                 //vec3_t  maxs; -    { 32, 32, 21 },                                 //vec3_t  crouchmaxs; -    { -32, -32, -4 },                               //vec3_t  deadmins; -    { 32, 32, 4 },                                  //vec3_t  deadmaxs; -    0.0f,                                           //float   zOffset -    24, 24,                                         //int     viewheight, crouchviewheight; -    LEVEL3_HEALTH,                                  //int     health; -    0.0f,                                           //float   fallDamage; -    LEVEL3_REGEN,                                   //int     regenRate; -    SCA_NOWEAPONDRIFT| -      SCA_FOVWARPS|SCA_ALIENSENSE,                  //int     abilities; -    WP_ALEVEL3,                                     //weapon_t  startWeapon -    0.0f,                                           //float   buildDist; -    110,                                            //int     fov; -    0.0005f,                                        //float   bob; -    1.3f,                                           //float   bobCycle; -    90,                                             //int     steptime; -    LEVEL3_SPEED,                                   //float   speed; -    10.0f,                                          //float   acceleration; -    1.0f,                                           //float   airAcceleration; -    6.0f,                                           //float   friction; -    200.0f,                                         //float   stopSpeed; -    270.0f,                                         //float   jumpMagnitude; -    0.5f,                                           //float   knockbackScale; -    { PCL_ALIEN_LEVEL4, PCL_ALIEN_LEVEL3_UPG, PCL_NONE },   //int     children[ 3 ]; -    LEVEL3_COST,                                    //int     cost; -    LEVEL3_VALUE                                    //int     value; -  }, -  { -    PCL_ALIEN_LEVEL3_UPG,                           //int     classnum; -    "level3upg",                                    //char    *classname; -    "Dragoon Upgrade",                              //char    *humanname; -    "prowl",                                        //char    *modelname; -    1.0f,                                           //float   modelScale; -    "default",                                      //char    *skinname; -    1.0f,                                           //float   shadowScale; -    "alien_general_hud",                            //char    *hudname; -    ( 1 << S3 ),                                    //int  stages -    { -32, -32, -21 },                              //vec3_t  mins; -    { 32, 32, 21 },                                 //vec3_t  maxs; -    { 32, 32, 21 },                                 //vec3_t  crouchmaxs; -    { -32, -32, -4 },                               //vec3_t  deadmins; -    { 32, 32, 4 },                                  //vec3_t  deadmaxs; -    0.0f,                                           //float   zOffset -    27, 27,                                         //int     viewheight, crouchviewheight; -    LEVEL3_UPG_HEALTH,                              //int     health; -    0.0f,                                           //float   fallDamage; -    LEVEL3_UPG_REGEN,                               //int     regenRate; -    SCA_NOWEAPONDRIFT| -      SCA_FOVWARPS|SCA_ALIENSENSE,                  //int     abilities; -    WP_ALEVEL3_UPG,                                 //weapon_t  startWeapon -    0.0f,                                           //float   buildDist; -    110,                                            //int     fov; -    0.0005f,                                        //float   bob; -    1.3f,                                           //float   bobCycle; -    90,                                             //int     steptime; -    LEVEL3_UPG_SPEED,                               //float   speed; -    10.0f,                                          //float   acceleration; -    1.0f,                                           //float   airAcceleration; -    6.0f,                                           //float   friction; -    200.0f,                                         //float   stopSpeed; -    270.0f,                                         //float   jumpMagnitude; -    0.4f,                                           //float   knockbackScale; -    { PCL_ALIEN_LEVEL4, PCL_NONE, PCL_NONE },       //int     children[ 3 ]; -    LEVEL3_UPG_COST,                                //int     cost; -    LEVEL3_UPG_VALUE                                //int     value; -  }, -  { -    PCL_ALIEN_LEVEL4,                               //int     classnum; -    "level4",                                       //char    *classname; -    "Big Mofo",                                     //char    *humanname; -    "mofo",                                         //char    *modelname; -    1.0f,                                           //float   modelScale; -    "default",                                      //char    *skinname; -    2.0f,                                           //float   shadowScale; -    "alien_general_hud",                            //char    *hudname; -    ( 1 << S3 ),                                    //int  stages -    { -30, -30, -20 },                              //vec3_t  mins; -    { 30, 30, 20 },                                 //vec3_t  maxs; -    { 30, 30, 20 },                                 //vec3_t  crouchmaxs; -    { -15, -15, -4 },                               //vec3_t  deadmins; -    { 15, 15, 4 },                                  //vec3_t  deadmaxs; -    0.0f,                                           //float   zOffset -    35, 35,                                         //int     viewheight, crouchviewheight; -    LEVEL4_HEALTH,                                  //int     health; -    0.0f,                                           //float   fallDamage; -    LEVEL4_REGEN,                                   //int     regenRate; -    SCA_NOWEAPONDRIFT| -      SCA_FOVWARPS|SCA_ALIENSENSE,                  //int     abilities; -    WP_ALEVEL4,                                     //weapon_t  startWeapon -    0.0f,                                           //float   buildDist; -    90,                                             //int     fov; -    0.001f,                                         //float   bob; -    1.1f,                                           //float   bobCycle; -    100,                                            //int     steptime; -    LEVEL4_SPEED,                                   //float   speed; -    10.0f,                                          //float   acceleration; -    1.0f,                                           //float   airAcceleration; -    6.0f,                                           //float   friction; -    100.0f,                                         //float   stopSpeed; -    170.0f,                                         //float   jumpMagnitude; -    0.1f,                                           //float   knockbackScale; -    { PCL_NONE, PCL_NONE, PCL_NONE },               //int     children[ 3 ]; -    LEVEL4_COST,                                    //int     cost; -    LEVEL4_VALUE                                    //int     value; -  }, -  { -    PCL_HUMAN,                                      //int     classnum; -    "human_base",                                   //char    *classname; -    "Human",                                        //char    *humanname; -    "sarge",                                        //char    *modelname; -    1.0f,                                           //float   modelScale; -    "default",                                      //char    *skinname; -    1.0f,                                           //float   shadowScale; -    "human_hud",                                    //char    *hudname; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ),            //int  stages -    { -15, -15, -24 },                              //vec3_t  mins; -    { 15, 15, 32 },                                 //vec3_t  maxs; -    { 15, 15, 16 },                                 //vec3_t  crouchmaxs; -    { -15, -15, -4 },                               //vec3_t  deadmins; -    { 15, 15, 4 },                                  //vec3_t  deadmaxs; -    0.0f,                                           //float   zOffset -    26, 12,                                         //int     viewheight, crouchviewheight; -    100,                                            //int     health; -    1.0f,                                           //float   fallDamage; -    0,                                              //int     regenRate; -    SCA_TAKESFALLDAMAGE| -      SCA_CANUSELADDERS,                            //int     abilities; -    WP_NONE, //special-cased in g_client.c          //weapon_t  startWeapon -    110.0f,                                         //float   buildDist; -    90,                                             //int     fov; -    0.002f,                                         //float   bob; -    1.0f,                                           //float   bobCycle; -    100,                                            //int     steptime; -    1.0f,                                           //float   speed; -    10.0f,                                          //float   acceleration; -    1.0f,                                           //float   airAcceleration; -    6.0f,                                           //float   friction; -    100.0f,                                         //float   stopSpeed; -    220.0f,                                         //float   jumpMagnitude; -    1.0f,                                           //float   knockbackScale; -    { PCL_NONE, PCL_NONE, PCL_NONE },               //int     children[ 3 ]; -    0,                                              //int     cost; -    0                                               //int     value; -  }, -  { -    //this isn't a real class, but a dummy to force the client to precache the model -    //FIXME: one day do this in a less hacky fashion -    PCL_HUMAN_BSUIT, "human_bsuit", "bsuit", - -    "keel", -    1.0f, -    "default", -    1.0f, - -    "bsuit", ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), { 0, 0, 0 }, { 0, 0, 0, }, -    { 0, 0, 0, }, { 0, 0, 0, }, { 0, 0, 0, }, 0.0f, 0, 0, 0, 0.0f, 0, 0, WP_NONE, 0.0f, 0, -    0.0f, 1.0f, 0, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 270.0f, 1.0f, { PCL_NONE, PCL_NONE, PCL_NONE }, 0, 0 -  } -}; - -int   bg_numPclasses = sizeof( bg_classList ) / sizeof( bg_classList[ 0 ] ); - -//separate from bg_classList to work around char struct init bug -classAttributeOverrides_t bg_classOverrideList[ PCL_NUM_CLASSES ]; - -/* -============== -BG_FindClassNumForName -============== -*/ -int BG_FindClassNumForName( char *name ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( !Q_stricmp( bg_classList[ i ].className, name ) ) -      return bg_classList[ i ].classNum; -  } - -  //wimp out -  return PCL_NONE; -} - -/* -============== -BG_FindNameForClassNum -============== -*/ -char *BG_FindNameForClassNum( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -      return bg_classList[ i ].className; -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindNameForClassNum\n" ); -  //wimp out -  return 0; -} - -/* -============== -BG_FindHumanNameForClassNum -============== -*/ -char *BG_FindHumanNameForClassNum( int pclass ) -{ -  int i; - -  if( bg_classOverrideList[ pclass ].humanName[ 0 ] != 0 ) -    return bg_classOverrideList[ pclass ].humanName; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -      return bg_classList[ i ].humanName; -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindHumanNameForClassNum\n" ); -  //wimp out -  return 0; -} - -/* -============== -BG_FindModelNameForClass -============== -*/ -char *BG_FindModelNameForClass( int pclass ) -{ -  int i; - -  if( bg_classOverrideList[ pclass ].modelName[ 0 ] != 0 ) -    return bg_classOverrideList[ pclass ].modelName; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -      return bg_classList[ i ].modelName; -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindModelNameForClass\n" ); -  //note: must return a valid modelName! -  return bg_classList[ 0 ].modelName; -} - -/* -============== -BG_FindModelScaleForClass -============== -*/ -float BG_FindModelScaleForClass( int pclass ) -{ -  int i; - -  if( bg_classOverrideList[ pclass ].modelScale != 0.0f ) -    return bg_classOverrideList[ pclass ].modelScale; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].modelScale; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindModelScaleForClass( %d )\n", pclass ); -  return 1.0f; -} - -/* -============== -BG_FindSkinNameForClass -============== -*/ -char *BG_FindSkinNameForClass( int pclass ) -{ -  int i; - -  if( bg_classOverrideList[ pclass ].skinName[ 0 ] != 0 ) -    return bg_classOverrideList[ pclass ].skinName; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -      return bg_classList[ i ].skinName; -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindSkinNameForClass\n" ); -  //note: must return a valid modelName! -  return bg_classList[ 0 ].skinName; -} - -/* -============== -BG_FindShadowScaleForClass -============== -*/ -float BG_FindShadowScaleForClass( int pclass ) -{ -  int i; - -  if( bg_classOverrideList[ pclass ].shadowScale != 0.0f ) -    return bg_classOverrideList[ pclass ].shadowScale; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].shadowScale; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindShadowScaleForClass( %d )\n", pclass ); -  return 1.0f; -} - -/* -============== -BG_FindHudNameForClass -============== -*/ -char *BG_FindHudNameForClass( int pclass ) -{ -  int i; - -  if( bg_classOverrideList[ pclass ].hudName[ 0 ] != 0 ) -    return bg_classOverrideList[ pclass ].hudName; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -      return bg_classList[ i ].hudName; -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindHudNameForClass\n" ); -  //note: must return a valid hudName! -  return bg_classList[ 0 ].hudName; -} - -/* -============== -BG_FindStagesForClass -============== -*/ -qboolean BG_FindStagesForClass( int pclass, stage_t stage ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      if( bg_classList[ i ].stages & ( 1 << stage ) ) -        return qtrue; -      else -        return qfalse; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStagesForClass\n" ); -  return qfalse; -} - -/* -============== -BG_FindBBoxForClass -============== -*/ -void BG_FindBBoxForClass( int pclass, vec3_t mins, vec3_t maxs, vec3_t cmaxs, vec3_t dmins, vec3_t dmaxs ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      if( mins != NULL ) -      { -        VectorCopy( bg_classList[ i ].mins, mins ); - -        if( VectorLength( bg_classOverrideList[ pclass ].mins ) ) -          VectorCopy( bg_classOverrideList[ pclass ].mins, mins ); -      } - -      if( maxs != NULL ) -      { -        VectorCopy( bg_classList[ i ].maxs, maxs ); - -        if( VectorLength( bg_classOverrideList[ pclass ].maxs ) ) -          VectorCopy( bg_classOverrideList[ pclass ].maxs, maxs ); -      } - -      if( cmaxs != NULL ) -      { -        VectorCopy( bg_classList[ i ].crouchMaxs, cmaxs ); - -        if( VectorLength( bg_classOverrideList[ pclass ].crouchMaxs ) ) -          VectorCopy( bg_classOverrideList[ pclass ].crouchMaxs, cmaxs ); -      } - -      if( dmins != NULL ) -      { -        VectorCopy( bg_classList[ i ].deadMins, dmins ); - -        if( VectorLength( bg_classOverrideList[ pclass ].deadMins ) ) -          VectorCopy( bg_classOverrideList[ pclass ].deadMins, dmins ); -      } - -      if( dmaxs != NULL ) -      { -        VectorCopy( bg_classList[ i ].deadMaxs, dmaxs ); - -        if( VectorLength( bg_classOverrideList[ pclass ].deadMaxs ) ) -          VectorCopy( bg_classOverrideList[ pclass ].deadMaxs, dmaxs ); -      } - -      return; -    } -  } - -  if( mins != NULL ) -    VectorCopy( bg_classList[ 0 ].mins,        mins ); - -  if( maxs != NULL ) -    VectorCopy( bg_classList[ 0 ].maxs,        maxs ); - -  if( cmaxs != NULL ) -    VectorCopy( bg_classList[ 0 ].crouchMaxs,  cmaxs ); - -  if( dmins != NULL ) -    VectorCopy( bg_classList[ 0 ].deadMins,    dmins ); - -  if( dmaxs != NULL ) -    VectorCopy( bg_classList[ 0 ].deadMaxs,    dmaxs ); -} - -/* -============== -BG_FindZOffsetForClass -============== -*/ -float BG_FindZOffsetForClass( int pclass ) -{ -  int i; - -  if( bg_classOverrideList[ pclass ].zOffset != 0.0f ) -    return bg_classOverrideList[ pclass ].zOffset; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].zOffset; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindZOffsetForClass\n" ); -  return 0.0f; -} - -/* -============== -BG_FindViewheightForClass -============== -*/ -void BG_FindViewheightForClass( int pclass, int *viewheight, int *cViewheight ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      if( viewheight != NULL ) -        *viewheight = bg_classList[ i ].viewheight; - -      if( cViewheight != NULL ) -        *cViewheight = bg_classList[ i ].crouchViewheight; - -      return; -    } -  } - -  if( viewheight != NULL ) -    *viewheight = bg_classList[ 0 ].viewheight; - -  if( cViewheight != NULL ) -    *cViewheight = bg_classList[ 0 ].crouchViewheight; -} - -/* -============== -BG_FindHealthForClass -============== -*/ -int BG_FindHealthForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].health; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindHealthForClass\n" ); -  return 100; -} - -/* -============== -BG_FindFallDamageForClass -============== -*/ -float BG_FindFallDamageForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].fallDamage; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindFallDamageForClass\n" ); -  return 100; -} - -/* -============== -BG_FindRegenRateForClass -============== -*/ -int BG_FindRegenRateForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].regenRate; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindRegenRateForClass\n" ); -  return 0; -} - -/* -============== -BG_FindFovForClass -============== -*/ -int BG_FindFovForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].fov; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindFovForClass\n" ); -  return 90; -} - -/* -============== -BG_FindBobForClass -============== -*/ -float BG_FindBobForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].bob; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindBobForClass\n" ); -  return 0.002; -} - -/* -============== -BG_FindBobCycleForClass -============== -*/ -float BG_FindBobCycleForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].bobCycle; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindBobCycleForClass\n" ); -  return 1.0f; -} - -/* -============== -BG_FindSpeedForClass -============== -*/ -float BG_FindSpeedForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].speed; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindSpeedForClass\n" ); -  return 1.0f; -} - -/* -============== -BG_FindAccelerationForClass -============== -*/ -float BG_FindAccelerationForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].acceleration; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindAccelerationForClass\n" ); -  return 10.0f; -} - -/* -============== -BG_FindAirAccelerationForClass -============== -*/ -float BG_FindAirAccelerationForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].airAcceleration; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindAirAccelerationForClass\n" ); -  return 1.0f; -} - -/* -============== -BG_FindFrictionForClass -============== -*/ -float BG_FindFrictionForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].friction; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindFrictionForClass\n" ); -  return 6.0f; -} - -/* -============== -BG_FindStopSpeedForClass -============== -*/ -float BG_FindStopSpeedForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].stopSpeed; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStopSpeedForClass\n" ); -  return 100.0f; -} - -/* -============== -BG_FindJumpMagnitudeForClass -============== -*/ -float BG_FindJumpMagnitudeForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].jumpMagnitude; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindJumpMagnitudeForClass\n" ); -  return 270.0f; -} - -/* -============== -BG_FindKnockbackScaleForClass -============== -*/ -float BG_FindKnockbackScaleForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].knockbackScale; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindKnockbackScaleForClass\n" ); -  return 1.0f; -} - -/* -============== -BG_FindSteptimeForClass -============== -*/ -int BG_FindSteptimeForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].steptime; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindSteptimeForClass\n" ); -  return 200; -} - -/* -============== -BG_ClassHasAbility -============== -*/ -qboolean BG_ClassHasAbility( int pclass, int ability ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return ( bg_classList[ i ].abilities & ability ); -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindStartWeaponForClass -============== -*/ -weapon_t BG_FindStartWeaponForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].startWeapon; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStartWeaponForClass\n" ); -  return WP_NONE; -} - -/* -============== -BG_FindBuildDistForClass -============== -*/ -float BG_FindBuildDistForClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].buildDist; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindBuildDistForClass\n" ); -  return 0.0f; -} - -/* -============== -BG_ClassCanEvolveFromTo -============== -*/ -int BG_ClassCanEvolveFromTo( int fclass, int tclass, int credits, int num ) -{ -  int i, j, cost; - -  cost = BG_FindCostOfClass( tclass ); - -  //base case -  if( credits < cost ) -    return -1; - -  if( fclass == PCL_NONE || tclass == PCL_NONE ) -    return -1; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == fclass ) -    { -      for( j = 0; j < 3; j++ ) -        if( bg_classList[ i ].children[ j ] == tclass ) -          return num + cost; - -      for( j = 0; j < 3; j++ ) -      { -        int sub; - -        cost = BG_FindCostOfClass( bg_classList[ i ].children[ j ] ); -        sub = BG_ClassCanEvolveFromTo( bg_classList[ i ].children[ j ], -                                       tclass, credits - cost, num + cost ); -        if( sub >= 0 ) -          return sub; -      } - -      return -1; //may as well return by this point -    } -  } - -  return -1; -} - -/* -============== -BG_FindValueOfClass -============== -*/ -int BG_FindValueOfClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].value; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindValueOfClass\n" ); -  return 0; -} - -/* -============== -BG_FindCostOfClass -============== -*/ -int BG_FindCostOfClass( int pclass ) -{ -  int i; - -  for( i = 0; i < bg_numPclasses; i++ ) -  { -    if( bg_classList[ i ].classNum == pclass ) -    { -      return bg_classList[ i ].cost; -    } -  } - -  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindCostOfClass\n" ); -  return 0; -} - -/* -============== -BG_FindOverrideForClass -============== -*/ -static classAttributeOverrides_t *BG_FindOverrideForClass( int pclass ) -{ -  return &bg_classOverrideList[ pclass ]; -} - -/* -====================== -BG_ParseClassFile - -Parses a configuration file describing a class -====================== -*/ -static qboolean BG_ParseClassFile( const char *filename, classAttributeOverrides_t *cao ) -{ -  char          *text_p; -  int           i; -  int           len; -  char          *token; -  char          text[ 20000 ]; -  fileHandle_t  f; -  float         scale = 0.0f; - - -  // load the file -  len = trap_FS_FOpenFile( filename, &f, FS_READ ); -  if( len <= 0 ) -    return qfalse; - -  if( len >= sizeof( text ) - 1 ) -  { -    Com_Printf( S_COLOR_RED "ERROR: Class file %s too long\n", filename ); -    return qfalse; -  } - -  trap_FS_Read( text, len, f ); -  text[ len ] = 0; -  trap_FS_FCloseFile( f ); - -  // parse the text -  text_p = text; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( &text_p ); - -    if( !token ) -      break; - -    if( !Q_stricmp( token, "" ) ) -      break; - -    if( !Q_stricmp( token, "model" ) ) -    { -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      Q_strncpyz( cao->modelName, token, sizeof( cao->modelName ) ); - -      continue; -    } -    else if( !Q_stricmp( token, "skin" ) ) -    { -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      Q_strncpyz( cao->skinName, token, sizeof( cao->skinName ) ); - -      continue; -    } -    else if( !Q_stricmp( token, "hud" ) ) -    { -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      Q_strncpyz( cao->hudName, token, sizeof( cao->hudName ) ); - -      continue; -    } -    else if( !Q_stricmp( token, "modelScale" ) ) -    { -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      scale = atof( token ); - -      if( scale < 0.0f ) -        scale = 0.0f; - -      cao->modelScale = scale; - -      continue; -    } -    else if( !Q_stricmp( token, "shadowScale" ) ) -    { -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      scale = atof( token ); - -      if( scale < 0.0f ) -        scale = 0.0f; - -      cao->shadowScale = scale; - -      continue; -    } -    else if( !Q_stricmp( token, "mins" ) ) -    { -      for( i = 0; i <= 2; i++ ) -      { -        token = COM_Parse( &text_p ); -        if( !token ) -          break; - -        cao->mins[ i ] = atof( token ); -      } - -      continue; -    } -    else if( !Q_stricmp( token, "maxs" ) ) -    { -      for( i = 0; i <= 2; i++ ) -      { -        token = COM_Parse( &text_p ); -        if( !token ) -          break; - -        cao->maxs[ i ] = atof( token ); -      } - -      continue; -    } -    else if( !Q_stricmp( token, "deadMins" ) ) -    { -      for( i = 0; i <= 2; i++ ) -      { -        token = COM_Parse( &text_p ); -        if( !token ) -          break; - -        cao->deadMins[ i ] = atof( token ); -      } - -      continue; -    } -    else if( !Q_stricmp( token, "deadMaxs" ) ) -    { -      for( i = 0; i <= 2; i++ ) -      { -        token = COM_Parse( &text_p ); -        if( !token ) -          break; - -        cao->deadMaxs[ i ] = atof( token ); -      } - -      continue; -    } -    else if( !Q_stricmp( token, "crouchMaxs" ) ) -    { -      for( i = 0; i <= 2; i++ ) -      { -        token = COM_Parse( &text_p ); -        if( !token ) -          break; - -        cao->crouchMaxs[ i ] = atof( token ); -      } - -      continue; -    } -    else if( !Q_stricmp( token, "zOffset" ) ) -    { -      float offset; - -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      offset = atof( token ); - -      cao->zOffset = offset; - -      continue; -    } -    else if( !Q_stricmp( token, "name" ) ) -    { -      token = COM_Parse( &text_p ); -      if( !token ) -        break; - -      Q_strncpyz( cao->humanName, token, sizeof( cao->humanName ) ); - -      continue; -    } - - -    Com_Printf( S_COLOR_RED "ERROR: unknown token '%s'\n", token ); -    return qfalse; -  } - -  return qtrue; -} - -/* -=============== -BG_InitClassOverrides - -Set any overrides specfied by file -=============== -*/ -void BG_InitClassOverrides( void ) -{ -  int                       i; -  classAttributeOverrides_t *cao; - -  for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ ) -  { -    cao = BG_FindOverrideForClass( i ); - -    BG_ParseClassFile( va( "overrides/classes/%s.cfg", BG_FindNameForClassNum( i ) ), cao ); -  } -} - -//////////////////////////////////////////////////////////////////////////////// - -weaponAttributes_t bg_weapons[ ] = -{ -  { -    WP_BLASTER,           //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    0,                    //int       slots; -    "blaster",            //char      *weaponName; -    "Blaster",            //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    BLASTER_REPEAT,       //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_MACHINEGUN,        //int       weaponNum; -    RIFLE_PRICE,          //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "rifle",              //char      *weaponName; -    "Rifle",              //char      *weaponHumanName; -    RIFLE_CLIPSIZE,       //int       maxAmmo; -    RIFLE_MAXCLIPS,       //int       maxClips; -    qfalse,               //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    RIFLE_REPEAT,         //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    RIFLE_RELOAD,         //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_SHOTGUN,           //int       weaponNum; -    SHOTGUN_PRICE,        //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "shotgun",            //char      *weaponName; -    "Shotgun",            //char      *weaponHumanName; -    SHOTGUN_SHELLS,       //int       maxAmmo; -    SHOTGUN_MAXCLIPS,     //int       maxClips; -    qfalse,               //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    SHOTGUN_REPEAT,       //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    SHOTGUN_RELOAD,       //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_FLAMER,            //int       weaponNum; -    FLAMER_PRICE,         //int       price; -    ( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "flamer",             //char      *weaponName; -    "Flame Thrower",      //char      *weaponHumanName; -    FLAMER_GAS,           //int       maxAmmo; -    0,                    //int       maxClips; -    qfalse,               //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    FLAMER_REPEAT,        //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_CHAINGUN,          //int       weaponNum; -    CHAINGUN_PRICE,       //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "chaingun",           //char      *weaponName; -    "Chaingun",           //char      *weaponHumanName; -    CHAINGUN_BULLETS,     //int       maxAmmo; -    0,                    //int       maxClips; -    qfalse,               //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    CHAINGUN_REPEAT,      //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_MASS_DRIVER,       //int       weaponNum; -    MDRIVER_PRICE,        //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "mdriver",            //char      *weaponName; -    "Mass Driver",        //char      *weaponHumanName; -    MDRIVER_CLIPSIZE,     //int       maxAmmo; -    MDRIVER_MAXCLIPS,     //int       maxClips; -    qfalse,               //int       infiniteAmmo; -    qtrue,                //int       usesEnergy; -    MDRIVER_REPEAT,       //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    MDRIVER_RELOAD,       //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qtrue,                //qboolean  canZoom; -    20.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_PULSE_RIFLE,       //int       weaponNum; -    PRIFLE_PRICE,         //int       price; -    ( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "prifle",             //char      *weaponName; -    "Pulse Rifle",        //char      *weaponHumanName; -    PRIFLE_CLIPS,         //int       maxAmmo; -    PRIFLE_MAXCLIPS,      //int       maxClips; -    qfalse,               //int       infiniteAmmo; -    qtrue,                //int       usesEnergy; -    PRIFLE_REPEAT,        //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    PRIFLE_RELOAD,        //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_LUCIFER_CANNON,    //int       weaponNum; -    LCANNON_PRICE,        //int       price; -    ( 1 << S3 ),          //int  stages -    SLOT_WEAPON,          //int       slots; -    "lcannon",            //char      *weaponName; -    "Lucifer Cannon",     //char      *weaponHumanName; -    LCANNON_AMMO,         //int       maxAmmo; -    0,                    //int       maxClips; -    qfalse,               //int       infiniteAmmo; -    qtrue,                //int       usesEnergy; -    LCANNON_REPEAT,       //int       repeatRate1; -    LCANNON_CHARGEREPEAT, //int       repeatRate2; -    0,                    //int       repeatRate3; -    LCANNON_RELOAD,       //int       reloadTime; -    qtrue,                //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_LAS_GUN,           //int       weaponNum; -    LASGUN_PRICE,         //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "lgun",               //char      *weaponName; -    "Las Gun",            //char      *weaponHumanName; -    LASGUN_AMMO,          //int       maxAmmo; -    0,                    //int       maxClips; -    qfalse,               //int       infiniteAmmo; -    qtrue,                //int       usesEnergy; -    LASGUN_REPEAT,        //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    LASGUN_RELOAD,        //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_PAIN_SAW,          //int       weaponNum; -    PAINSAW_PRICE,        //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "psaw",               //char      *weaponName; -    "Pain Saw",           //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    PAINSAW_REPEAT,       //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_GRENADE,           //int       weaponNum; -    GRENADE_PRICE,        //int       price; -    ( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_NONE,            //int       slots; -    "grenade",            //char      *weaponName; -    "Grenade",            //char      *weaponHumanName; -    1,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qfalse,               //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    GRENADE_REPEAT,       //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_HBUILD,            //int       weaponNum; -    HBUILD_PRICE,         //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "ckit",               //char      *weaponName; -    "Construction Kit",   //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    HBUILD_REPEAT,        //int       repeatRate1; -    HBUILD_REPEAT,        //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qtrue,                //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    HBUILD_DELAY,         //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_HBUILD2,           //int       weaponNum; -    HBUILD2_PRICE,        //int       price; -    ( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "ackit",              //char      *weaponName; -    "Adv Construction Kit",//char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    HBUILD2_REPEAT,       //int       repeatRate1; -    HBUILD2_REPEAT,       //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qtrue,                //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    HBUILD2_DELAY,        //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_ABUILD,            //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "abuild",             //char      *weaponName; -    "Alien build weapon", //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    ABUILDER_BUILD_REPEAT,//int       repeatRate1; -    ABUILDER_BUILD_REPEAT,//int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qtrue,                //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    ABUILDER_BASE_DELAY,  //int       buildDelay; -    WUT_ALIENS            //WUTeam_t  team; -  }, -  { -    WP_ABUILD2,           //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "abuild2",            //char      *weaponName; -    "Alien build weapon2",//char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    ABUILDER_BUILD_REPEAT,//int       repeatRate1; -    ABUILDER_CLAW_REPEAT, //int       repeatRate2; -    ABUILDER_BLOB_REPEAT, //int       repeatRate3; -    0,                    //int       reloadTime; -    qtrue,                //qboolean  hasAltMode; -    qtrue,                //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qtrue,                //qboolean  purchasable; -    ABUILDER_ADV_DELAY,   //int       buildDelay; -    WUT_ALIENS            //WUTeam_t  team; -  }, -  { -    WP_ALEVEL0,           //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "bite",               //char      *weaponName; -    "Bite",               //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    LEVEL0_BITE_REPEAT,  //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_ALIENS            //WUTeam_t  team; -  }, -  { -    WP_ALEVEL3,           //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "pounce",             //char      *weaponName; -    "Claw and pounce",    //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    LEVEL3_CLAW_REPEAT,  //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_ALIENS            //WUTeam_t  team; -  }, -  { -    WP_ALEVEL3_UPG,       //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "pounce_upgrade",     //char      *weaponName; -    "Claw and pounce (upgrade)", //char      *weaponHumanName; -    3,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    LEVEL3_CLAW_U_REPEAT,//int       repeatRate1; -    0,                    //int       repeatRate2; -    LEVEL3_BOUNCEBALL_REPEAT,//int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qtrue,                //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_ALIENS            //WUTeam_t  team; -  }, -  { -    WP_ALEVEL1,             //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "grabandclaw",        //char      *weaponName; -    "Claws",              //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    LEVEL1_CLAW_REPEAT,    //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_ALIENS            //WUTeam_t  team; -  }, -  { -    WP_ALEVEL1_UPG,         //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "grabandclaw_upgrade",//char      *weaponName; -    "Claws Upgrade",      //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    LEVEL1_CLAW_U_REPEAT,  //int       repeatRate1; -    LEVEL1_PCLOUD_REPEAT,  //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qtrue,                //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_ALIENS            //WUTeam_t  team; -  }, -  { -    WP_ALEVEL2,           //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "areazap",            //char      *weaponName; -    "Area Zap",           //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    LEVEL2_CLAW_REPEAT,  //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_ALIENS            //WUTeam_t  team; -  }, -  { -    WP_ALEVEL2_UPG,       //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "directzap",          //char      *weaponName; -    "Directed Zap",       //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    LEVEL2_CLAW_U_REPEAT,//int       repeatRate1; -    LEVEL2_AREAZAP_REPEAT,//int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qtrue,                //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_ALIENS            //WUTeam_t  team; -  }, -  { -    WP_ALEVEL4,           //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "charge",             //char      *weaponName; -    "Charge",             //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    LEVEL4_CLAW_REPEAT,    //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_ALIENS            //WUTeam_t  team; -  }, -  { -    WP_LOCKBLOB_LAUNCHER, //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "lockblob",           //char      *weaponName; -    "Lock Blob",          //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    500,                  //int       repeatRate1; -    500,                  //int       repeatRate2; -    500,                  //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_ALIENS            //WUTeam_t  team; -  }, -  { -    WP_HIVE,              //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "hive",               //char      *weaponName; -    "Hive",               //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    500,                  //int       repeatRate1; -    500,                  //int       repeatRate2; -    500,                  //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_ALIENS            //WUTeam_t  team; -  }, -  { -    WP_MGTURRET,          //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "mgturret",           //char      *weaponName; -    "Machinegun Turret",  //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qfalse,               //int       usesEnergy; -    0,                    //int       repeatRate1; -    0,                    //int       repeatRate2; -    0,                    //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  }, -  { -    WP_TESLAGEN,          //int       weaponNum; -    0,                    //int       price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_WEAPON,          //int       slots; -    "teslagen",           //char      *weaponName; -    "Tesla Generator",    //char      *weaponHumanName; -    0,                    //int       maxAmmo; -    0,                    //int       maxClips; -    qtrue,                //int       infiniteAmmo; -    qtrue,                //int       usesEnergy; -    500,                  //int       repeatRate1; -    500,                  //int       repeatRate2; -    500,                  //int       repeatRate3; -    0,                    //int       reloadTime; -    qfalse,               //qboolean  hasAltMode; -    qfalse,               //qboolean  hasThirdMode; -    qfalse,               //qboolean  canZoom; -    90.0f,                //float     zoomFov; -    qfalse,               //qboolean  purchasable; -    0,                    //int       buildDelay; -    WUT_HUMANS            //WUTeam_t  team; -  } -}; - -int   bg_numWeapons = sizeof( bg_weapons ) / sizeof( bg_weapons[ 0 ] ); - -/* -============== -BG_FindPriceForWeapon -============== -*/ -int BG_FindPriceForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      return bg_weapons[ i ].price; -    } -  } - -  return 100; -} - -/* -============== -BG_FindStagesForWeapon -============== -*/ -qboolean BG_FindStagesForWeapon( int weapon, stage_t stage ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      if( bg_weapons[ i ].stages & ( 1 << stage ) ) -        return qtrue; -      else -        return qfalse; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindSlotsForWeapon -============== -*/ -int BG_FindSlotsForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      return bg_weapons[ i ].slots; -    } -  } - -  return SLOT_WEAPON; -} - -/* -============== -BG_FindNameForWeapon -============== -*/ -char *BG_FindNameForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -      return bg_weapons[ i ].weaponName; -  } - -  //wimp out -  return 0; -} - -/* -============== -BG_FindWeaponNumForName -============== -*/ -int BG_FindWeaponNumForName( char *name ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( !Q_stricmp( bg_weapons[ i ].weaponName, name ) ) -      return bg_weapons[ i ].weaponNum; -  } - -  //wimp out -  return WP_NONE; -} - -/* -============== -BG_FindHumanNameForWeapon -============== -*/ -char *BG_FindHumanNameForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -      return bg_weapons[ i ].weaponHumanName; -  } - -  //wimp out -  return 0; -} - -/* -============== -BG_FindAmmoForWeapon -============== -*/ -void BG_FindAmmoForWeapon( int weapon, int *maxAmmo, int *maxClips ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      if( maxAmmo != NULL ) -        *maxAmmo = bg_weapons[ i ].maxAmmo; -      if( maxClips != NULL ) -        *maxClips = bg_weapons[ i ].maxClips; - -      //no need to keep going -      break; -    } -  } -} - -/* -============== -BG_FindInfinteAmmoForWeapon -============== -*/ -qboolean BG_FindInfinteAmmoForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      return bg_weapons[ i ].infiniteAmmo; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindUsesEnergyForWeapon -============== -*/ -qboolean BG_FindUsesEnergyForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      return bg_weapons[ i ].usesEnergy; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindRepeatRate1ForWeapon -============== -*/ -int BG_FindRepeatRate1ForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -      return bg_weapons[ i ].repeatRate1; -  } - -  return 1000; -} - -/* -============== -BG_FindRepeatRate2ForWeapon -============== -*/ -int BG_FindRepeatRate2ForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -      return bg_weapons[ i ].repeatRate2; -  } - -  return 1000; -} - -/* -============== -BG_FindRepeatRate3ForWeapon -============== -*/ -int BG_FindRepeatRate3ForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -      return bg_weapons[ i ].repeatRate3; -  } - -  return 1000; -} - -/* -============== -BG_FindReloadTimeForWeapon -============== -*/ -int BG_FindReloadTimeForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      return bg_weapons[ i ].reloadTime; -    } -  } - -  return 1000; -} - -/* -============== -BG_WeaponHasAltMode -============== -*/ -qboolean BG_WeaponHasAltMode( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      return bg_weapons[ i ].hasAltMode; -    } -  } - -  return qfalse; -} - -/* -============== -BG_WeaponHasThirdMode -============== -*/ -qboolean BG_WeaponHasThirdMode( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      return bg_weapons[ i ].hasThirdMode; -    } -  } - -  return qfalse; -} - -/* -============== -BG_WeaponCanZoom -============== -*/ -qboolean BG_WeaponCanZoom( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      return bg_weapons[ i ].canZoom; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindZoomFovForWeapon -============== -*/ -float BG_FindZoomFovForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      return bg_weapons[ i ].zoomFov; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindPurchasableForWeapon -============== -*/ -qboolean BG_FindPurchasableForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      return bg_weapons[ i ].purchasable; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindBuildDelayForWeapon -============== -*/ -int BG_FindBuildDelayForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      return bg_weapons[ i ].buildDelay; -    } -  } - -  return 0; -} - -/* -============== -BG_FindTeamForWeapon -============== -*/ -WUTeam_t BG_FindTeamForWeapon( int weapon ) -{ -  int i; - -  for( i = 0; i < bg_numWeapons; i++ ) -  { -    if( bg_weapons[ i ].weaponNum == weapon ) -    { -      return bg_weapons[ i ].team; -    } -  } - -  return WUT_NONE; -} - -//////////////////////////////////////////////////////////////////////////////// - -upgradeAttributes_t bg_upgrades[ ] = -{ -  { -    UP_LIGHTARMOUR,         //int   upgradeNum; -    LIGHTARMOUR_PRICE,      //int   price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_TORSO|SLOT_ARMS|SLOT_LEGS, //int   slots; -    "larmour",              //char  *upgradeName; -    "Light Armour",         //char  *upgradeHumanName; -    "icons/iconu_larmour", -    qtrue,                  //qboolean purchasable -    WUT_HUMANS              //WUTeam_t  team; -  }, -  { -    UP_HELMET,              //int   upgradeNum; -    HELMET_PRICE,           //int   price; -    ( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_HEAD,              //int   slots; -    "helmet",               //char  *upgradeName; -    "Helmet",               //char  *upgradeHumanName; -    "icons/iconu_helmet", -    qtrue,                  //qboolean purchasable -    WUT_HUMANS              //WUTeam_t  team; -  }, -  { -    UP_MEDKIT,              //int   upgradeNum; -    MEDKIT_PRICE,           //int   price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_NONE,              //int   slots; -    "medkit",               //char  *upgradeName; -    "Medkit",               //char  *upgradeHumanName; -    "icons/iconu_atoxin", -    qfalse,                 //qboolean purchasable -    WUT_HUMANS              //WUTeam_t  team; -  }, -  { -    UP_BATTPACK,            //int   upgradeNum; -    BATTPACK_PRICE,         //int   price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_BACKPACK,          //int   slots; -    "battpack",             //char  *upgradeName; -    "Battery Pack",         //char  *upgradeHumanName; -    "icons/iconu_battpack", -    qtrue,                  //qboolean purchasable -    WUT_HUMANS              //WUTeam_t  team; -  }, -  { -    UP_JETPACK,             //int   upgradeNum; -    JETPACK_PRICE,          //int   price; -    ( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_BACKPACK,          //int   slots; -    "jetpack",              //char  *upgradeName; -    "Jet Pack",             //char  *upgradeHumanName; -    "icons/iconu_jetpack", -    qtrue,                  //qboolean purchasable -    WUT_HUMANS              //WUTeam_t  team; -  }, -  { -    UP_BATTLESUIT,          //int   upgradeNum; -    BSUIT_PRICE,            //int   price; -    ( 1 << S3 ),            //int  stages -    SLOT_HEAD|SLOT_TORSO|SLOT_ARMS|SLOT_LEGS|SLOT_BACKPACK, //int   slots; -    "bsuit",                //char  *upgradeName; -    "Battlesuit",           //char  *upgradeHumanName; -    "icons/iconu_bsuit", -    qtrue,                  //qboolean purchasable -    WUT_HUMANS              //WUTeam_t  team; -  }, -  { -    UP_GRENADE,             //int   upgradeNum; -    GRENADE_PRICE,          //int   price; -    ( 1 << S2 )|( 1 << S3 ),//int  stages -    SLOT_NONE,              //int   slots; -    "gren",                 //char  *upgradeName; -    "Grenade",              //char  *upgradeHumanName; -    0, -    qtrue,                  //qboolean purchasable -    WUT_HUMANS              //WUTeam_t  team; -  }, -  { -    UP_AMMO,                //int   upgradeNum; -    0,                      //int   price; -    ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int  stages -    SLOT_NONE,              //int   slots; -    "ammo",                 //char  *upgradeName; -    "Ammunition",           //char  *upgradeHumanName; -    0, -    qtrue,                  //qboolean purchasable -    WUT_HUMANS              //WUTeam_t  team; -  } -}; - -int   bg_numUpgrades = sizeof( bg_upgrades ) / sizeof( bg_upgrades[ 0 ] ); - -/* -============== -BG_FindPriceForUpgrade -============== -*/ -int BG_FindPriceForUpgrade( int upgrade ) -{ -  int i; - -  for( i = 0; i < bg_numUpgrades; i++ ) -  { -    if( bg_upgrades[ i ].upgradeNum == upgrade ) -    { -      return bg_upgrades[ i ].price; -    } -  } - -  return 100; -} - -/* -============== -BG_FindStagesForUpgrade -============== -*/ -qboolean BG_FindStagesForUpgrade( int upgrade, stage_t stage ) -{ -  int i; - -  for( i = 0; i < bg_numUpgrades; i++ ) -  { -    if( bg_upgrades[ i ].upgradeNum == upgrade ) -    { -      if( bg_upgrades[ i ].stages & ( 1 << stage ) ) -        return qtrue; -      else -        return qfalse; -    } -  } - -  return qfalse; -} - -/* -============== -BG_FindSlotsForUpgrade -============== -*/ -int BG_FindSlotsForUpgrade( int upgrade ) -{ -  int i; - -  for( i = 0; i < bg_numUpgrades; i++ ) -  { -    if( bg_upgrades[ i ].upgradeNum == upgrade ) -    { -      return bg_upgrades[ i ].slots; -    } -  } - -  return SLOT_NONE; -} - -/* -============== -BG_FindNameForUpgrade -============== -*/ -char *BG_FindNameForUpgrade( int upgrade ) -{ -  int i; - -  for( i = 0; i < bg_numUpgrades; i++ ) -  { -    if( bg_upgrades[ i ].upgradeNum == upgrade ) -      return bg_upgrades[ i ].upgradeName; -  } - -  //wimp out -  return 0; -} - -/* -============== -BG_FindUpgradeNumForName -============== -*/ -int BG_FindUpgradeNumForName( char *name ) -{ -  int i; - -  for( i = 0; i < bg_numUpgrades; i++ ) -  { -    if( !Q_stricmp( bg_upgrades[ i ].upgradeName, name ) ) -      return bg_upgrades[ i ].upgradeNum; -  } - -  //wimp out -  return UP_NONE; -} - -/* -============== -BG_FindHumanNameForUpgrade -============== -*/ -char *BG_FindHumanNameForUpgrade( int upgrade ) -{ -  int i; - -  for( i = 0; i < bg_numUpgrades; i++ ) -  { -    if( bg_upgrades[ i ].upgradeNum == upgrade ) -      return bg_upgrades[ i ].upgradeHumanName; -  } - -  //wimp out -  return 0; -} - -/* -============== -BG_FindIconForUpgrade -============== -*/ -char *BG_FindIconForUpgrade( int upgrade ) -{ -  int i; - -  for( i = 0; i < bg_numUpgrades; i++ ) -  { -    if( bg_upgrades[ i ].upgradeNum == upgrade ) -      return bg_upgrades[ i ].icon; -  } - -  //wimp out -  return 0; -} - -/* -============== -BG_FindPurchasableForUpgrade -============== -*/ -qboolean BG_FindPurchasableForUpgrade( int upgrade ) -{ -  int i; - -  for( i = 0; i < bg_numUpgrades; i++ ) -  { -    if( bg_upgrades[ i ].upgradeNum == upgrade ) -      return bg_upgrades[ i ].purchasable; -  } - -  return qfalse; -} - -/* -============== -BG_FindTeamForUpgrade -============== -*/ -WUTeam_t BG_FindTeamForUpgrade( int upgrade ) -{ -  int i; - -  for( i = 0; i < bg_numUpgrades; i++ ) -  { -    if( bg_upgrades[ i ].upgradeNum == upgrade ) -    { -      return bg_upgrades[ i ].team; -    } -  } - -  return WUT_NONE; -} - -//////////////////////////////////////////////////////////////////////////////// - -/* -================ -BG_EvaluateTrajectory - -================ -*/ -void BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result ) -{ -  float   deltaTime; -  float   phase; - -  switch( tr->trType ) -  { -    case TR_STATIONARY: -    case TR_INTERPOLATE: -      VectorCopy( tr->trBase, result ); -      break; - -    case TR_LINEAR: -      deltaTime = ( atTime - tr->trTime ) * 0.001;  // milliseconds to seconds -      VectorMA( tr->trBase, deltaTime, tr->trDelta, result ); -      break; - -    case TR_SINE: -      deltaTime = ( atTime - tr->trTime ) / (float)tr->trDuration; -      phase = sin( deltaTime * M_PI * 2 ); -      VectorMA( tr->trBase, phase, tr->trDelta, result ); -      break; - -    case TR_LINEAR_STOP: -      if( atTime > tr->trTime + tr->trDuration ) -        atTime = tr->trTime + tr->trDuration; - -      deltaTime = ( atTime - tr->trTime ) * 0.001;  // milliseconds to seconds -      if( deltaTime < 0 ) -        deltaTime = 0; - -      VectorMA( tr->trBase, deltaTime, tr->trDelta, result ); -      break; - -    case TR_GRAVITY: -      deltaTime = ( atTime - tr->trTime ) * 0.001;  // milliseconds to seconds -      VectorMA( tr->trBase, deltaTime, tr->trDelta, result ); -      result[ 2 ] -= 0.5 * DEFAULT_GRAVITY * deltaTime * deltaTime;   // FIXME: local gravity... -      break; - -    case TR_BUOYANCY: -      deltaTime = ( atTime - tr->trTime ) * 0.001;  // milliseconds to seconds -      VectorMA( tr->trBase, deltaTime, tr->trDelta, result ); -      result[ 2 ] += 0.5 * DEFAULT_GRAVITY * deltaTime * deltaTime;   // FIXME: local gravity... -      break; - -    default: -      Com_Error( ERR_DROP, "BG_EvaluateTrajectory: unknown trType: %i", tr->trTime ); -      break; -  } -} - -/* -================ -BG_EvaluateTrajectoryDelta - -For determining velocity at a given time -================ -*/ -void BG_EvaluateTrajectoryDelta( const trajectory_t *tr, int atTime, vec3_t result ) -{ -  float deltaTime; -  float phase; - -  switch( tr->trType ) -  { -    case TR_STATIONARY: -    case TR_INTERPOLATE: -      VectorClear( result ); -      break; - -    case TR_LINEAR: -      VectorCopy( tr->trDelta, result ); -      break; - -    case TR_SINE: -      deltaTime = ( atTime - tr->trTime ) / (float)tr->trDuration; -      phase = cos( deltaTime * M_PI * 2 );  // derivative of sin = cos -      phase *= 0.5; -      VectorScale( tr->trDelta, phase, result ); -      break; - -    case TR_LINEAR_STOP: -      if( atTime > tr->trTime + tr->trDuration ) -      { -        VectorClear( result ); -        return; -      } -      VectorCopy( tr->trDelta, result ); -      break; - -    case TR_GRAVITY: -      deltaTime = ( atTime - tr->trTime ) * 0.001;  // milliseconds to seconds -      VectorCopy( tr->trDelta, result ); -      result[ 2 ] -= DEFAULT_GRAVITY * deltaTime;   // FIXME: local gravity... -      break; - -    case TR_BUOYANCY: -      deltaTime = ( atTime - tr->trTime ) * 0.001;  // milliseconds to seconds -      VectorCopy( tr->trDelta, result ); -      result[ 2 ] += DEFAULT_GRAVITY * deltaTime;   // FIXME: local gravity... -      break; - -    default: -      Com_Error( ERR_DROP, "BG_EvaluateTrajectoryDelta: unknown trType: %i", tr->trTime ); -      break; -  } -} - -char *eventnames[ ] = -{ -  "EV_NONE", - -  "EV_FOOTSTEP", -  "EV_FOOTSTEP_METAL", -  "EV_FOOTSTEP_SQUELCH", -  "EV_FOOTSPLASH", -  "EV_FOOTWADE", -  "EV_SWIM", - -  "EV_STEP_4", -  "EV_STEP_8", -  "EV_STEP_12", -  "EV_STEP_16", - -  "EV_STEPDN_4", -  "EV_STEPDN_8", -  "EV_STEPDN_12", -  "EV_STEPDN_16", - -  "EV_FALL_SHORT", -  "EV_FALL_MEDIUM", -  "EV_FALL_FAR", -  "EV_FALLING", - -  "EV_JUMP", -  "EV_WATER_TOUCH", // foot touches -  "EV_WATER_LEAVE", // foot leaves -  "EV_WATER_UNDER", // head touches -  "EV_WATER_CLEAR", // head leaves - -  "EV_NOAMMO", -  "EV_CHANGE_WEAPON", -  "EV_FIRE_WEAPON", -  "EV_FIRE_WEAPON2", -  "EV_FIRE_WEAPON3", - -  "EV_PLAYER_RESPAWN", //TA: for fovwarp effects -  "EV_PLAYER_TELEPORT_IN", -  "EV_PLAYER_TELEPORT_OUT", - -  "EV_GRENADE_BOUNCE",    // eventParm will be the soundindex - -  "EV_GENERAL_SOUND", -  "EV_GLOBAL_SOUND",    // no attenuation - -  "EV_BULLET_HIT_FLESH", -  "EV_BULLET_HIT_WALL", - -  "EV_SHOTGUN", - -  "EV_MISSILE_HIT", -  "EV_MISSILE_MISS", -  "EV_MISSILE_MISS_METAL", -  "EV_TESLATRAIL", -  "EV_BULLET",        // otherEntity is the shooter - -  "EV_LEV1_GRAB", -  "EV_LEV4_CHARGE_PREPARE", -  "EV_LEV4_CHARGE_START", - -  "EV_PAIN", -  "EV_DEATH1", -  "EV_DEATH2", -  "EV_DEATH3", -  "EV_OBITUARY", - -  "EV_GIB_PLAYER",      // gib a previously living player - -  "EV_BUILD_CONSTRUCT", //TA -  "EV_BUILD_DESTROY",   //TA -  "EV_BUILD_DELAY",     //TA: can't build yet -  "EV_BUILD_REPAIR",    //TA: repairing buildable -  "EV_BUILD_REPAIRED",  //TA: buildable has full health -  "EV_HUMAN_BUILDABLE_EXPLOSION", -  "EV_ALIEN_BUILDABLE_EXPLOSION", -  "EV_ALIEN_ACIDTUBE", - -  "EV_MEDKIT_USED", - -  "EV_ALIEN_EVOLVE", -  "EV_ALIEN_EVOLVE_FAILED", - -  "EV_DEBUG_LINE", -  "EV_STOPLOOPINGSOUND", -  "EV_TAUNT", - -  "EV_OVERMIND_ATTACK", //TA: overmind under attack -  "EV_OVERMIND_DYING",  //TA: overmind close to death -  "EV_OVERMIND_SPAWNS", //TA: overmind needs spawns - -  "EV_DCC_ATTACK",      //TA: dcc under attack - -  "EV_RPTUSE_SOUND"     //TA: trigger a sound -}; - -/* -=============== -BG_AddPredictableEventToPlayerstate - -Handles the sequence numbers -=============== -*/ - -void  trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ); - -void BG_AddPredictableEventToPlayerstate( int newEvent, int eventParm, playerState_t *ps ) -{ -#ifdef _DEBUG -  { -    char buf[ 256 ]; -    trap_Cvar_VariableStringBuffer( "showevents", buf, sizeof( buf ) ); - -    if( atof( buf ) != 0 ) -    { -#ifdef QAGAME -      Com_Printf( " game event svt %5d -> %5d: num = %20s parm %d\n", -                  ps->pmove_framecount/*ps->commandTime*/, ps->eventSequence, eventnames[ newEvent ], eventParm); -#else -      Com_Printf( "Cgame event svt %5d -> %5d: num = %20s parm %d\n", -                  ps->pmove_framecount/*ps->commandTime*/, ps->eventSequence, eventnames[ newEvent ], eventParm); -#endif -    } -  } -#endif -  ps->events[ ps->eventSequence & ( MAX_PS_EVENTS - 1 ) ] = newEvent; -  ps->eventParms[ ps->eventSequence & ( MAX_PS_EVENTS - 1 ) ] = eventParm; -  ps->eventSequence++; -} - - -/* -======================== -BG_PlayerStateToEntityState - -This is done after each set of usercmd_t on the server, -and after local prediction on the client -======================== -*/ -void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean snap ) -{ -  int     i; - -  if( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPECTATOR || ps->pm_type == PM_FREEZE ) -    s->eType = ET_INVISIBLE; -  else if( ps->persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) -    s->eType = ET_INVISIBLE; -  else -    s->eType = ET_PLAYER; - -  s->number = ps->clientNum; - -  s->pos.trType = TR_INTERPOLATE; -  VectorCopy( ps->origin, s->pos.trBase ); - -  if( snap ) -    SnapVector( s->pos.trBase ); - -  //set the trDelta for flag direction -  VectorCopy( ps->velocity, s->pos.trDelta ); - -  s->apos.trType = TR_INTERPOLATE; -  VectorCopy( ps->viewangles, s->apos.trBase ); - -  if( snap ) -    SnapVector( s->apos.trBase ); - -  //TA: i need for other things :) -  //s->angles2[YAW] = ps->movementDir; -  s->time2 = ps->movementDir; -  s->legsAnim = ps->legsAnim; -  s->torsoAnim = ps->torsoAnim; -  s->clientNum = ps->clientNum;   // ET_PLAYER looks here instead of at number -                    // so corpses can also reference the proper config -  s->eFlags = ps->eFlags; -  if( ps->stats[STAT_HEALTH] <= 0 ) -    s->eFlags |= EF_DEAD; -  else -    s->eFlags &= ~EF_DEAD; - -  if( ps->stats[ STAT_STATE ] & SS_BLOBLOCKED ) -    s->eFlags |= EF_BLOBLOCKED; -  else -    s->eFlags &= ~EF_BLOBLOCKED; - -  if( ps->externalEvent ) -  { -    s->event = ps->externalEvent; -    s->eventParm = ps->externalEventParm; -  } -  else if( ps->entityEventSequence < ps->eventSequence ) -  { -    int   seq; - -    if( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS ) -      ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS; - -    seq = ps->entityEventSequence & ( MAX_PS_EVENTS - 1 ); -    s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 ); -    s->eventParm = ps->eventParms[ seq ]; -    ps->entityEventSequence++; -  } - -  s->weapon = ps->weapon; -  s->groundEntityNum = ps->groundEntityNum; - -  //store items held and active items in otherEntityNum -  s->modelindex = 0; -  s->modelindex2 = 0; -  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -  { -    if( BG_InventoryContainsUpgrade( i, ps->stats ) ) -    { -      s->modelindex |= 1 << i; - -      if( BG_UpgradeIsActive( i, ps->stats ) ) -        s->modelindex2 |= 1 << i; -    } -  } - -  //TA: use powerups field to store team/class info: -  s->powerups = ps->stats[ STAT_PTEAM ] | ( ps->stats[ STAT_PCLASS ] << 8 ); - -  //TA: have to get the surfNormal thru somehow... -  VectorCopy( ps->grapplePoint, s->angles2 ); -  if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) -    s->eFlags |= EF_WALLCLIMBCEILING; - -  s->loopSound = ps->loopSound; -  s->generic1 = ps->generic1; - -  if( s->generic1 <= WPM_NONE || s->generic1 >= WPM_NUM_WEAPONMODES ) -    s->generic1 = WPM_PRIMARY; -} - - -/* -======================== -BG_PlayerStateToEntityStateExtraPolate - -This is done after each set of usercmd_t on the server, -and after local prediction on the client -======================== -*/ -void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s, int time, qboolean snap ) -{ -  int     i; - -  if( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPECTATOR || ps->pm_type == PM_FREEZE ) -    s->eType = ET_INVISIBLE; -  else if( ps->persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) -    s->eType = ET_INVISIBLE; -  else -    s->eType = ET_PLAYER; - -  s->number = ps->clientNum; - -  s->pos.trType = TR_LINEAR_STOP; -  VectorCopy( ps->origin, s->pos.trBase ); - -  if( snap ) -    SnapVector( s->pos.trBase ); - -  // set the trDelta for flag direction and linear prediction -  VectorCopy( ps->velocity, s->pos.trDelta ); -  // set the time for linear prediction -  s->pos.trTime = time; -  // set maximum extra polation time -  s->pos.trDuration = 50; // 1000 / sv_fps (default = 20) - -  s->apos.trType = TR_INTERPOLATE; -  VectorCopy( ps->viewangles, s->apos.trBase ); -  if( snap ) -    SnapVector( s->apos.trBase ); - -  //TA: i need for other things :) -  //s->angles2[YAW] = ps->movementDir; -  s->time2 = ps->movementDir; -  s->legsAnim = ps->legsAnim; -  s->torsoAnim = ps->torsoAnim; -  s->clientNum = ps->clientNum;   // ET_PLAYER looks here instead of at number -                    // so corpses can also reference the proper config -  s->eFlags = ps->eFlags; - -  if( ps->stats[STAT_HEALTH] <= 0 ) -    s->eFlags |= EF_DEAD; -  else -    s->eFlags &= ~EF_DEAD; - -  if( ps->stats[ STAT_STATE ] & SS_BLOBLOCKED ) -    s->eFlags |= EF_BLOBLOCKED; -  else -    s->eFlags &= ~EF_BLOBLOCKED; - -  if( ps->externalEvent ) -  { -    s->event = ps->externalEvent; -    s->eventParm = ps->externalEventParm; -  } -  else if( ps->entityEventSequence < ps->eventSequence ) -  { -    int   seq; - -    if( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS ) -      ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS; - -    seq = ps->entityEventSequence & ( MAX_PS_EVENTS - 1 ); -    s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 ); -    s->eventParm = ps->eventParms[ seq ]; -    ps->entityEventSequence++; -  } - -  s->weapon = ps->weapon; -  s->groundEntityNum = ps->groundEntityNum; - -  //store items held and active items in otherEntityNum -  s->modelindex = 0; -  s->modelindex2 = 0; - -  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -  { -    if( BG_InventoryContainsUpgrade( i, ps->stats ) ) -    { -      s->modelindex |= 1 << i; - -      if( BG_UpgradeIsActive( i, ps->stats ) ) -        s->modelindex2 |= 1 << i; -    } -  } - -  //TA: use powerups field to store team/class info: -  s->powerups = ps->stats[ STAT_PTEAM ] | ( ps->stats[ STAT_PCLASS ] << 8 ); - -  //TA: have to get the surfNormal thru somehow... -  VectorCopy( ps->grapplePoint, s->angles2 ); -  if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) -    s->eFlags |= EF_WALLCLIMBCEILING; - -  s->loopSound = ps->loopSound; -  s->generic1 = ps->generic1; - -  if( s->generic1 <= WPM_NONE || s->generic1 >= WPM_NUM_WEAPONMODES ) -    s->generic1 = WPM_PRIMARY; -} - -/* -======================== -BG_UnpackAmmoArray - -Extract the ammo quantity from the array -======================== -*/ -void BG_UnpackAmmoArray( int weapon, int psAmmo[ ], int psAmmo2[ ], int *ammo, int *clips ) -{ -  int   ammoarray[ 32 ]; -  int   i; - -  for( i = 0; i <= 15; i++ ) -    ammoarray[ i ] = psAmmo[ i ]; - -  for( i = 16; i <= 31; i++ ) -    ammoarray[ i ] = psAmmo2[ i - 16 ]; - -  if( ammo != NULL ) -    *ammo = ammoarray[ weapon ] & 0x0FFF; - -  if( clips != NULL ) -    *clips = ( ammoarray[ weapon ] >> 12 ) & 0x0F; -} - -/* -======================== -BG_PackAmmoArray - -Pack the ammo quantity into the array -======================== -*/ -void BG_PackAmmoArray( int weapon, int psAmmo[ ], int psAmmo2[ ], int ammo, int clips ) -{ -  int   weaponvalue; - -  weaponvalue = ammo | ( clips << 12 ); - -  if( weapon <= 15 ) -    psAmmo[ weapon ] = weaponvalue; -  else if( weapon >= 16 ) -    psAmmo2[ weapon - 16 ] = weaponvalue; -} - -/* -======================== -BG_WeaponIsFull - -Check if a weapon has full ammo -======================== -*/ -qboolean BG_WeaponIsFull( weapon_t weapon, int stats[ ], int psAmmo[ ], int psAmmo2[ ] ) -{ -  int maxAmmo, maxClips; -  int ammo, clips; - -  BG_FindAmmoForWeapon( weapon, &maxAmmo, &maxClips ); -  BG_UnpackAmmoArray( weapon, psAmmo, psAmmo2, &ammo, &clips ); - -  if( BG_InventoryContainsUpgrade( UP_BATTPACK, stats ) ) -    maxAmmo = (int)( (float)maxAmmo * BATTPACK_MODIFIER ); - -  return ( maxAmmo == ammo ) && ( maxClips == clips ); -} - -/* -======================== -BG_AddWeaponToInventory - -Give a player a weapon -======================== -*/ -void BG_AddWeaponToInventory( int weapon, int stats[ ] ) -{ -  int  weaponList; - -  weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 ); - -  weaponList |= ( 1 << weapon ); - -  stats[ STAT_WEAPONS ] = weaponList & 0x0000FFFF; -  stats[ STAT_WEAPONS2 ] = ( weaponList & 0xFFFF0000 ) >> 16; - -  if( stats[ STAT_SLOTS ] & BG_FindSlotsForWeapon( weapon ) ) -    Com_Printf( S_COLOR_YELLOW "WARNING: Held items conflict with weapon %d\n", weapon ); - -  stats[ STAT_SLOTS ] |= BG_FindSlotsForWeapon( weapon ); -} - -/* -======================== -BG_RemoveWeaponToInventory - -Take a weapon from a player -======================== -*/ -void BG_RemoveWeaponFromInventory( int weapon, int stats[ ] ) -{ -  int  weaponList; - -  weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 ); - -  weaponList &= ~( 1 << weapon ); - -  stats[ STAT_WEAPONS ] = weaponList & 0x0000FFFF; -  stats[ STAT_WEAPONS2 ] = ( weaponList & 0xFFFF0000 ) >> 16; - -  stats[ STAT_SLOTS ] &= ~BG_FindSlotsForWeapon( weapon ); -} - -/* -======================== -BG_InventoryContainsWeapon - -Does the player hold a weapon? -======================== -*/ -qboolean BG_InventoryContainsWeapon( int weapon, int stats[ ] ) -{ -  int  weaponList; - -  weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 ); - -  return( weaponList & ( 1 << weapon ) ); -} - -/* -======================== -BG_AddUpgradeToInventory - -Give the player an upgrade -======================== -*/ -void BG_AddUpgradeToInventory( int item, int stats[ ] ) -{ -  stats[ STAT_ITEMS ] |= ( 1 << item ); - -  if( stats[ STAT_SLOTS ] & BG_FindSlotsForUpgrade( item ) ) -    Com_Printf( S_COLOR_YELLOW "WARNING: Held items conflict with upgrade %d\n", item ); - -  stats[ STAT_SLOTS ] |= BG_FindSlotsForUpgrade( item ); -} - -/* -======================== -BG_RemoveUpgradeFromInventory - -Take an upgrade from the player -======================== -*/ -void BG_RemoveUpgradeFromInventory( int item, int stats[ ] ) -{ -  stats[ STAT_ITEMS ] &= ~( 1 << item ); - -  stats[ STAT_SLOTS ] &= ~BG_FindSlotsForUpgrade( item ); -} - -/* -======================== -BG_InventoryContainsUpgrade - -Does the player hold an upgrade? -======================== -*/ -qboolean BG_InventoryContainsUpgrade( int item, int stats[ ] ) -{ -  return( stats[ STAT_ITEMS ] & ( 1 << item ) ); -} - -/* -======================== -BG_ActivateUpgrade - -Activates an upgrade -======================== -*/ -void BG_ActivateUpgrade( int item, int stats[ ] ) -{ -  stats[ STAT_ACTIVEITEMS ] |= ( 1 << item ); -} - -/* -======================== -BG_DeactivateUpgrade - -Deactivates an upgrade -======================== -*/ -void BG_DeactivateUpgrade( int item, int stats[ ] ) -{ -  stats[ STAT_ACTIVEITEMS ] &= ~( 1 << item ); -} - -/* -======================== -BG_UpgradeIsActive - -Is this upgrade active? -======================== -*/ -qboolean BG_UpgradeIsActive( int item, int stats[ ] ) -{ -  return( stats[ STAT_ACTIVEITEMS ] & ( 1 << item ) ); -} - -/* -=============== -BG_RotateAxis - -Shared axis rotation function -=============== -*/ -qboolean BG_RotateAxis( vec3_t surfNormal, vec3_t inAxis[ 3 ], -                        vec3_t outAxis[ 3 ], qboolean inverse, qboolean ceiling ) -{ -  vec3_t  refNormal = { 0.0f, 0.0f, 1.0f }; -  vec3_t  ceilingNormal = { 0.0f, 0.0f, -1.0f }; -  vec3_t  localNormal, xNormal; -  float   rotAngle; - -  //the grapplePoint being a surfNormal rotation Normal hack... see above :) -  if( ceiling ) -  { -    VectorCopy( ceilingNormal, localNormal ); -    VectorCopy( surfNormal, xNormal ); -  } -  else -  { -    //cross the reference normal and the surface normal to get the rotation axis -    VectorCopy( surfNormal, localNormal ); -    CrossProduct( localNormal, refNormal, xNormal ); -    VectorNormalize( xNormal ); -  } - -  //can't rotate with no rotation vector -  if( VectorLength( xNormal ) != 0.0f ) -  { -    rotAngle = RAD2DEG( acos( DotProduct( localNormal, refNormal ) ) ); - -    if( inverse ) -      rotAngle = -rotAngle; - -    AngleNormalize180( rotAngle ); - -    //hmmm could get away with only one rotation and some clever stuff later... but i'm lazy -    RotatePointAroundVector( outAxis[ 0 ], xNormal, inAxis[ 0 ], -rotAngle ); -    RotatePointAroundVector( outAxis[ 1 ], xNormal, inAxis[ 1 ], -rotAngle ); -    RotatePointAroundVector( outAxis[ 2 ], xNormal, inAxis[ 2 ], -rotAngle ); -  } -  else -    return qfalse; - -  return qtrue; -} - -/* -=============== -BG_PositionBuildableRelativeToPlayer - -Find a place to build a buildable -=============== -*/ -void BG_PositionBuildableRelativeToPlayer( const playerState_t *ps, -                                           const vec3_t mins, const vec3_t maxs, -                                           void (*trace)( trace_t *, const vec3_t, const vec3_t, -                                                          const vec3_t, const vec3_t, int, int ), -                                           vec3_t outOrigin, vec3_t outAngles, trace_t *tr ) -{ -  vec3_t  forward, entityOrigin, targetOrigin; -  vec3_t  angles, playerOrigin, playerNormal; -  float   buildDist; - -  if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) -  { -    if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) -      VectorSet( playerNormal, 0.0f, 0.0f, -1.0f ); -    else -      VectorCopy( ps->grapplePoint, playerNormal ); -  } -  else -    VectorSet( playerNormal, 0.0f, 0.0f, 1.0f ); - -  VectorCopy( ps->viewangles, angles ); -  VectorCopy( ps->origin, playerOrigin ); -  buildDist = BG_FindBuildDistForClass( ps->stats[ STAT_PCLASS ] ); - -  AngleVectors( angles, forward, NULL, NULL ); -  ProjectPointOnPlane( forward, forward, playerNormal ); -  VectorNormalize( forward ); - -  VectorMA( playerOrigin, buildDist, forward, entityOrigin ); - -  VectorCopy( entityOrigin, targetOrigin ); - -  //so buildings can be placed facing slopes -  VectorMA( entityOrigin, 32, playerNormal, entityOrigin ); - -  //so buildings drop to floor -  VectorMA( targetOrigin, -128, playerNormal, targetOrigin ); - -  (*trace)( tr, entityOrigin, mins, maxs, targetOrigin, ps->clientNum, MASK_PLAYERSOLID ); -  VectorCopy( tr->endpos, entityOrigin ); -  VectorMA( entityOrigin, 0.1f, playerNormal, outOrigin ); -  vectoangles( forward, outAngles ); -} - -/* -=============== -BG_GetValueOfHuman - -Returns the kills value of some human player -=============== -*/ -int BG_GetValueOfHuman( playerState_t *ps ) -{ -  int     i, worth = 0; -  float   portion; - -  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -  { -    if( BG_InventoryContainsUpgrade( i, ps->stats ) ) -      worth += BG_FindPriceForUpgrade( i ); -  } - -  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) -  { -    if( BG_InventoryContainsWeapon( i, ps->stats ) ) -      worth += BG_FindPriceForWeapon( i ); -  } - -  portion = worth / (float)HUMAN_MAXED; - -  if( portion < 0.01f ) -    portion = 0.01f; -  else if( portion > 1.0f ) -    portion = 1.0f; - -  return ceil( ALIEN_MAX_SINGLE_KILLS * portion ); -} - -/* -=============== -atof_neg - -atof with an allowance for negative values -=============== -*/ -float atof_neg( char *token, qboolean allowNegative ) -{ -  float value; - -  value = atof( token ); - -  if( !allowNegative && value < 0.0f ) -    value = 1.0f; - -  return value; -} - -/* -=============== -atoi_neg - -atoi with an allowance for negative values -=============== -*/ -int atoi_neg( char *token, qboolean allowNegative ) -{ -  int value; - -  value = atoi( token ); - -  if( !allowNegative && value < 0 ) -    value = 1; - -  return value; -} - -/* -=============== -BG_ParseCSVEquipmentList -=============== -*/ -void BG_ParseCSVEquipmentList( const char *string, weapon_t *weapons, int weaponsSize, -    upgrade_t *upgrades, int upgradesSize ) -{ -  char      buffer[ MAX_STRING_CHARS ]; -  int       i = 0, j = 0; -  char      *p, *q; -  qboolean  EOS = qfalse; - -  Q_strncpyz( buffer, string, MAX_STRING_CHARS ); - -  p = q = buffer; - -  while( *p != '\0' ) -  { -    //skip to first , or EOS -    while( *p != ',' && *p != '\0' ) -      p++; - -    if( *p == '\0' ) -      EOS = qtrue; - -    *p = '\0'; - -    //strip leading whitespace -    while( *q == ' ' ) -      q++; - -    if( weaponsSize ) -      weapons[ i ] = BG_FindWeaponNumForName( q ); - -    if( upgradesSize ) -      upgrades[ j ] = BG_FindUpgradeNumForName( q ); - -    if( weaponsSize && weapons[ i ] == WP_NONE && -        upgradesSize && upgrades[ j ] == UP_NONE ) -      Com_Printf( S_COLOR_YELLOW "WARNING: unknown equipment %s\n", q ); -    else if( weaponsSize && weapons[ i ] != WP_NONE ) -      i++; -    else if( upgradesSize && upgrades[ j ] != UP_NONE ) -      j++; - -    if( !EOS ) -    { -      p++; -      q = p; -    } -    else -      break; - -    if( i == ( weaponsSize - 1 ) || j == ( upgradesSize - 1 ) ) -      break; -  } - -  if( weaponsSize ) -    weapons[ i ] = WP_NONE; - -  if( upgradesSize ) -    upgrades[ j ] = UP_NONE; -} - -/* -=============== -BG_ParseCSVClassList -=============== -*/ -void BG_ParseCSVClassList( const char *string, pClass_t *classes, int classesSize ) -{ -  char      buffer[ MAX_STRING_CHARS ]; -  int       i = 0; -  char      *p, *q; -  qboolean  EOS = qfalse; - -  Q_strncpyz( buffer, string, MAX_STRING_CHARS ); - -  p = q = buffer; - -  while( *p != '\0' ) -  { -    //skip to first , or EOS -    while( *p != ',' && *p != '\0' ) -      p++; - -    if( *p == '\0' ) -      EOS = qtrue; - -    *p = '\0'; - -    //strip leading whitespace -    while( *q == ' ' ) -      q++; - -    classes[ i ] = BG_FindClassNumForName( q ); - -    if( classes[ i ] == PCL_NONE ) -      Com_Printf( S_COLOR_YELLOW "WARNING: unknown class %s\n", q ); -    else -      i++; - -    if( !EOS ) -    { -      p++; -      q = p; -    } -    else -      break; -  } - -  classes[ i ] = PCL_NONE; -} - -/* -=============== -BG_ParseCSVBuildableList -=============== -*/ -void BG_ParseCSVBuildableList( const char *string, buildable_t *buildables, int buildablesSize ) -{ -  char      buffer[ MAX_STRING_CHARS ]; -  int       i = 0; -  char      *p, *q; -  qboolean  EOS = qfalse; - -  Q_strncpyz( buffer, string, MAX_STRING_CHARS ); - -  p = q = buffer; - -  while( *p != '\0' ) -  { -    //skip to first , or EOS -    while( *p != ',' && *p != '\0' ) -      p++; - -    if( *p == '\0' ) -      EOS = qtrue; - -    *p = '\0'; - -    //strip leading whitespace -    while( *q == ' ' ) -      q++; - -    buildables[ i ] = BG_FindClassNumForName( q ); - -    if( buildables[ i ] == BA_NONE ) -      Com_Printf( S_COLOR_YELLOW "WARNING: unknown buildable %s\n", q ); -    else -      i++; - -    if( !EOS ) -    { -      p++; -      q = p; -    } -    else -      break; -  } - -  buildables[ i ] = BA_NONE; -} diff --git a/mod/src/game/bg_pmove.c b/mod/src/game/bg_pmove.c deleted file mode 100644 index 88432f81..00000000 --- a/mod/src/game/bg_pmove.c +++ /dev/null @@ -1,3471 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// bg_pmove.c -- both games player movement code -// takes a playerstate and a usercmd as input and returns a modifed playerstate - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "q_shared.h" -#include "bg_public.h" -#include "bg_local.h" - -pmove_t     *pm; -pml_t       pml; - -// movement parameters -float pm_stopspeed = 100.0f; -float pm_duckScale = 0.25f; -float pm_swimScale = 0.50f; -float pm_wadeScale = 0.70f; - -float pm_accelerate = 10.0f; -float pm_airaccelerate = 1.0f; -float pm_wateraccelerate = 4.0f; -float pm_flyaccelerate = 4.0f; - -float pm_friction = 6.0f; -float pm_waterfriction = 1.0f; -float pm_flightfriction = 6.0f; -float pm_spectatorfriction = 5.0f; - -int   c_pmove = 0; - -/* -=============== -PM_AddEvent - -=============== -*/ -void PM_AddEvent( int newEvent ) -{ -  BG_AddPredictableEventToPlayerstate( newEvent, 0, pm->ps ); -} - -/* -=============== -PM_AddTouchEnt -=============== -*/ -void PM_AddTouchEnt( int entityNum ) -{ -  int   i; - -  if( entityNum == ENTITYNUM_WORLD ) -    return; - -  if( pm->numtouch == MAXTOUCH ) -    return; - -  // see if it is already added -  for( i = 0 ; i < pm->numtouch ; i++ ) -  { -    if( pm->touchents[ i ] == entityNum ) -      return; -  } - -  // add it -  pm->touchents[ pm->numtouch ] = entityNum; -  pm->numtouch++; -} - -/* -=================== -PM_StartTorsoAnim -=================== -*/ -static void PM_StartTorsoAnim( int anim ) -{ -  if( pm->ps->pm_type >= PM_DEAD ) -    return; - -  pm->ps->torsoAnim = ( ( pm->ps->torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) -    | anim; -} - -/* -=================== -PM_StartLegsAnim -=================== -*/ -static void PM_StartLegsAnim( int anim ) -{ -  if( pm->ps->pm_type >= PM_DEAD ) -    return; - -  //legsTimer is clamped too tightly for nonsegmented models -  if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -  { -    if( pm->ps->legsTimer > 0 ) -      return;   // a high priority animation is running -  } -  else -  { -    if( pm->ps->torsoTimer > 0 ) -      return;   // a high priority animation is running -  } - -  pm->ps->legsAnim = ( ( pm->ps->legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) -    | anim; -} - -/* -=================== -PM_ContinueLegsAnim -=================== -*/ -static void PM_ContinueLegsAnim( int anim ) -{ -  if( ( pm->ps->legsAnim & ~ANIM_TOGGLEBIT ) == anim ) -    return; - -  //legsTimer is clamped too tightly for nonsegmented models -  if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -  { -    if( pm->ps->legsTimer > 0 ) -      return;   // a high priority animation is running -  } -  else -  { -    if( pm->ps->torsoTimer > 0 ) -      return;   // a high priority animation is running -  } - -  PM_StartLegsAnim( anim ); -} - -/* -=================== -PM_ContinueTorsoAnim -=================== -*/ -static void PM_ContinueTorsoAnim( int anim ) -{ -  if( ( pm->ps->torsoAnim & ~ANIM_TOGGLEBIT ) == anim ) -    return; - -  if( pm->ps->torsoTimer > 0 ) -    return;   // a high priority animation is running - -  PM_StartTorsoAnim( anim ); -} - -/* -=================== -PM_ForceLegsAnim -=================== -*/ -static void PM_ForceLegsAnim( int anim ) -{ -  //legsTimer is clamped too tightly for nonsegmented models -  if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -    pm->ps->legsTimer = 0; -  else -    pm->ps->torsoTimer = 0; - -  PM_StartLegsAnim( anim ); -} - - -/* -================== -PM_ClipVelocity - -Slide off of the impacting surface -================== -*/ -void PM_ClipVelocity( vec3_t in, vec3_t normal, vec3_t out, float overbounce ) -{ -  float backoff; -  float change; -  int   i; - -  backoff = DotProduct( in, normal ); - -  //Com_Printf( "%1.0f ", backoff ); - -  if( backoff < 0 ) -    backoff *= overbounce; -  else -    backoff /= overbounce; - -  for( i = 0; i < 3; i++ ) -  { -    change = normal[ i ] * backoff; -    //Com_Printf( "%1.0f ", change ); -    out[ i ] = in[ i ] - change; -  } - -  //Com_Printf( "   " ); -} - - -/* -================== -PM_Friction - -Handles both ground friction and water friction -================== -*/ -static void PM_Friction( void ) -{ -  vec3_t  vec; -  float   *vel; -  float   speed, newspeed, control; -  float   drop; - -  vel = pm->ps->velocity; - -  //TA: make sure vertical velocity is NOT set to zero when wall climbing -  VectorCopy( vel, vec ); -  if( pml.walking && !( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) ) -    vec[ 2 ] = 0; // ignore slope movement - -  speed = VectorLength( vec ); - -  if( speed < 1 ) -  { -    vel[ 0 ] = 0; -    vel[ 1 ] = 0;   // allow sinking underwater -    // FIXME: still have z friction underwater? -    return; -  } - -  drop = 0; - -  // apply ground friction -  if( pm->waterlevel <= 1 ) -  { -    if( ( pml.walking || pml.ladder ) && !( pml.groundTrace.surfaceFlags & SURF_SLICK ) ) -    { -      // if getting knocked back, no friction -      if( !( pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) ) -      { -        float stopSpeed = BG_FindStopSpeedForClass( pm->ps->stats[ STAT_PCLASS ] ); - -        control = speed < stopSpeed ? stopSpeed : speed; -        drop += control * BG_FindFrictionForClass( pm->ps->stats[ STAT_PCLASS ] ) * pml.frametime; -      } -    } -  } - -  // apply water friction even if just wading -  if( pm->waterlevel ) -    drop += speed * pm_waterfriction * pm->waterlevel * pml.frametime; - -  // apply flying friction -  if( pm->ps->pm_type == PM_JETPACK ) -    drop += speed * pm_flightfriction * pml.frametime; - -  if( pm->ps->pm_type == PM_SPECTATOR ) -    drop += speed * pm_spectatorfriction * pml.frametime; - -  // scale the velocity -  newspeed = speed - drop; -  if( newspeed < 0 ) -    newspeed = 0; - -  newspeed /= speed; - -  vel[ 0 ] = vel[ 0 ] * newspeed; -  vel[ 1 ] = vel[ 1 ] * newspeed; -  vel[ 2 ] = vel[ 2 ] * newspeed; -} - - -/* -============== -PM_Accelerate - -Handles user intended acceleration -============== -*/ -static void PM_Accelerate( vec3_t wishdir, float wishspeed, float accel ) -{ -#if 1 -  // q2 style -  int     i; -  float   addspeed, accelspeed, currentspeed; - -  currentspeed = DotProduct( pm->ps->velocity, wishdir ); -  addspeed = wishspeed - currentspeed; -  if( addspeed <= 0 ) -    return; - -  accelspeed = accel * pml.frametime * wishspeed; -  if( accelspeed > addspeed ) -    accelspeed = addspeed; - -  for( i = 0; i < 3; i++ ) -    pm->ps->velocity[ i ] += accelspeed * wishdir[ i ]; -#else -  // proper way (avoids strafe jump maxspeed bug), but feels bad -  vec3_t    wishVelocity; -  vec3_t    pushDir; -  float     pushLen; -  float     canPush; - -  VectorScale( wishdir, wishspeed, wishVelocity ); -  VectorSubtract( wishVelocity, pm->ps->velocity, pushDir ); -  pushLen = VectorNormalize( pushDir ); - -  canPush = accel * pml.frametime * wishspeed; -  if( canPush > pushLen ) -    canPush = pushLen; - -  VectorMA( pm->ps->velocity, canPush, pushDir, pm->ps->velocity ); -#endif -} - - - -/* -============ -PM_CmdScale - -Returns the scale factor to apply to cmd movements -This allows the clients to use axial -127 to 127 values for all directions -without getting a sqrt(2) distortion in speed. -============ -*/ -static float PM_CmdScale( usercmd_t *cmd ) -{ -  int         max; -  float       total; -  float       scale; -  float       modifier = 1.0f; - -  if( pm->ps->stats[ STAT_PTEAM ] == PTE_HUMANS && pm->ps->pm_type == PM_NORMAL ) -  { -    if( pm->ps->stats[ STAT_STATE ] & SS_SPEEDBOOST ) -      modifier *= HUMAN_SPRINT_MODIFIER; -    else -      modifier *= HUMAN_JOG_MODIFIER; - -    if( cmd->forwardmove < 0 ) -    { -      //can't run backwards -      modifier *= HUMAN_BACK_MODIFIER; -    } -    else if( cmd->rightmove ) -    { -      //can't move that fast sideways -      modifier *= HUMAN_SIDE_MODIFIER; -    } - -    //must have +ve stamina to jump -    if( pm->ps->stats[ STAT_STAMINA ] < 0 ) -      cmd->upmove = 0; - -    //slow down once stamina depletes -    if( pm->ps->stats[ STAT_STAMINA ] <= -500 ) -      modifier *= (float)( pm->ps->stats[ STAT_STAMINA ] + 1000 ) / 500.0f; - -    if( pm->ps->stats[ STAT_STATE ] & SS_CREEPSLOWED ) -    { -      if( BG_InventoryContainsUpgrade( UP_LIGHTARMOUR, pm->ps->stats ) || -          BG_InventoryContainsUpgrade( UP_BATTLESUIT, pm->ps->stats ) ) -        modifier *= CREEP_ARMOUR_MODIFIER; -      else -        modifier *= CREEP_MODIFIER; -    } -  } - -  if( pm->ps->weapon == WP_ALEVEL4 && pm->ps->pm_flags & PMF_CHARGE ) -    modifier *= ( 1.0f + ( pm->ps->stats[ STAT_MISC ] / (float)LEVEL4_CHARGE_TIME ) * -        ( LEVEL4_CHARGE_SPEED - 1.0f ) ); - -  //slow player if charging up for a pounce -  if( ( pm->ps->weapon == WP_ALEVEL3 || pm->ps->weapon == WP_ALEVEL3_UPG ) && -      cmd->buttons & BUTTON_ATTACK2 ) -    modifier *= LEVEL3_POUNCE_SPEED_MOD; - -  //slow the player if slow locked -  if( pm->ps->stats[ STAT_STATE ] & SS_SLOWLOCKED ) -    modifier *= ABUILDER_BLOB_SPEED_MOD; - -  if( pm->ps->pm_type == PM_GRABBED ) -    modifier = 0.0f; - -  if( pm->ps->pm_type != PM_SPECTATOR && pm->ps->pm_type != PM_NOCLIP ) -  { -    if( BG_FindJumpMagnitudeForClass( pm->ps->stats[ STAT_PCLASS ] ) == 0.0f ) -      cmd->upmove = 0; - -    //prevent speed distortions for non ducking classes -    if( !( pm->ps->pm_flags & PMF_DUCKED ) && pm->ps->pm_type != PM_JETPACK && cmd->upmove < 0 ) -      cmd->upmove = 0; -  } - -  max = abs( cmd->forwardmove ); -  if( abs( cmd->rightmove ) > max ) -    max = abs( cmd->rightmove ); - -  if( abs( cmd->upmove ) > max ) -    max = abs( cmd->upmove ); - -  if( !max ) -    return 0; - -  total = sqrt( cmd->forwardmove * cmd->forwardmove -    + cmd->rightmove * cmd->rightmove + cmd->upmove * cmd->upmove ); - -  scale = (float)pm->ps->speed * max / ( 127.0 * total ) * modifier; - -  return scale; -} - - -/* -================ -PM_SetMovementDir - -Determine the rotation of the legs reletive -to the facing dir -================ -*/ -static void PM_SetMovementDir( void ) -{ -  if( pm->cmd.forwardmove || pm->cmd.rightmove ) -  { -    if( pm->cmd.rightmove == 0 && pm->cmd.forwardmove > 0 ) -      pm->ps->movementDir = 0; -    else if( pm->cmd.rightmove < 0 && pm->cmd.forwardmove > 0 ) -      pm->ps->movementDir = 1; -    else if( pm->cmd.rightmove < 0 && pm->cmd.forwardmove == 0 ) -      pm->ps->movementDir = 2; -    else if( pm->cmd.rightmove < 0 && pm->cmd.forwardmove < 0 ) -      pm->ps->movementDir = 3; -    else if( pm->cmd.rightmove == 0 && pm->cmd.forwardmove < 0 ) -      pm->ps->movementDir = 4; -    else if( pm->cmd.rightmove > 0 && pm->cmd.forwardmove < 0 ) -      pm->ps->movementDir = 5; -    else if( pm->cmd.rightmove > 0 && pm->cmd.forwardmove == 0 ) -      pm->ps->movementDir = 6; -    else if( pm->cmd.rightmove > 0 && pm->cmd.forwardmove > 0 ) -      pm->ps->movementDir = 7; -  } -  else -  { -    // if they aren't actively going directly sideways, -    // change the animation to the diagonal so they -    // don't stop too crooked -    if( pm->ps->movementDir == 2 ) -      pm->ps->movementDir = 1; -    else if( pm->ps->movementDir == 6 ) -      pm->ps->movementDir = 7; -  } -} - - -/* -============= -PM_CheckCharge -============= -*/ -static void PM_CheckCharge( void ) -{ -  if( pm->ps->weapon != WP_ALEVEL4 ) -    return; - -  if( pm->cmd.buttons & BUTTON_ATTACK2 && -      !( pm->ps->stats[ STAT_STATE ] & SS_CHARGING ) ) -  { -    pm->ps->pm_flags &= ~PMF_CHARGE; -    return; -  } - -  if( pm->ps->stats[ STAT_MISC ] > 0 ) -    pm->ps->pm_flags |= PMF_CHARGE; -  else -    pm->ps->pm_flags &= ~PMF_CHARGE; -} - -/* -============= -PM_CheckPounce -============= -*/ -static qboolean PM_CheckPounce( void ) -{ -  if( pm->ps->weapon != WP_ALEVEL3 && -      pm->ps->weapon != WP_ALEVEL3_UPG ) -    return qfalse; - -  if( pm->cmd.buttons & BUTTON_ATTACK2 ) -  { -    pm->ps->pm_flags &= ~PMF_CHARGE; -    return qfalse; -  } - -  if( pm->ps->pm_flags & PMF_CHARGE ) -    return qfalse; - -  if( pm->ps->stats[ STAT_MISC ] == 0 ) -    return qfalse; - -  pml.groundPlane = qfalse;   // jumping away -  pml.walking = qfalse; - -  pm->ps->pm_flags |= PMF_CHARGE; - -  pm->ps->groundEntityNum = ENTITYNUM_NONE; - -  VectorMA( pm->ps->velocity, pm->ps->stats[ STAT_MISC ], pml.forward, pm->ps->velocity ); - -  PM_AddEvent( EV_JUMP ); - -  if( pm->cmd.forwardmove >= 0 ) -  { -    if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -      PM_ForceLegsAnim( LEGS_JUMP ); -    else -      PM_ForceLegsAnim( NSPA_JUMP ); - -    pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP; -  } -  else -  { -    if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -      PM_ForceLegsAnim( LEGS_JUMPB ); -    else -      PM_ForceLegsAnim( NSPA_JUMPBACK ); - -    pm->ps->pm_flags |= PMF_BACKWARDS_JUMP; -  } - -  return qtrue; -} - -/* -============= -PM_CheckWallJump -============= -*/ -static qboolean PM_CheckWallJump( void ) -{ -  vec3_t  dir, forward, right; -  vec3_t  refNormal = { 0.0f, 0.0f, 1.0f }; -  float   normalFraction = 1.5f; -  float   cmdFraction = 1.0f; -  float   upFraction = 1.5f; - -  if( pm->ps->pm_flags & PMF_RESPAWNED ) -    return qfalse;    // don't allow jump until all buttons are up - -  if( pm->cmd.upmove < 10 ) -    // not holding jump -    return qfalse; - -  if( pm->ps->pm_flags & PMF_TIME_WALLJUMP ) -    return qfalse; - -  // must wait for jump to be released -  if( pm->ps->pm_flags & PMF_JUMP_HELD && -      pm->ps->grapplePoint[ 2 ] == 1.0f ) -  { -    // clear upmove so cmdscale doesn't lower running speed -    pm->cmd.upmove = 0; -    return qfalse; -  } - -  pm->ps->pm_flags |= PMF_TIME_WALLJUMP; -  pm->ps->pm_time = 200; - -  pml.groundPlane = qfalse;   // jumping away -  pml.walking = qfalse; -  pm->ps->pm_flags |= PMF_JUMP_HELD; - -  pm->ps->groundEntityNum = ENTITYNUM_NONE; - -  ProjectPointOnPlane( forward, pml.forward, pm->ps->grapplePoint ); -  ProjectPointOnPlane( right, pml.right, pm->ps->grapplePoint ); - -  VectorScale( pm->ps->grapplePoint, normalFraction, dir ); - -  if( pm->cmd.forwardmove > 0 ) -    VectorMA( dir, cmdFraction, forward, dir ); -  else if( pm->cmd.forwardmove < 0 ) -    VectorMA( dir, -cmdFraction, forward, dir ); - -  if( pm->cmd.rightmove > 0 ) -    VectorMA( dir, cmdFraction, right, dir ); -  else if( pm->cmd.rightmove < 0 ) -    VectorMA( dir, -cmdFraction, right, dir ); - -  VectorMA( dir, upFraction, refNormal, dir ); -  VectorNormalize( dir ); - -  VectorMA( pm->ps->velocity, BG_FindJumpMagnitudeForClass( pm->ps->stats[ STAT_PCLASS ] ), -            dir, pm->ps->velocity ); - -  //for a long run of wall jumps the velocity can get pretty large, this caps it -  if( VectorLength( pm->ps->velocity ) > LEVEL2_WALLJUMP_MAXSPEED ) -  { -    VectorNormalize( pm->ps->velocity ); -    VectorScale( pm->ps->velocity, LEVEL2_WALLJUMP_MAXSPEED, pm->ps->velocity ); -  } - -  PM_AddEvent( EV_JUMP ); - -  if( pm->cmd.forwardmove >= 0 ) -  { -    if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -      PM_ForceLegsAnim( LEGS_JUMP ); -    else -      PM_ForceLegsAnim( NSPA_JUMP ); - -    pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP; -  } -  else -  { -    if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -      PM_ForceLegsAnim( LEGS_JUMPB ); -    else -      PM_ForceLegsAnim( NSPA_JUMPBACK ); - -    pm->ps->pm_flags |= PMF_BACKWARDS_JUMP; -  } - -  return qtrue; -} - -/* -============= -PM_CheckJump -============= -*/ -static qboolean PM_CheckJump( void ) -{ -  if( BG_FindJumpMagnitudeForClass( pm->ps->stats[ STAT_PCLASS ] ) == 0.0f ) -    return qfalse; - -  if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_WALLJUMPER ) ) -    return PM_CheckWallJump( ); - -  //can't jump and pounce at the same time -  if( ( pm->ps->weapon == WP_ALEVEL3 || -        pm->ps->weapon == WP_ALEVEL3_UPG ) && -      pm->ps->stats[ STAT_MISC ] > 0 ) -    return qfalse; - -  //can't jump and charge at the same time -  if( ( pm->ps->weapon == WP_ALEVEL4 ) && -      pm->ps->stats[ STAT_MISC ] > 0 ) -    return qfalse; - -  if( ( pm->ps->stats[ STAT_PTEAM ] == PTE_HUMANS ) && -      ( pm->ps->stats[ STAT_STAMINA ] < 0 ) ) -    return qfalse; - -  if( pm->ps->pm_flags & PMF_RESPAWNED ) -    return qfalse;    // don't allow jump until all buttons are up - -  if( pm->cmd.upmove < 10 ) -    // not holding jump -    return qfalse; - -  //can't jump whilst grabbed -  if( pm->ps->pm_type == PM_GRABBED ) -  { -    pm->cmd.upmove = 0; -    return qfalse; -  } - -  // must wait for jump to be released -  if( pm->ps->pm_flags & PMF_JUMP_HELD ) -  { -    // clear upmove so cmdscale doesn't lower running speed -    pm->cmd.upmove = 0; -    return qfalse; -  } - -  pml.groundPlane = qfalse;   // jumping away -  pml.walking = qfalse; -  pm->ps->pm_flags |= PMF_JUMP_HELD; - -  //TA: take some stamina off -  if( pm->ps->stats[ STAT_PTEAM ] == PTE_HUMANS ) -    pm->ps->stats[ STAT_STAMINA ] -= 500; - -  pm->ps->groundEntityNum = ENTITYNUM_NONE; - -  //TA: jump away from wall -  if( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) -  { -    vec3_t normal = { 0, 0, -1 }; - -    if( !( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) ) -      VectorCopy( pm->ps->grapplePoint, normal ); - -    VectorMA( pm->ps->velocity, BG_FindJumpMagnitudeForClass( pm->ps->stats[ STAT_PCLASS ] ), -              normal, pm->ps->velocity ); -  } -  else -    pm->ps->velocity[ 2 ] = BG_FindJumpMagnitudeForClass( pm->ps->stats[ STAT_PCLASS ] ); - -  PM_AddEvent( EV_JUMP ); - -  if( pm->cmd.forwardmove >= 0 ) -  { -    if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -      PM_ForceLegsAnim( LEGS_JUMP ); -    else -      PM_ForceLegsAnim( NSPA_JUMP ); - -    pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP; -  } -  else -  { -    if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -      PM_ForceLegsAnim( LEGS_JUMPB ); -    else -      PM_ForceLegsAnim( NSPA_JUMPBACK ); - -    pm->ps->pm_flags |= PMF_BACKWARDS_JUMP; -  } - -  return qtrue; -} - -/* -============= -PM_CheckWaterJump -============= -*/ -static qboolean PM_CheckWaterJump( void ) -{ -  vec3_t  spot; -  int     cont; -  vec3_t  flatforward; - -  if( pm->ps->pm_time ) -    return qfalse; - -  // check for water jump -  if( pm->waterlevel != 2 ) -    return qfalse; - -  flatforward[ 0 ] = pml.forward[ 0 ]; -  flatforward[ 1 ] = pml.forward[ 1 ]; -  flatforward[ 2 ] = 0; -  VectorNormalize( flatforward ); - -  VectorMA( pm->ps->origin, 30, flatforward, spot ); -  spot[ 2 ] += 4; -  cont = pm->pointcontents( spot, pm->ps->clientNum ); - -  if( !( cont & CONTENTS_SOLID ) ) -    return qfalse; - -  spot[ 2 ] += 16; -  cont = pm->pointcontents( spot, pm->ps->clientNum ); - -  if( cont ) -    return qfalse; - -  // jump out of water -  VectorScale( pml.forward, 200, pm->ps->velocity ); -  pm->ps->velocity[ 2 ] = 350; - -  pm->ps->pm_flags |= PMF_TIME_WATERJUMP; -  pm->ps->pm_time = 2000; - -  return qtrue; -} - -//============================================================================ - - -/* -=================== -PM_WaterJumpMove - -Flying out of the water -=================== -*/ -static void PM_WaterJumpMove( void ) -{ -  // waterjump has no control, but falls - -  PM_StepSlideMove( qtrue, qfalse ); - -  pm->ps->velocity[ 2 ] -= pm->ps->gravity * pml.frametime; -  if( pm->ps->velocity[ 2 ] < 0 ) -  { -    // cancel as soon as we are falling down again -    pm->ps->pm_flags &= ~PMF_ALL_TIMES; -    pm->ps->pm_time = 0; -  } -} - -/* -=================== -PM_WaterMove - -=================== -*/ -static void PM_WaterMove( void ) -{ -  int   i; -  vec3_t  wishvel; -  float wishspeed; -  vec3_t  wishdir; -  float scale; -  float vel; - -  if( PM_CheckWaterJump( ) ) -  { -    PM_WaterJumpMove(); -    return; -  } -#if 0 -  // jump = head for surface -  if ( pm->cmd.upmove >= 10 ) { -    if (pm->ps->velocity[2] > -300) { -      if ( pm->watertype == CONTENTS_WATER ) { -        pm->ps->velocity[2] = 100; -      } else if (pm->watertype == CONTENTS_SLIME) { -        pm->ps->velocity[2] = 80; -      } else { -        pm->ps->velocity[2] = 50; -      } -    } -  } -#endif -  PM_Friction( ); - -  scale = PM_CmdScale( &pm->cmd ); -  // -  // user intentions -  // -  if( !scale ) -  { -    wishvel[ 0 ] = 0; -    wishvel[ 1 ] = 0; -    wishvel[ 2 ] = -60;   // sink towards bottom -  } -  else -  { -    for( i = 0; i < 3; i++ ) -      wishvel[ i ] = scale * pml.forward[ i ] * pm->cmd.forwardmove + scale * pml.right[ i ] * pm->cmd.rightmove; - -    wishvel[ 2 ] += scale * pm->cmd.upmove; -  } - -  VectorCopy( wishvel, wishdir ); -  wishspeed = VectorNormalize( wishdir ); - -  if( wishspeed > pm->ps->speed * pm_swimScale ) -    wishspeed = pm->ps->speed * pm_swimScale; - -  PM_Accelerate( wishdir, wishspeed, pm_wateraccelerate ); - -  // make sure we can go up slopes easily under water -  if( pml.groundPlane && DotProduct( pm->ps->velocity, pml.groundTrace.plane.normal ) < 0 ) -  { -    vel = VectorLength( pm->ps->velocity ); -    // slide along the ground plane -    PM_ClipVelocity( pm->ps->velocity, pml.groundTrace.plane.normal, -      pm->ps->velocity, OVERCLIP ); - -    VectorNormalize( pm->ps->velocity ); -    VectorScale( pm->ps->velocity, vel, pm->ps->velocity ); -  } - -  PM_SlideMove( qfalse ); -} - -/* -=================== -PM_JetPackMove - -Only with the jetpack -=================== -*/ -static void PM_JetPackMove( void ) -{ -  int     i; -  vec3_t  wishvel; -  float   wishspeed; -  vec3_t  wishdir; -  float   scale; - -  //normal slowdown -  PM_Friction( ); - -  scale = PM_CmdScale( &pm->cmd ); - -  // user intentions -  for( i = 0; i < 2; i++ ) -    wishvel[ i ] = scale * pml.forward[ i ] * pm->cmd.forwardmove + scale * pml.right[ i ] * pm->cmd.rightmove; - -  if( pm->cmd.upmove > 0.0f ) -    wishvel[ 2 ] = JETPACK_FLOAT_SPEED; -  if( pm->cmd.upmove < 0.0f ) -    wishvel[ 2 ] = -JETPACK_SINK_SPEED; - -  VectorCopy( wishvel, wishdir ); -  wishspeed = VectorNormalize( wishdir ); - -  PM_Accelerate( wishdir, wishspeed, pm_flyaccelerate ); - -  PM_StepSlideMove( qfalse, qfalse ); - -  if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -    PM_ContinueLegsAnim( LEGS_LAND ); -  else -    PM_ContinueLegsAnim( NSPA_LAND ); -} - - - - -/* -=================== -PM_FlyMove - -Only with the flight powerup -=================== -*/ -static void PM_FlyMove( void ) -{ -  int     i; -  vec3_t  wishvel; -  float   wishspeed; -  vec3_t  wishdir; -  float   scale; - -  // normal slowdown -  PM_Friction( ); - -  scale = PM_CmdScale( &pm->cmd ); -  // -  // user intentions -  // -  if( !scale ) -  { -    wishvel[ 0 ] = 0; -    wishvel[ 1 ] = 0; -    wishvel[ 2 ] = 0; -  } -  else -  { -    for( i = 0; i < 3; i++ ) -      wishvel[ i ] = scale * pml.forward[ i ] * pm->cmd.forwardmove + scale * pml.right[ i ] * pm->cmd.rightmove; - -    wishvel[ 2 ] += scale * pm->cmd.upmove; -  } - -  VectorCopy( wishvel, wishdir ); -  wishspeed = VectorNormalize( wishdir ); - -  PM_Accelerate( wishdir, wishspeed, pm_flyaccelerate ); - -  PM_StepSlideMove( qfalse, qfalse ); -} - - -/* -=================== -PM_AirMove - -=================== -*/ -static void PM_AirMove( void ) -{ -  int       i; -  vec3_t    wishvel; -  float     fmove, smove; -  vec3_t    wishdir; -  float     wishspeed; -  float     scale; -  usercmd_t cmd; - -  PM_Friction( ); - -  fmove = pm->cmd.forwardmove; -  smove = pm->cmd.rightmove; - -  cmd = pm->cmd; -  scale = PM_CmdScale( &cmd ); - -  // set the movementDir so clients can rotate the legs for strafing -  PM_SetMovementDir( ); - -  // project moves down to flat plane -  pml.forward[ 2 ] = 0; -  pml.right[ 2 ] = 0; -  VectorNormalize( pml.forward ); -  VectorNormalize( pml.right ); - -  for( i = 0; i < 2; i++ ) -    wishvel[ i ] = pml.forward[ i ] * fmove + pml.right[ i ] * smove; - -  wishvel[ 2 ] = 0; - -  VectorCopy( wishvel, wishdir ); -  wishspeed = VectorNormalize( wishdir ); -  wishspeed *= scale; - -  // not on ground, so little effect on velocity -  PM_Accelerate( wishdir, wishspeed, -    BG_FindAirAccelerationForClass( pm->ps->stats[ STAT_PCLASS ] ) ); - -  // we may have a ground plane that is very steep, even -  // though we don't have a groundentity -  // slide along the steep plane -  if( pml.groundPlane ) -    PM_ClipVelocity( pm->ps->velocity, pml.groundTrace.plane.normal, -      pm->ps->velocity, OVERCLIP ); - -  PM_StepSlideMove( qtrue, qfalse ); -} - -/* -=================== -PM_ClimbMove - -=================== -*/ -static void PM_ClimbMove( void ) -{ -  int       i; -  vec3_t    wishvel; -  float     fmove, smove; -  vec3_t    wishdir; -  float     wishspeed; -  float     scale; -  usercmd_t cmd; -  float     accelerate; -  float     vel; - -  if( pm->waterlevel > 2 && DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) -  { -    // begin swimming -    PM_WaterMove( ); -    return; -  } - - -  if( PM_CheckJump( ) || PM_CheckPounce( ) ) -  { -    // jumped away -    if( pm->waterlevel > 1 ) -      PM_WaterMove( ); -    else -      PM_AirMove( ); - -    return; -  } - -  PM_Friction( ); - -  fmove = pm->cmd.forwardmove; -  smove = pm->cmd.rightmove; - -  cmd = pm->cmd; -  scale = PM_CmdScale( &cmd ); - -  // set the movementDir so clients can rotate the legs for strafing -  PM_SetMovementDir( ); - -  // project the forward and right directions onto the ground plane -  PM_ClipVelocity( pml.forward, pml.groundTrace.plane.normal, pml.forward, OVERCLIP ); -  PM_ClipVelocity( pml.right, pml.groundTrace.plane.normal, pml.right, OVERCLIP ); -  // -  VectorNormalize( pml.forward ); -  VectorNormalize( pml.right ); - -  for( i = 0; i < 3; i++ ) -    wishvel[ i ] = pml.forward[ i ] * fmove + pml.right[ i ] * smove; - -  // when going up or down slopes the wish velocity should Not be zero -//  wishvel[2] = 0; - -  VectorCopy( wishvel, wishdir ); -  wishspeed = VectorNormalize( wishdir ); -  wishspeed *= scale; - -  // clamp the speed lower if ducking -  if( pm->ps->pm_flags & PMF_DUCKED ) -  { -    if( wishspeed > pm->ps->speed * pm_duckScale ) -      wishspeed = pm->ps->speed * pm_duckScale; -  } - -  // clamp the speed lower if wading or walking on the bottom -  if( pm->waterlevel ) -  { -    float waterScale; - -    waterScale = pm->waterlevel / 3.0; -    waterScale = 1.0 - ( 1.0 - pm_swimScale ) * waterScale; -    if( wishspeed > pm->ps->speed * waterScale ) -      wishspeed = pm->ps->speed * waterScale; -  } - -  // when a player gets hit, they temporarily lose -  // full control, which allows them to be moved a bit -  if( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) -    accelerate = BG_FindAirAccelerationForClass( pm->ps->stats[ STAT_PCLASS ] ); -  else -    accelerate = BG_FindAccelerationForClass( pm->ps->stats[ STAT_PCLASS ] ); - -  PM_Accelerate( wishdir, wishspeed, accelerate ); - -  if( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) -    pm->ps->velocity[ 2 ] -= pm->ps->gravity * pml.frametime; - -  vel = VectorLength( pm->ps->velocity ); - -  // slide along the ground plane -  PM_ClipVelocity( pm->ps->velocity, pml.groundTrace.plane.normal, -    pm->ps->velocity, OVERCLIP ); - -  // don't decrease velocity when going up or down a slope -  VectorNormalize( pm->ps->velocity ); -  VectorScale( pm->ps->velocity, vel, pm->ps->velocity ); - -  // don't do anything if standing still -  if( !pm->ps->velocity[ 0 ] && !pm->ps->velocity[ 1 ] && !pm->ps->velocity[ 2 ] ) -    return; - -  PM_StepSlideMove( qfalse, qfalse ); -} - - -/* -=================== -PM_WalkMove - -=================== -*/ -static void PM_WalkMove( void ) -{ -  int       i; -  vec3_t    wishvel; -  float     fmove, smove; -  vec3_t    wishdir; -  float     wishspeed; -  float     scale; -  usercmd_t cmd; -  float     accelerate; -  float     vel; - -  if( pm->waterlevel > 2 && DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) -  { -    // begin swimming -    PM_WaterMove( ); -    return; -  } - - -  if( PM_CheckJump( ) || PM_CheckPounce( ) ) -  { -    // jumped away -    if( pm->waterlevel > 1 ) -      PM_WaterMove( ); -    else -      PM_AirMove( ); - -    return; -  } - -  //charging -  PM_CheckCharge( ); - -  PM_Friction( ); - -  fmove = pm->cmd.forwardmove; -  smove = pm->cmd.rightmove; - -  cmd = pm->cmd; -  scale = PM_CmdScale( &cmd ); - -  // set the movementDir so clients can rotate the legs for strafing -  PM_SetMovementDir( ); - -  // project moves down to flat plane -  pml.forward[ 2 ] = 0; -  pml.right[ 2 ] = 0; - -  // project the forward and right directions onto the ground plane -  PM_ClipVelocity( pml.forward, pml.groundTrace.plane.normal, pml.forward, OVERCLIP ); -  PM_ClipVelocity( pml.right, pml.groundTrace.plane.normal, pml.right, OVERCLIP ); -  // -  VectorNormalize( pml.forward ); -  VectorNormalize( pml.right ); - -  for( i = 0; i < 3; i++ ) -    wishvel[ i ] = pml.forward[ i ] * fmove + pml.right[ i ] * smove; - -  // when going up or down slopes the wish velocity should Not be zero -//  wishvel[2] = 0; - -  VectorCopy( wishvel, wishdir ); -  wishspeed = VectorNormalize( wishdir ); -  wishspeed *= scale; - -  // clamp the speed lower if ducking -  if( pm->ps->pm_flags & PMF_DUCKED ) -  { -    if( wishspeed > pm->ps->speed * pm_duckScale ) -      wishspeed = pm->ps->speed * pm_duckScale; -  } - -  // clamp the speed lower if wading or walking on the bottom -  if( pm->waterlevel ) -  { -    float waterScale; - -    waterScale = pm->waterlevel / 3.0; -    waterScale = 1.0 - ( 1.0 - pm_swimScale ) * waterScale; -    if( wishspeed > pm->ps->speed * waterScale ) -      wishspeed = pm->ps->speed * waterScale; -  } - -  // when a player gets hit, they temporarily lose -  // full control, which allows them to be moved a bit -  if( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) -    accelerate = BG_FindAirAccelerationForClass( pm->ps->stats[ STAT_PCLASS ] ); -  else -    accelerate = BG_FindAccelerationForClass( pm->ps->stats[ STAT_PCLASS ] ); - -  PM_Accelerate( wishdir, wishspeed, accelerate ); - -  //Com_Printf("velocity = %1.1f %1.1f %1.1f\n", pm->ps->velocity[0], pm->ps->velocity[1], pm->ps->velocity[2]); -  //Com_Printf("velocity1 = %1.1f\n", VectorLength(pm->ps->velocity)); - -  if( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) -    pm->ps->velocity[ 2 ] -= pm->ps->gravity * pml.frametime; -  else -  { -    // don't reset the z velocity for slopes -//    pm->ps->velocity[2] = 0; -  } - -  vel = VectorLength( pm->ps->velocity ); - -  // slide along the ground plane -  PM_ClipVelocity( pm->ps->velocity, pml.groundTrace.plane.normal, -    pm->ps->velocity, OVERCLIP ); - -  // don't decrease velocity when going up or down a slope -  VectorNormalize( pm->ps->velocity ); -  VectorScale( pm->ps->velocity, vel, pm->ps->velocity ); - -  // don't do anything if standing still -  if( !pm->ps->velocity[ 0 ] && !pm->ps->velocity[ 1 ] ) -    return; - -  PM_StepSlideMove( qfalse, qfalse ); - -  //Com_Printf("velocity2 = %1.1f\n", VectorLength(pm->ps->velocity)); - -} - - -/* -=================== -PM_LadderMove - -Basically a rip of PM_WaterMove with a few changes -=================== -*/ -static void PM_LadderMove( void ) -{ -  int     i; -  vec3_t  wishvel; -  float   wishspeed; -  vec3_t  wishdir; -  float   scale; -  float   vel; - -  PM_Friction( ); - -  scale = PM_CmdScale( &pm->cmd ); - -  for( i = 0; i < 3; i++ ) -    wishvel[ i ] = scale * pml.forward[ i ] * pm->cmd.forwardmove + scale * pml.right[ i ] * pm->cmd.rightmove; - -  wishvel[ 2 ] += scale * pm->cmd.upmove; - -  VectorCopy( wishvel, wishdir ); -  wishspeed = VectorNormalize( wishdir ); - -  if( wishspeed > pm->ps->speed * pm_swimScale ) -    wishspeed = pm->ps->speed * pm_swimScale; - -  PM_Accelerate( wishdir, wishspeed, pm_accelerate ); - -  //slanty ladders -  if( pml.groundPlane && DotProduct( pm->ps->velocity, pml.groundTrace.plane.normal ) < 0.0f ) -  { -    vel = VectorLength( pm->ps->velocity ); - -    // slide along the ground plane -    PM_ClipVelocity( pm->ps->velocity, pml.groundTrace.plane.normal, -      pm->ps->velocity, OVERCLIP ); - -    VectorNormalize( pm->ps->velocity ); -    VectorScale( pm->ps->velocity, vel, pm->ps->velocity ); -  } - -  PM_SlideMove( qfalse ); -} - - -/* -============= -PM_CheckLadder - -Check to see if the player is on a ladder or not -============= -*/ -static void PM_CheckLadder( void ) -{ -  vec3_t  forward, end; -  trace_t trace; - -  //test if class can use ladders -  if( !BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_CANUSELADDERS ) ) -  { -    pml.ladder = qfalse; -    return; -  } - -  VectorCopy( pml.forward, forward ); -  forward[ 2 ] = 0.0f; - -  VectorMA( pm->ps->origin, 1.0f, forward, end ); - -  pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, MASK_PLAYERSOLID ); - -  if( ( trace.fraction < 1.0f ) && ( trace.surfaceFlags & SURF_LADDER ) ) -    pml.ladder = qtrue; -  else -    pml.ladder = qfalse; -} - - -/* -============== -PM_DeadMove -============== -*/ -static void PM_DeadMove( void ) -{ -  float forward; - -  if( !pml.walking ) -    return; - -  // extra friction - -  forward = VectorLength( pm->ps->velocity ); -  forward -= 20; - -  if( forward <= 0 ) -    VectorClear( pm->ps->velocity ); -  else -  { -    VectorNormalize( pm->ps->velocity ); -    VectorScale( pm->ps->velocity, forward, pm->ps->velocity ); -  } -} - - -/* -=============== -PM_NoclipMove -=============== -*/ -static void PM_NoclipMove( void ) -{ -  float   speed, drop, friction, control, newspeed; -  int     i; -  vec3_t  wishvel; -  float   fmove, smove; -  vec3_t  wishdir; -  float   wishspeed; -  float   scale; - -  pm->ps->viewheight = DEFAULT_VIEWHEIGHT; - -  // friction - -  speed = VectorLength( pm->ps->velocity ); - -  if( speed < 1 ) -  { -    VectorCopy( vec3_origin, pm->ps->velocity ); -  } -  else -  { -    drop = 0; - -    friction = pm_friction * 1.5; // extra friction -    control = speed < pm_stopspeed ? pm_stopspeed : speed; -    drop += control * friction * pml.frametime; - -    // scale the velocity -    newspeed = speed - drop; - -    if( newspeed < 0 ) -      newspeed = 0; - -    newspeed /= speed; - -    VectorScale( pm->ps->velocity, newspeed, pm->ps->velocity ); -  } - -  // accelerate -  scale = PM_CmdScale( &pm->cmd ); - -  fmove = pm->cmd.forwardmove; -  smove = pm->cmd.rightmove; - -  for( i = 0; i < 3; i++ ) -    wishvel[ i ] = pml.forward[ i ] * fmove + pml.right[ i ] * smove; - -  wishvel[ 2 ] += pm->cmd.upmove; - -  VectorCopy( wishvel, wishdir ); -  wishspeed = VectorNormalize( wishdir ); -  wishspeed *= scale; - -  PM_Accelerate( wishdir, wishspeed, pm_accelerate ); - -  // move -  VectorMA( pm->ps->origin, pml.frametime, pm->ps->velocity, pm->ps->origin ); -} - -//============================================================================ - -/* -================ -PM_FootstepForSurface - -Returns an event number apropriate for the groundsurface -================ -*/ -static int PM_FootstepForSurface( void ) -{ -  //TA: -  if( pm->ps->stats[ STAT_STATE ] & SS_CREEPSLOWED ) -    return EV_FOOTSTEP_SQUELCH; - -  if( pml.groundTrace.surfaceFlags & SURF_NOSTEPS ) -    return 0; - -  if( pml.groundTrace.surfaceFlags & SURF_METALSTEPS ) -    return EV_FOOTSTEP_METAL; - -  return EV_FOOTSTEP; -} - - -/* -================= -PM_CrashLand - -Check for hard landings that generate sound events -================= -*/ -static void PM_CrashLand( void ) -{ -  float   delta; -  float   dist; -  float   vel, acc; -  float   t; -  float   a, b, c, den; - -  // decide which landing animation to use -  if( pm->ps->pm_flags & PMF_BACKWARDS_JUMP ) -  { -    if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -      PM_ForceLegsAnim( LEGS_LANDB ); -    else -      PM_ForceLegsAnim( NSPA_LANDBACK ); -  } -  else -  { -    if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -      PM_ForceLegsAnim( LEGS_LAND ); -    else -      PM_ForceLegsAnim( NSPA_LAND ); -  } - -  if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -    pm->ps->legsTimer = TIMER_LAND; -  else -    pm->ps->torsoTimer = TIMER_LAND; - -  // calculate the exact velocity on landing -  dist = pm->ps->origin[ 2 ] - pml.previous_origin[ 2 ]; -  vel = pml.previous_velocity[ 2 ]; -  acc = -pm->ps->gravity; - -  a = acc / 2; -  b = vel; -  c = -dist; - -  den =  b * b - 4 * a * c; -  if( den < 0 ) -    return; - -  t = (-b - sqrt( den ) ) / ( 2 * a ); - -  delta = vel + t * acc; -  delta = delta*delta * 0.0001; - -  // ducking while falling doubles damage -  if( pm->ps->pm_flags & PMF_DUCKED ) -    delta *= 2; - -  // never take falling damage if completely underwater -  if( pm->waterlevel == 3 ) -    return; - -  // reduce falling damage if there is standing water -  if( pm->waterlevel == 2 ) -    delta *= 0.25; - -  if( pm->waterlevel == 1 ) -    delta *= 0.5; - -  if( delta < 1 ) -    return; - -  // create a local entity event to play the sound - -  // SURF_NODAMAGE is used for bounce pads where you don't ever -  // want to take damage or play a crunch sound -  if( !( pml.groundTrace.surfaceFlags & SURF_NODAMAGE ) ) -  { -    pm->ps->stats[ STAT_FALLDIST ] = delta; - -    if( delta > AVG_FALL_DISTANCE ) -    { -      PM_AddEvent( EV_FALL_FAR ); -    } -    else if( delta > MIN_FALL_DISTANCE ) -    { -      // this is a pain grunt, so don't play it if dead -      if( pm->ps->stats[STAT_HEALTH] > 0 ) -        PM_AddEvent( EV_FALL_MEDIUM ); -    } -    else -    { -      if( delta > 7 ) -        PM_AddEvent( EV_FALL_SHORT ); -      else -        PM_AddEvent( PM_FootstepForSurface( ) ); -    } -  } - -  // start footstep cycle over -  pm->ps->bobCycle = 0; -} - - -/* -============= -PM_CorrectAllSolid -============= -*/ -static int PM_CorrectAllSolid( trace_t *trace ) -{ -  int       i, j, k; -  vec3_t    point; - -  if( pm->debugLevel ) -    Com_Printf("%i:allsolid\n", c_pmove); - -  // jitter around -  for( i = -1; i <= 1; i++ ) -  { -    for( j = -1; j <= 1; j++ ) -    { -      for( k = -1; k <= 1; k++ ) -      { -        VectorCopy( pm->ps->origin, point ); -        point[ 0 ] += (float)i; -        point[ 1 ] += (float)j; -        point[ 2 ] += (float)k; -        pm->trace( trace, point, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask ); - -        if( !trace->allsolid ) -        { -          point[ 0 ] = pm->ps->origin[ 0 ]; -          point[ 1 ] = pm->ps->origin[ 1 ]; -          point[ 2 ] = pm->ps->origin[ 2 ] - 0.25; - -          pm->trace( trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask ); -          pml.groundTrace = *trace; -          return qtrue; -        } -      } -    } -  } - -  pm->ps->groundEntityNum = ENTITYNUM_NONE; -  pml.groundPlane = qfalse; -  pml.walking = qfalse; - -  return qfalse; -} - - -/* -============= -PM_GroundTraceMissed - -The ground trace didn't hit a surface, so we are in freefall -============= -*/ -static void PM_GroundTraceMissed( void ) -{ -  trace_t   trace; -  vec3_t    point; - -  if( pm->ps->groundEntityNum != ENTITYNUM_NONE ) -  { -    // we just transitioned into freefall -    if( pm->debugLevel ) -      Com_Printf( "%i:lift\n", c_pmove ); - -    // if they aren't in a jumping animation and the ground is a ways away, force into it -    // if we didn't do the trace, the player would be backflipping down staircases -    VectorCopy( pm->ps->origin, point ); -    point[ 2 ] -= 64.0f; - -    pm->trace( &trace, pm->ps->origin, NULL, NULL, point, pm->ps->clientNum, pm->tracemask ); -    if( trace.fraction == 1.0f ) -    { -      if( pm->cmd.forwardmove >= 0 ) -      { -        if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -          PM_ForceLegsAnim( LEGS_JUMP ); -        else -          PM_ForceLegsAnim( NSPA_JUMP ); - -        pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP; -      } -      else -      { -        if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -          PM_ForceLegsAnim( LEGS_JUMPB ); -        else -          PM_ForceLegsAnim( NSPA_JUMPBACK ); - -        pm->ps->pm_flags |= PMF_BACKWARDS_JUMP; -      } -    } -  } - -  if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_TAKESFALLDAMAGE ) ) -  { -    if( pm->ps->velocity[ 2 ] < FALLING_THRESHOLD && pml.previous_velocity[ 2 ] >= FALLING_THRESHOLD ) -      PM_AddEvent( EV_FALLING ); -  } - -  pm->ps->groundEntityNum = ENTITYNUM_NONE; -  pml.groundPlane = qfalse; -  pml.walking = qfalse; -} - - -/* -============= -PM_GroundClimbTrace -============= -*/ -static void PM_GroundClimbTrace( void ) -{ -  vec3_t    surfNormal, movedir, lookdir, point; -  vec3_t    refNormal = { 0.0f, 0.0f, 1.0f }; -  vec3_t    ceilingNormal = { 0.0f, 0.0f, -1.0f }; -  vec3_t    toAngles, surfAngles; -  trace_t   trace; -  int       i; - -  //used for delta correction -  vec3_t    traceCROSSsurf, traceCROSSref, surfCROSSref; -  float     traceDOTsurf, traceDOTref, surfDOTref, rTtDOTrTsTt; -  float     traceANGsurf, traceANGref, surfANGref; -  vec3_t    horizontal = { 1.0f, 0.0f, 0.0f }; //arbituary vector perpendicular to refNormal -  vec3_t    refTOtrace, refTOsurfTOtrace, tempVec; -  int       rTtANGrTsTt; -  float     ldDOTtCs, d; -  vec3_t    abc; - -  //TA: If we're on the ceiling then grapplePoint is a rotation normal.. otherwise its a surface normal. -  //    would have been nice if Carmack had left a few random variables in the ps struct for mod makers -  if( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) -    VectorCopy( ceilingNormal, surfNormal ); -  else -    VectorCopy( pm->ps->grapplePoint, surfNormal ); - -  //construct a vector which reflects the direction the player is looking wrt the surface normal -  ProjectPointOnPlane( movedir, pml.forward, surfNormal ); -  VectorNormalize( movedir ); - -  VectorCopy( movedir, lookdir ); - -  if( pm->cmd.forwardmove < 0 ) -    VectorNegate( movedir, movedir ); - -  //allow strafe transitions -  if( pm->cmd.rightmove ) -  { -    VectorCopy( pml.right, movedir ); - -    if( pm->cmd.rightmove < 0 ) -      VectorNegate( movedir, movedir ); -  } - -  for( i = 0; i <= 4; i++ ) -  { -    switch ( i ) -    { -      case 0: -        //we are going to step this frame so skip the transition test -        if( PM_PredictStepMove( ) ) -          continue; - -        //trace into direction we are moving -        VectorMA( pm->ps->origin, 0.25f, movedir, point ); -        pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask ); -        break; - -      case 1: -        //trace straight down anto "ground" surface -        VectorMA( pm->ps->origin, -0.25f, surfNormal, point ); -        pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask ); -        break; - -      case 2: -        if( pml.groundPlane != qfalse && PM_PredictStepMove( ) ) -        { -          //step down -          VectorMA( pm->ps->origin, -STEPSIZE, surfNormal, point ); -          pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask ); -        } -        else -          continue; -        break; - -      case 3: -        //trace "underneath" BBOX so we can traverse angles > 180deg -        if( pml.groundPlane != qfalse ) -        { -          VectorMA( pm->ps->origin, -16.0f, surfNormal, point ); -          VectorMA( point, -16.0f, movedir, point ); -          pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask ); -        } -        else -          continue; -        break; - -      case 4: -        //fall back so we don't have to modify PM_GroundTrace too much -        VectorCopy( pm->ps->origin, point ); -        point[ 2 ] = pm->ps->origin[ 2 ] - 0.25f; -        pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask ); -        break; -    } - -    //if we hit something -    if( trace.fraction < 1.0f && !( trace.surfaceFlags & ( SURF_SKY | SURF_SLICK ) ) && -        !( trace.entityNum != ENTITYNUM_WORLD && i != 4 ) ) -    { -      if( i == 2 || i == 3 ) -      { -        if( i == 2 ) -          PM_StepEvent( pm->ps->origin, trace.endpos, surfNormal ); - -        VectorCopy( trace.endpos, pm->ps->origin ); -      } - -      //calculate a bunch of stuff... -      CrossProduct( trace.plane.normal, surfNormal, traceCROSSsurf ); -      VectorNormalize( traceCROSSsurf ); - -      CrossProduct( trace.plane.normal, refNormal, traceCROSSref ); -      VectorNormalize( traceCROSSref ); - -      CrossProduct( surfNormal, refNormal, surfCROSSref ); -      VectorNormalize( surfCROSSref ); - -      //calculate angle between surf and trace -      traceDOTsurf = DotProduct( trace.plane.normal, surfNormal ); -      traceANGsurf = RAD2DEG( acos( traceDOTsurf ) ); - -      if( traceANGsurf > 180.0f ) -        traceANGsurf -= 180.0f; - -      //calculate angle between trace and ref -      traceDOTref = DotProduct( trace.plane.normal, refNormal ); -      traceANGref = RAD2DEG( acos( traceDOTref ) ); - -      if( traceANGref > 180.0f ) -        traceANGref -= 180.0f; - -      //calculate angle between surf and ref -      surfDOTref = DotProduct( surfNormal, refNormal ); -      surfANGref = RAD2DEG( acos( surfDOTref ) ); - -      if( surfANGref > 180.0f ) -        surfANGref -= 180.0f; - -      //if the trace result and old surface normal are different then we must have transided to a new -      //surface... do some stuff... -      if( !VectorCompare( trace.plane.normal, surfNormal ) ) -      { -        //if the trace result or the old vector is not the floor or ceiling correct the YAW angle -        if( !VectorCompare( trace.plane.normal, refNormal ) && !VectorCompare( surfNormal, refNormal ) && -            !VectorCompare( trace.plane.normal, ceilingNormal ) && !VectorCompare( surfNormal, ceilingNormal ) ) -        { -          //behold the evil mindfuck from hell -          //it has fucked mind like nothing has fucked mind before - -          //calculate reference rotated through to trace plane -          RotatePointAroundVector( refTOtrace, traceCROSSref, horizontal, -traceANGref ); - -          //calculate reference rotated through to surf plane then to trace plane -          RotatePointAroundVector( tempVec, surfCROSSref, horizontal, -surfANGref ); -          RotatePointAroundVector( refTOsurfTOtrace, traceCROSSsurf, tempVec, -traceANGsurf ); - -          //calculate angle between refTOtrace and refTOsurfTOtrace -          rTtDOTrTsTt = DotProduct( refTOtrace, refTOsurfTOtrace ); -          rTtANGrTsTt = ANGLE2SHORT( RAD2DEG( acos( rTtDOTrTsTt ) ) ); - -          if( rTtANGrTsTt > 32768 ) -            rTtANGrTsTt -= 32768; - -          CrossProduct( refTOtrace, refTOsurfTOtrace, tempVec ); -          VectorNormalize( tempVec ); -          if( DotProduct( trace.plane.normal, tempVec ) > 0.0f ) -            rTtANGrTsTt = -rTtANGrTsTt; - -          //phew! - correct the angle -          pm->ps->delta_angles[ YAW ] -= rTtANGrTsTt; -        } - -        //construct a plane dividing the surf and trace normals -        CrossProduct( traceCROSSsurf, surfNormal, abc ); -        VectorNormalize( abc ); -        d = DotProduct( abc, pm->ps->origin ); - -        //construct a point representing where the player is looking -        VectorAdd( pm->ps->origin, lookdir, point ); - -        //check whether point is on one side of the plane, if so invert the correction angle -        if( ( abc[ 0 ] * point[ 0 ] + abc[ 1 ] * point[ 1 ] + abc[ 2 ] * point[ 2 ] - d ) > 0 ) -          traceANGsurf = -traceANGsurf; - -        //find the . product of the lookdir and traceCROSSsurf -        if( ( ldDOTtCs = DotProduct( lookdir, traceCROSSsurf ) ) < 0.0f ) -        { -          VectorInverse( traceCROSSsurf ); -          ldDOTtCs = DotProduct( lookdir, traceCROSSsurf ); -        } - -        //set the correction angle -        traceANGsurf *= 1.0f - ldDOTtCs; - -        if( !( pm->ps->persistant[ PERS_STATE ] & PS_WALLCLIMBINGFOLLOW ) ) -        { -          //correct the angle -          pm->ps->delta_angles[ PITCH ] -= ANGLE2SHORT( traceANGsurf ); -        } - -        //transition from wall to ceiling -        //normal for subsequent viewangle rotations -        if( VectorCompare( trace.plane.normal, ceilingNormal ) ) -        { -          CrossProduct( surfNormal, trace.plane.normal, pm->ps->grapplePoint ); -          VectorNormalize( pm->ps->grapplePoint ); -          pm->ps->stats[ STAT_STATE ] |= SS_WALLCLIMBINGCEILING; -        } - -        //transition from ceiling to wall -        //we need to do some different angle correction here cos GPISROTVEC -        if( VectorCompare( surfNormal, ceilingNormal ) ) -        { -          vectoangles( trace.plane.normal, toAngles ); -          vectoangles( pm->ps->grapplePoint, surfAngles ); - -          pm->ps->delta_angles[ 1 ] -= ANGLE2SHORT( ( ( surfAngles[ 1 ] - toAngles[ 1 ] ) * 2 ) - 180.0f ); -        } -      } - -      pml.groundTrace = trace; - -      //so everything knows where we're wallclimbing (ie client side) -      pm->ps->eFlags |= EF_WALLCLIMB; - -      //if we're not stuck to the ceiling then set grapplePoint to be a surface normal -      if( !VectorCompare( trace.plane.normal, ceilingNormal ) ) -      { -        //so we know what surface we're stuck to -        VectorCopy( trace.plane.normal, pm->ps->grapplePoint ); -        pm->ps->stats[ STAT_STATE ] &= ~SS_WALLCLIMBINGCEILING; -      } - -      //IMPORTANT: break out of the for loop if we've hit something -      break; -    } -    else if( trace.allsolid ) -    { -      // do something corrective if the trace starts in a solid... -      if( !PM_CorrectAllSolid( &trace ) ) -        return; -    } -  } - -  if( trace.fraction >= 1.0f ) -  { -    // if the trace didn't hit anything, we are in free fall -    PM_GroundTraceMissed( ); -    pml.groundPlane = qfalse; -    pml.walking = qfalse; -    pm->ps->eFlags &= ~EF_WALLCLIMB; - -    //just transided from ceiling to floor... apply delta correction -    if( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) -    { -      vec3_t  forward, rotated, angles; - -      AngleVectors( pm->ps->viewangles, forward, NULL, NULL ); - -      RotatePointAroundVector( rotated, pm->ps->grapplePoint, forward, 180.0f ); -      vectoangles( rotated, angles ); - -      pm->ps->delta_angles[ YAW ] -= ANGLE2SHORT( angles[ YAW ] - pm->ps->viewangles[ YAW ] ); -    } - -    pm->ps->stats[ STAT_STATE ] &= ~SS_WALLCLIMBINGCEILING; - -    //we get very bizarre effects if we don't do this :0 -    VectorCopy( refNormal, pm->ps->grapplePoint ); -    return; -  } - -  pml.groundPlane = qtrue; -  pml.walking = qtrue; - -  // hitting solid ground will end a waterjump -  if( pm->ps->pm_flags & PMF_TIME_WATERJUMP ) -  { -    pm->ps->pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND); -    pm->ps->pm_time = 0; -  } - -  pm->ps->groundEntityNum = trace.entityNum; - -  // don't reset the z velocity for slopes -//  pm->ps->velocity[2] = 0; - -  PM_AddTouchEnt( trace.entityNum ); -} - - -/* -============= -PM_GroundTrace -============= -*/ -static void PM_GroundTrace( void ) -{ -  vec3_t      point; -  vec3_t      movedir; -  vec3_t      refNormal = { 0.0f, 0.0f, 1.0f }; -  trace_t     trace; - -  if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_WALLCLIMBER ) ) -  { -    if( pm->ps->persistant[ PERS_STATE ] & PS_WALLCLIMBINGTOGGLE ) -    { -      //toggle wall climbing if holding crouch -      if( pm->cmd.upmove < 0 && !( pm->ps->pm_flags & PMF_CROUCH_HELD ) ) -      { -        if( !( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) ) -          pm->ps->stats[ STAT_STATE ] |= SS_WALLCLIMBING; -        else if( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) -          pm->ps->stats[ STAT_STATE ] &= ~SS_WALLCLIMBING; - -        pm->ps->pm_flags |= PMF_CROUCH_HELD; -      } -      else if( pm->cmd.upmove >= 0 ) -        pm->ps->pm_flags &= ~PMF_CROUCH_HELD; -    } -    else -    { -      if( pm->cmd.upmove < 0 ) -        pm->ps->stats[ STAT_STATE ] |= SS_WALLCLIMBING; -      else if( pm->cmd.upmove >= 0 ) -        pm->ps->stats[ STAT_STATE ] &= ~SS_WALLCLIMBING; -    } - -    if( pm->ps->pm_type == PM_DEAD ) -      pm->ps->stats[ STAT_STATE ] &= ~SS_WALLCLIMBING; - -    if( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) -    { -      PM_GroundClimbTrace( ); -      return; -    } - -    //just transided from ceiling to floor... apply delta correction -    if( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) -    { -      vec3_t  forward, rotated, angles; - -      AngleVectors( pm->ps->viewangles, forward, NULL, NULL ); - -      RotatePointAroundVector( rotated, pm->ps->grapplePoint, forward, 180.0f ); -      vectoangles( rotated, angles ); - -      pm->ps->delta_angles[ YAW ] -= ANGLE2SHORT( angles[ YAW ] - pm->ps->viewangles[ YAW ] ); -    } -  } - -  pm->ps->stats[ STAT_STATE ] &= ~SS_WALLCLIMBING; -  pm->ps->stats[ STAT_STATE ] &= ~SS_WALLCLIMBINGCEILING; -  pm->ps->eFlags &= ~EF_WALLCLIMB; - -  point[ 0 ] = pm->ps->origin[ 0 ]; -  point[ 1 ] = pm->ps->origin[ 1 ]; -  point[ 2 ] = pm->ps->origin[ 2 ] - 0.25f; - -  pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask ); - -  pml.groundTrace = trace; - -  // do something corrective if the trace starts in a solid... -  if( trace.allsolid ) -    if( !PM_CorrectAllSolid( &trace ) ) -      return; - -  //make sure that the surfNormal is reset to the ground -  VectorCopy( refNormal, pm->ps->grapplePoint ); - -  // if the trace didn't hit anything, we are in free fall -  if( trace.fraction == 1.0f ) -  { -    qboolean  steppedDown = qfalse; - -    // try to step down -    if( pml.groundPlane != qfalse && PM_PredictStepMove( ) ) -    { -      //step down -      point[ 0 ] = pm->ps->origin[ 0 ]; -      point[ 1 ] = pm->ps->origin[ 1 ]; -      point[ 2 ] = pm->ps->origin[ 2 ] - STEPSIZE; -      pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask ); - -      //if we hit something -      if( trace.fraction < 1.0f ) -      { -        PM_StepEvent( pm->ps->origin, trace.endpos, refNormal ); -        VectorCopy( trace.endpos, pm->ps->origin ); -        steppedDown = qtrue; -      } -    } - -    if( !steppedDown ) -    { -      PM_GroundTraceMissed( ); -      pml.groundPlane = qfalse; -      pml.walking = qfalse; - -      if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_WALLJUMPER ) ) -      { -        ProjectPointOnPlane( movedir, pml.forward, refNormal ); -        VectorNormalize( movedir ); - -        if( pm->cmd.forwardmove < 0 ) -          VectorNegate( movedir, movedir ); - -        //allow strafe transitions -        if( pm->cmd.rightmove ) -        { -          VectorCopy( pml.right, movedir ); - -          if( pm->cmd.rightmove < 0 ) -            VectorNegate( movedir, movedir ); -        } - -        //trace into direction we are moving -        VectorMA( pm->ps->origin, 0.25f, movedir, point ); -        pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask ); - -        if( trace.fraction < 1.0f && !( trace.surfaceFlags & ( SURF_SKY | SURF_SLICK ) ) && -            ( trace.entityNum == ENTITYNUM_WORLD ) ) -        { -          if( !VectorCompare( trace.plane.normal, pm->ps->grapplePoint ) ) -          { -            VectorCopy( trace.plane.normal, pm->ps->grapplePoint ); -            PM_CheckWallJump( ); -          } -        } -      } - -      return; -    } -  } - -  // check if getting thrown off the ground -  if( pm->ps->velocity[ 2 ] > 0.0f && DotProduct( pm->ps->velocity, trace.plane.normal ) > 10.0f ) -  { -    if( pm->debugLevel ) -      Com_Printf( "%i:kickoff\n", c_pmove ); - -    // go into jump animation -    if( pm->cmd.forwardmove >= 0 ) -    { -      if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -        PM_ForceLegsAnim( LEGS_JUMP ); -      else -        PM_ForceLegsAnim( NSPA_JUMP ); - -      pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP; -    } -    else -    { -      if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -        PM_ForceLegsAnim( LEGS_JUMPB ); -      else -        PM_ForceLegsAnim( NSPA_JUMPBACK ); - -      pm->ps->pm_flags |= PMF_BACKWARDS_JUMP; -    } - -    pm->ps->groundEntityNum = ENTITYNUM_NONE; -    pml.groundPlane = qfalse; -    pml.walking = qfalse; -    return; -  } - -  // slopes that are too steep will not be considered onground -  if( trace.plane.normal[ 2 ] < MIN_WALK_NORMAL ) -  { -    if( pm->debugLevel ) -      Com_Printf( "%i:steep\n", c_pmove ); - -    // FIXME: if they can't slide down the slope, let them -    // walk (sharp crevices) -    pm->ps->groundEntityNum = ENTITYNUM_NONE; -    pml.groundPlane = qtrue; -    pml.walking = qfalse; -    return; -  } - -  pml.groundPlane = qtrue; -  pml.walking = qtrue; - -  // hitting solid ground will end a waterjump -  if( pm->ps->pm_flags & PMF_TIME_WATERJUMP ) -  { -    pm->ps->pm_flags &= ~( PMF_TIME_WATERJUMP | PMF_TIME_LAND ); -    pm->ps->pm_time = 0; -  } - -  if( pm->ps->groundEntityNum == ENTITYNUM_NONE ) -  { -    // just hit the ground -    if( pm->debugLevel ) -      Com_Printf( "%i:Land\n", c_pmove ); - -    if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_TAKESFALLDAMAGE ) ) -      PM_CrashLand( ); - -    // don't do landing time if we were just going down a slope -    if( pml.previous_velocity[ 2 ] < -200 ) -    { -      // don't allow another jump for a little while -      pm->ps->pm_flags |= PMF_TIME_LAND; -      pm->ps->pm_time = 250; -    } -  } - -  pm->ps->groundEntityNum = trace.entityNum; - -  // don't reset the z velocity for slopes -//  pm->ps->velocity[2] = 0; - -  PM_AddTouchEnt( trace.entityNum ); -} - - -/* -============= -PM_SetWaterLevel  FIXME: avoid this twice?  certainly if not moving -============= -*/ -static void PM_SetWaterLevel( void ) -{ -  vec3_t  point; -  int     cont; -  int     sample1; -  int     sample2; - -  // -  // get waterlevel, accounting for ducking -  // -  pm->waterlevel = 0; -  pm->watertype = 0; - -  point[ 0 ] = pm->ps->origin[ 0 ]; -  point[ 1 ] = pm->ps->origin[ 1 ]; -  point[ 2 ] = pm->ps->origin[ 2 ] + MINS_Z + 1; -  cont = pm->pointcontents( point, pm->ps->clientNum ); - -  if( cont & MASK_WATER ) -  { -    sample2 = pm->ps->viewheight - MINS_Z; -    sample1 = sample2 / 2; - -    pm->watertype = cont; -    pm->waterlevel = 1; -    point[ 2 ] = pm->ps->origin[ 2 ] + MINS_Z + sample1; -    cont = pm->pointcontents( point, pm->ps->clientNum ); - -    if( cont & MASK_WATER ) -    { -      pm->waterlevel = 2; -      point[ 2 ] = pm->ps->origin[ 2 ] + MINS_Z + sample2; -      cont = pm->pointcontents( point, pm->ps->clientNum ); - -      if( cont & MASK_WATER ) -        pm->waterlevel = 3; -    } -  } -} - - - -/* -============== -PM_CheckDuck - -Sets mins, maxs, and pm->ps->viewheight -============== -*/ -static void PM_CheckDuck (void) -{ -  trace_t trace; -  vec3_t PCmins, PCmaxs, PCcmaxs; -  int PCvh, PCcvh; - -  BG_FindBBoxForClass( pm->ps->stats[ STAT_PCLASS ], PCmins, PCmaxs, PCcmaxs, NULL, NULL ); -  BG_FindViewheightForClass( pm->ps->stats[ STAT_PCLASS ], &PCvh, &PCcvh ); - -  //TA: iD bug? you can still crouch when you're a spectator -  if( pm->ps->persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) -    PCcvh = PCvh; - -  pm->mins[ 0 ] = PCmins[ 0 ]; -  pm->mins[ 1 ] = PCmins[ 1 ]; - -  pm->maxs[ 0 ] = PCmaxs[ 0 ]; -  pm->maxs[ 1 ] = PCmaxs[ 1 ]; - -  pm->mins[ 2 ] = PCmins[ 2 ]; - -  if( pm->ps->pm_type == PM_DEAD ) -  { -    pm->maxs[ 2 ] = -8; -    pm->ps->viewheight = DEAD_VIEWHEIGHT; -    return; -  } - -  //TA: If the standing and crouching viewheights are the same the class can't crouch -  if( ( pm->cmd.upmove < 0 ) && ( PCvh != PCcvh ) && -      pm->ps->pm_type != PM_JETPACK && -      !BG_InventoryContainsUpgrade( UP_BATTLESUIT, pm->ps->stats ) ) -  { -    // duck -    pm->ps->pm_flags |= PMF_DUCKED; -  } -  else -  { -    // stand up if possible -    if( pm->ps->pm_flags & PMF_DUCKED ) -    { -      // try to stand up -      pm->maxs[ 2 ] = PCmaxs[ 2 ]; -      pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, pm->ps->origin, pm->ps->clientNum, pm->tracemask ); -      if( !trace.allsolid ) -        pm->ps->pm_flags &= ~PMF_DUCKED; -    } -  } - -  if( pm->ps->pm_flags & PMF_DUCKED ) -  { -    pm->maxs[ 2 ] = PCcmaxs[ 2 ]; -    pm->ps->viewheight = PCcvh; -  } -  else -  { -    pm->maxs[ 2 ] = PCmaxs[ 2 ]; -    pm->ps->viewheight = PCvh; -  } -} - - - -//=================================================================== - - -/* -=============== -PM_Footsteps -=============== -*/ -static void PM_Footsteps( void ) -{ -  float     bobmove; -  int       old; -  qboolean  footstep; - -  // -  // calculate speed and cycle to be used for -  // all cyclic walking effects -  // -  if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_WALLCLIMBER ) && ( pml.groundPlane ) ) -  { -    //TA: FIXME: yes yes i know this is wrong -    pm->xyspeed = sqrt( pm->ps->velocity[ 0 ] * pm->ps->velocity[ 0 ] -                      + pm->ps->velocity[ 1 ] * pm->ps->velocity[ 1 ] -                      + pm->ps->velocity[ 2 ] * pm->ps->velocity[ 2 ] ); -  } -  else -    pm->xyspeed = sqrt( pm->ps->velocity[ 0 ] * pm->ps->velocity[ 0 ] -      + pm->ps->velocity[ 1 ] * pm->ps->velocity[ 1 ] ); - -  if( pm->ps->groundEntityNum == ENTITYNUM_NONE ) -  { -    // airborne leaves position in cycle intact, but doesn't advance -    if( pm->waterlevel > 1 ) -    { -      if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -        PM_ContinueLegsAnim( LEGS_SWIM ); -      else -        PM_ContinueLegsAnim( NSPA_SWIM ); -    } - -    return; -  } - -  // if not trying to move -  if( !pm->cmd.forwardmove && !pm->cmd.rightmove ) -  { -    if( pm->xyspeed < 5 ) -    { -      pm->ps->bobCycle = 0; // start at beginning of cycle again -      if( pm->ps->pm_flags & PMF_DUCKED ) -      { -        if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -          PM_ContinueLegsAnim( LEGS_IDLECR ); -        else -          PM_ContinueLegsAnim( NSPA_STAND ); -      } -      else -      { -        if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -          PM_ContinueLegsAnim( LEGS_IDLE ); -        else -          PM_ContinueLegsAnim( NSPA_STAND ); -      } -    } -    return; -  } - - -  footstep = qfalse; - -  if( pm->ps->pm_flags & PMF_DUCKED ) -  { -    bobmove = 0.5;  // ducked characters bob much faster - -    if( pm->ps->pm_flags & PMF_BACKWARDS_RUN ) -    { -      if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -        PM_ContinueLegsAnim( LEGS_BACKCR ); -      else -      { -        if( pm->cmd.rightmove > 0 && !pm->cmd.forwardmove ) -          PM_ContinueLegsAnim( NSPA_WALKRIGHT ); -        else if( pm->cmd.rightmove < 0 && !pm->cmd.forwardmove ) -          PM_ContinueLegsAnim( NSPA_WALKLEFT ); -        else -          PM_ContinueLegsAnim( NSPA_WALKBACK ); -      } -    } -    else -    { -      if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -        PM_ContinueLegsAnim( LEGS_WALKCR ); -      else -      { -        if( pm->cmd.rightmove > 0 && !pm->cmd.forwardmove ) -          PM_ContinueLegsAnim( NSPA_WALKRIGHT ); -        else if( pm->cmd.rightmove < 0 && !pm->cmd.forwardmove ) -          PM_ContinueLegsAnim( NSPA_WALKLEFT ); -        else -          PM_ContinueLegsAnim( NSPA_WALK ); -      } -    } - -    // ducked characters never play footsteps -  } -  else -  { -    if( !( pm->cmd.buttons & BUTTON_WALKING ) ) -    { -      bobmove = 0.4f; // faster speeds bob faster - -      if( pm->ps->weapon == WP_ALEVEL4 && pm->ps->pm_flags & PMF_CHARGE ) -        PM_ContinueLegsAnim( NSPA_CHARGE ); -      else if( pm->ps->pm_flags & PMF_BACKWARDS_RUN ) -      { -        if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -          PM_ContinueLegsAnim( LEGS_BACK ); -        else -        { -          if( pm->cmd.rightmove > 0 && !pm->cmd.forwardmove ) -            PM_ContinueLegsAnim( NSPA_RUNRIGHT ); -          else if( pm->cmd.rightmove < 0 && !pm->cmd.forwardmove ) -            PM_ContinueLegsAnim( NSPA_RUNLEFT ); -          else -            PM_ContinueLegsAnim( NSPA_RUNBACK ); -        } -      } -      else -      { -        if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -          PM_ContinueLegsAnim( LEGS_RUN ); -        else -        { -          if( pm->cmd.rightmove > 0 && !pm->cmd.forwardmove ) -            PM_ContinueLegsAnim( NSPA_RUNRIGHT ); -          else if( pm->cmd.rightmove < 0 && !pm->cmd.forwardmove ) -            PM_ContinueLegsAnim( NSPA_RUNLEFT ); -          else -            PM_ContinueLegsAnim( NSPA_RUN ); -        } -      } - -      footstep = qtrue; -    } -    else -    { -      bobmove = 0.3f; // walking bobs slow -      if( pm->ps->pm_flags & PMF_BACKWARDS_RUN ) -      { -        if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -          PM_ContinueLegsAnim( LEGS_BACKWALK ); -        else -        { -          if( pm->cmd.rightmove > 0 && !pm->cmd.forwardmove ) -            PM_ContinueLegsAnim( NSPA_WALKRIGHT ); -          else if( pm->cmd.rightmove < 0 && !pm->cmd.forwardmove ) -            PM_ContinueLegsAnim( NSPA_WALKLEFT ); -          else -            PM_ContinueLegsAnim( NSPA_WALKBACK ); -        } -      } -      else -      { -        if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -          PM_ContinueLegsAnim( LEGS_WALK ); -        else -        { -          if( pm->cmd.rightmove > 0 && !pm->cmd.forwardmove ) -            PM_ContinueLegsAnim( NSPA_WALKRIGHT ); -          else if( pm->cmd.rightmove < 0 && !pm->cmd.forwardmove ) -            PM_ContinueLegsAnim( NSPA_WALKLEFT ); -          else -            PM_ContinueLegsAnim( NSPA_WALK ); -        } -      } -    } -  } - -  bobmove *= BG_FindBobCycleForClass( pm->ps->stats[ STAT_PCLASS ] ); - -  if( pm->ps->stats[ STAT_STATE ] & SS_SPEEDBOOST ) -    bobmove *= HUMAN_SPRINT_MODIFIER; - -  // check for footstep / splash sounds -  old = pm->ps->bobCycle; -  pm->ps->bobCycle = (int)( old + bobmove * pml.msec ) & 255; - -  // if we just crossed a cycle boundary, play an apropriate footstep event -  if( ( ( old + 64 ) ^ ( pm->ps->bobCycle + 64 ) ) & 128 ) -  { -    if( pm->waterlevel == 0 ) -    { -      // on ground will only play sounds if running -      if( footstep && !pm->noFootsteps ) -        PM_AddEvent( PM_FootstepForSurface( ) ); -    } -    else if( pm->waterlevel == 1 ) -    { -      // splashing -      PM_AddEvent( EV_FOOTSPLASH ); -    } -    else if( pm->waterlevel == 2 ) -    { -      // wading / swimming at surface -      PM_AddEvent( EV_SWIM ); -    } -    else if( pm->waterlevel == 3 ) -    { -      // no sound when completely underwater -    } -  } -} - -/* -============== -PM_WaterEvents - -Generate sound events for entering and leaving water -============== -*/ -static void PM_WaterEvents( void ) -{ -  // FIXME? -  // -  // if just entered a water volume, play a sound -  // -  if( !pml.previous_waterlevel && pm->waterlevel ) -    PM_AddEvent( EV_WATER_TOUCH ); - -  // -  // if just completely exited a water volume, play a sound -  // -  if( pml.previous_waterlevel && !pm->waterlevel ) -    PM_AddEvent( EV_WATER_LEAVE ); - -  // -  // check for head just going under water -  // -  if( pml.previous_waterlevel != 3 && pm->waterlevel == 3 ) -    PM_AddEvent( EV_WATER_UNDER ); - -  // -  // check for head just coming out of water -  // -  if( pml.previous_waterlevel == 3 && pm->waterlevel != 3 ) -    PM_AddEvent( EV_WATER_CLEAR ); -} - - -/* -=============== -PM_BeginWeaponChange -=============== -*/ -static void PM_BeginWeaponChange( int weapon ) -{ -  if( weapon < WP_NONE || weapon >= WP_NUM_WEAPONS ) -    return; - -  if( !BG_InventoryContainsWeapon( weapon, pm->ps->stats ) && weapon != WP_NONE ) -    return; - -  if( pm->ps->weaponstate == WEAPON_DROPPING ) -    return; - -  PM_AddEvent( EV_CHANGE_WEAPON ); -  pm->ps->weaponstate = WEAPON_DROPPING; -  pm->ps->weaponTime += 200; -  pm->ps->persistant[ PERS_NEWWEAPON ] = weapon; - -  //reset build weapon -  pm->ps->stats[ STAT_BUILDABLE ] = BA_NONE; - -  if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -    PM_StartTorsoAnim( TORSO_DROP ); -} - - -/* -=============== -PM_FinishWeaponChange -=============== -*/ -static void PM_FinishWeaponChange( void ) -{ -  int   weapon; - -  weapon = pm->ps->persistant[ PERS_NEWWEAPON ]; -  if( weapon < WP_NONE || weapon >= WP_NUM_WEAPONS ) -    weapon = WP_NONE; - -  if( !BG_InventoryContainsWeapon( weapon, pm->ps->stats ) ) -    weapon = WP_NONE; - -  pm->ps->weapon = weapon; -  pm->ps->weaponstate = WEAPON_RAISING; -  pm->ps->weaponTime += 250; - -  if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -    PM_StartTorsoAnim( TORSO_RAISE ); -} - - -/* -============== -PM_TorsoAnimation - -============== -*/ -static void PM_TorsoAnimation( void ) -{ -  if( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) -    return; - -  if( pm->ps->weaponstate == WEAPON_READY ) -  { -    if( pm->ps->weapon == WP_BLASTER ) -      PM_ContinueTorsoAnim( TORSO_STAND2 ); -    else -      PM_ContinueTorsoAnim( TORSO_STAND ); -  } -} - - -/* -============== -PM_Weapon - -Generates weapon events and modifes the weapon counter -============== -*/ -static void PM_Weapon( void ) -{ -  int           addTime = 200; //default addTime - should never be used -  int           ammo, clips, maxClips; -  qboolean      attack1 = qfalse; -  qboolean      attack2 = qfalse; -  qboolean      attack3 = qfalse; - -  // don't allow attack until all buttons are up -  if( pm->ps->pm_flags & PMF_RESPAWNED ) -    return; - -  // ignore if spectator -  if( pm->ps->persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) -    return; - -  if( pm->ps->stats[ STAT_STATE ] & SS_INFESTING ) -    return; - -  if( pm->ps->stats[ STAT_STATE ] & SS_HOVELING ) -    return; - -  // check for dead player -  if( pm->ps->stats[ STAT_HEALTH ] <= 0 ) -  { -    pm->ps->weapon = WP_NONE; -    return; -  } - -  // make weapon function -  if( pm->ps->weaponTime > 0 ) -    pm->ps->weaponTime -= pml.msec; - -  // check for weapon change -  // can't change if weapon is firing, but can change -  // again if lowering or raising -  if( pm->ps->weaponTime <= 0 || pm->ps->weaponstate != WEAPON_FIRING ) -  { -    //TA: must press use to switch weapons -    if( pm->cmd.buttons & BUTTON_USE_HOLDABLE ) -    { -      if( !( pm->ps->pm_flags & PMF_USE_ITEM_HELD ) ) -      { -        if( pm->cmd.weapon <= 32 ) -        { -          //if trying to select a weapon, select it -          if( pm->ps->weapon != pm->cmd.weapon ) -            PM_BeginWeaponChange( pm->cmd.weapon ); -        } -        else if( pm->cmd.weapon > 32 ) -        { -          //if trying to toggle an upgrade, toggle it -          if( BG_InventoryContainsUpgrade( pm->cmd.weapon - 32, pm->ps->stats ) ) //sanity check -          { -            if( BG_UpgradeIsActive( pm->cmd.weapon - 32, pm->ps->stats ) ) -              BG_DeactivateUpgrade( pm->cmd.weapon - 32, pm->ps->stats ); -            else -              BG_ActivateUpgrade( pm->cmd.weapon - 32, pm->ps->stats ); -          } -        } -        pm->ps->pm_flags |= PMF_USE_ITEM_HELD; -      } -    } -    else -      pm->ps->pm_flags &= ~PMF_USE_ITEM_HELD; - -    //something external thinks a weapon change is necessary -    if( pm->ps->pm_flags & PMF_WEAPON_SWITCH ) -    { -      pm->ps->pm_flags &= ~PMF_WEAPON_SWITCH; -      PM_BeginWeaponChange( pm->ps->persistant[ PERS_NEWWEAPON ] ); -    } -  } - -  if( pm->ps->weaponTime > 0 ) -    return; - -  // change weapon if time -  if( pm->ps->weaponstate == WEAPON_DROPPING ) -  { -    PM_FinishWeaponChange( ); -    return; -  } - -  if( pm->ps->weaponstate == WEAPON_RAISING ) -  { -    pm->ps->weaponstate = WEAPON_READY; - -    if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -    { -      if( pm->ps->weapon == WP_BLASTER ) -        PM_ContinueTorsoAnim( TORSO_STAND2 ); -      else -        PM_ContinueTorsoAnim( TORSO_STAND ); -    } - -    return; -  } - -  // start the animation even if out of ammo - -  BG_UnpackAmmoArray( pm->ps->weapon, pm->ps->ammo, pm->ps->powerups, &ammo, &clips ); -  BG_FindAmmoForWeapon( pm->ps->weapon, NULL, &maxClips ); - -  // check for out of ammo -  if( !ammo && !clips && !BG_FindInfinteAmmoForWeapon( pm->ps->weapon ) ) -  { -    PM_AddEvent( EV_NOAMMO ); -    pm->ps->weaponTime += 200; -    return; -  } - -  //done reloading so give em some ammo -  if( pm->ps->weaponstate == WEAPON_RELOADING ) -  { -    if( maxClips > 0 ) -    { -      clips--; -      BG_FindAmmoForWeapon( pm->ps->weapon, &ammo, NULL ); -    } - -    if( BG_FindUsesEnergyForWeapon( pm->ps->weapon ) && -        BG_InventoryContainsUpgrade( UP_BATTPACK, pm->ps->stats ) ) -      ammo = (int)( (float)ammo * BATTPACK_MODIFIER ); - -    BG_PackAmmoArray( pm->ps->weapon, pm->ps->ammo, pm->ps->powerups, ammo, clips ); - -    //allow some time for the weapon to be raised -    pm->ps->weaponstate = WEAPON_RAISING; -    PM_StartTorsoAnim( TORSO_RAISE ); -    pm->ps->weaponTime += 250; -    return; -  } - -  // check for end of clip -  if( ( !ammo || pm->ps->pm_flags & PMF_WEAPON_RELOAD ) && clips ) -  { -    pm->ps->pm_flags &= ~PMF_WEAPON_RELOAD; - -    pm->ps->weaponstate = WEAPON_RELOADING; - -    //drop the weapon -    PM_StartTorsoAnim( TORSO_DROP ); - -    addTime = BG_FindReloadTimeForWeapon( pm->ps->weapon ); - -    pm->ps->weaponTime += addTime; -    return; -  } - -  //check if non-auto primary/secondary attacks are permited -  switch( pm->ps->weapon ) -  { -    case WP_ALEVEL0: -      //venom is only autohit -      attack1 = attack2 = attack3 = qfalse; - -      if( !pm->autoWeaponHit[ pm->ps->weapon ] ) -      { -        pm->ps->weaponTime = 0; -        pm->ps->weaponstate = WEAPON_READY; -        return; -      } -      break; - -    case WP_ALEVEL3: -    case WP_ALEVEL3_UPG: -      //pouncing has primary secondary AND autohit procedures -      attack1 = pm->cmd.buttons & BUTTON_ATTACK; -      attack2 = pm->cmd.buttons & BUTTON_ATTACK2; -      attack3 = pm->cmd.buttons & BUTTON_USE_HOLDABLE; - -      if( !pm->autoWeaponHit[ pm->ps->weapon ] && !attack1 && !attack2 && !attack3 ) -      { -        pm->ps->weaponTime = 0; -        pm->ps->weaponstate = WEAPON_READY; -        return; -      } -      break; - -    case WP_LUCIFER_CANNON: -      attack1 = pm->cmd.buttons & BUTTON_ATTACK; -      attack2 = pm->cmd.buttons & BUTTON_ATTACK2; -      attack3 = pm->cmd.buttons & BUTTON_USE_HOLDABLE; - -      if( ( attack1 || pm->ps->stats[ STAT_MISC ] == 0 ) && !attack2 && !attack3 ) -      { -        if( pm->ps->stats[ STAT_MISC ] < LCANNON_TOTAL_CHARGE ) -        { -          pm->ps->weaponTime = 0; -          pm->ps->weaponstate = WEAPON_READY; -          return; -        } -        else -          attack1 = !attack1; -      } - -      //erp this looks confusing -      if( pm->ps->stats[ STAT_MISC ] > 0 ) -        attack1 = !attack1; -      break; - -    default: -      //by default primary and secondary attacks are allowed -      attack1 = pm->cmd.buttons & BUTTON_ATTACK; -      attack2 = pm->cmd.buttons & BUTTON_ATTACK2; -      attack3 = pm->cmd.buttons & BUTTON_USE_HOLDABLE; - -      if( !attack1 && !attack2 && !attack3 ) -      { -        pm->ps->weaponTime = 0; -        pm->ps->weaponstate = WEAPON_READY; -        return; -      } -      break; -  } - -  //TA: fire events for non auto weapons -  if( attack3 ) -  { -    if( BG_WeaponHasThirdMode( pm->ps->weapon ) ) -    { -      //hacky special case for slowblob -      if( pm->ps->weapon == WP_ALEVEL3_UPG && !ammo ) -      { -        PM_AddEvent( EV_NOAMMO ); -        pm->ps->weaponTime += 200; -        return; -      } - -      pm->ps->generic1 = WPM_TERTIARY; -      PM_AddEvent( EV_FIRE_WEAPON3 ); -      addTime = BG_FindRepeatRate3ForWeapon( pm->ps->weapon ); -    } -    else -    { -      pm->ps->weaponTime = 0; -      pm->ps->weaponstate = WEAPON_READY; -      return; -    } -  } -  else if( attack2 ) -  { -    if( BG_WeaponHasAltMode( pm->ps->weapon ) ) -    { -      pm->ps->generic1 = WPM_SECONDARY; -      PM_AddEvent( EV_FIRE_WEAPON2 ); -      addTime = BG_FindRepeatRate2ForWeapon( pm->ps->weapon ); -    } -    else -    { -      pm->ps->weaponTime = 0; -      pm->ps->weaponstate = WEAPON_READY; -      return; -    } -  } -  else if( attack1 ) -  { -    pm->ps->generic1 = WPM_PRIMARY; -    PM_AddEvent( EV_FIRE_WEAPON ); -    addTime = BG_FindRepeatRate1ForWeapon( pm->ps->weapon ); -  } - -  //TA: fire events for autohit weapons -  if( pm->autoWeaponHit[ pm->ps->weapon ] ) -  { -    switch( pm->ps->weapon ) -    { -      case WP_ALEVEL0: -        pm->ps->generic1 = WPM_PRIMARY; -        PM_AddEvent( EV_FIRE_WEAPON ); -        addTime = BG_FindRepeatRate1ForWeapon( pm->ps->weapon ); -        break; - -      case WP_ALEVEL3: -      case WP_ALEVEL3_UPG: -        pm->ps->generic1 = WPM_SECONDARY; -        PM_AddEvent( EV_FIRE_WEAPON2 ); -        addTime = BG_FindRepeatRate2ForWeapon( pm->ps->weapon ); -        break; - -      default: -        break; -    } -  } - -  if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -  { -    //FIXME: this should be an option in the client weapon.cfg -    switch( pm->ps->weapon ) -    { -      case WP_FLAMER: -        if( pm->ps->weaponstate == WEAPON_READY ) -        { -          PM_StartTorsoAnim( TORSO_ATTACK ); -        } -        break; - -      case WP_BLASTER: -        PM_StartTorsoAnim( TORSO_ATTACK2 ); -        break; - -      default: -        PM_StartTorsoAnim( TORSO_ATTACK ); -        break; -    } -  } -  else -  { -    if( pm->ps->weapon == WP_ALEVEL4 ) -    { -      //hack to get random attack animations -      //FIXME: does pm->ps->weaponTime cycle enough? -      int num = abs( pm->ps->weaponTime ) % 3; - -      if( num == 0 ) -        PM_ForceLegsAnim( NSPA_ATTACK1 ); -      else if( num == 1 ) -        PM_ForceLegsAnim( NSPA_ATTACK2 ); -      else if( num == 2 ) -        PM_ForceLegsAnim( NSPA_ATTACK3 ); -    } -    else -    { -      if( attack1 ) -        PM_ForceLegsAnim( NSPA_ATTACK1 ); -      else if( attack2 ) -        PM_ForceLegsAnim( NSPA_ATTACK2 ); -      else if( attack3 ) -        PM_ForceLegsAnim( NSPA_ATTACK3 ); -    } - -    pm->ps->torsoTimer = TIMER_ATTACK; -  } - -  pm->ps->weaponstate = WEAPON_FIRING; - -  // take an ammo away if not infinite -  if( !BG_FindInfinteAmmoForWeapon( pm->ps->weapon ) ) -  { -    //special case for lCanon -    if( pm->ps->weapon == WP_LUCIFER_CANNON && attack1 ) -    { -      ammo -= (int)( ceil( ( (float)pm->ps->stats[ STAT_MISC ] / (float)LCANNON_TOTAL_CHARGE ) * 10.0f ) ); - -      //stay on the safe side -      if( ammo < 0 ) -        ammo = 0; -    } -    else -      ammo--; - -    BG_PackAmmoArray( pm->ps->weapon, pm->ps->ammo, pm->ps->powerups, ammo, clips ); -  } -  else if( pm->ps->weapon == WP_ALEVEL3_UPG && attack3 ) -  { -    //special case for slowblob -    ammo--; -    BG_PackAmmoArray( pm->ps->weapon, pm->ps->ammo, pm->ps->powerups, ammo, clips ); -  } - -  //FIXME: predicted angles miss a problem?? -  if( pm->ps->weapon == WP_CHAINGUN ) -  { -    if( pm->ps->pm_flags & PMF_DUCKED || -        BG_InventoryContainsUpgrade( UP_BATTLESUIT, pm->ps->stats ) ) -    { -      pm->ps->delta_angles[ PITCH ] -= ANGLE2SHORT( ( ( random() * 0.5 ) - 0.125 ) * ( 30 / (float)addTime ) ); -      pm->ps->delta_angles[ YAW ] -= ANGLE2SHORT( ( ( random() * 0.5 ) - 0.25 ) * ( 30.0 / (float)addTime ) ); -    } -    else -    { -      pm->ps->delta_angles[ PITCH ] -= ANGLE2SHORT( ( ( random() * 8 ) - 2 ) * ( 30.0 / (float)addTime ) ); -      pm->ps->delta_angles[ YAW ] -= ANGLE2SHORT( ( ( random() * 8 ) - 4 ) * ( 30.0 / (float)addTime ) ); -    } -  } - -  pm->ps->weaponTime += addTime; -} - -/* -================ -PM_Animate -================ -*/ -static void PM_Animate( void ) -{ -  if( pm->cmd.buttons & BUTTON_GESTURE ) -  { -    if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -    { -      if( pm->ps->torsoTimer == 0 ) -      { -        PM_StartTorsoAnim( TORSO_GESTURE ); -        pm->ps->torsoTimer = TIMER_GESTURE; - -        PM_AddEvent( EV_TAUNT ); -      } -    } -    else -    { -      if( pm->ps->torsoTimer == 0 ) -      { -        PM_ForceLegsAnim( NSPA_GESTURE ); -        pm->ps->torsoTimer = TIMER_GESTURE; - -        PM_AddEvent( EV_TAUNT ); -      } -    } -  } -} - - -/* -================ -PM_DropTimers -================ -*/ -static void PM_DropTimers( void ) -{ -  // drop misc timing counter -  if( pm->ps->pm_time ) -  { -    if( pml.msec >= pm->ps->pm_time ) -    { -      pm->ps->pm_flags &= ~PMF_ALL_TIMES; -      pm->ps->pm_time = 0; -    } -    else -      pm->ps->pm_time -= pml.msec; -  } - -  // drop animation counter -  if( pm->ps->legsTimer > 0 ) -  { -    pm->ps->legsTimer -= pml.msec; - -    if( pm->ps->legsTimer < 0 ) -      pm->ps->legsTimer = 0; -  } - -  if( pm->ps->torsoTimer > 0 ) -  { -    pm->ps->torsoTimer -= pml.msec; - -    if( pm->ps->torsoTimer < 0 ) -      pm->ps->torsoTimer = 0; -  } -} - - -/* -================ -PM_UpdateViewAngles - -This can be used as another entry point when only the viewangles -are being updated instead of a full move -================ -*/ -void PM_UpdateViewAngles( playerState_t *ps, const usercmd_t *cmd ) -{ -  short   temp[ 3 ]; -  int     i; -  vec3_t  axis[ 3 ], rotaxis[ 3 ]; -  vec3_t  tempang; - -  if( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPINTERMISSION ) -    return;   // no view changes at all - -  if( ps->pm_type != PM_SPECTATOR && ps->stats[ STAT_HEALTH ] <= 0 ) -    return;   // no view changes at all - -  // circularly clamp the angles with deltas -  for( i = 0; i < 3; i++ ) -  { -    temp[ i ] = cmd->angles[ i ] + ps->delta_angles[ i ]; - -    if( i == PITCH ) -    { -      // don't let the player look up or down more than 90 degrees -      if( temp[ i ] > 16000 ) -      { -        ps->delta_angles[ i ] = 16000 - cmd->angles[ i ]; -        temp[ i ] = 16000; -      } -      else if( temp[ i ] < -16000 ) -      { -        ps->delta_angles[ i ] = -16000 - cmd->angles[ i ]; -        temp[ i ] = -16000; -      } -    } -    tempang[ i ] = SHORT2ANGLE( temp[ i ] ); -  } - -  //convert viewangles -> axis -  AnglesToAxis( tempang, axis ); - -  if( !( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) || -      !BG_RotateAxis( ps->grapplePoint, axis, rotaxis, qfalse, -                      ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) ) -    AxisCopy( axis, rotaxis ); - -  //convert the new axis back to angles -  AxisToAngles( rotaxis, tempang ); - -  //force angles to -180 <= x <= 180 -  for( i = 0; i < 3; i++ ) -  { -    while( tempang[ i ] > 180 ) -      tempang[ i ] -= 360; - -    while( tempang[ i ] < 180 ) -      tempang[ i ] += 360; -  } - -  //actually set the viewangles -  for( i = 0; i < 3; i++ ) -    ps->viewangles[ i ] = tempang[ i ]; - -  //pull the view into the lock point -  if( ps->pm_type == PM_GRABBED && !BG_InventoryContainsUpgrade( UP_BATTLESUIT, ps->stats ) ) -  { -    vec3_t  dir, angles; - -    ByteToDir( ps->stats[ STAT_VIEWLOCK ], dir ); -    vectoangles( dir, angles ); - -    for( i = 0; i < 3; i++ ) -    { -      float diff = AngleSubtract( ps->viewangles[ i ], angles[ i ] ); - -      while( diff > 180.0f ) -        diff -= 360.0f; -      while( diff < -180.0f ) -        diff += 360.0f; - -      if( diff < -90.0f ) -        ps->delta_angles[ i ] += ANGLE2SHORT( fabs( diff ) - 90.0f ); -      else if( diff > 90.0f ) -        ps->delta_angles[ i ] -= ANGLE2SHORT( fabs( diff ) - 90.0f ); - -      if( diff < 0.0f ) -        ps->delta_angles[ i ] += ANGLE2SHORT( fabs( diff ) * 0.05f ); -      else if( diff > 0.0f ) -        ps->delta_angles[ i ] -= ANGLE2SHORT( fabs( diff ) * 0.05f ); -    } -  } -} - - -/* -================ -PmoveSingle - -================ -*/ -void trap_SnapVector( float *v ); - -void PmoveSingle( pmove_t *pmove ) -{ -  int ammo, clips; - -  pm = pmove; - -  BG_UnpackAmmoArray( pm->ps->weapon, pm->ps->ammo, pm->ps->powerups, &ammo, &clips ); - -  // this counter lets us debug movement problems with a journal -  // by setting a conditional breakpoint fot the previous frame -  c_pmove++; - -  // clear results -  pm->numtouch = 0; -  pm->watertype = 0; -  pm->waterlevel = 0; - -  if( pm->ps->stats[ STAT_HEALTH ] <= 0 ) -    pm->tracemask &= ~CONTENTS_BODY;  // corpses can fly through bodies - -  // make sure walking button is clear if they are running, to avoid -  // proxy no-footsteps cheats -  if( abs( pm->cmd.forwardmove ) > 64 || abs( pm->cmd.rightmove ) > 64 ) -    pm->cmd.buttons &= ~BUTTON_WALKING; - -  // set the talk balloon flag -  if( pm->cmd.buttons & BUTTON_TALK ) -    pm->ps->eFlags |= EF_TALK; -  else -    pm->ps->eFlags &= ~EF_TALK; - -  // set the firing flag for continuous beam weapons -  if( !(pm->ps->pm_flags & PMF_RESPAWNED) && pm->ps->pm_type != PM_INTERMISSION && -      ( pm->cmd.buttons & BUTTON_ATTACK ) && -      ( ( ammo > 0 || clips > 0 ) || BG_FindInfinteAmmoForWeapon( pm->ps->weapon ) ) ) -    pm->ps->eFlags |= EF_FIRING; -  else -    pm->ps->eFlags &= ~EF_FIRING; - -  // set the firing flag for continuous beam weapons -  if( !(pm->ps->pm_flags & PMF_RESPAWNED) && pm->ps->pm_type != PM_INTERMISSION && -      ( pm->cmd.buttons & BUTTON_ATTACK2 ) && -      ( ( ammo > 0 || clips > 0 ) || BG_FindInfinteAmmoForWeapon( pm->ps->weapon ) ) ) -    pm->ps->eFlags |= EF_FIRING2; -  else -    pm->ps->eFlags &= ~EF_FIRING2; - -  // set the firing flag for continuous beam weapons -  if( !(pm->ps->pm_flags & PMF_RESPAWNED) && pm->ps->pm_type != PM_INTERMISSION && -      ( pm->cmd.buttons & BUTTON_USE_HOLDABLE ) && -      ( ( ammo > 0 || clips > 0 ) || BG_FindInfinteAmmoForWeapon( pm->ps->weapon ) ) ) -    pm->ps->eFlags |= EF_FIRING3; -  else -    pm->ps->eFlags &= ~EF_FIRING3; - - -  // clear the respawned flag if attack and use are cleared -  if( pm->ps->stats[STAT_HEALTH] > 0 && -      !( pm->cmd.buttons & ( BUTTON_ATTACK | BUTTON_USE_HOLDABLE ) ) ) -    pm->ps->pm_flags &= ~PMF_RESPAWNED; - -  // if talk button is down, dissallow all other input -  // this is to prevent any possible intercept proxy from -  // adding fake talk balloons -  if( pmove->cmd.buttons & BUTTON_TALK ) -  { -    pmove->cmd.buttons = BUTTON_TALK; -    pmove->cmd.forwardmove = 0; -    pmove->cmd.rightmove = 0; -    pmove->cmd.upmove = 0; -  } - -  // clear all pmove local vars -  memset( &pml, 0, sizeof( pml ) ); - -  // determine the time -  pml.msec = pmove->cmd.serverTime - pm->ps->commandTime; - -  if( pml.msec < 1 ) -    pml.msec = 1; -  else if( pml.msec > 200 ) -    pml.msec = 200; - -  pm->ps->commandTime = pmove->cmd.serverTime; - -  // save old org in case we get stuck -  VectorCopy( pm->ps->origin, pml.previous_origin ); - -  // save old velocity for crashlanding -  VectorCopy( pm->ps->velocity, pml.previous_velocity ); - -  pml.frametime = pml.msec * 0.001; - -  AngleVectors( pm->ps->viewangles, pml.forward, pml.right, pml.up ); - -  if( pm->cmd.upmove < 10 ) -  { -    // not holding jump -    pm->ps->pm_flags &= ~PMF_JUMP_HELD; -  } - -  // decide if backpedaling animations should be used -  if( pm->cmd.forwardmove < 0 ) -    pm->ps->pm_flags |= PMF_BACKWARDS_RUN; -  else if( pm->cmd.forwardmove > 0 || ( pm->cmd.forwardmove == 0 && pm->cmd.rightmove ) ) -    pm->ps->pm_flags &= ~PMF_BACKWARDS_RUN; - -  if( pm->ps->pm_type >= PM_DEAD ) -  { -    pm->cmd.forwardmove = 0; -    pm->cmd.rightmove = 0; -    pm->cmd.upmove = 0; -  } - -  if( pm->ps->pm_type == PM_SPECTATOR ) -  { -    // update the viewangles -    PM_UpdateViewAngles( pm->ps, &pm->cmd ); -    PM_CheckDuck( ); -    PM_FlyMove( ); -    PM_DropTimers( ); -    return; -  } - -  if( pm->ps->pm_type == PM_NOCLIP ) -  { -    PM_UpdateViewAngles( pm->ps, &pm->cmd ); -    PM_NoclipMove( ); -    PM_DropTimers( ); -    return; -  } - -  if( pm->ps->pm_type == PM_FREEZE) -    return;   // no movement at all - -  if( pm->ps->pm_type == PM_INTERMISSION || pm->ps->pm_type == PM_SPINTERMISSION ) -    return;   // no movement at all - -  // set watertype, and waterlevel -  PM_SetWaterLevel( ); -  pml.previous_waterlevel = pmove->waterlevel; - -  // set mins, maxs, and viewheight -  PM_CheckDuck( ); - -  PM_CheckLadder( ); - -  // set groundentity -  PM_GroundTrace( ); - -  // update the viewangles -  PM_UpdateViewAngles( pm->ps, &pm->cmd ); - -  if( pm->ps->pm_type == PM_DEAD || pm->ps->pm_type == PM_GRABBED ) -    PM_DeadMove( ); - -  PM_DropTimers( ); - -  if( pm->ps->pm_type == PM_JETPACK ) -    PM_JetPackMove( ); -  else if( pm->ps->pm_flags & PMF_TIME_WATERJUMP ) -    PM_WaterJumpMove( ); -  else if( pm->waterlevel > 1 ) -    PM_WaterMove( ); -  else if( pml.ladder ) -    PM_LadderMove( ); -  else if( pml.walking ) -  { -    if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_WALLCLIMBER ) && -        ( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) ) -      PM_ClimbMove( ); //TA: walking on any surface -    else -      PM_WalkMove( ); // walking on ground -  } -  else -    PM_AirMove( ); - -  PM_Animate( ); - -  // set groundentity, watertype, and waterlevel -  PM_GroundTrace( ); -  //TA: must update after every GroundTrace() - yet more clock cycles down the drain :( (14 vec rotations/frame) -  // update the viewangles -  PM_UpdateViewAngles( pm->ps, &pm->cmd ); - -  PM_SetWaterLevel( ); - -  // weapons -  PM_Weapon( ); - -  // torso animation -  PM_TorsoAnimation( ); - -  // footstep events / legs animations -  PM_Footsteps( ); - -  // entering / leaving water splashes -  PM_WaterEvents( ); - -  // snap some parts of playerstate to save network bandwidth -  trap_SnapVector( pm->ps->velocity ); -} - - -/* -================ -Pmove - -Can be called by either the server or the client -================ -*/ -void Pmove( pmove_t *pmove ) -{ -  int finalTime; - -  finalTime = pmove->cmd.serverTime; - -  if( finalTime < pmove->ps->commandTime ) -    return; // should not happen - -  if( finalTime > pmove->ps->commandTime + 1000 ) -    pmove->ps->commandTime = finalTime - 1000; - -  pmove->ps->pmove_framecount = ( pmove->ps->pmove_framecount + 1 ) & ( ( 1 << PS_PMOVEFRAMECOUNTBITS ) - 1 ); - -  // chop the move up if it is too long, to prevent framerate -  // dependent behavior -  while( pmove->ps->commandTime != finalTime ) -  { -    int   msec; - -    msec = finalTime - pmove->ps->commandTime; - -    if( pmove->pmove_fixed ) -    { -      if( msec > pmove->pmove_msec ) -        msec = pmove->pmove_msec; -    } -    else -    { -      if( msec > 66 ) -        msec = 66; -    } - - -    pmove->cmd.serverTime = pmove->ps->commandTime + msec; -    PmoveSingle( pmove ); - -    if( pmove->ps->pm_flags & PMF_JUMP_HELD ) -      pmove->cmd.upmove = 20; -  } -} diff --git a/mod/src/game/bg_public.h b/mod/src/game/bg_public.h deleted file mode 100644 index fa84b440..00000000 --- a/mod/src/game/bg_public.h +++ /dev/null @@ -1,1299 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// bg_public.h -- definitions shared by both the server game and client game modules - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -//tremulous balance header -#include "tremulous.h" - -// because games can change separately from the main system version, we need a -// second version that must match between game and cgame -#define GAME_VERSION            "tremulous" - -#define DEFAULT_GRAVITY         800 - -#define SCORE_NOT_PRESENT       -9999 // for the CS_SCORES[12] when only one player is present - -#define VOTE_TIME               30000 // 30 seconds before vote times out - -#define MINS_Z                  -24 -#define DEFAULT_VIEWHEIGHT      26 -#define CROUCH_VIEWHEIGHT       12 -#define DEAD_VIEWHEIGHT         -14 //TA: watch for mins[ 2 ] less than this causing - -// -// config strings are a general means of communicating variable length strings -// from the server to all connected clients. -// - -// CS_SERVERINFO and CS_SYSTEMINFO are defined in q_shared.h -#define CS_MUSIC            2 -#define CS_MESSAGE          3   // from the map worldspawn's message field -#define CS_MOTD             4   // g_motd string for server message of the day -#define CS_WARMUP           5   // server time when the match will be restarted -#define CS_SCORES1          6 -#define CS_SCORES2          7 -#define CS_VOTE_TIME        8 -#define CS_VOTE_STRING      9 -#define CS_VOTE_YES         10 -#define CS_VOTE_NO          11 - -#define CS_TEAMVOTE_TIME    12 -#define CS_TEAMVOTE_STRING  14 -#define CS_TEAMVOTE_YES     16 -#define CS_TEAMVOTE_NO      18 - -#define CS_GAME_VERSION     20 -#define CS_LEVEL_START_TIME 21    // so the timer only shows the current level -#define CS_INTERMISSION     22    // when 1, fraglimit/timelimit has been hit and intermission will start in a second or two -#define CS_FLAGSTATUS       23    // string indicating flag status in CTF -#define CS_SHADERSTATE      24 -#define CS_BOTINFO          25 -#define CS_CLIENTS_READY    26    //TA: following suggestion in STAT_ enum STAT_CLIENTS_READY becomes a configstring - -//TA: extra stuff: -#define CS_BUILDPOINTS      28 -#define CS_STAGES           29 -#define CS_SPAWNS           30 - -#define CS_MODELS           33 -#define CS_SOUNDS           (CS_MODELS+MAX_MODELS) -#define CS_SHADERS          (CS_SOUNDS+MAX_SOUNDS) -#define CS_PARTICLE_SYSTEMS (CS_SHADERS+MAX_SHADERS) -#define CS_PLAYERS          (CS_PARTICLE_SYSTEMS+MAX_GAME_PARTICLE_SYSTEMS) -#define CS_PRECACHES        (CS_PLAYERS+MAX_CLIENTS) -#define CS_LOCATIONS        (CS_PRECACHES+MAX_CLIENTS) -#define CS_PARTICLE_FILES   (CS_LOCATIONS+MAX_LOCATIONS) - -#define CS_MAX              (CS_PARTICLE_FILES+MAX_PARTICLE_FILES) - -#if (CS_MAX) > MAX_CONFIGSTRINGS -#error overflow: (CS_MAX) > MAX_CONFIGSTRINGS -#endif - -typedef enum -{ -  GENDER_MALE, -  GENDER_FEMALE, -  GENDER_NEUTER -} gender_t; - -/* -=================================================================================== - -PMOVE MODULE - -The pmove code takes a player_state_t and a usercmd_t and generates a new player_state_t -and some other output data.  Used for local prediction on the client game and true -movement on the server game. -=================================================================================== -*/ - -typedef enum -{ -  PM_NORMAL,        // can accelerate and turn -  PM_NOCLIP,        // noclip movement -  PM_SPECTATOR,     // still run into walls -  PM_JETPACK,       // jetpack physics -  PM_GRABBED,       // like dead, but for when the player is still live -  PM_DEAD,          // no acceleration or turning, but free falling -  PM_FREEZE,        // stuck in place with no control -  PM_INTERMISSION,  // no movement or status bar -  PM_SPINTERMISSION // no movement or status bar -} pmtype_t; - -typedef enum -{ -  WEAPON_READY, -  WEAPON_RAISING, -  WEAPON_DROPPING, -  WEAPON_FIRING, -  WEAPON_RELOADING -} weaponstate_t; - -// pmove->pm_flags -#define PMF_DUCKED          1 -#define PMF_JUMP_HELD       2 -#define PMF_CROUCH_HELD     4 -#define PMF_BACKWARDS_JUMP  8       // go into backwards land -#define PMF_BACKWARDS_RUN   16      // coast down to backwards run -#define PMF_TIME_LAND       32      // pm_time is time before rejump -#define PMF_TIME_KNOCKBACK  64      // pm_time is an air-accelerate only time -#define PMF_TIME_WATERJUMP  256     // pm_time is waterjump -#define PMF_RESPAWNED       512     // clear after attack and jump buttons come up -#define PMF_USE_ITEM_HELD   1024 -#define PMF_WEAPON_RELOAD   2048    //TA: force a weapon switch -#define PMF_FOLLOW          4096    // spectate following another player -#define PMF_QUEUED          8192    //TA: player is queued -#define PMF_TIME_WALLJUMP   16384   //TA: for limiting wall jumping -#define PMF_CHARGE          32768   //TA: keep track of pouncing -#define PMF_WEAPON_SWITCH   65536   //TA: force a weapon switch - - -#define PMF_ALL_TIMES (PMF_TIME_WATERJUMP|PMF_TIME_LAND|PMF_TIME_KNOCKBACK|PMF_TIME_WALLJUMP) - -#define MAXTOUCH  32 -typedef struct -{ -  // state (in / out) -  playerState_t *ps; - -  // command (in) -  usercmd_t     cmd; -  int           tracemask;      // collide against these types of surfaces -  int           debugLevel;     // if set, diagnostic output will be printed -  qboolean      noFootsteps;    // if the game is setup for no footsteps by the server -  qboolean      autoWeaponHit[ 32 ]; //FIXME: TA: remind myself later this might be a problem - -  int           framecount; - -  // results (out) -  int           numtouch; -  int           touchents[ MAXTOUCH ]; - -  vec3_t        mins, maxs;     // bounding box size - -  int           watertype; -  int           waterlevel; - -  float         xyspeed; - -  // for fixed msec Pmove -  int           pmove_fixed; -  int           pmove_msec; - -  // callbacks to test the world -  // these will be different functions during game and cgame -  /*void    (*trace)( trace_t *results, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, int passEntityNum, int contentMask );*/ -  void          (*trace)( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, -                          const vec3_t end, int passEntityNum, int contentMask ); - - -  int           (*pointcontents)( const vec3_t point, int passEntityNum ); -} pmove_t; - -// if a full pmove isn't done on the client, you can just update the angles -void PM_UpdateViewAngles( playerState_t *ps, const usercmd_t *cmd ); -void Pmove( pmove_t *pmove ); - -//=================================================================================== - - -// player_state->stats[] indexes -typedef enum -{ -  STAT_HEALTH, -  STAT_ITEMS, -  STAT_SLOTS,           //TA: tracks the amount of stuff human players are carrying -  STAT_ACTIVEITEMS, -  STAT_WEAPONS,         // 16 bit fields -  STAT_WEAPONS2,        //TA: another 16 bits to push the max weapon count up -  STAT_MAX_HEALTH, // health / armor limit, changable by handicap -  STAT_PCLASS,    //TA: player class (for aliens AND humans) -  STAT_PTEAM,     //TA: player team -  STAT_STAMINA,   //TA: stamina (human only) -  STAT_STATE,     //TA: client states e.g. wall climbing -  STAT_MISC,      //TA: for uh...misc stuff -  STAT_BUILDABLE, //TA: which ghost model to display for building -  STAT_BOOSTTIME, //TA: time left for boost (alien only) -  STAT_FALLDIST,  //TA: the distance the player fell -  STAT_VIEWLOCK   //TA: direction to lock the view in -} statIndex_t; - -#define SCA_WALLCLIMBER         0x00000001 -#define SCA_TAKESFALLDAMAGE     0x00000002 -#define SCA_CANZOOM             0x00000004 -#define SCA_NOWEAPONDRIFT       0x00000008 -#define SCA_FOVWARPS            0x00000010 -#define SCA_ALIENSENSE          0x00000020 -#define SCA_CANUSELADDERS       0x00000040 -#define SCA_WALLJUMPER          0x00000080 - -#define SS_WALLCLIMBING         0x00000001 -#define SS_WALLCLIMBINGCEILING  0x00000002 -#define SS_CREEPSLOWED          0x00000004 -#define SS_SPEEDBOOST           0x00000008 -#define SS_INFESTING            0x00000010 -#define SS_GRABBED              0x00000020 -#define SS_BLOBLOCKED           0x00000040 -#define SS_POISONED             0x00000080 -#define SS_HOVELING             0x00000100 -#define SS_BOOSTED              0x00000200 -#define SS_SLOWLOCKED           0x00000400 -#define SS_POISONCLOUDED        0x00000800 -#define SS_MEDKIT_ACTIVE        0x00001000 -#define SS_CHARGING             0x00002000 - -#define SB_VALID_TOGGLEBIT      0x00004000 - -#define MAX_STAMINA             1000 - -#define BOOST_TIME              20000 - -// player_state->persistant[] indexes -// these fields are the only part of player_state that isn't -// cleared on respawn -typedef enum -{ -  PERS_SCORE,           // !!! MUST NOT CHANGE, SERVER AND GAME BOTH REFERENCE !!! -  PERS_HITS,            // total points damage inflicted so damage beeps can sound on change -  PERS_RANK, -  PERS_TEAM, -  PERS_SPAWN_COUNT,     // incremented every respawn -  PERS_ATTACKER,        // clientnum of last damage inflicter -  PERS_KILLED,          // count of the number of times you died - -  //TA: -  PERS_STATE, -  PERS_CREDIT,    // human credit -  PERS_BANK,      // human credit in the bank -  PERS_QUEUEPOS,  // position in the spawn queue -  PERS_NEWWEAPON  // weapon to switch to -} persEnum_t; - -#define PS_WALLCLIMBINGFOLLOW   0x00000001 -#define PS_WALLCLIMBINGTOGGLE   0x00000002 -#define PS_NONSEGMODEL          0x00000004 - -// entityState_t->eFlags -#define EF_DEAD             0x00000001    // don't draw a foe marker over players with EF_DEAD -#define EF_TELEPORT_BIT     0x00000002    // toggled every time the origin abruptly changes -#define EF_PLAYER_EVENT     0x00000004 -#define EF_BOUNCE           0x00000008    // for missiles -#define EF_BOUNCE_HALF      0x00000010    // for missiles -#define EF_NO_BOUNCE_SOUND  0x00000020    // for missiles -#define EF_WALLCLIMB        0x00000040    // TA: wall walking -#define EF_WALLCLIMBCEILING 0x00000080    // TA: wall walking ceiling hack -#define EF_NODRAW           0x00000100    // may have an event, but no model (unspawned items) -#define EF_FIRING           0x00000200    // for lightning gun -#define EF_FIRING2          0x00000400    // alt fire -#define EF_FIRING3          0x00000800    // third fire -#define EF_MOVER_STOP       0x00001000    // will push otherwise -#define EF_TALK             0x00002000    // draw a talk balloon -#define EF_CONNECTION       0x00004000    // draw a connection trouble sprite -#define EF_VOTED            0x00008000    // already cast a vote -#define EF_TEAMVOTED        0x00010000    // already cast a vote -#define EF_BLOBLOCKED       0x00020000    // TA: caught by a trapper -#define EF_REAL_LIGHT       0x00040000    // TA: light sprites according to ambient light - -typedef enum -{ -  PW_NONE, - -  PW_QUAD, -  PW_BATTLESUIT, -  PW_HASTE, -  PW_INVIS, -  PW_REGEN, -  PW_FLIGHT, - -  PW_REDFLAG, -  PW_BLUEFLAG, -  PW_BALL, - -  PW_NUM_POWERUPS -} powerup_t; - -typedef enum -{ -  HI_NONE, - -  HI_TELEPORTER, -  HI_MEDKIT, - -  HI_NUM_HOLDABLE -} holdable_t; - -typedef enum -{ -  WPM_NONE, - -  WPM_PRIMARY, -  WPM_SECONDARY, -  WPM_TERTIARY, - -  WPM_NUM_WEAPONMODES -} weaponMode_t; - -typedef enum -{ -  WP_NONE, - -  WP_ALEVEL0, -  WP_ALEVEL1, -  WP_ALEVEL1_UPG, -  WP_ALEVEL2, -  WP_ALEVEL2_UPG, -  WP_ALEVEL3, -  WP_ALEVEL3_UPG, -  WP_ALEVEL4, - -  WP_BLASTER, -  WP_MACHINEGUN, -  WP_PAIN_SAW, -  WP_SHOTGUN, -  WP_LAS_GUN, -  WP_MASS_DRIVER, -  WP_CHAINGUN, -  WP_PULSE_RIFLE, -  WP_FLAMER, -  WP_LUCIFER_CANNON, -  WP_GRENADE, - -  WP_LOCKBLOB_LAUNCHER, -  WP_HIVE, -  WP_TESLAGEN, -  WP_MGTURRET, - -  //build weapons must remain in a block -  WP_ABUILD, -  WP_ABUILD2, -  WP_HBUILD2, -  WP_HBUILD, -  //ok? - -  WP_NUM_WEAPONS -} weapon_t; - -typedef enum -{ -  UP_NONE, - -  UP_LIGHTARMOUR, -  UP_HELMET, -  UP_MEDKIT, -  UP_BATTPACK, -  UP_JETPACK, -  UP_BATTLESUIT, -  UP_GRENADE, - -  UP_AMMO, - -  UP_NUM_UPGRADES -} upgrade_t; - -typedef enum -{ -  WUT_NONE, - -  WUT_ALIENS, -  WUT_HUMANS, - -  WUT_NUM_TEAMS -} WUTeam_t; - -//TA: bitmasks for upgrade slots -#define SLOT_NONE       0x00000000 -#define SLOT_HEAD       0x00000001 -#define SLOT_TORSO      0x00000002 -#define SLOT_ARMS       0x00000004 -#define SLOT_LEGS       0x00000008 -#define SLOT_BACKPACK   0x00000010 -#define SLOT_WEAPON     0x00000020 -#define SLOT_SIDEARM    0x00000040 - -typedef enum -{ -  BA_NONE, - -  BA_A_SPAWN, -  BA_A_OVERMIND, - -  BA_A_BARRICADE, -  BA_A_ACIDTUBE, -  BA_A_TRAPPER, -  BA_A_BOOSTER, -  BA_A_HIVE, - -  BA_A_HOVEL, - -  BA_H_SPAWN, - -  BA_H_MGTURRET, -  BA_H_TESLAGEN, - -  BA_H_ARMOURY, -  BA_H_DCC, -  BA_H_MEDISTAT, - -  BA_H_REACTOR, -  BA_H_REPEATER, - -  BA_NUM_BUILDABLES -} buildable_t; - -typedef enum -{ -  BIT_NONE, - -  BIT_ALIENS, -  BIT_HUMANS, - -  BIT_NUM_TEAMS -} buildableTeam_t; - -#define B_HEALTH_BITS       5 -#define B_HEALTH_SCALE      (float)((1<<B_HEALTH_BITS)-1) - -#define B_SPAWNED_TOGGLEBIT 0x00000020 -#define B_POWERED_TOGGLEBIT 0x00000040 -#define B_DCCED_TOGGLEBIT   0x00000080 - - -// reward sounds (stored in ps->persistant[PERS_PLAYEREVENTS]) -#define PLAYEREVENT_DENIEDREWARD      0x0001 -#define PLAYEREVENT_GAUNTLETREWARD    0x0002 -#define PLAYEREVENT_HOLYSHIT          0x0004 - -// entityState_t->event values -// entity events are for effects that take place reletive -// to an existing entities origin.  Very network efficient. - -// two bits at the top of the entityState->event field -// will be incremented with each change in the event so -// that an identical event started twice in a row can -// be distinguished.  And off the value with ~EV_EVENT_BITS -// to retrieve the actual event number -#define EV_EVENT_BIT1   0x00000100 -#define EV_EVENT_BIT2   0x00000200 -#define EV_EVENT_BITS   (EV_EVENT_BIT1|EV_EVENT_BIT2) - -#define EVENT_VALID_MSEC  300 - -typedef enum -{ -  EV_NONE, - -  EV_FOOTSTEP, -  EV_FOOTSTEP_METAL, -  EV_FOOTSTEP_SQUELCH, -  EV_FOOTSPLASH, -  EV_FOOTWADE, -  EV_SWIM, - -  EV_STEP_4, -  EV_STEP_8, -  EV_STEP_12, -  EV_STEP_16, - -  EV_STEPDN_4, -  EV_STEPDN_8, -  EV_STEPDN_12, -  EV_STEPDN_16, - -  EV_FALL_SHORT, -  EV_FALL_MEDIUM, -  EV_FALL_FAR, -  EV_FALLING, - -  EV_JUMP, -  EV_WATER_TOUCH, // foot touches -  EV_WATER_LEAVE, // foot leaves -  EV_WATER_UNDER, // head touches -  EV_WATER_CLEAR, // head leaves - -  EV_NOAMMO, -  EV_CHANGE_WEAPON, -  EV_FIRE_WEAPON, -  EV_FIRE_WEAPON2, -  EV_FIRE_WEAPON3, - -  EV_PLAYER_RESPAWN, //TA: for fovwarp effects -  EV_PLAYER_TELEPORT_IN, -  EV_PLAYER_TELEPORT_OUT, - -  EV_GRENADE_BOUNCE,    // eventParm will be the soundindex - -  EV_GENERAL_SOUND, -  EV_GLOBAL_SOUND,    // no attenuation - -  EV_BULLET_HIT_FLESH, -  EV_BULLET_HIT_WALL, - -  EV_SHOTGUN, - -  EV_MISSILE_HIT, -  EV_MISSILE_MISS, -  EV_MISSILE_MISS_METAL, -  EV_TESLATRAIL, -  EV_BULLET,        // otherEntity is the shooter - -  EV_LEV1_GRAB, -  EV_LEV4_CHARGE_PREPARE, -  EV_LEV4_CHARGE_START, - -  EV_PAIN, -  EV_DEATH1, -  EV_DEATH2, -  EV_DEATH3, -  EV_OBITUARY, - -  EV_GIB_PLAYER,      // gib a previously living player - -  EV_BUILD_CONSTRUCT, //TA -  EV_BUILD_DESTROY,   //TA -  EV_BUILD_DELAY,     //TA: can't build yet -  EV_BUILD_REPAIR,    //TA: repairing buildable -  EV_BUILD_REPAIRED,  //TA: buildable has full health -  EV_HUMAN_BUILDABLE_EXPLOSION, -  EV_ALIEN_BUILDABLE_EXPLOSION, -  EV_ALIEN_ACIDTUBE, - -  EV_MEDKIT_USED, - -  EV_ALIEN_EVOLVE, -  EV_ALIEN_EVOLVE_FAILED, - -  EV_DEBUG_LINE, -  EV_STOPLOOPINGSOUND, -  EV_TAUNT, - -  EV_OVERMIND_ATTACK, //TA: overmind under attack -  EV_OVERMIND_DYING,  //TA: overmind close to death -  EV_OVERMIND_SPAWNS, //TA: overmind needs spawns - -  EV_DCC_ATTACK,      //TA: dcc under attack - -  EV_RPTUSE_SOUND     //TA: trigger a sound -} entity_event_t; - -typedef enum -{ -  MN_TEAM, -  MN_A_TEAMFULL, -  MN_H_TEAMFULL, - -  //alien stuff -  MN_A_CLASS, -  MN_A_BUILD, -  MN_A_INFEST, -  MN_A_HOVEL_OCCUPIED, -  MN_A_HOVEL_BLOCKED, -  MN_A_NOEROOM, -  MN_A_TOOCLOSE, -  MN_A_NOOVMND_EVOLVE, - -  //alien build -  MN_A_SPWNWARN, -  MN_A_OVERMIND, -  MN_A_NOASSERT, -  MN_A_NOCREEP, -  MN_A_NOOVMND, -  MN_A_NOROOM, -  MN_A_NORMAL, -  MN_A_HOVEL, -  MN_A_HOVEL_EXIT, - -  //human stuff -  MN_H_SPAWN, -  MN_H_BUILD, -  MN_H_ARMOURY, -  MN_H_NOSLOTS, -  MN_H_NOFUNDS, -  MN_H_ITEMHELD, - -  //human build -  MN_H_REPEATER, -  MN_H_NOPOWER, -  MN_H_NOTPOWERED, -  MN_H_NODCC, -  MN_H_REACTOR, -  MN_H_NOROOM, -  MN_H_NORMAL, -  MN_H_TNODEWARN, -  MN_H_RPTWARN, -  MN_H_RPTWARN2 -} dynMenu_t; - -// animations -typedef enum -{ -  BOTH_DEATH1, -  BOTH_DEAD1, -  BOTH_DEATH2, -  BOTH_DEAD2, -  BOTH_DEATH3, -  BOTH_DEAD3, - -  TORSO_GESTURE, - -  TORSO_ATTACK, -  TORSO_ATTACK2, - -  TORSO_DROP, -  TORSO_RAISE, - -  TORSO_STAND, -  TORSO_STAND2, - -  LEGS_WALKCR, -  LEGS_WALK, -  LEGS_RUN, -  LEGS_BACK, -  LEGS_SWIM, - -  LEGS_JUMP, -  LEGS_LAND, - -  LEGS_JUMPB, -  LEGS_LANDB, - -  LEGS_IDLE, -  LEGS_IDLECR, - -  LEGS_TURN, - -  TORSO_GETFLAG, -  TORSO_GUARDBASE, -  TORSO_PATROL, -  TORSO_FOLLOWME, -  TORSO_AFFIRMATIVE, -  TORSO_NEGATIVE, - -  MAX_PLAYER_ANIMATIONS, - -  LEGS_BACKCR, -  LEGS_BACKWALK, -  FLAG_RUN, -  FLAG_STAND, -  FLAG_STAND2RUN, - -  MAX_PLAYER_TOTALANIMATIONS -} playerAnimNumber_t; - -// nonsegmented animations -typedef enum -{ -  NSPA_STAND, - -  NSPA_GESTURE, - -  NSPA_WALK, -  NSPA_RUN, -  NSPA_RUNBACK, -  NSPA_CHARGE, - -  NSPA_RUNLEFT, -  NSPA_WALKLEFT, -  NSPA_RUNRIGHT, -  NSPA_WALKRIGHT, - -  NSPA_SWIM, - -  NSPA_JUMP, -  NSPA_LAND, -  NSPA_JUMPBACK, -  NSPA_LANDBACK, - -  NSPA_TURN, - -  NSPA_ATTACK1, -  NSPA_ATTACK2, -  NSPA_ATTACK3, - -  NSPA_PAIN1, -  NSPA_PAIN2, - -  NSPA_DEATH1, -  NSPA_DEAD1, -  NSPA_DEATH2, -  NSPA_DEAD2, -  NSPA_DEATH3, -  NSPA_DEAD3, - -  MAX_NONSEG_PLAYER_ANIMATIONS, - -  NSPA_WALKBACK, - -  MAX_NONSEG_PLAYER_TOTALANIMATIONS -} nonSegPlayerAnimNumber_t; - -//TA: for buildable animations -typedef enum -{ -  BANIM_NONE, - -  BANIM_CONSTRUCT1, -  BANIM_CONSTRUCT2, - -  BANIM_IDLE1, -  BANIM_IDLE2, -  BANIM_IDLE3, - -  BANIM_ATTACK1, -  BANIM_ATTACK2, - -  BANIM_SPAWN1, -  BANIM_SPAWN2, - -  BANIM_PAIN1, -  BANIM_PAIN2, - -  BANIM_DESTROY1, -  BANIM_DESTROY2, -  BANIM_DESTROYED, - -  MAX_BUILDABLE_ANIMATIONS -} buildableAnimNumber_t; - -typedef struct animation_s -{ -  int   firstFrame; -  int   numFrames; -  int   loopFrames;     // 0 to numFrames -  int   frameLerp;      // msec between frames -  int   initialLerp;    // msec to get to first frame -  int   reversed;     // true if animation is reversed -  int   flipflop;     // true if animation should flipflop back to base -} animation_t; - - -// flip the togglebit every time an animation -// changes so a restart of the same anim can be detected -#define ANIM_TOGGLEBIT    0x80 -#define ANIM_FORCEBIT     0x40 - - -typedef enum -{ -  TEAM_FREE, -  TEAM_SPECTATOR, - -  TEAM_NUM_TEAMS -} team_t; - -// Time between location updates -#define TEAM_LOCATION_UPDATE_TIME   1000 - -// How many players on the overlay -#define TEAM_MAXOVERLAY   32 - -//TA: player classes -typedef enum -{ -  PCL_NONE, - -  //builder classes -  PCL_ALIEN_BUILDER0, -  PCL_ALIEN_BUILDER0_UPG, - -  //offensive classes -  PCL_ALIEN_LEVEL0, -  PCL_ALIEN_LEVEL1, -  PCL_ALIEN_LEVEL1_UPG, -  PCL_ALIEN_LEVEL2, -  PCL_ALIEN_LEVEL2_UPG, -  PCL_ALIEN_LEVEL3, -  PCL_ALIEN_LEVEL3_UPG, -  PCL_ALIEN_LEVEL4, - -  //human class -  PCL_HUMAN, -  PCL_HUMAN_BSUIT, - -  PCL_NUM_CLASSES -} pClass_t; - - -//TA: player teams -typedef enum -{ -  PTE_NONE, -  PTE_ALIENS, -  PTE_HUMANS, - -  PTE_NUM_TEAMS -} pTeam_t; - - -// means of death -typedef enum -{ -  MOD_UNKNOWN, -  MOD_SHOTGUN, -  MOD_BLASTER, -  MOD_PAINSAW, -  MOD_MACHINEGUN, -  MOD_CHAINGUN, -  MOD_PRIFLE, -  MOD_MDRIVER, -  MOD_LASGUN, -  MOD_LCANNON, -  MOD_LCANNON_SPLASH, -  MOD_FLAMER, -  MOD_FLAMER_SPLASH, -  MOD_GRENADE, -  MOD_WATER, -  MOD_SLIME, -  MOD_LAVA, -  MOD_CRUSH, -  MOD_TELEFRAG, -  MOD_FALLING, -  MOD_SUICIDE, -  MOD_TARGET_LASER, -  MOD_TRIGGER_HURT, - -  MOD_ABUILDER_CLAW, -  MOD_LEVEL0_BITE, -  MOD_LEVEL1_CLAW, -  MOD_LEVEL1_PCLOUD, -  MOD_LEVEL3_CLAW, -  MOD_LEVEL3_POUNCE, -  MOD_LEVEL3_BOUNCEBALL, -  MOD_LEVEL2_CLAW, -  MOD_LEVEL2_ZAP, -  MOD_LEVEL4_CLAW, -  MOD_LEVEL4_CHARGE, - -  MOD_SLOWBLOB, -  MOD_POISON, -  MOD_SWARM, - -  MOD_HSPAWN, -  MOD_TESLAGEN, -  MOD_MGTURRET, -  MOD_REACTOR, - -  MOD_ASPAWN, -  MOD_ATUBE, -  MOD_OVERMIND -} meansOfDeath_t; - - -//--------------------------------------------------------- - -//TA: player class record -typedef struct -{ -  int       classNum; - -  char      *className; -  char      *humanName; - -  char      *modelName; -  float     modelScale; -  char      *skinName; -  float     shadowScale; - -  char      *hudName; - -  int       stages; - -  vec3_t    mins; -  vec3_t    maxs; -  vec3_t    crouchMaxs; -  vec3_t    deadMins; -  vec3_t    deadMaxs; -  float     zOffset; - -  int       viewheight; -  int       crouchViewheight; - -  int       health; -  float     fallDamage; -  int       regenRate; - -  int       abilities; - -  weapon_t  startWeapon; - -  float     buildDist; - -  int       fov; -  float     bob; -  float     bobCycle; -  int       steptime; - -  float     speed; -  float     acceleration; -  float     airAcceleration; -  float     friction; -  float     stopSpeed; -  float     jumpMagnitude; -  float     knockbackScale; - -  int       children[ 3 ]; -  int       cost; -  int       value; -} classAttributes_t; - -typedef struct -{ -  char      modelName[ MAX_QPATH ]; -  float     modelScale; -  char      skinName[ MAX_QPATH ]; -  float     shadowScale; -  char      hudName[ MAX_QPATH ]; -  char      humanName[ MAX_STRING_CHARS ]; - -  vec3_t    mins; -  vec3_t    maxs; -  vec3_t    crouchMaxs; -  vec3_t    deadMins; -  vec3_t    deadMaxs; -  float     zOffset; -} classAttributeOverrides_t; - -//stages -typedef enum -{ -  S1, -  S2, -  S3 -} stage_t; - -#define MAX_BUILDABLE_MODELS 4 - -//TA: buildable item record -typedef struct -{ -  int       buildNum; - -  char      *buildName; -  char      *humanName; -  char      *entityName; - -  char      *models[ MAX_BUILDABLE_MODELS ]; -  float     modelScale; - -  vec3_t    mins; -  vec3_t    maxs; -  float     zOffset; - -  trType_t  traj; -  float     bounce; - -  int       buildPoints; -  int       stages; - -  int       health; -  int       regenRate; - -  int       splashDamage; -  int       splashRadius; - -  int       meansOfDeath; - -  int       team; -  weapon_t  buildWeapon; - -  int       idleAnim; - -  int       nextthink; -  int       buildTime; -  qboolean  usable; - -  int       turretRange; -  int       turretFireSpeed; -  weapon_t  turretProjType; - -  float     minNormal; -  qboolean  invertNormal; - -  qboolean  creepTest; -  int       creepSize; - -  qboolean  dccTest; -  qboolean  reactorTest; -} buildableAttributes_t; - -typedef struct -{ -  char      models[ MAX_BUILDABLE_MODELS ][ MAX_QPATH ]; - -  float     modelScale; -  vec3_t    mins; -  vec3_t    maxs; -  float     zOffset; -} buildableAttributeOverrides_t; - -//TA: weapon record -typedef struct -{ -  int       weaponNum; - -  int       price; -  int       stages; - -  int       slots; - -  char      *weaponName; -  char      *weaponHumanName; - -  int       maxAmmo; -  int       maxClips; -  qboolean  infiniteAmmo; -  qboolean  usesEnergy; - -  int       repeatRate1; -  int       repeatRate2; -  int       repeatRate3; -  int       reloadTime; - -  qboolean  hasAltMode; -  qboolean  hasThirdMode; - -  qboolean  canZoom; -  float     zoomFov; - -  qboolean  purchasable; - -  int       buildDelay; - -  WUTeam_t  team; -} weaponAttributes_t; - -//TA: upgrade record -typedef struct -{ -  int       upgradeNum; - -  int       price; -  int       stages; - -  int       slots; - -  char      *upgradeName; -  char      *upgradeHumanName; - -  char      *icon; - -  qboolean  purchasable; - -  WUTeam_t  team; -} upgradeAttributes_t; - - -//TA: -void      BG_UnpackAmmoArray( int weapon, int psAmmo[ ], int psAmmo2[ ], int *ammo, int *clips ); -void      BG_PackAmmoArray( int weapon, int psAmmo[ ], int psAmmo2[ ], int ammo, int clips ); -qboolean  BG_WeaponIsFull( weapon_t weapon, int stats[ ], int psAmmo[ ], int psAmmo2[ ] ); -void      BG_AddWeaponToInventory( int weapon, int stats[ ] ); -void      BG_RemoveWeaponFromInventory( int weapon, int stats[ ] ); -qboolean  BG_InventoryContainsWeapon( int weapon, int stats[ ] ); -void      BG_AddUpgradeToInventory( int item, int stats[ ] ); -void      BG_RemoveUpgradeFromInventory( int item, int stats[ ] ); -qboolean  BG_InventoryContainsUpgrade( int item, int stats[ ] ); -void      BG_ActivateUpgrade( int item, int stats[ ] ); -void      BG_DeactivateUpgrade( int item, int stats[ ] ); -qboolean  BG_UpgradeIsActive( int item, int stats[ ] ); -qboolean  BG_RotateAxis( vec3_t surfNormal, vec3_t inAxis[ 3 ], -                         vec3_t outAxis[ 3 ], qboolean inverse, qboolean ceiling ); -void      BG_PositionBuildableRelativeToPlayer( const playerState_t *ps, -                                                const vec3_t mins, const vec3_t maxs, -                                                void (*trace)( trace_t *, const vec3_t, const vec3_t, -                                                               const vec3_t, const vec3_t, int, int ), -                                                vec3_t outOrigin, vec3_t outAngles, trace_t *tr ); -int       BG_GetValueOfHuman( playerState_t *ps ); - -int       BG_FindBuildNumForName( char *name ); -int       BG_FindBuildNumForEntityName( char *name ); -char      *BG_FindNameForBuildable( int bclass ); -char      *BG_FindHumanNameForBuildable( int bclass ); -char      *BG_FindEntityNameForBuildable( int bclass ); -char      *BG_FindModelsForBuildable( int bclass, int modelNum ); -float     BG_FindModelScaleForBuildable( int bclass ); -void      BG_FindBBoxForBuildable( int bclass, vec3_t mins, vec3_t maxs ); -float     BG_FindZOffsetForBuildable( int pclass ); -int       BG_FindHealthForBuildable( int bclass ); -int       BG_FindRegenRateForBuildable( int bclass ); -trType_t  BG_FindTrajectoryForBuildable( int bclass ); -float     BG_FindBounceForBuildable( int bclass ); -int       BG_FindBuildPointsForBuildable( int bclass ); -qboolean  BG_FindStagesForBuildable( int bclass, stage_t stage ); -int       BG_FindSplashDamageForBuildable( int bclass ); -int       BG_FindSplashRadiusForBuildable( int bclass ); -int       BG_FindMODForBuildable( int bclass ); -int       BG_FindTeamForBuildable( int bclass ); -weapon_t  BG_FindBuildWeaponForBuildable( int bclass ); -int       BG_FindAnimForBuildable( int bclass ); -int       BG_FindNextThinkForBuildable( int bclass ); -int       BG_FindBuildTimeForBuildable( int bclass ); -qboolean  BG_FindUsableForBuildable( int bclass ); -int       BG_FindRangeForBuildable( int bclass ); -int       BG_FindFireSpeedForBuildable( int bclass ); -weapon_t  BG_FindProjTypeForBuildable( int bclass ); -float     BG_FindMinNormalForBuildable( int bclass ); -qboolean  BG_FindInvertNormalForBuildable( int bclass ); -int       BG_FindCreepTestForBuildable( int bclass ); -int       BG_FindCreepSizeForBuildable( int bclass ); -int       BG_FindDCCTestForBuildable( int bclass ); -int       BG_FindUniqueTestForBuildable( int bclass ); -void      BG_InitBuildableOverrides( void ); - -int       BG_FindClassNumForName( char *name ); -char      *BG_FindNameForClassNum( int pclass ); -char      *BG_FindHumanNameForClassNum( int pclass ); -char      *BG_FindModelNameForClass( int pclass ); -float     BG_FindModelScaleForClass( int pclass ); -char      *BG_FindSkinNameForClass( int pclass ); -float     BG_FindShadowScaleForClass( int pclass ); -char      *BG_FindHudNameForClass( int pclass ); -qboolean  BG_FindStagesForClass( int pclass, stage_t stage ); -void      BG_FindBBoxForClass( int pclass, vec3_t mins, vec3_t maxs, vec3_t cmaxs, vec3_t dmins, vec3_t dmaxs ); -float     BG_FindZOffsetForClass( int pclass ); -void      BG_FindViewheightForClass( int pclass, int *viewheight, int *cViewheight ); -int       BG_FindHealthForClass( int pclass ); -float     BG_FindFallDamageForClass( int pclass ); -int       BG_FindRegenRateForClass( int pclass ); -int       BG_FindFovForClass( int pclass ); -float     BG_FindBobForClass( int pclass ); -float     BG_FindBobCycleForClass( int pclass ); -float     BG_FindSpeedForClass( int pclass ); -float     BG_FindAccelerationForClass( int pclass ); -float     BG_FindAirAccelerationForClass( int pclass ); -float     BG_FindFrictionForClass( int pclass ); -float     BG_FindStopSpeedForClass( int pclass ); -float     BG_FindJumpMagnitudeForClass( int pclass ); -float     BG_FindKnockbackScaleForClass( int pclass ); -int       BG_FindSteptimeForClass( int pclass ); -qboolean  BG_ClassHasAbility( int pclass, int ability ); -weapon_t  BG_FindStartWeaponForClass( int pclass ); -float     BG_FindBuildDistForClass( int pclass ); -int       BG_ClassCanEvolveFromTo( int fclass, int tclass, int credits, int num ); -int       BG_FindCostOfClass( int pclass ); -int       BG_FindValueOfClass( int pclass ); -void      BG_InitClassOverrides( void ); - -int       BG_FindPriceForWeapon( int weapon ); -qboolean  BG_FindStagesForWeapon( int weapon, stage_t stage ); -int       BG_FindSlotsForWeapon( int weapon ); -char      *BG_FindNameForWeapon( int weapon ); -int       BG_FindWeaponNumForName( char *name ); -char      *BG_FindHumanNameForWeapon( int weapon ); -char      *BG_FindModelsForWeapon( int weapon, int modelNum ); -char      *BG_FindIconForWeapon( int weapon ); -char      *BG_FindCrosshairForWeapon( int weapon ); -int       BG_FindCrosshairSizeForWeapon( int weapon ); -void      BG_FindAmmoForWeapon( int weapon, int *maxAmmo, int *maxClips ); -qboolean  BG_FindInfinteAmmoForWeapon( int weapon ); -qboolean  BG_FindUsesEnergyForWeapon( int weapon ); -int       BG_FindRepeatRate1ForWeapon( int weapon ); -int       BG_FindRepeatRate2ForWeapon( int weapon ); -int       BG_FindRepeatRate3ForWeapon( int weapon ); -int       BG_FindReloadTimeForWeapon( int weapon ); -qboolean  BG_WeaponHasAltMode( int weapon ); -qboolean  BG_WeaponHasThirdMode( int weapon ); -qboolean  BG_WeaponCanZoom( int weapon ); -float     BG_FindZoomFovForWeapon( int weapon ); -qboolean  BG_FindPurchasableForWeapon( int weapon ); -int       BG_FindBuildDelayForWeapon( int weapon ); -WUTeam_t  BG_FindTeamForWeapon( int weapon ); - -int       BG_FindPriceForUpgrade( int upgrade ); -qboolean  BG_FindStagesForUpgrade( int upgrade, stage_t stage ); -int       BG_FindSlotsForUpgrade( int upgrade ); -char      *BG_FindNameForUpgrade( int upgrade ); -int       BG_FindUpgradeNumForName( char *name ); -char      *BG_FindHumanNameForUpgrade( int upgrade ); -char      *BG_FindIconForUpgrade( int upgrade ); -qboolean  BG_FindPurchasableForUpgrade( int upgrade ); -WUTeam_t  BG_FindTeamForUpgrade( int upgrade ); - -// content masks -#define MASK_ALL          (-1) -#define MASK_SOLID        (CONTENTS_SOLID) -#define MASK_PLAYERSOLID  (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_BODY) -#define MASK_DEADSOLID    (CONTENTS_SOLID|CONTENTS_PLAYERCLIP) -#define MASK_WATER        (CONTENTS_WATER|CONTENTS_LAVA|CONTENTS_SLIME) -#define MASK_OPAQUE       (CONTENTS_SOLID|CONTENTS_SLIME|CONTENTS_LAVA) -#define MASK_SHOT         (CONTENTS_SOLID|CONTENTS_BODY) - - -// -// entityState_t->eType -// -typedef enum -{ -  ET_GENERAL, -  ET_PLAYER, -  ET_ITEM, - -  ET_BUILDABLE,       //TA: buildable type - -  ET_MISSILE, -  ET_MOVER, -  ET_BEAM, -  ET_PORTAL, -  ET_SPEAKER, -  ET_PUSH_TRIGGER, -  ET_TELEPORT_TRIGGER, -  ET_INVISIBLE, -  ET_GRAPPLE,       // grapple hooked on wall - -  ET_CORPSE, -  ET_PARTICLE_SYSTEM, -  ET_ANIMMAPOBJ, -  ET_MODELDOOR, -  ET_LIGHTFLARE, -  ET_LEV2_ZAP_CHAIN, - -  ET_EVENTS       // any of the EV_* events can be added freestanding -              // by setting eType to ET_EVENTS + eventNum -              // this avoids having to set eFlags and eventNum -} entityType_t; - -void  BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result ); -void  BG_EvaluateTrajectoryDelta( const trajectory_t *tr, int atTime, vec3_t result ); - -void  BG_AddPredictableEventToPlayerstate( int newEvent, int eventParm, playerState_t *ps ); - -void  BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean snap ); -void  BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s, int time, qboolean snap ); - -qboolean  BG_PlayerTouchesItem( playerState_t *ps, entityState_t *item, int atTime ); - -#define ARENAS_PER_TIER   4 -#define MAX_ARENAS      1024 -#define MAX_ARENAS_TEXT   8192 - -#define MAX_BOTS      1024 -#define MAX_BOTS_TEXT   8192 - -//TA: conceptually should live in q_shared.h -void    AxisToAngles( vec3_t axis[3], vec3_t angles ); -#define Vector2Set(v, x, y) ((v)[0]=(x), (v)[1]=(y)) -float   pointToLineDistance( const vec3_t point, const vec3_t p1, const vec3_t p2 ); -#define MAX(x,y) (x)>(y)?(x):(y) -#define MIN(x,y) (x)<(y)?(x):(y) - - -// Ridah -void GetPerpendicularViewVector( const vec3_t point, const vec3_t p1, -                                 const vec3_t p2, vec3_t up ); -void ProjectPointOntoVector( vec3_t point, vec3_t vStart, -                             vec3_t vEnd, vec3_t vProj ); -float VectorDistance( vec3_t v1, vec3_t v2 ); -// done. - -//call roundf in place of round on non VM platforms -#ifdef Q3_VM -#define roundf round -#else -#define round roundf -#endif - -#define M_ROOT3 1.732050808f -float VectorMinComponent( vec3_t v ); -float VectorMaxComponent( vec3_t v ); -float round( float v ); - -float atof_neg( char *token, qboolean allowNegative ); -int   atoi_neg( char *token, qboolean allowNegative ); - -void BG_ParseCSVEquipmentList( const char *string, weapon_t *weapons, int weaponsSize, -    upgrade_t *upgrades, int upgradesSize ); -void BG_ParseCSVClassList( const char *string, pClass_t *classes, int classesSize ); -void BG_ParseCSVBuildableList( const char *string, buildable_t *buildables, int buildablesSize ); diff --git a/mod/src/game/bg_slidemove.c b/mod/src/game/bg_slidemove.c deleted file mode 100644 index 47f1ec04..00000000 --- a/mod/src/game/bg_slidemove.c +++ /dev/null @@ -1,408 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// bg_slidemove.c -- part of bg_pmove functionality - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "q_shared.h" -#include "bg_public.h" -#include "bg_local.h" - -/* - -input: origin, velocity, bounds, groundPlane, trace function - -output: origin, velocity, impacts, stairup boolean - -*/ - -/* -================== -PM_SlideMove - -Returns qtrue if the velocity was clipped in some way -================== -*/ -#define MAX_CLIP_PLANES 5 -qboolean  PM_SlideMove( qboolean gravity ) -{ -  int     bumpcount, numbumps; -  vec3_t  dir; -  float   d; -  int     numplanes; -  vec3_t  planes[MAX_CLIP_PLANES]; -  vec3_t  primal_velocity; -  vec3_t  clipVelocity; -  int     i, j, k; -  trace_t trace; -  vec3_t  end; -  float   time_left; -  float   into; -  vec3_t  endVelocity; -  vec3_t  endClipVelocity; - -  numbumps = 4; - -  VectorCopy( pm->ps->velocity, primal_velocity ); - -  if( gravity ) -  { -    VectorCopy( pm->ps->velocity, endVelocity ); -    endVelocity[ 2 ] -= pm->ps->gravity * pml.frametime; -    pm->ps->velocity[ 2 ] = ( pm->ps->velocity[ 2 ] + endVelocity[ 2 ] ) * 0.5; -    primal_velocity[ 2 ] = endVelocity[ 2 ]; - -    if( pml.groundPlane ) -    { -      // slide along the ground plane -      PM_ClipVelocity( pm->ps->velocity, pml.groundTrace.plane.normal, -        pm->ps->velocity, OVERCLIP ); -    } -  } - -  time_left = pml.frametime; - -  // never turn against the ground plane -  if( pml.groundPlane ) -  { -    numplanes = 1; -    VectorCopy( pml.groundTrace.plane.normal, planes[ 0 ] ); -  } -  else -    numplanes = 0; - -  // never turn against original velocity -  VectorNormalize2( pm->ps->velocity, planes[ numplanes ] ); -  numplanes++; - -  for( bumpcount = 0; bumpcount < numbumps; bumpcount++ ) -  { -    // calculate position we are trying to move to -    VectorMA( pm->ps->origin, time_left, pm->ps->velocity, end ); - -    // see if we can make it there -    pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemask ); - -    if( trace.allsolid ) -    { -      // entity is completely trapped in another solid -      pm->ps->velocity[ 2 ] = 0;  // don't build up falling damage, but allow sideways acceleration -      return qtrue; -    } - -    if( trace.fraction > 0 ) -    { -      // actually covered some distance -      VectorCopy( trace.endpos, pm->ps->origin ); -    } - -    if( trace.fraction == 1 ) -       break;   // moved the entire distance - -    // save entity for contact -    PM_AddTouchEnt( trace.entityNum ); - -    time_left -= time_left * trace.fraction; - -    if( numplanes >= MAX_CLIP_PLANES ) -    { -      // this shouldn't really happen -      VectorClear( pm->ps->velocity ); -      return qtrue; -    } - -    // -    // if this is the same plane we hit before, nudge velocity -    // out along it, which fixes some epsilon issues with -    // non-axial planes -    // -    for( i = 0 ; i < numplanes ; i++ ) -    { -      if( DotProduct( trace.plane.normal, planes[i] ) > 0.99 ) -      { -        VectorAdd( trace.plane.normal, pm->ps->velocity, pm->ps->velocity ); -        break; -      } -    } - -    if( i < numplanes ) -      continue; - -    VectorCopy( trace.plane.normal, planes[ numplanes ] ); -    numplanes++; - -    // -    // modify velocity so it parallels all of the clip planes -    // - -    // find a plane that it enters -    for( i = 0; i < numplanes; i++ ) -    { -      into = DotProduct( pm->ps->velocity, planes[ i ] ); -      if( into >= 0.1 ) -        continue;   // move doesn't interact with the plane - -      // see how hard we are hitting things -      if( -into > pml.impactSpeed ) -        pml.impactSpeed = -into; - -      // slide along the plane -      PM_ClipVelocity( pm->ps->velocity, planes[ i ], clipVelocity, OVERCLIP ); - -      // slide along the plane -      PM_ClipVelocity( endVelocity, planes[ i ], endClipVelocity, OVERCLIP ); - -      // see if there is a second plane that the new move enters -      for( j = 0; j < numplanes; j++ ) -      { -        if( j == i ) -          continue; - -        if( DotProduct( clipVelocity, planes[ j ] ) >= 0.1 ) -          continue;   // move doesn't interact with the plane - -        // try clipping the move to the plane -        PM_ClipVelocity( clipVelocity, planes[ j ], clipVelocity, OVERCLIP ); -        PM_ClipVelocity( endClipVelocity, planes[ j ], endClipVelocity, OVERCLIP ); - -        // see if it goes back into the first clip plane -        if( DotProduct( clipVelocity, planes[ i ] ) >= 0 ) -          continue; - -        // slide the original velocity along the crease -        CrossProduct( planes[ i ], planes[ j ], dir ); -        VectorNormalize( dir ); -        d = DotProduct( dir, pm->ps->velocity ); -        VectorScale( dir, d, clipVelocity ); - -        CrossProduct( planes[ i ], planes[ j ], dir); -        VectorNormalize( dir ); -        d = DotProduct( dir, endVelocity ); -        VectorScale( dir, d, endClipVelocity ); - -        // see if there is a third plane the the new move enters -        for( k = 0; k < numplanes; k++ ) -        { -          if( k == i || k == j ) -            continue; - -          if( DotProduct( clipVelocity, planes[ k ] ) >= 0.1 ) -            continue;   // move doesn't interact with the plane - -          // stop dead at a tripple plane interaction -          VectorClear( pm->ps->velocity ); -          return qtrue; -        } -      } - -      // if we have fixed all interactions, try another move -      VectorCopy( clipVelocity, pm->ps->velocity ); -      VectorCopy( endClipVelocity, endVelocity ); -      break; -    } -  } - -  if( gravity ) -    VectorCopy( endVelocity, pm->ps->velocity ); - -  // don't change velocity if in a timer (FIXME: is this correct?) -  if( pm->ps->pm_time ) -    VectorCopy( primal_velocity, pm->ps->velocity ); - -  return ( bumpcount != 0 ); -} - -/* -================== -PM_StepEvent -================== -*/ -void PM_StepEvent( vec3_t from, vec3_t to, vec3_t normal ) -{ -  float   size; -  vec3_t  delta, dNormal; - -  VectorSubtract( from, to, delta ); -  VectorCopy( delta, dNormal ); -  VectorNormalize( dNormal ); - -  size = DotProduct( normal, dNormal ) * VectorLength( delta ); - -  if( size > 0.0f ) -  { -    if( size > 2.0f ) -    { -      if( size < 7.0f ) -        PM_AddEvent( EV_STEPDN_4 ); -      else if( size < 11.0f ) -        PM_AddEvent( EV_STEPDN_8 ); -      else if( size < 15.0f ) -        PM_AddEvent( EV_STEPDN_12 ); -      else -        PM_AddEvent( EV_STEPDN_16 ); -    } -  } -  else -  { -    size = fabs( size ); - -    if( size > 2.0f ) -    { -      if( size < 7.0f ) -        PM_AddEvent( EV_STEP_4 ); -      else if( size < 11.0f ) -        PM_AddEvent( EV_STEP_8 ); -      else if( size < 15.0f ) -        PM_AddEvent( EV_STEP_12 ); -      else -        PM_AddEvent( EV_STEP_16 ); -    } -  } - -  if( pm->debugLevel ) -    Com_Printf( "%i:stepped\n", c_pmove ); -} - -/* -================== -PM_StepSlideMove -================== -*/ -qboolean PM_StepSlideMove( qboolean gravity, qboolean predictive ) -{ -  vec3_t    start_o, start_v; -  vec3_t    down_o, down_v; -  trace_t   trace; -  vec3_t    normal; -  vec3_t    step_v, step_vNormal; -  vec3_t    up, down; -  float     stepSize; -  qboolean  stepped = qfalse; - -  if( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) -  { -    if( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) -      VectorSet( normal, 0.0f, 0.0f, -1.0f ); -    else -      VectorCopy( pm->ps->grapplePoint, normal ); -  } -  else -    VectorSet( normal, 0.0f, 0.0f, 1.0f ); - -  VectorCopy( pm->ps->origin, start_o ); -  VectorCopy( pm->ps->velocity, start_v ); - -  if( PM_SlideMove( gravity ) == 0 ) -  { -    VectorCopy( start_o, down ); -    VectorMA( down, -STEPSIZE, normal, down ); -    pm->trace( &trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask ); - -    //we can step down -    if( trace.fraction > 0.01f && trace.fraction < 1.0f && -        !trace.allsolid && pml.groundPlane != qfalse ) -    { -      if( pm->debugLevel ) -        Com_Printf( "%d: step down\n", c_pmove ); - -      stepped = qtrue; -    } -  } -  else -  { -    VectorCopy( start_o, down ); -    VectorMA( down, -STEPSIZE, normal, down ); -    pm->trace( &trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask ); -    // never step up when you still have up velocity -    if( DotProduct( trace.plane.normal, pm->ps->velocity ) > 0.0f && -        ( trace.fraction == 1.0f || DotProduct( trace.plane.normal, normal ) < 0.7f ) ) -    { -      return stepped; -    } - -    VectorCopy( pm->ps->origin, down_o ); -    VectorCopy( pm->ps->velocity, down_v ); - -    VectorCopy( start_o, up ); -    VectorMA( up, STEPSIZE, normal, up ); - -    // test the player position if they were a stepheight higher -    pm->trace( &trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask ); -    if( trace.allsolid ) -    { -      if( pm->debugLevel ) -        Com_Printf( "%i:bend can't step\n", c_pmove ); - -      return stepped;   // can't step up -    } - -    VectorSubtract( trace.endpos, start_o, step_v ); -    VectorCopy( step_v, step_vNormal ); -    VectorNormalize( step_vNormal ); - -    stepSize = DotProduct( normal, step_vNormal ) * VectorLength( step_v ); -    // try slidemove from this position -    VectorCopy( trace.endpos, pm->ps->origin ); -    VectorCopy( start_v, pm->ps->velocity ); - -    if( PM_SlideMove( gravity ) == 0 ) -    { -      if( pm->debugLevel ) -        Com_Printf( "%d: step up\n", c_pmove ); - -      stepped = qtrue; -    } - -    // push down the final amount -    VectorCopy( pm->ps->origin, down ); -    VectorMA( down, -stepSize, normal, down ); -    pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask ); - -    if( !trace.allsolid ) -      VectorCopy( trace.endpos, pm->ps->origin ); - -    if( trace.fraction < 1.0f ) -      PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP ); -  } - -  if( !predictive && stepped ) -    PM_StepEvent( start_o, pm->ps->origin, normal ); - -  return stepped; -} - -/* -================== -PM_PredictStepMove -================== -*/ -qboolean PM_PredictStepMove( void ) -{ -  vec3_t  velocity, origin; -  float   impactSpeed; -  qboolean  stepped = qfalse; - -  VectorCopy( pm->ps->velocity, velocity ); -  VectorCopy( pm->ps->origin, origin ); -  impactSpeed = pml.impactSpeed; - -  if( PM_StepSlideMove( qfalse, qtrue ) ) -    stepped = qtrue; - -  VectorCopy( velocity, pm->ps->velocity ); -  VectorCopy( origin, pm->ps->origin ); -  pml.impactSpeed = impactSpeed; - -  return stepped; -} diff --git a/mod/src/game/g_active.c b/mod/src/game/g_active.c deleted file mode 100644 index fc66ccff..00000000 --- a/mod/src/game/g_active.c +++ /dev/null @@ -1,1524 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -/* -=============== -G_DamageFeedback - -Called just before a snapshot is sent to the given player. -Totals up all damage and generates both the player_state_t -damage values to that client for pain blends and kicks, and -global pain sound events for all clients. -=============== -*/ -void P_DamageFeedback( gentity_t *player ) -{ -  gclient_t *client; -  float     count; -  vec3_t    angles; - -  client = player->client; -  if( client->ps.pm_type == PM_DEAD ) -    return; - -  // total points of damage shot at the player this frame -  count = client->damage_blood + client->damage_armor; -  if( count == 0 ) -    return;   // didn't take any damage - -  if( count > 255 ) -    count = 255; - -  // send the information to the client - -  // world damage (falling, slime, etc) uses a special code -  // to make the blend blob centered instead of positional -  if( client->damage_fromWorld ) -  { -    client->ps.damagePitch = 255; -    client->ps.damageYaw = 255; - -    client->damage_fromWorld = qfalse; -  } -  else -  { -    vectoangles( client->damage_from, angles ); -    client->ps.damagePitch = angles[ PITCH ] / 360.0 * 256; -    client->ps.damageYaw = angles[ YAW ] / 360.0 * 256; -  } - -  // play an apropriate pain sound -  if( ( level.time > player->pain_debounce_time ) && !( player->flags & FL_GODMODE ) ) -  { -    player->pain_debounce_time = level.time + 700; -    G_AddEvent( player, EV_PAIN, player->health ); -    client->ps.damageEvent++; -  } - - -  client->ps.damageCount = count; - -  // -  // clear totals -  // -  client->damage_blood = 0; -  client->damage_armor = 0; -  client->damage_knockback = 0; -} - - - -/* -============= -P_WorldEffects - -Check for lava / slime contents and drowning -============= -*/ -void P_WorldEffects( gentity_t *ent ) -{ -  int       waterlevel; - -  if( ent->client->noclip ) -  { -    ent->client->airOutTime = level.time + 12000; // don't need air -    return; -  } - -  waterlevel = ent->waterlevel; - -  // -  // check for drowning -  // -  if( waterlevel == 3 ) -  { -    // if out of air, start drowning -    if( ent->client->airOutTime < level.time) -    { -      // drown! -      ent->client->airOutTime += 1000; -      if( ent->health > 0 ) -      { -        // take more damage the longer underwater -        ent->damage += 2; -        if( ent->damage > 15 ) -          ent->damage = 15; - -        // play a gurp sound instead of a normal pain sound -        if( ent->health <= ent->damage ) -          G_Sound( ent, CHAN_VOICE, G_SoundIndex( "*drown.wav" ) ); -        else if( rand( ) & 1 ) -          G_Sound( ent, CHAN_VOICE, G_SoundIndex( "sound/player/gurp1.wav" ) ); -        else -          G_Sound( ent, CHAN_VOICE, G_SoundIndex( "sound/player/gurp2.wav" ) ); - -        // don't play a normal pain sound -        ent->pain_debounce_time = level.time + 200; - -        G_Damage( ent, NULL, NULL, NULL, NULL, -          ent->damage, DAMAGE_NO_ARMOR, MOD_WATER ); -      } -    } -  } -  else -  { -    ent->client->airOutTime = level.time + 12000; -    ent->damage = 2; -  } - -  // -  // check for sizzle damage (move to pmove?) -  // -  if( waterlevel && -      ( ent->watertype & ( CONTENTS_LAVA | CONTENTS_SLIME ) ) ) -  { -    if( ent->health > 0 && -        ent->pain_debounce_time <= level.time  ) -    { -      if( ent->watertype & CONTENTS_LAVA ) -      { -        G_Damage( ent, NULL, NULL, NULL, NULL, -          30 * waterlevel, 0, MOD_LAVA ); -      } - -      if( ent->watertype & CONTENTS_SLIME ) -      { -        G_Damage( ent, NULL, NULL, NULL, NULL, -          10 * waterlevel, 0, MOD_SLIME ); -      } -    } -  } -} - - - -/* -=============== -G_SetClientSound -=============== -*/ -void G_SetClientSound( gentity_t *ent ) -{ -  if( ent->waterlevel && ( ent->watertype & ( CONTENTS_LAVA | CONTENTS_SLIME ) ) ) -    ent->client->ps.loopSound = level.snd_fry; -  else -    ent->client->ps.loopSound = 0; -} - - - -//============================================================== - -/* -============== -ClientImpacts -============== -*/ -void ClientImpacts( gentity_t *ent, pmove_t *pm ) -{ -  int       i, j; -  trace_t   trace; -  gentity_t *other; - -  memset( &trace, 0, sizeof( trace ) ); - -  for( i = 0; i < pm->numtouch; i++ ) -  { -    for( j = 0; j < i; j++ ) -    { -      if( pm->touchents[ j ] == pm->touchents[ i ] ) -        break; -    } - -    if( j != i ) -      continue; // duplicated - -    other = &g_entities[ pm->touchents[ i ] ]; - -    if( ( ent->r.svFlags & SVF_BOT ) && ( ent->touch ) ) -      ent->touch( ent, other, &trace ); - -    //charge attack -    if( ent->client->ps.weapon == WP_ALEVEL4 && -        ent->client->ps.stats[ STAT_MISC ] > 0 && -        ent->client->charging ) -      ChargeAttack( ent, other ); - -    if( !other->touch ) -      continue; - -    other->touch( other, ent, &trace ); -  } -} - -/* -============ -G_TouchTriggers - -Find all trigger entities that ent's current position touches. -Spectators will only interact with teleporters. -============ -*/ -void  G_TouchTriggers( gentity_t *ent ) -{ -  int       i, num; -  int       touch[MAX_GENTITIES]; -  gentity_t *hit; -  trace_t   trace; -  vec3_t    mins, maxs; -  vec3_t    pmins, pmaxs; -  static    vec3_t range = { 10, 10, 10 }; - -  if( !ent->client ) -    return; - -  // dead clients don't activate triggers! -  if( ent->client->ps.stats[ STAT_HEALTH ] <= 0 ) -    return; - -  BG_FindBBoxForClass( ent->client->ps.stats[ STAT_PCLASS ], -                       pmins, pmaxs, NULL, NULL, NULL ); - -  VectorAdd( ent->client->ps.origin, pmins, mins ); -  VectorAdd( ent->client->ps.origin, pmaxs, maxs ); - -  VectorSubtract( mins, range, mins ); -  VectorAdd( maxs, range, maxs ); - -  num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES ); - -  // can't use ent->absmin, because that has a one unit pad -  VectorAdd( ent->client->ps.origin, ent->r.mins, mins ); -  VectorAdd( ent->client->ps.origin, ent->r.maxs, maxs ); - -  for( i = 0; i < num; i++ ) -  { -    hit = &g_entities[ touch[ i ] ]; - -    if( !hit->touch && !ent->touch ) -      continue; - -    if( !( hit->r.contents & CONTENTS_TRIGGER ) ) -      continue; - -    // ignore most entities if a spectator -    if( ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) || -        ( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) || -        ( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) ) -    { -      if( hit->s.eType != ET_TELEPORT_TRIGGER && -          // this is ugly but adding a new ET_? type will -          // most likely cause network incompatibilities -          hit->touch != Touch_DoorTrigger ) -      { -        //check for manually triggered doors -        manualTriggerSpectator( hit, ent ); -        continue; -      } -    } - -    if( !trap_EntityContact( mins, maxs, hit ) ) -      continue; - -    memset( &trace, 0, sizeof( trace ) ); - -    if( hit->touch ) -      hit->touch( hit, ent, &trace ); - -    if( ( ent->r.svFlags & SVF_BOT ) && ( ent->touch ) ) -      ent->touch( ent, hit, &trace ); -  } - -  // if we didn't touch a jump pad this pmove frame -  if( ent->client->ps.jumppad_frame != ent->client->ps.pmove_framecount ) -  { -    ent->client->ps.jumppad_frame = 0; -    ent->client->ps.jumppad_ent = 0; -  } -} - -/* -================= -SpectatorThink -================= -*/ -void SpectatorThink( gentity_t *ent, usercmd_t *ucmd ) -{ -  pmove_t pm; -  gclient_t *client; - -  client = ent->client; - -  client->oldbuttons = client->buttons; -  client->buttons = ucmd->buttons; - -  if( client->sess.spectatorState != SPECTATOR_FOLLOW ) -  { -    if( client->sess.spectatorState == SPECTATOR_LOCKED ) -      client->ps.pm_type = PM_FREEZE; -    else -      client->ps.pm_type = PM_SPECTATOR; - -    client->ps.speed = BG_FindSpeedForClass( client->ps.stats[ STAT_PCLASS ] ); - -    client->ps.stats[ STAT_STAMINA ] = 0; -    client->ps.stats[ STAT_MISC ] = 0; -    client->ps.stats[ STAT_BUILDABLE ] = 0; -    client->ps.stats[ STAT_PCLASS ] = PCL_NONE; -    client->ps.weapon = WP_NONE; - -    // set up for pmove -    memset( &pm, 0, sizeof( pm ) ); -    pm.ps = &client->ps; -    pm.cmd = *ucmd; -    pm.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY; // spectators can fly through bodies -    pm.trace = trap_Trace; -    pm.pointcontents = trap_PointContents; - -    // perform a pmove -    Pmove( &pm ); - -    // save results of pmove -    VectorCopy( client->ps.origin, ent->s.origin ); - -    G_TouchTriggers( ent ); -    trap_UnlinkEntity( ent ); - -    if( ( client->buttons & BUTTON_ATTACK ) && !( client->oldbuttons & BUTTON_ATTACK ) ) -    { -      //if waiting in a queue remove from the queue -      if( client->ps.pm_flags & PMF_QUEUED ) -      { -        if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -          G_RemoveFromSpawnQueue( &level.alienSpawnQueue, client->ps.clientNum ); -        else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -          G_RemoveFromSpawnQueue( &level.humanSpawnQueue, client->ps.clientNum ); - -        client->pers.classSelection = PCL_NONE; -        client->ps.stats[ STAT_PCLASS ] = PCL_NONE; -      } -      else if( client->pers.classSelection == PCL_NONE ) -      { -        if( client->pers.teamSelection == PTE_NONE ) -          G_TriggerMenu( client->ps.clientNum, MN_TEAM ); -        else if( client->pers.teamSelection == PTE_ALIENS ) -          G_TriggerMenu( client->ps.clientNum, MN_A_CLASS ); -        else if( client->pers.teamSelection == PTE_HUMANS ) -          G_TriggerMenu( client->ps.clientNum, MN_H_SPAWN ); -      } -    } - -    //set the queue position for the client side -    if( client->ps.pm_flags & PMF_QUEUED ) -    { -      if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -      { -        client->ps.persistant[ PERS_QUEUEPOS ] = -          G_GetPosInSpawnQueue( &level.alienSpawnQueue, client->ps.clientNum ); -      } -      else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -      { -        client->ps.persistant[ PERS_QUEUEPOS ] = -          G_GetPosInSpawnQueue( &level.humanSpawnQueue, client->ps.clientNum ); -      } -    } -  } - -  if( ( client->buttons & BUTTON_USE_HOLDABLE ) && !( client->oldbuttons & BUTTON_USE_HOLDABLE ) ) -    Cmd_Follow_f( ent, qtrue ); -} - - - -/* -================= -ClientInactivityTimer - -Returns qfalse if the client is dropped -================= -*/ -qboolean ClientInactivityTimer( gclient_t *client ) -{ -  if( ! g_inactivity.integer ) -  { -    // give everyone some time, so if the operator sets g_inactivity during -    // gameplay, everyone isn't kicked -    client->inactivityTime = level.time + 60 * 1000; -    client->inactivityWarning = qfalse; -  } -  else if( client->pers.cmd.forwardmove || -           client->pers.cmd.rightmove || -           client->pers.cmd.upmove || -           ( client->pers.cmd.buttons & BUTTON_ATTACK ) ) -  { -    client->inactivityTime = level.time + g_inactivity.integer * 1000; -    client->inactivityWarning = qfalse; -  } -  else if( !client->pers.localClient ) -  { -    if( level.time > client->inactivityTime ) -    { -      trap_DropClient( client - level.clients, "Dropped due to inactivity" ); -      return qfalse; -    } - -    if( level.time > client->inactivityTime - 10000 && !client->inactivityWarning ) -    { -      client->inactivityWarning = qtrue; -      G_SendCommandFromServer( client - level.clients, "cp \"Ten seconds until inactivity drop!\n\"" ); -    } -  } - -  return qtrue; -} - -/* -================== -ClientTimerActions - -Actions that happen once a second -================== -*/ -void ClientTimerActions( gentity_t *ent, int msec ) -{ -  gclient_t *client; -  usercmd_t *ucmd; -  int       aForward, aRight; - -  ucmd = &ent->client->pers.cmd; - -  aForward  = abs( ucmd->forwardmove ); -  aRight    = abs( ucmd->rightmove ); - -  client = ent->client; -  client->time100 += msec; -  client->time1000 += msec; -  client->time10000 += msec; - -  while ( client->time100 >= 100 ) -  { -    client->time100 -= 100; - -    //if not trying to run then not trying to sprint -    if( aForward <= 64 ) -      client->ps.stats[ STAT_STATE ] &= ~SS_SPEEDBOOST; - -    if( BG_InventoryContainsUpgrade( UP_JETPACK, client->ps.stats ) && BG_UpgradeIsActive( UP_JETPACK, client->ps.stats ) ) -      client->ps.stats[ STAT_STATE ] &= ~SS_SPEEDBOOST; - -    if( ( client->ps.stats[ STAT_STATE ] & SS_SPEEDBOOST ) &&  ucmd->upmove >= 0 ) -    { -      //subtract stamina -      if( BG_InventoryContainsUpgrade( UP_LIGHTARMOUR, client->ps.stats ) ) -        client->ps.stats[ STAT_STAMINA ] -= STAMINA_LARMOUR_TAKE; -      else -        client->ps.stats[ STAT_STAMINA ] -= STAMINA_SPRINT_TAKE; - -      if( client->ps.stats[ STAT_STAMINA ] < -MAX_STAMINA ) -        client->ps.stats[ STAT_STAMINA ] = -MAX_STAMINA; -    } - -    if( ( aForward <= 64 && aForward > 5 ) || ( aRight <= 64 && aRight > 5 ) ) -    { -      //restore stamina -      client->ps.stats[ STAT_STAMINA ] += STAMINA_WALK_RESTORE; - -      if( client->ps.stats[ STAT_STAMINA ] > MAX_STAMINA ) -        client->ps.stats[ STAT_STAMINA ] = MAX_STAMINA; -    } -    else if( aForward <= 5 && aRight <= 5 ) -    { -      //restore stamina faster -      client->ps.stats[ STAT_STAMINA ] += STAMINA_STOP_RESTORE; - -      if( client->ps.stats[ STAT_STAMINA ] > MAX_STAMINA ) -        client->ps.stats[ STAT_STAMINA ] = MAX_STAMINA; -    } - -    //client is charging up for a pounce -    if( client->ps.weapon == WP_ALEVEL3 || client->ps.weapon == WP_ALEVEL3_UPG ) -    { -      int pounceSpeed = 0; - -      if( client->ps.weapon == WP_ALEVEL3 ) -        pounceSpeed = LEVEL3_POUNCE_SPEED; -      else if( client->ps.weapon == WP_ALEVEL3_UPG ) -        pounceSpeed = LEVEL3_POUNCE_UPG_SPEED; - -      if( client->ps.stats[ STAT_MISC ] < pounceSpeed && ucmd->buttons & BUTTON_ATTACK2 ) -        client->ps.stats[ STAT_MISC ] += ( 100.0f / (float)LEVEL3_POUNCE_CHARGE_TIME ) * pounceSpeed; - -      if( !( ucmd->buttons & BUTTON_ATTACK2 ) ) -      { -        if( client->ps.stats[ STAT_MISC ] > 0 ) -        { -          client->allowedToPounce = qtrue; -          client->pouncePayload = client->ps.stats[ STAT_MISC ]; -        } - -        client->ps.stats[ STAT_MISC ] = 0; -      } - -      if( client->ps.stats[ STAT_MISC ] > pounceSpeed ) -        client->ps.stats[ STAT_MISC ] = pounceSpeed; -    } - -    //client is charging up for a... charge -    if( client->ps.weapon == WP_ALEVEL4 ) -    { -      if( client->ps.stats[ STAT_MISC ] < LEVEL4_CHARGE_TIME && ucmd->buttons & BUTTON_ATTACK2 && -          !client->charging ) -      { -        client->charging = qfalse; //should already be off, just making sure -        client->ps.stats[ STAT_STATE ] &= ~SS_CHARGING; - -        if( ucmd->forwardmove > 0 ) -        { -          //trigger charge sound...is quite annoying -          //if( client->ps.stats[ STAT_MISC ] <= 0 ) -          //  G_AddEvent( ent, EV_LEV4_CHARGE_PREPARE, 0 ); - -          client->ps.stats[ STAT_MISC ] += (int)( 100 * (float)LEVEL4_CHARGE_CHARGE_RATIO ); - -          if( client->ps.stats[ STAT_MISC ] > LEVEL4_CHARGE_TIME ) -            client->ps.stats[ STAT_MISC ] = LEVEL4_CHARGE_TIME; -        } -        else -          client->ps.stats[ STAT_MISC ] = 0; -      } - -      if( !( ucmd->buttons & BUTTON_ATTACK2 ) || client->charging || -          client->ps.stats[ STAT_MISC ] == LEVEL4_CHARGE_TIME ) -      { -        if( client->ps.stats[ STAT_MISC ] > LEVEL4_MIN_CHARGE_TIME ) -        { -          client->ps.stats[ STAT_MISC ] -= 100; - -          if( client->charging == qfalse ) -            G_AddEvent( ent, EV_LEV4_CHARGE_START, 0 ); - -          client->charging = qtrue; -          client->ps.stats[ STAT_STATE ] |= SS_CHARGING; - -          //if the charger has stopped moving take a chunk of charge away -          if( VectorLength( client->ps.velocity ) < 64.0f || aRight ) -            client->ps.stats[ STAT_MISC ] = client->ps.stats[ STAT_MISC ] / 2; - -          //can't charge backwards -          if( ucmd->forwardmove < 0 ) -            client->ps.stats[ STAT_MISC ] = 0; -        } -        else -          client->ps.stats[ STAT_MISC ] = 0; - - -        if( client->ps.stats[ STAT_MISC ] <= 0 ) -        { -          client->ps.stats[ STAT_MISC ] = 0; -          client->charging = qfalse; -          client->ps.stats[ STAT_STATE ] &= ~SS_CHARGING; -        } -      } -    } - -    //client is charging up an lcannon -    if( client->ps.weapon == WP_LUCIFER_CANNON ) -    { -      int ammo; - -      BG_UnpackAmmoArray( WP_LUCIFER_CANNON, client->ps.ammo, client->ps.powerups, &ammo, NULL ); - -      if( client->ps.stats[ STAT_MISC ] < LCANNON_TOTAL_CHARGE && ucmd->buttons & BUTTON_ATTACK ) -        client->ps.stats[ STAT_MISC ] += ( 100.0f / LCANNON_CHARGE_TIME ) * LCANNON_TOTAL_CHARGE; - -      if( client->ps.stats[ STAT_MISC ] > LCANNON_TOTAL_CHARGE ) -        client->ps.stats[ STAT_MISC ] = LCANNON_TOTAL_CHARGE; - -      if( client->ps.stats[ STAT_MISC ] > ( ammo * LCANNON_TOTAL_CHARGE ) / 10 ) -        client->ps.stats[ STAT_MISC ] = ammo * LCANNON_TOTAL_CHARGE / 10; -    } - -    switch( client->ps.weapon ) -    { -      case WP_ABUILD: -      case WP_ABUILD2: -      case WP_HBUILD: -      case WP_HBUILD2: -        //set validity bit on buildable -        if( ( client->ps.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) > BA_NONE ) -        { -          int     dist = BG_FindBuildDistForClass( ent->client->ps.stats[ STAT_PCLASS ] ); -          vec3_t  dummy; - -          if( G_itemFits( ent, client->ps.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT, -                          dist, dummy ) == IBE_NONE ) -            client->ps.stats[ STAT_BUILDABLE ] |= SB_VALID_TOGGLEBIT; -          else -            client->ps.stats[ STAT_BUILDABLE ] &= ~SB_VALID_TOGGLEBIT; -        } - -        //update build timer -        if( client->ps.stats[ STAT_MISC ] > 0 ) -          client->ps.stats[ STAT_MISC ] -= 100; - -        if( client->ps.stats[ STAT_MISC ] < 0 ) -          client->ps.stats[ STAT_MISC ] = 0; -        break; - -      default: -        break; -    } - -    if( client->ps.stats[ STAT_STATE ] & SS_MEDKIT_ACTIVE ) -    { -      int remainingStartupTime = MEDKIT_STARTUP_TIME - ( level.time - client->lastMedKitTime ); - -      if( remainingStartupTime < 0 ) -      { -        if( ent->health < ent->client->ps.stats[ STAT_MAX_HEALTH ] && -            ent->client->medKitHealthToRestore && -            ent->client->ps.pm_type != PM_DEAD ) -        { -          ent->client->medKitHealthToRestore--; -          ent->health++; -        } -        else -          ent->client->ps.stats[ STAT_STATE ] &= ~SS_MEDKIT_ACTIVE; -      } -      else -      { -        if( ent->health < ent->client->ps.stats[ STAT_MAX_HEALTH ] && -            ent->client->medKitHealthToRestore && -            ent->client->ps.pm_type != PM_DEAD ) -        { -          //partial increase -          if( level.time > client->medKitIncrementTime ) -          { -            ent->client->medKitHealthToRestore--; -            ent->health++; - -            client->medKitIncrementTime = level.time + -              ( remainingStartupTime / MEDKIT_STARTUP_SPEED ); -          } -        } -        else -          ent->client->ps.stats[ STAT_STATE ] &= ~SS_MEDKIT_ACTIVE; -      } -    } -  } - -  while( client->time1000 >= 1000 ) -  { -    client->time1000 -= 1000; - -    //client is poison clouded -    if( client->ps.stats[ STAT_STATE ] & SS_POISONCLOUDED ) -      G_Damage( ent, client->lastPoisonCloudedClient, client->lastPoisonCloudedClient, NULL, NULL, -                LEVEL1_PCLOUD_DMG, 0, MOD_LEVEL1_PCLOUD ); - -    //client is poisoned -    if( client->ps.stats[ STAT_STATE ] & SS_POISONED ) -    { -      int i; -      int seconds = ( ( level.time - client->lastPoisonTime ) / 1000 ) + 1; -      int damage = ALIEN_POISON_DMG, damage2 = 0; - -      for( i = 0; i < seconds; i++ ) -      { -        if( i == seconds - 1 ) -          damage2 = damage; - -        damage *= ALIEN_POISON_DIVIDER; -      } - -      damage = damage2 - damage; - -      G_Damage( ent, client->lastPoisonClient, client->lastPoisonClient, NULL, NULL, -                damage, 0, MOD_POISON ); -    } - -    //replenish alien health -    if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -    { -      int       entityList[ MAX_GENTITIES ]; -      vec3_t    range = { LEVEL4_REGEN_RANGE, LEVEL4_REGEN_RANGE, LEVEL4_REGEN_RANGE }; -      vec3_t    mins, maxs; -      int       i, num; -      gentity_t *boostEntity; -      float     modifier = 1.0f; - -      VectorAdd( client->ps.origin, range, maxs ); -      VectorSubtract( client->ps.origin, range, mins ); - -      num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -      for( i = 0; i < num; i++ ) -      { -        boostEntity = &g_entities[ entityList[ i ] ]; - -        if( boostEntity->client && boostEntity->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS && -            boostEntity->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_LEVEL4 ) -        { -          modifier = LEVEL4_REGEN_MOD; -          break; -        } -        else if( boostEntity->s.eType == ET_BUILDABLE && -            boostEntity->s.modelindex == BA_A_BOOSTER && -            boostEntity->spawned ) -        { -          modifier = BOOSTER_REGEN_MOD; -          break; -        } -      } - -      if( ent->health > 0 && ent->health < client->ps.stats[ STAT_MAX_HEALTH ] && -          ( ent->lastDamageTime + ALIEN_REGEN_DAMAGE_TIME ) < level.time ) -        ent->health += BG_FindRegenRateForClass( client->ps.stats[ STAT_PCLASS ] ) * modifier; - -      if( ent->health > client->ps.stats[ STAT_MAX_HEALTH ] ) -        ent->health = client->ps.stats[ STAT_MAX_HEALTH ]; -    } -  } - -  while( client->time10000 >= 10000 ) -  { -    client->time10000 -= 10000; - -    if( client->ps.weapon == WP_ALEVEL3_UPG ) -    { -      int ammo, maxAmmo; - -      BG_FindAmmoForWeapon( WP_ALEVEL3_UPG, &maxAmmo, NULL ); -      BG_UnpackAmmoArray( WP_ALEVEL3_UPG, client->ps.ammo, client->ps.powerups, &ammo, NULL ); - -      if( ammo < maxAmmo ) -      { -        ammo++; -        BG_PackAmmoArray( WP_ALEVEL3_UPG, client->ps.ammo, client->ps.powerups, ammo, 0 ); -      } -    } -  } -} - -/* -==================== -ClientIntermissionThink -==================== -*/ -void ClientIntermissionThink( gclient_t *client ) -{ -  client->ps.eFlags &= ~EF_TALK; -  client->ps.eFlags &= ~EF_FIRING; -  client->ps.eFlags &= ~EF_FIRING2; - -  // the level will exit when everyone wants to or after timeouts - -  // swap and latch button actions -  client->oldbuttons = client->buttons; -  client->buttons = client->pers.cmd.buttons; -  if( client->buttons & ( BUTTON_ATTACK | BUTTON_USE_HOLDABLE ) & ( client->oldbuttons ^ client->buttons ) ) -    client->readyToExit = 1; -} - - -/* -================ -ClientEvents - -Events will be passed on to the clients for presentation, -but any server game effects are handled here -================ -*/ -void ClientEvents( gentity_t *ent, int oldEventSequence ) -{ -  int       i; -  int       event; -  gclient_t *client; -  int       damage; -  vec3_t    dir; -  vec3_t    point, mins; -  float     fallDistance; -  pClass_t  class; - -  client = ent->client; -  class = client->ps.stats[ STAT_PCLASS ]; - -  if( oldEventSequence < client->ps.eventSequence - MAX_PS_EVENTS ) -    oldEventSequence = client->ps.eventSequence - MAX_PS_EVENTS; - -  for( i = oldEventSequence; i < client->ps.eventSequence; i++ ) -  { -    event = client->ps.events[ i & ( MAX_PS_EVENTS - 1 ) ]; - -    switch( event ) -    { -      case EV_FALL_MEDIUM: -      case EV_FALL_FAR: -        if( ent->s.eType != ET_PLAYER ) -          break;    // not in the player model - -        fallDistance = ( (float)client->ps.stats[ STAT_FALLDIST ] - MIN_FALL_DISTANCE ) / -                         ( MAX_FALL_DISTANCE - MIN_FALL_DISTANCE ); - -        if( fallDistance < 0.0f ) -          fallDistance = 0.0f; -        else if( fallDistance > 1.0f ) -          fallDistance = 1.0f; - -        damage = (int)( (float)BG_FindHealthForClass( class ) * -                 BG_FindFallDamageForClass( class ) * fallDistance ); - -        VectorSet( dir, 0, 0, 1 ); -        BG_FindBBoxForClass( class, mins, NULL, NULL, NULL, NULL ); -        mins[ 0 ] = mins[ 1 ] = 0.0f; -        VectorAdd( client->ps.origin, mins, point ); - -        ent->pain_debounce_time = level.time + 200; // no normal pain sound -        G_Damage( ent, NULL, NULL, dir, point, damage, DAMAGE_NO_LOCDAMAGE, MOD_FALLING ); -        break; - -      case EV_FIRE_WEAPON: -        FireWeapon( ent ); -        break; - -      case EV_FIRE_WEAPON2: -        FireWeapon2( ent ); -        break; - -      case EV_FIRE_WEAPON3: -        FireWeapon3( ent ); -        break; - -      case EV_NOAMMO: -        //if we just ran out of grenades, remove the inventory item -        if( ent->s.weapon == WP_GRENADE ) -        { -          int j; - -          BG_RemoveWeaponFromInventory( ent->s.weapon, ent->client->ps.stats ); - -          //switch to the first non blaster weapon -          for( j = WP_NONE + 1; j < WP_NUM_WEAPONS; j++ ) -          { -            if( j == WP_BLASTER ) -              continue; - -            if( BG_InventoryContainsWeapon( j, ent->client->ps.stats ) ) -            { -              G_ForceWeaponChange( ent, j ); -              break; -            } -          } - -          //only got the blaster to switch to -          if( j == WP_NUM_WEAPONS ) -            G_ForceWeaponChange( ent, WP_BLASTER ); - -          //update ClientInfo -          ClientUserinfoChanged( ent->client->ps.clientNum ); -        } - -        break; - -      default: -        break; -    } -  } -} - - -/* -============== -SendPendingPredictableEvents -============== -*/ -void SendPendingPredictableEvents( playerState_t *ps ) -{ -  gentity_t *t; -  int       event, seq; -  int       extEvent, number; - -  // if there are still events pending -  if( ps->entityEventSequence < ps->eventSequence ) -  { -    // create a temporary entity for this event which is sent to everyone -    // except the client who generated the event -    seq = ps->entityEventSequence & ( MAX_PS_EVENTS - 1 ); -    event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 ); -    // set external event to zero before calling BG_PlayerStateToEntityState -    extEvent = ps->externalEvent; -    ps->externalEvent = 0; -    // create temporary entity for event -    t = G_TempEntity( ps->origin, event ); -    number = t->s.number; -    BG_PlayerStateToEntityState( ps, &t->s, qtrue ); -    t->s.number = number; -    t->s.eType = ET_EVENTS + event; -    t->s.eFlags |= EF_PLAYER_EVENT; -    t->s.otherEntityNum = ps->clientNum; -    // send to everyone except the client who generated the event -    t->r.svFlags |= SVF_NOTSINGLECLIENT; -    t->r.singleClient = ps->clientNum; -    // set back external event -    ps->externalEvent = extEvent; -  } -} - -/* -============== -ClientThink - -This will be called once for each client frame, which will -usually be a couple times for each server frame on fast clients. - -If "g_synchronousClients 1" is set, this will be called exactly -once for each server frame, which makes for smooth demo recording. -============== -*/ -void ClientThink_real( gentity_t *ent ) -{ -  gclient_t *client; -  pmove_t   pm; -  int       oldEventSequence; -  int       msec; -  usercmd_t *ucmd; - -  client = ent->client; - -  // don't think if the client is not yet connected (and thus not yet spawned in) -  if( client->pers.connected != CON_CONNECTED ) -    return; - -  // mark the time, so the connection sprite can be removed -  ucmd = &ent->client->pers.cmd; - -  // sanity check the command time to prevent speedup cheating -  if( ucmd->serverTime > level.time + 200 ) -  { -    ucmd->serverTime = level.time + 200; -//    G_Printf("serverTime <<<<<\n" ); -  } - -  if( ucmd->serverTime < level.time - 1000 ) -  { -    ucmd->serverTime = level.time - 1000; -//    G_Printf("serverTime >>>>>\n" ); -  } - -  msec = ucmd->serverTime - client->ps.commandTime; -  // following others may result in bad times, but we still want -  // to check for follow toggles -  if( msec < 1 && client->sess.spectatorState != SPECTATOR_FOLLOW ) -    return; - -  if( msec > 200 ) -    msec = 200; - -  if( pmove_msec.integer < 8 ) -    trap_Cvar_Set( "pmove_msec", "8" ); -  else if( pmove_msec.integer > 33 ) -    trap_Cvar_Set( "pmove_msec", "33" ); - -  if( pmove_fixed.integer || client->pers.pmoveFixed ) -  { -    ucmd->serverTime = ( ( ucmd->serverTime + pmove_msec.integer - 1 ) / pmove_msec.integer ) * pmove_msec.integer; -    //if (ucmd->serverTime - client->ps.commandTime <= 0) -    //  return; -  } - -  // -  // check for exiting intermission -  // -  if( level.intermissiontime ) -  { -    ClientIntermissionThink( client ); -    return; -  } - -  // spectators don't do much -  if( client->sess.sessionTeam == TEAM_SPECTATOR ) -  { -    if( client->sess.spectatorState == SPECTATOR_SCOREBOARD ) -      return; - -    SpectatorThink( ent, ucmd ); -    return; -  } - -  G_UpdatePTRConnection( client ); - -  // check for inactivity timer, but never drop the local client of a non-dedicated server -  if( !ClientInactivityTimer( client ) ) -    return; - -  if( client->noclip ) -    client->ps.pm_type = PM_NOCLIP; -  else if( client->ps.stats[ STAT_HEALTH ] <= 0 ) -    client->ps.pm_type = PM_DEAD; -  else if( client->ps.stats[ STAT_STATE ] & SS_INFESTING || -           client->ps.stats[ STAT_STATE ] & SS_HOVELING ) -    client->ps.pm_type = PM_FREEZE; -  else if( client->ps.stats[ STAT_STATE ] & SS_BLOBLOCKED || -           client->ps.stats[ STAT_STATE ] & SS_GRABBED ) -    client->ps.pm_type = PM_GRABBED; -  else if( BG_InventoryContainsUpgrade( UP_JETPACK, client->ps.stats ) && BG_UpgradeIsActive( UP_JETPACK, client->ps.stats ) ) -    client->ps.pm_type = PM_JETPACK; -  else -    client->ps.pm_type = PM_NORMAL; - -  if( client->ps.stats[ STAT_STATE ] & SS_GRABBED && -      client->grabExpiryTime < level.time ) -    client->ps.stats[ STAT_STATE ] &= ~SS_GRABBED; - -  if( client->ps.stats[ STAT_STATE ] & SS_BLOBLOCKED && -      client->lastLockTime + 5000 < level.time ) -    client->ps.stats[ STAT_STATE ] &= ~SS_BLOBLOCKED; - -  if( client->ps.stats[ STAT_STATE ] & SS_SLOWLOCKED && -      client->lastLockTime + ABUILDER_BLOB_TIME < level.time ) -    client->ps.stats[ STAT_STATE ] &= ~SS_SLOWLOCKED; - -  client->ps.stats[ STAT_BOOSTTIME ] = level.time - client->lastBoostedTime; - -  if( client->ps.stats[ STAT_STATE ] & SS_BOOSTED && -      client->lastBoostedTime + BOOST_TIME < level.time ) -    client->ps.stats[ STAT_STATE ] &= ~SS_BOOSTED; - -  if( client->ps.stats[ STAT_STATE ] & SS_POISONCLOUDED && -      client->lastPoisonCloudedTime + LEVEL1_PCLOUD_TIME < level.time ) -    client->ps.stats[ STAT_STATE ] &= ~SS_POISONCLOUDED; - -  if( client->ps.stats[ STAT_STATE ] & SS_POISONED && -      client->lastPoisonTime + ALIEN_POISON_TIME < level.time ) -    client->ps.stats[ STAT_STATE ] &= ~SS_POISONED; - -  client->ps.gravity = g_gravity.value; - -  if( BG_InventoryContainsUpgrade( UP_MEDKIT, client->ps.stats ) && -      BG_UpgradeIsActive( UP_MEDKIT, client->ps.stats ) ) -  { -    //if currently using a medkit or have no need for a medkit now -    if( client->ps.stats[ STAT_STATE ] & SS_MEDKIT_ACTIVE || -        ( client->ps.stats[ STAT_HEALTH ] == client->ps.stats[ STAT_MAX_HEALTH ] && -          !( client->ps.stats[ STAT_STATE ] & SS_POISONED ) ) ) -    { -      BG_DeactivateUpgrade( UP_MEDKIT, client->ps.stats ); -    } -    else if( client->ps.stats[ STAT_HEALTH ] > 0 ) -    { -      //remove anti toxin -      BG_DeactivateUpgrade( UP_MEDKIT, client->ps.stats ); -      BG_RemoveUpgradeFromInventory( UP_MEDKIT, client->ps.stats ); - -      client->ps.stats[ STAT_STATE ] &= ~SS_POISONED; -      client->poisonImmunityTime = level.time + MEDKIT_POISON_IMMUNITY_TIME; - -      client->ps.stats[ STAT_STATE ] |= SS_MEDKIT_ACTIVE; -      client->lastMedKitTime = level.time; -      client->medKitHealthToRestore = -        client->ps.stats[ STAT_MAX_HEALTH ] - client->ps.stats[ STAT_HEALTH ]; -      client->medKitIncrementTime = level.time + -        ( MEDKIT_STARTUP_TIME / MEDKIT_STARTUP_SPEED ); - -      G_AddEvent( ent, EV_MEDKIT_USED, 0 ); -    } -  } - -  if( BG_InventoryContainsUpgrade( UP_GRENADE, client->ps.stats ) && -      BG_UpgradeIsActive( UP_GRENADE, client->ps.stats ) ) -  { -    int lastWeapon = ent->s.weapon; - -    //remove grenade -    BG_DeactivateUpgrade( UP_GRENADE, client->ps.stats ); -    BG_RemoveUpgradeFromInventory( UP_GRENADE, client->ps.stats ); - -    //M-M-M-M-MONSTER HACK -    ent->s.weapon = WP_GRENADE; -    FireWeapon( ent ); -    ent->s.weapon = lastWeapon; -  } - -  // set speed -  client->ps.speed = g_speed.value * BG_FindSpeedForClass( client->ps.stats[ STAT_PCLASS ] ); - -  if( client->lastCreepSlowTime + CREEP_TIMEOUT < level.time ) -    client->ps.stats[ STAT_STATE ] &= ~SS_CREEPSLOWED; - -  //randomly disable the jet pack if damaged -  if( BG_InventoryContainsUpgrade( UP_JETPACK, client->ps.stats ) && -      BG_UpgradeIsActive( UP_JETPACK, client->ps.stats ) ) -  { -    if( ent->lastDamageTime + JETPACK_DISABLE_TIME > level.time ) -    { -      if( random( ) > JETPACK_DISABLE_CHANCE ) -        client->ps.pm_type = PM_NORMAL; -    } - -    //switch jetpack off if no reactor -    if( !level.reactorPresent ) -      BG_DeactivateUpgrade( UP_JETPACK, client->ps.stats ); -  } - -  // set up for pmove -  oldEventSequence = client->ps.eventSequence; - -  memset( &pm, 0, sizeof( pm ) ); - -  if( !( ucmd->buttons & BUTTON_TALK ) ) //&& client->ps.weaponTime <= 0 ) //TA: erk more server load -  { -    switch( client->ps.weapon ) -    { -      case WP_ALEVEL0: -        if( client->ps.weaponTime <= 0 ) -          pm.autoWeaponHit[ client->ps.weapon ] = CheckVenomAttack( ent ); -        break; - -      case WP_ALEVEL1: -      case WP_ALEVEL1_UPG: -        CheckGrabAttack( ent ); -        break; - -      case WP_ALEVEL3: -      case WP_ALEVEL3_UPG: -        if( client->ps.weaponTime <= 0 ) -          pm.autoWeaponHit[ client->ps.weapon ] = CheckPounceAttack( ent ); -        break; - -      default: -        break; -    } -  } - -  if( ent->flags & FL_FORCE_GESTURE ) -  { -    ent->flags &= ~FL_FORCE_GESTURE; -    ent->client->pers.cmd.buttons |= BUTTON_GESTURE; -  } - -  pm.ps = &client->ps; -  pm.cmd = *ucmd; - -  if( pm.ps->pm_type == PM_DEAD ) -    pm.tracemask = MASK_PLAYERSOLID; // & ~CONTENTS_BODY; - -  if( pm.ps->stats[ STAT_STATE ] & SS_INFESTING || -      pm.ps->stats[ STAT_STATE ] & SS_HOVELING ) -    pm.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY; -  else -    pm.tracemask = MASK_PLAYERSOLID; - -  pm.trace = trap_Trace; -  pm.pointcontents = trap_PointContents; -  pm.debugLevel = g_debugMove.integer; -  pm.noFootsteps = 0; - -  pm.pmove_fixed = pmove_fixed.integer | client->pers.pmoveFixed; -  pm.pmove_msec = pmove_msec.integer; - -  VectorCopy( client->ps.origin, client->oldOrigin ); - -  // moved from after Pmove -- potentially the cause of -  // future triggering bugs -  if( !ent->client->noclip ) -    G_TouchTriggers( ent ); - -  Pmove( &pm ); - -  // save results of pmove -  if( ent->client->ps.eventSequence != oldEventSequence ) -    ent->eventTime = level.time; - -  if( g_smoothClients.integer ) -    BG_PlayerStateToEntityStateExtraPolate( &ent->client->ps, &ent->s, ent->client->ps.commandTime, qtrue ); -  else -    BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, qtrue ); - -  SendPendingPredictableEvents( &ent->client->ps ); - -  if( !( ent->client->ps.eFlags & EF_FIRING ) ) -    client->fireHeld = qfalse;    // for grapple -  if( !( ent->client->ps.eFlags & EF_FIRING2 ) ) -    client->fire2Held = qfalse; - -  // use the snapped origin for linking so it matches client predicted versions -  VectorCopy( ent->s.pos.trBase, ent->r.currentOrigin ); - -  VectorCopy( pm.mins, ent->r.mins ); -  VectorCopy( pm.maxs, ent->r.maxs ); - -  ent->waterlevel = pm.waterlevel; -  ent->watertype = pm.watertype; - -  // execute client events -  ClientEvents( ent, oldEventSequence ); - -  // link entity now, after any personal teleporters have been used -  trap_LinkEntity( ent ); - -  // NOTE: now copy the exact origin over otherwise clients can be snapped into solid -  VectorCopy( ent->client->ps.origin, ent->r.currentOrigin ); -  VectorCopy( ent->client->ps.origin, ent->s.origin ); - -  // touch other objects -  ClientImpacts( ent, &pm ); - -  // save results of triggers and client events -  if( ent->client->ps.eventSequence != oldEventSequence ) -    ent->eventTime = level.time; - -  // swap and latch button actions -  client->oldbuttons = client->buttons; -  client->buttons = ucmd->buttons; -  client->latched_buttons |= client->buttons & ~client->oldbuttons; - -  if( ( client->buttons & BUTTON_GETFLAG ) && !( client->oldbuttons & BUTTON_GETFLAG ) && -       client->ps.stats[ STAT_HEALTH ] > 0 ) -  { -    trace_t   trace; -    vec3_t    view, point; -    gentity_t *traceEnt; - -    if( client->ps.stats[ STAT_STATE ] & SS_HOVELING ) -    { -      gentity_t *hovel = client->hovel; - -      //only let the player out if there is room -      if( !AHovel_Blocked( hovel, ent, qtrue ) ) -      { -        //prevent lerping -        client->ps.eFlags ^= EF_TELEPORT_BIT; -        client->ps.eFlags &= ~EF_NODRAW; - -        //client leaves hovel -        client->ps.stats[ STAT_STATE ] &= ~SS_HOVELING; - -        //hovel is empty -        G_setBuildableAnim( hovel, BANIM_ATTACK2, qfalse ); -        hovel->active = qfalse; -      } -      else -      { -        //exit is blocked -        G_TriggerMenu( ent->client->ps.clientNum, MN_A_HOVEL_BLOCKED ); -      } -    } -    else -    { -#define USE_OBJECT_RANGE 64 - -      int       entityList[ MAX_GENTITIES ]; -      vec3_t    range = { USE_OBJECT_RANGE, USE_OBJECT_RANGE, USE_OBJECT_RANGE }; -      vec3_t    mins, maxs; -      int       i, num; -      int       j; -      qboolean  upgrade = qfalse; - -      //TA: look for object infront of player -      AngleVectors( client->ps.viewangles, view, NULL, NULL ); -      VectorMA( client->ps.origin, USE_OBJECT_RANGE, view, point ); -      trap_Trace( &trace, client->ps.origin, NULL, NULL, point, ent->s.number, MASK_SHOT ); - -      traceEnt = &g_entities[ trace.entityNum ]; - -      if( traceEnt && traceEnt->biteam == client->ps.stats[ STAT_PTEAM ] && traceEnt->use ) -        traceEnt->use( traceEnt, ent, ent ); //other and activator are the same in this context -      else -      { -        //no entity in front of player - do a small area search - -        VectorAdd( client->ps.origin, range, maxs ); -        VectorSubtract( client->ps.origin, range, mins ); - -        num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -        for( i = 0; i < num; i++ ) -        { -          traceEnt = &g_entities[ entityList[ i ] ]; - -          if( traceEnt && traceEnt->biteam == client->ps.stats[ STAT_PTEAM ] && traceEnt->use ) -          { -            traceEnt->use( traceEnt, ent, ent ); //other and activator are the same in this context -            break; -          } -        } - -        if( i == num && client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -        { -          for( j = PCL_NONE + 1; j < PCL_NUM_CLASSES; j++ ) -          { -            if( BG_ClassCanEvolveFromTo( client->ps.stats[ STAT_PCLASS ], j, -                                         client->ps.persistant[ PERS_CREDIT ], 0 ) >= 0 && -                BG_FindStagesForClass( j, g_alienStage.integer ) && G_ClassIsAllowed( j ) ) -            { -              upgrade = qtrue; -              break; -            } -          } - -          if( upgrade ) -          { -            //no nearby objects and alien - show class menu -            G_TriggerMenu( ent->client->ps.clientNum, MN_A_INFEST ); -          } -          else -          { -            //flash frags -            G_AddEvent( ent, EV_ALIEN_EVOLVE_FAILED, 0 ); -          } -        } -      } -    } -  } - -  // check for respawning -  if( client->ps.stats[ STAT_HEALTH ] <= 0 ) -  { -    // wait for the attack button to be pressed -    if( level.time > client->respawnTime ) -    { -      // forcerespawn is to prevent users from waiting out powerups -      if( g_forcerespawn.integer > 0 && -        ( level.time - client->respawnTime ) > 0 ) -      { -        respawn( ent ); -        return; -      } - -      // pressing attack or use is the normal respawn method -      if( ucmd->buttons & ( BUTTON_ATTACK | BUTTON_USE_HOLDABLE ) ) -      { -        respawn( ent ); -      } -    } -    return; -  } - -  if( level.framenum > client->retriggerArmouryMenu && client->retriggerArmouryMenu ) -  { -    G_TriggerMenu( client->ps.clientNum, MN_H_ARMOURY ); - -    client->retriggerArmouryMenu = 0; -  } - -  // Give clients some credit periodically -  if( ent->client->lastKillTime + FREEKILL_PERIOD < level.time ) -  { -    if( g_suddenDeathTime.integer && -        ( level.time - level.startTime >= g_suddenDeathTime.integer * 60000 ) ) -    { -      //gotta love logic like this eh? -    } -    else if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -      G_AddCreditToClient( ent->client, FREEKILL_ALIEN, qtrue ); -    else if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -      G_AddCreditToClient( ent->client, FREEKILL_HUMAN, qtrue ); - -    ent->client->lastKillTime = level.time; -  } - -  // perform once-a-second actions -  ClientTimerActions( ent, msec ); -   -  if( ent->suicideTime > 0 && ent->suicideTime < level.time ) -  { -    ent->flags &= ~FL_GODMODE; -    ent->client->ps.stats[ STAT_HEALTH ] = ent->health = 0; -    player_die( ent, ent, ent, 100000, MOD_SUICIDE ); - -    ent->suicideTime = 0; -  } -} - -/* -================== -ClientThink - -A new command has arrived from the client -================== -*/ -void ClientThink( int clientNum ) -{ -  gentity_t *ent; - -  ent = g_entities + clientNum; -  trap_GetUsercmd( clientNum, &ent->client->pers.cmd ); - -  // mark the time we got info, so we can display the -  // phone jack if they don't get any for a while -  ent->client->lastCmdTime = level.time; - -  if( !(ent->r.svFlags & SVF_BOT) && !g_synchronousClients.integer ) -    ClientThink_real( ent ); -} - - -void G_RunClient( gentity_t *ent ) -{ -  if( !( ent->r.svFlags & SVF_BOT ) && !g_synchronousClients.integer ) -    return; - -  ent->client->pers.cmd.serverTime = level.time; -  ClientThink_real( ent ); -} - - -/* -================== -SpectatorClientEndFrame - -================== -*/ -void SpectatorClientEndFrame( gentity_t *ent ) -{ -  gclient_t *cl; -  int       clientNum, flags; - -  // if we are doing a chase cam or a remote view, grab the latest info -  if( ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) -  { -    clientNum = ent->client->sess.spectatorClient; - -    if( clientNum >= 0 ) -    { -      cl = &level.clients[ clientNum ]; - -      if( cl->pers.connected == CON_CONNECTED && cl->sess.sessionTeam != TEAM_SPECTATOR ) -      { -        flags = ( cl->ps.eFlags & ~( EF_VOTED | EF_TEAMVOTED ) ) | -          ( ent->client->ps.eFlags & ( EF_VOTED | EF_TEAMVOTED ) ); -        ent->client->ps = cl->ps; -        ent->client->ps.pm_flags |= PMF_FOLLOW; -        ent->client->ps.eFlags = flags; -      } -    } -  } -} - -/* -============== -ClientEndFrame - -Called at the end of each server frame for each connected client -A fast client will have multiple ClientThink for each ClientEdFrame, -while a slow client may have multiple ClientEndFrame between ClientThink. -============== -*/ -void ClientEndFrame( gentity_t *ent ) -{ -  clientPersistant_t  *pers; - -  if( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) -  { -    SpectatorClientEndFrame( ent ); -    return; -  } - -  pers = &ent->client->pers; - -  // -  // If the end of unit layout is displayed, don't give -  // the player any normal movement attributes -  // -  if( level.intermissiontime ) -    return; - -  // burn from lava, etc -  P_WorldEffects( ent ); - -  // apply all the damage taken this frame -  P_DamageFeedback( ent ); - -  // add the EF_CONNECTION flag if we haven't gotten commands recently -  if( level.time - ent->client->lastCmdTime > 1000 ) -    ent->s.eFlags |= EF_CONNECTION; -  else -    ent->s.eFlags &= ~EF_CONNECTION; - -  ent->client->ps.stats[ STAT_HEALTH ] = ent->health; // FIXME: get rid of ent->health... - -  G_SetClientSound( ent ); - -  // set the latest infor -  if( g_smoothClients.integer ) -    BG_PlayerStateToEntityStateExtraPolate( &ent->client->ps, &ent->s, ent->client->ps.commandTime, qtrue ); -  else -    BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, qtrue ); - -  SendPendingPredictableEvents( &ent->client->ps ); -} - - diff --git a/mod/src/game/g_buildable.c b/mod/src/game/g_buildable.c deleted file mode 100644 index 083e0662..00000000 --- a/mod/src/game/g_buildable.c +++ /dev/null @@ -1,2987 +0,0 @@ -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -/* -================ -G_setBuildableAnim - -Triggers an animation client side -================ -*/ -void G_setBuildableAnim( gentity_t *ent, buildableAnimNumber_t anim, qboolean force ) -{ -  int localAnim = anim; - -  if( force ) -    localAnim |= ANIM_FORCEBIT; - -  localAnim |= ( ( ent->s.legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ); - -  ent->s.legsAnim = localAnim; -} - -/* -================ -G_setIdleBuildableAnim - -Set the animation to use whilst no other animations are running -================ -*/ -void G_setIdleBuildableAnim( gentity_t *ent, buildableAnimNumber_t anim ) -{ -  ent->s.torsoAnim = anim; -} - -/* -=============== -G_CheckSpawnPoint - -Check if a spawn at a specified point is valid -=============== -*/ -gentity_t *G_CheckSpawnPoint( int spawnNum, vec3_t origin, vec3_t normal, -    buildable_t spawn, vec3_t spawnOrigin ) -{ -  float   displacement; -  vec3_t  mins, maxs; -  vec3_t  cmins, cmaxs; -  vec3_t  localOrigin; -  trace_t tr; - -  BG_FindBBoxForBuildable( spawn, mins, maxs ); - -  if( spawn == BA_A_SPAWN ) -  { -    VectorSet( cmins, -MAX_ALIEN_BBOX, -MAX_ALIEN_BBOX, -MAX_ALIEN_BBOX ); -    VectorSet( cmaxs,  MAX_ALIEN_BBOX,  MAX_ALIEN_BBOX,  MAX_ALIEN_BBOX ); - -    displacement = ( maxs[ 2 ] + MAX_ALIEN_BBOX ) * M_ROOT3; -    VectorMA( origin, displacement, normal, localOrigin ); - -    trap_Trace( &tr, origin, NULL, NULL, localOrigin, spawnNum, MASK_SHOT ); - -    if( tr.entityNum != ENTITYNUM_NONE ) -      return &g_entities[ tr.entityNum ]; - -    trap_Trace( &tr, localOrigin, cmins, cmaxs, localOrigin, -1, MASK_SHOT ); - -    if( tr.entityNum == ENTITYNUM_NONE ) -    { -      if( spawnOrigin != NULL ) -        VectorCopy( localOrigin, spawnOrigin ); - -      return NULL; -    } -    else -      return &g_entities[ tr.entityNum ]; -  } -  else if( spawn == BA_H_SPAWN ) -  { -    BG_FindBBoxForClass( PCL_HUMAN, cmins, cmaxs, NULL, NULL, NULL ); - -    VectorCopy( origin, localOrigin ); -    localOrigin[ 2 ] += maxs[ 2 ] + fabs( cmins[ 2 ] ) + 1.0f; - -    trap_Trace( &tr, origin, NULL, NULL, localOrigin, spawnNum, MASK_SHOT ); - -    if( tr.entityNum != ENTITYNUM_NONE ) -      return &g_entities[ tr.entityNum ]; - -    trap_Trace( &tr, localOrigin, cmins, cmaxs, localOrigin, -1, MASK_SHOT ); - -    if( tr.entityNum == ENTITYNUM_NONE ) -    { -      if( spawnOrigin != NULL ) -        VectorCopy( localOrigin, spawnOrigin ); - -      return NULL; -    } -    else -      return &g_entities[ tr.entityNum ]; -  } - -  return NULL; -} - -/* -================ -G_NumberOfDependants - -Return number of entities that depend on this one -================ -*/ -static int G_NumberOfDependants( gentity_t *self ) -{ -  int       i, n = 0; -  gentity_t *ent; - -  for ( i = 1, ent = g_entities + i; i < level.num_entities; i++, ent++ ) -  { -    if( ent->s.eType != ET_BUILDABLE ) -      continue; - -    if( ent->parentNode == self ) -      n++; -  } - -  return n; -} - -#define POWER_REFRESH_TIME  2000 - -/* -================ -findPower - -attempt to find power for self, return qtrue if successful -================ -*/ -static qboolean findPower( gentity_t *self ) -{ -  int       i; -  gentity_t *ent; -  gentity_t *closestPower = NULL; -  int       distance = 0; -  int       minDistance = 10000; -  vec3_t    temp_v; -  qboolean  foundPower = qfalse; - -  if( self->biteam != BIT_HUMANS ) -    return qfalse; - -  //reactor is always powered -  if( self->s.modelindex == BA_H_REACTOR ) -    return qtrue; - -  //if this already has power then stop now -  if( self->parentNode && self->parentNode->powered ) -    return qtrue; - -  //reset parent -  self->parentNode = NULL; - -  //iterate through entities -  for ( i = 1, ent = g_entities + i; i < level.num_entities; i++, ent++ ) -  { -    if( ent->s.eType != ET_BUILDABLE ) -      continue; - -    //if entity is a power item calculate the distance to it -    if( ( ent->s.modelindex == BA_H_REACTOR || ent->s.modelindex == BA_H_REPEATER ) && -        ent->spawned ) -    { -      VectorSubtract( self->s.origin, ent->s.origin, temp_v ); -      distance = VectorLength( temp_v ); -      if( distance < minDistance && ent->powered ) -      { -        closestPower = ent; -        minDistance = distance; -        foundPower = qtrue; -      } -    } -  } - -  //if there were no power items nearby give up -  if( !foundPower ) -    return qfalse; - -  //bleh -  if( ( closestPower->s.modelindex == BA_H_REACTOR && ( minDistance <= REACTOR_BASESIZE ) ) || -      ( closestPower->s.modelindex == BA_H_REPEATER && ( minDistance <= REPEATER_BASESIZE ) && -        closestPower->powered ) ) -  { -    self->parentNode = closestPower; - -    return qtrue; -  } -  else -    return qfalse; -} - -/* -================ -G_isPower - -Simple wrapper to findPower to check if a location has power -================ -*/ -qboolean G_isPower( vec3_t origin ) -{ -  gentity_t dummy; - -  dummy.parentNode = NULL; -  dummy.biteam = BIT_HUMANS; -  VectorCopy( origin, dummy.s.origin ); - -  return findPower( &dummy ); -} - -/* -================ -findDCC - -attempt to find a controlling DCC for self, return qtrue if successful -================ -*/ -static qboolean findDCC( gentity_t *self ) -{ -  int       i; -  gentity_t *ent; -  gentity_t *closestDCC = NULL; -  int       distance = 0; -  int       minDistance = 10000; -  vec3_t    temp_v; -  qboolean  foundDCC = qfalse; - -  if( self->biteam != BIT_HUMANS ) -    return qfalse; - -  //if this already has dcc then stop now -  if( self->dccNode && self->dccNode->powered ) -    return qtrue; - -  //reset parent -  self->dccNode = NULL; - -  //iterate through entities -  for( i = 1, ent = g_entities + i; i < level.num_entities; i++, ent++ ) -  { -    if( ent->s.eType != ET_BUILDABLE ) -      continue; - -    //if entity is a dcc calculate the distance to it -    if( ent->s.modelindex == BA_H_DCC && ent->spawned ) -    { -      VectorSubtract( self->s.origin, ent->s.origin, temp_v ); -      distance = VectorLength( temp_v ); -      if( distance < minDistance && ent->powered ) -      { -        closestDCC = ent; -        minDistance = distance; -        foundDCC = qtrue; -      } -    } -  } - -  //if there were no power items nearby give up -  if( !foundDCC ) -    return qfalse; - -  self->dccNode = closestDCC; - -  return qtrue; -} - -/* -================ -G_isDCC - -simple wrapper to findDCC to check for a dcc -================ -*/ -qboolean G_isDCC( void ) -{ -  gentity_t dummy; - -  dummy.dccNode = NULL; -  dummy.biteam = BIT_HUMANS; - -  return findDCC( &dummy ); -} - -/* -================ -findOvermind - -Attempt to find an overmind for self -================ -*/ -static qboolean findOvermind( gentity_t *self ) -{ -  int       i; -  gentity_t *ent; - -  if( self->biteam != BIT_ALIENS ) -    return qfalse; - -  //if this already has overmind then stop now -  if( self->overmindNode && self->overmindNode->health > 0 ) -    return qtrue; - -  //reset parent -  self->overmindNode = NULL; - -  //iterate through entities -  for( i = 1, ent = g_entities + i; i < level.num_entities; i++, ent++ ) -  { -    if( ent->s.eType != ET_BUILDABLE ) -      continue; - -    //if entity is an overmind calculate the distance to it -    if( ent->s.modelindex == BA_A_OVERMIND && ent->spawned && ent->health > 0 ) -    { -      self->overmindNode = ent; -      return qtrue; -    } -  } - -  return qfalse; -} - -/* -================ -G_isOvermind - -Simple wrapper to findOvermind to check if a location has an overmind -================ -*/ -qboolean G_isOvermind( void ) -{ -  gentity_t dummy; - -  dummy.overmindNode = NULL; -  dummy.biteam = BIT_ALIENS; - -  return findOvermind( &dummy ); -} - -/* -================ -findCreep - -attempt to find creep for self, return qtrue if successful -================ -*/ -static qboolean findCreep( gentity_t *self ) -{ -  int       i; -  gentity_t *ent; -  gentity_t *closestSpawn = NULL; -  int       distance = 0; -  int       minDistance = 10000; -  vec3_t    temp_v; - -  //don't check for creep if flying through the air -  if( self->s.groundEntityNum == -1 ) -    return qtrue; - -  //if self does not have a parentNode or it's parentNode is invalid find a new one -  if( ( self->parentNode == NULL ) || !self->parentNode->inuse ) -  { -    for ( i = 1, ent = g_entities + i; i < level.num_entities; i++, ent++ ) -    { -      if( ent->s.eType != ET_BUILDABLE ) -        continue; - -      if( ( ent->s.modelindex == BA_A_SPAWN || ent->s.modelindex == BA_A_OVERMIND ) && -          ent->spawned ) -      { -        VectorSubtract( self->s.origin, ent->s.origin, temp_v ); -        distance = VectorLength( temp_v ); -        if( distance < minDistance ) -        { -          closestSpawn = ent; -          minDistance = distance; -        } -      } -    } - -    if( minDistance <= CREEP_BASESIZE ) -    { -      self->parentNode = closestSpawn; -      return qtrue; -    } -    else -      return qfalse; -  } - -  //if we haven't returned by now then we must already have a valid parent -  return qtrue; -} - -/* -================ -isCreep - -simple wrapper to findCreep to check if a location has creep -================ -*/ -static qboolean isCreep( vec3_t origin ) -{ -  gentity_t dummy; - -  dummy.parentNode = NULL; -  VectorCopy( origin, dummy.s.origin ); - -  return findCreep( &dummy ); -} - -/* -================ -creepSlow - -Set any nearby humans' SS_CREEPSLOWED flag -================ -*/ -static void creepSlow( gentity_t *self ) -{ -  int         entityList[ MAX_GENTITIES ]; -  vec3_t      range; -  vec3_t      mins, maxs; -  int         i, num; -  gentity_t   *enemy; -  buildable_t buildable = self->s.modelindex; -  float       creepSize = (float)BG_FindCreepSizeForBuildable( buildable ); - -  VectorSet( range, creepSize, creepSize, creepSize ); - -  VectorAdd( self->s.origin, range, maxs ); -  VectorSubtract( self->s.origin, range, mins ); - -  //find humans -  num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -  for( i = 0; i < num; i++ ) -  { -    enemy = &g_entities[ entityList[ i ] ]; - -    if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS && -        enemy->client->ps.groundEntityNum != ENTITYNUM_NONE && -        G_Visible( self, enemy ) ) -    { -      enemy->client->ps.stats[ STAT_STATE ] |= SS_CREEPSLOWED; -      enemy->client->lastCreepSlowTime = level.time; -    } -  } -} - -/* -================ -nullDieFunction - -hack to prevent compilers complaining about function pointer -> NULL conversion -================ -*/ -static void nullDieFunction( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ) -{ -} - -/* -================ -freeBuildable -================ -*/ -static void freeBuildable( gentity_t *self ) -{ -  G_FreeEntity( self ); -} - - -//================================================================================== - - - -/* -================ -A_CreepRecede - -Called when an alien spawn dies -================ -*/ -void A_CreepRecede( gentity_t *self ) -{ -  //if the creep just died begin the recession -  if( !( self->s.eFlags & EF_DEAD ) ) -  { -    self->s.eFlags |= EF_DEAD; -    G_AddEvent( self, EV_BUILD_DESTROY, 0 ); - -    if( self->spawned ) -      self->s.time = -level.time; -    else -      self->s.time = -( level.time - -          (int)( (float)CREEP_SCALEDOWN_TIME * -                 ( 1.0f - ( (float)( level.time - self->buildTime ) / -                            (float)BG_FindBuildTimeForBuildable( self->s.modelindex ) ) ) ) ); -  } - -  //creep is still receeding -  if( ( self->timestamp + 10000 ) > level.time ) -    self->nextthink = level.time + 500; -  else //creep has died -    G_FreeEntity( self ); -} - - - - -//================================================================================== - - - - -/* -================ -ASpawn_Melt - -Called when an alien spawn dies -================ -*/ -void ASpawn_Melt( gentity_t *self ) -{ -  G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage, -    self->splashRadius, self, self->splashMethodOfDeath, PTE_ALIENS ); - -  //start creep recession -  if( !( self->s.eFlags & EF_DEAD ) ) -  { -    self->s.eFlags |= EF_DEAD; -    G_AddEvent( self, EV_BUILD_DESTROY, 0 ); - -    if( self->spawned ) -      self->s.time = -level.time; -    else -      self->s.time = -( level.time - -          (int)( (float)CREEP_SCALEDOWN_TIME * -                 ( 1.0f - ( (float)( level.time - self->buildTime ) / -                            (float)BG_FindBuildTimeForBuildable( self->s.modelindex ) ) ) ) ); -  } - -  //not dead yet -  if( ( self->timestamp + 10000 ) > level.time ) -    self->nextthink = level.time + 500; -  else //dead now -    G_FreeEntity( self ); -} - -/* -================ -ASpawn_Blast - -Called when an alien spawn dies -================ -*/ -void ASpawn_Blast( gentity_t *self ) -{ -  vec3_t  dir; - -  VectorCopy( self->s.origin2, dir ); - -  //do a bit of radius damage -  G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage, -    self->splashRadius, self, self->splashMethodOfDeath, PTE_ALIENS ); - -  //pretty events and item cleanup -  self->s.eFlags |= EF_NODRAW; //don't draw the model once it's destroyed -  G_AddEvent( self, EV_ALIEN_BUILDABLE_EXPLOSION, DirToByte( dir ) ); -  self->timestamp = level.time; -  self->think = ASpawn_Melt; -  self->nextthink = level.time + 500; //wait .5 seconds before damaging others - -  self->r.contents = 0;    //stop collisions... -  trap_LinkEntity( self ); //...requires a relink -} - -/* -================ -ASpawn_Die - -Called when an alien spawn dies -================ -*/ -void ASpawn_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ) -{ -  G_setBuildableAnim( self, BANIM_DESTROY1, qtrue ); -  G_setIdleBuildableAnim( self, BANIM_DESTROYED ); - -  self->die = nullDieFunction; -  self->think = ASpawn_Blast; - -  if( self->spawned ) -    self->nextthink = level.time + 5000; -  else -    self->nextthink = level.time; //blast immediately - -  self->s.eFlags &= ~EF_FIRING; //prevent any firing effects - -  if( attacker && attacker->client && attacker->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -  { -    if( self->s.modelindex == BA_A_OVERMIND ) -      G_AddCreditToClient( attacker->client, OVERMIND_VALUE, qtrue ); -    else if( self->s.modelindex == BA_A_SPAWN ) -      G_AddCreditToClient( attacker->client, ASPAWN_VALUE, qtrue ); -  } -} - -/* -================ -ASpawn_Think - -think function for Alien Spawn -================ -*/ -void ASpawn_Think( gentity_t *self ) -{ -  gentity_t *ent; - -  if( self->spawned ) -  { -    //only suicide if at rest -    if( self->s.groundEntityNum ) -    { -      if( ( ent = G_CheckSpawnPoint( self->s.number, self->s.origin, -              self->s.origin2, BA_A_SPAWN, NULL ) ) != NULL ) -      { -        if( ent->s.eType == ET_BUILDABLE || ent->s.number == ENTITYNUM_WORLD || -            ent->s.eType == ET_MOVER ) -        { -          G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE ); -          return; -        } - -        if( ent->s.eType == ET_CORPSE ) -          G_FreeEntity( ent ); //quietly remove -      } -    } -  } - -  creepSlow( self ); - -  self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); -} - -/* -================ -ASpawn_Pain - -pain function for Alien Spawn -================ -*/ -void ASpawn_Pain( gentity_t *self, gentity_t *attacker, int damage ) -{ -  G_setBuildableAnim( self, BANIM_PAIN1, qfalse ); -} - - - - - -//================================================================================== - - - - - -#define OVERMIND_ATTACK_PERIOD 10000 -#define OVERMIND_DYING_PERIOD  5000 -#define OVERMIND_SPAWNS_PERIOD 30000 - -/* -================ -AOvermind_Think - -Think function for Alien Overmind -================ -*/ -void AOvermind_Think( gentity_t *self ) -{ -  int       entityList[ MAX_GENTITIES ]; -  vec3_t    range = { OVERMIND_ATTACK_RANGE, OVERMIND_ATTACK_RANGE, OVERMIND_ATTACK_RANGE }; -  vec3_t    mins, maxs; -  int       i, num; -  gentity_t *enemy; - -  VectorAdd( self->s.origin, range, maxs ); -  VectorSubtract( self->s.origin, range, mins ); - -  if( self->spawned && ( self->health > 0 ) ) -  { -    //do some damage -    num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -    for( i = 0; i < num; i++ ) -    { -      enemy = &g_entities[ entityList[ i ] ]; - -      if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -      { -        self->timestamp = level.time; -        G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage, -          self->splashRadius, self, MOD_OVERMIND, PTE_ALIENS ); -        G_setBuildableAnim( self, BANIM_ATTACK1, qfalse ); -      } -    } - -    //low on spawns -    if( level.numAlienSpawns <= 0 && level.time > self->overmindSpawnsTimer ) -    { -      self->overmindSpawnsTimer = level.time + OVERMIND_SPAWNS_PERIOD; -      G_BroadcastEvent( EV_OVERMIND_SPAWNS, 0 ); -    } - -    //overmind dying -    if( self->health < ( OVERMIND_HEALTH / 10.0f ) && level.time > self->overmindDyingTimer ) -    { -      self->overmindDyingTimer = level.time + OVERMIND_DYING_PERIOD; -      G_BroadcastEvent( EV_OVERMIND_DYING, 0 ); -    } - -    //overmind under attack -    if( self->health < self->lastHealth && level.time > self->overmindAttackTimer ) -    { -      self->overmindAttackTimer = level.time + OVERMIND_ATTACK_PERIOD; -      G_BroadcastEvent( EV_OVERMIND_ATTACK, 0 ); -    } - -    self->lastHealth = self->health; -  } -  else -    self->overmindSpawnsTimer = level.time + OVERMIND_SPAWNS_PERIOD; - -  creepSlow( self ); - -  self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); -} - - - - - - -//================================================================================== - - - - - -/* -================ -ABarricade_Pain - -pain function for Alien Spawn -================ -*/ -void ABarricade_Pain( gentity_t *self, gentity_t *attacker, int damage ) -{ -  if( rand( ) % 1 ) -    G_setBuildableAnim( self, BANIM_PAIN1, qfalse ); -  else -    G_setBuildableAnim( self, BANIM_PAIN2, qfalse ); -} - -/* -================ -ABarricade_Blast - -Called when an alien spawn dies -================ -*/ -void ABarricade_Blast( gentity_t *self ) -{ -  vec3_t  dir; - -  VectorCopy( self->s.origin2, dir ); - -  //do a bit of radius damage -  G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage, -    self->splashRadius, self, self->splashMethodOfDeath, PTE_ALIENS ); - -  //pretty events and item cleanup -  self->s.eFlags |= EF_NODRAW; //don't draw the model once its destroyed -  G_AddEvent( self, EV_ALIEN_BUILDABLE_EXPLOSION, DirToByte( dir ) ); -  self->timestamp = level.time; -  self->think = A_CreepRecede; -  self->nextthink = level.time + 500; //wait .5 seconds before damaging others - -  self->r.contents = 0;    //stop collisions... -  trap_LinkEntity( self ); //...requires a relink -} - -/* -================ -ABarricade_Die - -Called when an alien spawn dies -================ -*/ -void ABarricade_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ) -{ -  G_setBuildableAnim( self, BANIM_DESTROY1, qtrue ); -  G_setIdleBuildableAnim( self, BANIM_DESTROYED ); - -  self->die = nullDieFunction; -  self->think = ABarricade_Blast; -  self->s.eFlags &= ~EF_FIRING; //prevent any firing effects - -  if( self->spawned ) -    self->nextthink = level.time + 5000; -  else -    self->nextthink = level.time; //blast immediately -} - -/* -================ -ABarricade_Think - -Think function for Alien Barricade -================ -*/ -void ABarricade_Think( gentity_t *self ) -{ -  //if there is no creep nearby die -  if( !findCreep( self ) ) -  { -    G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE ); -    return; -  } - -  creepSlow( self ); - -  self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); -} - - - - -//================================================================================== - - - - -void AAcidTube_Think( gentity_t *self ); - -/* -================ -AAcidTube_Damage - -Damage function for Alien Acid Tube -================ -*/ -void AAcidTube_Damage( gentity_t *self ) -{ -  if( self->spawned ) -  { -    if( !( self->s.eFlags & EF_FIRING ) ) -    { -      self->s.eFlags |= EF_FIRING; -      G_AddEvent( self, EV_ALIEN_ACIDTUBE, DirToByte( self->s.origin2 ) ); -    } - -    if( ( self->timestamp + ACIDTUBE_REPEAT ) > level.time ) -      self->think = AAcidTube_Damage; -    else -    { -      self->think = AAcidTube_Think; -      self->s.eFlags &= ~EF_FIRING; -    } - -    //do some damage -    G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage, -      self->splashRadius, self, self->splashMethodOfDeath, PTE_ALIENS ); -  } - -  creepSlow( self ); - -  self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); -} - -/* -================ -AAcidTube_Think - -Think function for Alien Acid Tube -================ -*/ -void AAcidTube_Think( gentity_t *self ) -{ -  int       entityList[ MAX_GENTITIES ]; -  vec3_t    range = { ACIDTUBE_RANGE, ACIDTUBE_RANGE, ACIDTUBE_RANGE }; -  vec3_t    mins, maxs; -  int       i, num; -  gentity_t *enemy; - -  VectorAdd( self->s.origin, range, maxs ); -  VectorSubtract( self->s.origin, range, mins ); - -  //if there is no creep nearby die -  if( !findCreep( self ) ) -  { -    G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE ); -    return; -  } - -  if( self->spawned && findOvermind( self ) ) -  { -    //do some damage -    num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -    for( i = 0; i < num; i++ ) -    { -      enemy = &g_entities[ entityList[ i ] ]; - -      if( !G_Visible( self, enemy ) ) -        continue; - -      if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -      { -        self->timestamp = level.time; -        self->think = AAcidTube_Damage; -        self->nextthink = level.time + 100; -        G_setBuildableAnim( self, BANIM_ATTACK1, qfalse ); -        return; -      } -    } -  } - -  creepSlow( self ); - -  self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); -} - - - - -//================================================================================== - - - - -/* -================ -AHive_Think - -Think function for Alien Hive -================ -*/ -void AHive_Think( gentity_t *self ) -{ -  int       entityList[ MAX_GENTITIES ]; -  vec3_t    range = { ACIDTUBE_RANGE, ACIDTUBE_RANGE, ACIDTUBE_RANGE }; -  vec3_t    mins, maxs; -  int       i, num; -  gentity_t *enemy; -  vec3_t    dirToTarget; - -  self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); - -  VectorAdd( self->s.origin, range, maxs ); -  VectorSubtract( self->s.origin, range, mins ); - -  //if there is no creep nearby die -  if( !findCreep( self ) ) -  { -    G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE ); -    return; -  } - -  if( self->timestamp < level.time ) -    self->active = qfalse; //nothing has returned in HIVE_REPEAT seconds, forget about it - -  if( self->spawned && !self->active && findOvermind( self ) ) -  { -    //do some damage -    num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -    for( i = 0; i < num; i++ ) -    { -      enemy = &g_entities[ entityList[ i ] ]; - -      if( enemy->health <= 0 ) -        continue; - -      if( !G_Visible( self, enemy ) ) -        continue; - -      if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -      { -        self->active = qtrue; -        self->target_ent = enemy; -        self->timestamp = level.time + HIVE_REPEAT; - -        VectorSubtract( enemy->s.pos.trBase, self->s.pos.trBase, dirToTarget ); -        VectorNormalize( dirToTarget ); -        vectoangles( dirToTarget, self->turretAim ); - -        //fire at target -        FireWeapon( self ); -        G_setBuildableAnim( self, BANIM_ATTACK1, qfalse ); -        return; -      } -    } -  } - -  creepSlow( self ); -} - - - - -//================================================================================== - - - - -#define HOVEL_TRACE_DEPTH 128.0f - -/* -================ -AHovel_Blocked - -Is this hovel entrance blocked? -================ -*/ -qboolean AHovel_Blocked( gentity_t *hovel, gentity_t *player, qboolean provideExit ) -{ -  vec3_t    forward, normal, origin, start, end, angles, hovelMaxs; -  vec3_t    mins, maxs; -  float     displacement; -  trace_t   tr; - -  BG_FindBBoxForBuildable( BA_A_HOVEL, NULL, hovelMaxs ); -  BG_FindBBoxForClass( player->client->ps.stats[ STAT_PCLASS ], -                       mins, maxs, NULL, NULL, NULL ); - -  VectorCopy( hovel->s.origin2, normal ); -  AngleVectors( hovel->s.angles, forward, NULL, NULL ); -  VectorInverse( forward ); - -  displacement = VectorMaxComponent( maxs ) * M_ROOT3 + -                 VectorMaxComponent( hovelMaxs ) * M_ROOT3 + 1.0f; - -  VectorMA( hovel->s.origin, displacement, forward, origin ); -  vectoangles( forward, angles ); - -  VectorMA( origin, HOVEL_TRACE_DEPTH, normal, start ); - -  //compute a place up in the air to start the real trace -  trap_Trace( &tr, origin, mins, maxs, start, player->s.number, MASK_PLAYERSOLID ); -  VectorMA( origin, ( HOVEL_TRACE_DEPTH * tr.fraction ) - 1.0f, normal, start ); -  VectorMA( origin, -HOVEL_TRACE_DEPTH, normal, end ); - -  trap_Trace( &tr, start, mins, maxs, end, player->s.number, MASK_PLAYERSOLID ); - -  if( tr.startsolid ) -    return qtrue; - -  VectorCopy( tr.endpos, origin ); - -  trap_Trace( &tr, origin, mins, maxs, origin, player->s.number, MASK_PLAYERSOLID ); - -  if( provideExit ) -  { -    G_SetOrigin( player, origin ); -    VectorCopy( origin, player->client->ps.origin ); -    VectorCopy( vec3_origin, player->client->ps.velocity ); -    SetClientViewAngle( player, angles ); -  } - -  if( tr.fraction < 1.0f ) -    return qtrue; -  else -    return qfalse; -} - -/* -================ -APropHovel_Blocked - -Wrapper to test a hovel placement for validity -================ -*/ -static qboolean APropHovel_Blocked( vec3_t origin, vec3_t angles, vec3_t normal, -                                    gentity_t *player ) -{ -  gentity_t hovel; - -  VectorCopy( origin, hovel.s.origin ); -  VectorCopy( angles, hovel.s.angles ); -  VectorCopy( normal, hovel.s.origin2 ); - -  return AHovel_Blocked( &hovel, player, qfalse ); -} - -/* -================ -AHovel_Use - -Called when an alien uses a hovel -================ -*/ -void AHovel_Use( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  vec3_t  hovelOrigin, hovelAngles, inverseNormal; - -  if( self->spawned && findOvermind( self ) ) -  { -    if( self->active ) -    { -      //this hovel is in use -      G_TriggerMenu( activator->client->ps.clientNum, MN_A_HOVEL_OCCUPIED ); -    } -    else if( ( ( activator->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_BUILDER0 ) || -               ( activator->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_BUILDER0_UPG ) ) && -             activator->health > 0 && self->health > 0 ) -    { -      if( AHovel_Blocked( self, activator, qfalse ) ) -      { -        //you can get in, but you can't get out -        G_TriggerMenu( activator->client->ps.clientNum, MN_A_HOVEL_BLOCKED ); -        return; -      } - -      self->active = qtrue; -      G_setBuildableAnim( self, BANIM_ATTACK1, qfalse ); - -      //prevent lerping -      activator->client->ps.eFlags ^= EF_TELEPORT_BIT; -      activator->client->ps.eFlags |= EF_NODRAW; - -      activator->client->ps.stats[ STAT_STATE ] |= SS_HOVELING; -      activator->client->hovel = self; -      self->builder = activator; - -      VectorCopy( self->s.pos.trBase, hovelOrigin ); -      VectorMA( hovelOrigin, 128.0f, self->s.origin2, hovelOrigin ); - -      VectorCopy( self->s.origin2, inverseNormal ); -      VectorInverse( inverseNormal ); -      vectoangles( inverseNormal, hovelAngles ); - -      VectorCopy( activator->s.pos.trBase, activator->client->hovelOrigin ); - -      G_SetOrigin( activator, hovelOrigin ); -      VectorCopy( hovelOrigin, activator->client->ps.origin ); -      SetClientViewAngle( activator, hovelAngles ); -    } -  } -} - - -/* -================ -AHovel_Think - -Think for alien hovel -================ -*/ -void AHovel_Think( gentity_t *self ) -{ -  if( self->spawned ) -  { -    if( self->active ) -      G_setIdleBuildableAnim( self, BANIM_IDLE2 ); -    else -      G_setIdleBuildableAnim( self, BANIM_IDLE1 ); -  } - -  creepSlow( self ); - -  self->nextthink = level.time + 200; -} - -/* -================ -AHovel_Die - -Die for alien hovel -================ -*/ -void AHovel_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ) -{ -  vec3_t  dir; - -  VectorCopy( self->s.origin2, dir ); - -  //do a bit of radius damage -  G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage, -    self->splashRadius, self, self->splashMethodOfDeath, PTE_ALIENS ); - -  //pretty events and item cleanup -  self->s.eFlags |= EF_NODRAW; //don't draw the model once its destroyed -  G_AddEvent( self, EV_ALIEN_BUILDABLE_EXPLOSION, DirToByte( dir ) ); -  self->s.eFlags &= ~EF_FIRING; //prevent any firing effects -  self->timestamp = level.time; -  self->think = ASpawn_Melt; -  self->nextthink = level.time + 500; //wait .5 seconds before damaging others - -  //if the hovel is occupied free the occupant -  if( self->active ) -  { -    gentity_t *builder = self->builder; -    vec3_t    newOrigin; -    vec3_t    newAngles; - -    VectorCopy( self->s.angles, newAngles ); -    newAngles[ ROLL ] = 0; - -    VectorCopy( self->s.origin, newOrigin ); -    VectorMA( newOrigin, 1.0f, self->s.origin2, newOrigin ); - -    //prevent lerping -    builder->client->ps.eFlags ^= EF_TELEPORT_BIT; -    builder->client->ps.eFlags &= ~EF_NODRAW; - -    G_SetOrigin( builder, newOrigin ); -    VectorCopy( newOrigin, builder->client->ps.origin ); -    SetClientViewAngle( builder, newAngles ); - -    //client leaves hovel -    builder->client->ps.stats[ STAT_STATE ] &= ~SS_HOVELING; -  } - -  self->r.contents = 0;    //stop collisions... -  trap_LinkEntity( self ); //...requires a relink -} - - - - - -//================================================================================== - - - - -/* -================ -ABooster_Touch - -Called when an alien touches a booster -================ -*/ -void ABooster_Touch( gentity_t *self, gentity_t *other, trace_t *trace ) -{ -  gclient_t *client = other->client; - -  if( !self->spawned ) -    return; - -  if( !findOvermind( self ) ) -    return; - -  if( !client ) -    return; - -  if( client && client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -    return; - -  //only allow boostage once every 30 seconds -  if( client->lastBoostedTime + BOOSTER_INTERVAL > level.time ) -    return; - -  if( !( client->ps.stats[ STAT_STATE ] & SS_BOOSTED ) ) -  { -    client->ps.stats[ STAT_STATE ] |= SS_BOOSTED; -    client->lastBoostedTime = level.time; -  } -} - - - - -//================================================================================== - -#define TRAPPER_ACCURACY 10 // lower is better - -/* -================ -ATrapper_FireOnEnemy - -Used by ATrapper_Think to fire at enemy -================ -*/ -void ATrapper_FireOnEnemy( gentity_t *self, int firespeed, float range ) -{ -  gentity_t *enemy = self->enemy; -  vec3_t    dirToTarget; -  vec3_t    halfAcceleration, thirdJerk; -  float     distanceToTarget = BG_FindRangeForBuildable( self->s.modelindex ); -  int       lowMsec = 0; -  int       highMsec = (int)( ( -    ( ( distanceToTarget * LOCKBLOB_SPEED ) + -      ( distanceToTarget * BG_FindSpeedForClass( enemy->client->ps.stats[ STAT_PCLASS ] ) ) ) / -    ( LOCKBLOB_SPEED * LOCKBLOB_SPEED ) ) * 1000.0f ); - -  VectorScale( enemy->acceleration, 1.0f / 2.0f, halfAcceleration ); -  VectorScale( enemy->jerk, 1.0f / 3.0f, thirdJerk ); - -  // highMsec and lowMsec can only move toward -  // one another, so the loop must terminate -  while( highMsec - lowMsec > TRAPPER_ACCURACY ) -  { -    int   partitionMsec = ( highMsec + lowMsec ) / 2; -    float time = (float)partitionMsec / 1000.0f; -    float projectileDistance = LOCKBLOB_SPEED * time; - -    VectorMA( enemy->s.pos.trBase, time, enemy->s.pos.trDelta, dirToTarget ); -    VectorMA( dirToTarget, time * time, halfAcceleration, dirToTarget ); -    VectorMA( dirToTarget, time * time * time, thirdJerk, dirToTarget ); -    VectorSubtract( dirToTarget, self->s.pos.trBase, dirToTarget ); -    distanceToTarget = VectorLength( dirToTarget ); - -    if( projectileDistance < distanceToTarget ) -      lowMsec = partitionMsec; -    else if( projectileDistance > distanceToTarget ) -      highMsec = partitionMsec; -    else if( projectileDistance == distanceToTarget ) -      break; // unlikely to happen -  } - -  VectorNormalize( dirToTarget ); -  vectoangles( dirToTarget, self->turretAim ); - -  //fire at target -  FireWeapon( self ); -  G_setBuildableAnim( self, BANIM_ATTACK1, qfalse ); -  self->count = level.time + firespeed; -} - -/* -================ -ATrapper_CheckTarget - -Used by ATrapper_Think to check enemies for validity -================ -*/ -qboolean ATrapper_CheckTarget( gentity_t *self, gentity_t *target, int range ) -{ -  vec3_t    distance; -  trace_t   trace; - -  if( !target ) // Do we have a target? -    return qfalse; -  if( !target->inuse ) // Does the target still exist? -    return qfalse; -  if( target == self ) // is the target us? -    return qfalse; -  if( !target->client ) // is the target a bot or player? -    return qfalse; -  if( target->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) // one of us? -    return qfalse; -  if( target->client->sess.sessionTeam == TEAM_SPECTATOR ) // is the target alive? -    return qfalse; -  if( target->health <= 0 ) // is the target still alive? -    return qfalse; -  if( target->client->ps.stats[ STAT_STATE ] & SS_BLOBLOCKED ) // locked? -    return qfalse; - -  VectorSubtract( target->r.currentOrigin, self->r.currentOrigin, distance ); -  if( VectorLength( distance ) > range ) // is the target within range? -    return qfalse; - -  //only allow a narrow field of "vision" -  VectorNormalize( distance ); //is now direction of target -  if( DotProduct( distance, self->s.origin2 ) < LOCKBLOB_DOT ) -    return qfalse; - -  trap_Trace( &trace, self->s.pos.trBase, NULL, NULL, target->s.pos.trBase, self->s.number, MASK_SHOT ); -  if ( trace.contents & CONTENTS_SOLID ) // can we see the target? -    return qfalse; - -  return qtrue; -} - -/* -================ -ATrapper_FindEnemy - -Used by ATrapper_Think to locate enemy gentities -================ -*/ -void ATrapper_FindEnemy( gentity_t *ent, int range ) -{ -  gentity_t *target; - -  //iterate through entities -  for( target = g_entities; target < &g_entities[ level.num_entities ]; target++ ) -  { -    //if target is not valid keep searching -    if( !ATrapper_CheckTarget( ent, target, range ) ) -      continue; - -    //we found a target -    ent->enemy = target; -    return; -  } - -  //couldn't find a target -  ent->enemy = NULL; -} - -/* -================ -ATrapper_Think - -think function for Alien Defense -================ -*/ -void ATrapper_Think( gentity_t *self ) -{ -  int range =     BG_FindRangeForBuildable( self->s.modelindex ); -  int firespeed = BG_FindFireSpeedForBuildable( self->s.modelindex ); - -  creepSlow( self ); - -  self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); - -  //if there is no creep nearby die -  if( !findCreep( self ) ) -  { -    G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE ); -    return; -  } - -  if( self->spawned && findOvermind( self ) ) -  { -    //if the current target is not valid find a new one -    if( !ATrapper_CheckTarget( self, self->enemy, range ) ) -      ATrapper_FindEnemy( self, range ); - -    //if a new target cannot be found don't do anything -    if( !self->enemy ) -      return; - -    //if we are pointing at our target and we can fire shoot it -    if( self->count < level.time ) -      ATrapper_FireOnEnemy( self, firespeed, range ); -  } -} - - - -//================================================================================== - - - -/* -================ -HRepeater_Think - -Think for human power repeater -================ -*/ -void HRepeater_Think( gentity_t *self ) -{ -  int       i; -  qboolean  reactor = qfalse; -  gentity_t *ent; - -  if( self->spawned ) -  { -    //iterate through entities -    for ( i = 1, ent = g_entities + i; i < level.num_entities; i++, ent++ ) -    { -      if( ent->s.eType != ET_BUILDABLE ) -        continue; - -      if( ent->s.modelindex == BA_H_REACTOR && ent->spawned ) -        reactor = qtrue; -    } -  } - -  if( G_NumberOfDependants( self ) == 0 ) -  { -    //if no dependants for x seconds then disappear -    if( self->count < 0 ) -      self->count = level.time; -    else if( self->count > 0 && ( ( level.time - self->count ) > REPEATER_INACTIVE_TIME ) ) -      G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE ); -  } -  else -    self->count = -1; - -  self->powered = reactor; - -  self->nextthink = level.time + POWER_REFRESH_TIME; -} - -/* -================ -HRepeater_Use - -Use for human power repeater -================ -*/ -void HRepeater_Use( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  if( self->health <= 0 ) -    return; - -  if( !self->spawned ) -    return; - -  if( other ) -    G_GiveClientMaxAmmo( other, qtrue ); -} - - -#define DCC_ATTACK_PERIOD 10000 - -/* -================ -HReactor_Think - -Think function for Human Reactor -================ -*/ -void HReactor_Think( gentity_t *self ) -{ -  int       entityList[ MAX_GENTITIES ]; -  vec3_t    range = { REACTOR_ATTACK_RANGE, REACTOR_ATTACK_RANGE, REACTOR_ATTACK_RANGE }; -  vec3_t    mins, maxs; -  int       i, num; -  gentity_t *enemy, *tent; - -  VectorAdd( self->s.origin, range, maxs ); -  VectorSubtract( self->s.origin, range, mins ); - -  if( self->spawned && ( self->health > 0 ) ) -  { -    //do some damage -    num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -    for( i = 0; i < num; i++ ) -    { -      enemy = &g_entities[ entityList[ i ] ]; - -      if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -      { -        self->timestamp = level.time; -        G_SelectiveRadiusDamage( self->s.pos.trBase, self, REACTOR_ATTACK_DAMAGE, -          REACTOR_ATTACK_RANGE, self, MOD_REACTOR, PTE_HUMANS ); - -        tent = G_TempEntity( enemy->s.pos.trBase, EV_TESLATRAIL ); - -        VectorCopy( self->s.pos.trBase, tent->s.origin2 ); - -        tent->s.generic1 = self->s.number; //src -        tent->s.clientNum = enemy->s.number; //dest -      } -    } - -    //reactor under attack -    if( self->health < self->lastHealth && -        level.time > level.humanBaseAttackTimer && G_isDCC( ) ) -    { -      level.humanBaseAttackTimer = level.time + DCC_ATTACK_PERIOD; -      G_BroadcastEvent( EV_DCC_ATTACK, 0 ); -    } - -    self->lastHealth = self->health; -  } - -  self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); -} - -//================================================================================== - - - -/* -================ -HArmoury_Activate - -Called when a human activates an Armoury -================ -*/ -void HArmoury_Activate( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  if( self->spawned ) -  { -    //only humans can activate this -    if( activator->client->ps.stats[ STAT_PTEAM ] != PTE_HUMANS ) -      return; - -    //if this is powered then call the armoury menu -    if( self->powered ) -      G_TriggerMenu( activator->client->ps.clientNum, MN_H_ARMOURY ); -    else -      G_TriggerMenu( activator->client->ps.clientNum, MN_H_NOTPOWERED ); -  } -} - -/* -================ -HArmoury_Think - -Think for armoury -================ -*/ -void HArmoury_Think( gentity_t *self ) -{ -  //make sure we have power -  self->nextthink = level.time + POWER_REFRESH_TIME; - -  self->powered = findPower( self ); -} - - - - -//================================================================================== - - - - - -/* -================ -HDCC_Think - -Think for dcc -================ -*/ -void HDCC_Think( gentity_t *self ) -{ -  //make sure we have power -  self->nextthink = level.time + POWER_REFRESH_TIME; - -  self->powered = findPower( self ); -} - - - - -//================================================================================== - -/* -================ -HMedistat_Think - -think function for Human Medistation -================ -*/ -void HMedistat_Think( gentity_t *self ) -{ -  int       entityList[ MAX_GENTITIES ]; -  vec3_t    mins, maxs; -  int       i, num; -  gentity_t *player; -  qboolean  occupied = qfalse; - -  self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); - -  //make sure we have power -  if( !( self->powered = findPower( self ) ) ) -  { -    self->nextthink = level.time + POWER_REFRESH_TIME; -    return; -  } - -  if( self->spawned ) -  { -    VectorAdd( self->s.origin, self->r.maxs, maxs ); -    VectorAdd( self->s.origin, self->r.mins, mins ); - -    mins[ 2 ] += fabs( self->r.mins[ 2 ] ) + self->r.maxs[ 2 ]; -    maxs[ 2 ] += 60; //player height - -    //if active use the healing idle -    if( self->active ) -      G_setIdleBuildableAnim( self, BANIM_IDLE2 ); - -    //check if a previous occupier is still here -    num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -    for( i = 0; i < num; i++ ) -    { -      player = &g_entities[ entityList[ i ] ]; - -      if( player->client && player->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -      { -        if( player->health < player->client->ps.stats[ STAT_MAX_HEALTH ] && -            player->client->ps.pm_type != PM_DEAD && -            self->enemy == player ) -          occupied = qtrue; -      } -    } - -    if( !occupied ) -    { -      self->enemy = NULL; - -      //look for something to heal -      for( i = 0; i < num; i++ ) -      { -        player = &g_entities[ entityList[ i ] ]; - -        if( player->client && player->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -        { -          if( player->health < player->client->ps.stats[ STAT_MAX_HEALTH ] && -              player->client->ps.pm_type != PM_DEAD ) -          { -            self->enemy = player; - -            //start the heal anim -            if( !self->active ) -            { -              G_setBuildableAnim( self, BANIM_ATTACK1, qfalse ); -              self->active = qtrue; -            } -          } -          else if( !BG_InventoryContainsUpgrade( UP_MEDKIT, player->client->ps.stats ) ) -            BG_AddUpgradeToInventory( UP_MEDKIT, player->client->ps.stats ); -        } -      } -    } - -    //nothing left to heal so go back to idling -    if( !self->enemy && self->active ) -    { -      G_setBuildableAnim( self, BANIM_CONSTRUCT2, qtrue ); -      G_setIdleBuildableAnim( self, BANIM_IDLE1 ); - -      self->active = qfalse; -    } -    else if( self->enemy ) //heal! -    { -      if( self->enemy->client && self->enemy->client->ps.stats[ STAT_STATE ] & SS_POISONED ) -        self->enemy->client->ps.stats[ STAT_STATE ] &= ~SS_POISONED; - -      if( self->enemy->client && self->enemy->client->ps.stats[ STAT_STATE ] & SS_MEDKIT_ACTIVE ) -        self->enemy->client->ps.stats[ STAT_STATE ] &= ~SS_MEDKIT_ACTIVE; - -      self->enemy->health++; - -      //if they're completely healed, give them a medkit -      if( self->enemy->health >= self->enemy->client->ps.stats[ STAT_MAX_HEALTH ] && -          !BG_InventoryContainsUpgrade( UP_MEDKIT, self->enemy->client->ps.stats ) ) -        BG_AddUpgradeToInventory( UP_MEDKIT, self->enemy->client->ps.stats ); -    } -  } -} - - - - -//================================================================================== - - - - -/* -================ -HMGTurret_TrackEnemy - -Used by HMGTurret_Think to track enemy location -================ -*/ -qboolean HMGTurret_TrackEnemy( gentity_t *self ) -{ -  vec3_t  dirToTarget, dttAdjusted, angleToTarget, angularDiff, xNormal; -  vec3_t  refNormal = { 0.0f, 0.0f, 1.0f }; -  float   temp, rotAngle; -  float   accuracyTolerance, angularSpeed; - -  if( self->lev1Grabbed ) -  { -    //can't turn fast if grabbed -    accuracyTolerance = MGTURRET_GRAB_ACCURACYTOLERANCE; -    angularSpeed = MGTURRET_GRAB_ANGULARSPEED; -  } -  else if( self->dcced ) -  { -    accuracyTolerance = MGTURRET_DCC_ACCURACYTOLERANCE; -    angularSpeed = MGTURRET_DCC_ANGULARSPEED; -  } -  else -  { -    accuracyTolerance = MGTURRET_ACCURACYTOLERANCE; -    angularSpeed = MGTURRET_ANGULARSPEED; -  } - -  VectorSubtract( self->enemy->s.pos.trBase, self->s.pos.trBase, dirToTarget ); - -  VectorNormalize( dirToTarget ); - -  CrossProduct( self->s.origin2, refNormal, xNormal ); -  VectorNormalize( xNormal ); -  rotAngle = RAD2DEG( acos( DotProduct( self->s.origin2, refNormal ) ) ); -  RotatePointAroundVector( dttAdjusted, xNormal, dirToTarget, rotAngle ); - -  vectoangles( dttAdjusted, angleToTarget ); - -  angularDiff[ PITCH ] = AngleSubtract( self->s.angles2[ PITCH ], angleToTarget[ PITCH ] ); -  angularDiff[ YAW ] = AngleSubtract( self->s.angles2[ YAW ], angleToTarget[ YAW ] ); - -  //if not pointing at our target then move accordingly -  if( angularDiff[ PITCH ] < (-accuracyTolerance) ) -    self->s.angles2[ PITCH ] += angularSpeed; -  else if( angularDiff[ PITCH ] > accuracyTolerance ) -    self->s.angles2[ PITCH ] -= angularSpeed; -  else -    self->s.angles2[ PITCH ] = angleToTarget[ PITCH ]; - -  //disallow vertical movement past a certain limit -  temp = fabs( self->s.angles2[ PITCH ] ); -  if( temp > 180 ) -    temp -= 360; - -  if( temp < -MGTURRET_VERTICALCAP ) -    self->s.angles2[ PITCH ] = (-360) + MGTURRET_VERTICALCAP; - -  //if not pointing at our target then move accordingly -  if( angularDiff[ YAW ] < (-accuracyTolerance) ) -    self->s.angles2[ YAW ] += angularSpeed; -  else if( angularDiff[ YAW ] > accuracyTolerance ) -    self->s.angles2[ YAW ] -= angularSpeed; -  else -    self->s.angles2[ YAW ] = angleToTarget[ YAW ]; - -  AngleVectors( self->s.angles2, dttAdjusted, NULL, NULL ); -  RotatePointAroundVector( dirToTarget, xNormal, dttAdjusted, -rotAngle ); -  vectoangles( dirToTarget, self->turretAim ); - -  //if pointing at our target return true -  if( abs( angleToTarget[ YAW ] - self->s.angles2[ YAW ] ) <= accuracyTolerance && -      abs( angleToTarget[ PITCH ] - self->s.angles2[ PITCH ] ) <= accuracyTolerance ) -    return qtrue; - -  return qfalse; -} - - -/* -================ -HMGTurret_CheckTarget - -Used by HMGTurret_Think to check enemies for validity -================ -*/ -qboolean HMGTurret_CheckTarget( gentity_t *self, gentity_t *target, qboolean ignorePainted ) -{ -  trace_t   trace; -  gentity_t *traceEnt; - -  if( !target ) -    return qfalse; - -  if( !target->client ) -    return qfalse; - -  if( target->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) -    return qfalse; - -  if( target->health <= 0 ) -    return qfalse; - -  if( Distance( self->s.origin, target->s.pos.trBase ) > MGTURRET_RANGE ) -    return qfalse; - -  //some turret has already selected this target -  if( self->dcced && target->targeted && target->targeted->powered && !ignorePainted ) -    return qfalse; - -  trap_Trace( &trace, self->s.pos.trBase, NULL, NULL, target->s.pos.trBase, self->s.number, MASK_SHOT ); - -  traceEnt = &g_entities[ trace.entityNum ]; - -  if( !traceEnt->client ) -    return qfalse; - -  if( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS ) -    return qfalse; - -  return qtrue; -} - - -/* -================ -HMGTurret_FindEnemy - -Used by HMGTurret_Think to locate enemy gentities -================ -*/ -void HMGTurret_FindEnemy( gentity_t *self ) -{ -  int       entityList[ MAX_GENTITIES ]; -  vec3_t    range; -  vec3_t    mins, maxs; -  int       i, num; -  gentity_t *target; - -  VectorSet( range, MGTURRET_RANGE, MGTURRET_RANGE, MGTURRET_RANGE ); -  VectorAdd( self->s.origin, range, maxs ); -  VectorSubtract( self->s.origin, range, mins ); - -  //find aliens -  num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -  for( i = 0; i < num; i++ ) -  { -    target = &g_entities[ entityList[ i ] ]; - -    if( target->client && target->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -    { -      //if target is not valid keep searching -      if( !HMGTurret_CheckTarget( self, target, qfalse ) ) -        continue; - -      //we found a target -      self->enemy = target; -      return; -    } -  } - -  if( self->dcced ) -  { -    //check again, this time ignoring painted targets -    for( i = 0; i < num; i++ ) -    { -      target = &g_entities[ entityList[ i ] ]; - -      if( target->client && target->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -      { -        //if target is not valid keep searching -        if( !HMGTurret_CheckTarget( self, target, qtrue ) ) -          continue; - -        //we found a target -        self->enemy = target; -        return; -      } -    } -  } - -  //couldn't find a target -  self->enemy = NULL; -} - - -/* -================ -HMGTurret_Think - -Think function for MG turret -================ -*/ -void HMGTurret_Think( gentity_t *self ) -{ -  int firespeed = BG_FindFireSpeedForBuildable( self->s.modelindex ); - -  self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); - -  //used for client side muzzle flashes -  self->s.eFlags &= ~EF_FIRING; - -  //if not powered don't do anything and check again for power next think -  if( !( self->powered = findPower( self ) ) ) -  { -    self->nextthink = level.time + POWER_REFRESH_TIME; -    return; -  } - -  if( self->spawned ) -  { -    //find a dcc for self -    self->dcced = findDCC( self ); - -    //if the current target is not valid find a new one -    if( !HMGTurret_CheckTarget( self, self->enemy, qfalse ) ) -    { -      if( self->enemy ) -        self->enemy->targeted = NULL; - -      HMGTurret_FindEnemy( self ); -    } - -    //if a new target cannot be found don't do anything -    if( !self->enemy ) -      return; - -    self->enemy->targeted = self; - -    //if we are pointing at our target and we can fire shoot it -    if( HMGTurret_TrackEnemy( self ) && ( self->count < level.time ) ) -    { -      //fire at target -      FireWeapon( self ); - -      self->s.eFlags |= EF_FIRING; -      G_AddEvent( self, EV_FIRE_WEAPON, 0 ); -      G_setBuildableAnim( self, BANIM_ATTACK1, qfalse ); - -      self->count = level.time + firespeed; -    } -  } -} - - - - -//================================================================================== - - - - -/* -================ -HTeslaGen_Think - -Think function for Tesla Generator -================ -*/ -void HTeslaGen_Think( gentity_t *self ) -{ -  int       entityList[ MAX_GENTITIES ]; -  vec3_t    range; -  vec3_t    mins, maxs; -  vec3_t    dir; -  int       i, num; -  gentity_t *enemy; - -  self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); - -  //if not powered don't do anything and check again for power next think -  if( !( self->powered = findPower( self ) ) || !( self->dcced = findDCC( self ) ) ) -  { -    self->s.eFlags &= ~EF_FIRING; -    self->nextthink = level.time + POWER_REFRESH_TIME; -    return; -  } - -  if( self->spawned && self->count < level.time ) -  { -    //used to mark client side effects -    self->s.eFlags &= ~EF_FIRING; - -    VectorSet( range, TESLAGEN_RANGE, TESLAGEN_RANGE, TESLAGEN_RANGE ); -    VectorAdd( self->s.origin, range, maxs ); -    VectorSubtract( self->s.origin, range, mins ); - -    //find aliens -    num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -    for( i = 0; i < num; i++ ) -    { -      enemy = &g_entities[ entityList[ i ] ]; - -      if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS && -          enemy->health > 0 ) -      { -        VectorSubtract( enemy->s.pos.trBase, self->s.pos.trBase, dir ); -        VectorNormalize( dir ); -        vectoangles( dir, self->turretAim ); - -        //fire at target -        FireWeapon( self ); -      } -    } - -    if( self->s.eFlags & EF_FIRING ) -    { -      G_AddEvent( self, EV_FIRE_WEAPON, 0 ); - -      //doesn't really need an anim -      //G_setBuildableAnim( self, BANIM_ATTACK1, qfalse ); - -      self->count = level.time + TESLAGEN_REPEAT; -    } -  } -} - - - - -//================================================================================== - - - - -/* -================ -HSpawn_Disappear - -Called when a human spawn is destroyed before it is spawned -think function -================ -*/ -void HSpawn_Disappear( gentity_t *self ) -{ -  vec3_t  dir; - -  // we don't have a valid direction, so just point straight up -  dir[ 0 ] = dir[ 1 ] = 0; -  dir[ 2 ] = 1; - -  self->s.eFlags |= EF_NODRAW; //don't draw the model once its destroyed -  self->timestamp = level.time; - -  self->think = freeBuildable; -  self->nextthink = level.time + 100; - -  self->r.contents = 0;    //stop collisions... -  trap_LinkEntity( self ); //...requires a relink -} - - -/* -================ -HSpawn_blast - -Called when a human spawn explodes -think function -================ -*/ -void HSpawn_Blast( gentity_t *self ) -{ -  vec3_t  dir; - -  // we don't have a valid direction, so just point straight up -  dir[ 0 ] = dir[ 1 ] = 0; -  dir[ 2 ] = 1; - -  self->s.eFlags |= EF_NODRAW; //don't draw the model once its destroyed -  G_AddEvent( self, EV_HUMAN_BUILDABLE_EXPLOSION, DirToByte( dir ) ); -  self->timestamp = level.time; - -  //do some radius damage -  G_RadiusDamage( self->s.pos.trBase, self, self->splashDamage, -    self->splashRadius, self, self->splashMethodOfDeath ); - -  self->think = freeBuildable; -  self->nextthink = level.time + 100; - -  self->r.contents = 0;    //stop collisions... -  trap_LinkEntity( self ); //...requires a relink -} - - -/* -================ -HSpawn_die - -Called when a human spawn dies -================ -*/ -void HSpawn_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ) -{ -  //pretty events and cleanup -  G_setBuildableAnim( self, BANIM_DESTROY1, qtrue ); -  G_setIdleBuildableAnim( self, BANIM_DESTROYED ); - -  self->die = nullDieFunction; -  self->powered = qfalse; //free up power -  self->s.eFlags &= ~EF_FIRING; //prevent any firing effects - -  if( self->spawned ) -  { -    self->think = HSpawn_Blast; -    self->nextthink = level.time + HUMAN_DETONATION_DELAY; -  } -  else -  { -    self->think = HSpawn_Disappear; -    self->nextthink = level.time; //blast immediately -  } - -  if( attacker && attacker->client && attacker->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -  { -    if( self->s.modelindex == BA_H_REACTOR ) -      G_AddCreditToClient( attacker->client, REACTOR_VALUE, qtrue ); -    else if( self->s.modelindex == BA_H_SPAWN ) -      G_AddCreditToClient( attacker->client, HSPAWN_VALUE, qtrue ); -  } -} - -/* -================ -HSpawn_Think - -Think for human spawn -================ -*/ -void HSpawn_Think( gentity_t *self ) -{ -  gentity_t *ent; - -  //make sure we have power -  self->powered = findPower( self ); - -  if( self->spawned ) -  { -    //only suicide if at rest -    if( self->s.groundEntityNum ) -    { -      if( ( ent = G_CheckSpawnPoint( self->s.number, self->s.origin, -              self->s.origin2, BA_H_SPAWN, NULL ) ) != NULL ) -      { -        if( ent->s.eType == ET_BUILDABLE || ent->s.number == ENTITYNUM_WORLD || -            ent->s.eType == ET_MOVER ) -        { -          G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE ); -          return; -        } - -        if( ent->s.eType == ET_CORPSE ) -          G_FreeEntity( ent ); //quietly remove -      } -    } - -    //spawn under attack -    if( self->health < self->lastHealth && -        level.time > level.humanBaseAttackTimer && G_isDCC( ) ) -    { -      level.humanBaseAttackTimer = level.time + DCC_ATTACK_PERIOD; -      G_BroadcastEvent( EV_DCC_ATTACK, 0 ); -    } - -    self->lastHealth = self->health; -  } - -  self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); -} - - - - -//================================================================================== - - -/* -============ -G_BuildableTouchTriggers - -Find all trigger entities that a buildable touches. -============ -*/ -void G_BuildableTouchTriggers( gentity_t *ent ) -{ -  int       i, num; -  int       touch[ MAX_GENTITIES ]; -  gentity_t *hit; -  trace_t   trace; -  vec3_t    mins, maxs; -  vec3_t    bmins, bmaxs; -  static    vec3_t range = { 10, 10, 10 }; - -  // dead buildables don't activate triggers! -  if( ent->health <= 0 ) -    return; - -  BG_FindBBoxForBuildable( ent->s.modelindex, bmins, bmaxs ); - -  VectorAdd( ent->s.origin, bmins, mins ); -  VectorAdd( ent->s.origin, bmaxs, maxs ); - -  VectorSubtract( mins, range, mins ); -  VectorAdd( maxs, range, maxs ); - -  num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES ); - -  VectorAdd( ent->s.origin, bmins, mins ); -  VectorAdd( ent->s.origin, bmaxs, maxs ); - -  for( i = 0; i < num; i++ ) -  { -    hit = &g_entities[ touch[ i ] ]; - -    if( !hit->touch ) -      continue; - -    if( !( hit->r.contents & CONTENTS_TRIGGER ) ) -      continue; - -    //ignore buildables not yet spawned -    if( !ent->spawned ) -      continue; - -    if( !trap_EntityContact( mins, maxs, hit ) ) -      continue; - -    memset( &trace, 0, sizeof( trace ) ); - -    if( hit->touch ) -      hit->touch( hit, ent, &trace ); -  } -} - - -/* -=============== -G_BuildableThink - -General think function for buildables -=============== -*/ -void G_BuildableThink( gentity_t *ent, int msec ) -{ -  int bHealth = BG_FindHealthForBuildable( ent->s.modelindex ); -  int bRegen = BG_FindRegenRateForBuildable( ent->s.modelindex ); -  int bTime = BG_FindBuildTimeForBuildable( ent->s.modelindex ); - -  //pack health, power and dcc - -  //toggle spawned flag for buildables -  if( !ent->spawned ) -  { -    if( ent->buildTime + bTime < level.time ) -      ent->spawned = qtrue; -  } - -  ent->s.generic1 = (int)( ( (float)ent->health / (float)bHealth ) * B_HEALTH_SCALE ); - -  if( ent->s.generic1 < 0 ) -    ent->s.generic1 = 0; - -  if( ent->powered ) -    ent->s.generic1 |= B_POWERED_TOGGLEBIT; - -  if( ent->dcced ) -    ent->s.generic1 |= B_DCCED_TOGGLEBIT; - -  if( ent->spawned ) -    ent->s.generic1 |= B_SPAWNED_TOGGLEBIT; - -  ent->time1000 += msec; - -  if( ent->time1000 >= 1000 ) -  { -    ent->time1000 -= 1000; - -    if( !ent->spawned ) -      ent->health += (int)( ceil( (float)bHealth / (float)( bTime * 0.001 ) ) ); -    else if( ent->biteam == BIT_ALIENS && ent->health > 0 && ent->health < bHealth && -        bRegen && ( ent->lastDamageTime + ALIEN_REGEN_DAMAGE_TIME ) < level.time ) -      ent->health += bRegen; - -    if( ent->health > bHealth ) -      ent->health = bHealth; -  } - -  if( ent->lev1Grabbed && ent->lev1GrabTime + LEVEL1_GRAB_TIME < level.time ) -    ent->lev1Grabbed = qfalse; - -  if( ent->clientSpawnTime > 0 ) -    ent->clientSpawnTime -= msec; - -  if( ent->clientSpawnTime < 0 ) -    ent->clientSpawnTime = 0; - -  //check if this buildable is touching any triggers -  G_BuildableTouchTriggers( ent ); - -  //fall back on normal physics routines -  G_Physics( ent, msec ); -} - - -/* -=============== -G_BuildableRange - -Check whether a point is within some range of a type of buildable -=============== -*/ -qboolean G_BuildableRange( vec3_t origin, float r, buildable_t buildable ) -{ -  int       entityList[ MAX_GENTITIES ]; -  vec3_t    range; -  vec3_t    mins, maxs; -  int       i, num; -  gentity_t *ent; - -  VectorSet( range, r, r, r ); -  VectorAdd( origin, range, maxs ); -  VectorSubtract( origin, range, mins ); - -  num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -  for( i = 0; i < num; i++ ) -  { -    ent = &g_entities[ entityList[ i ] ]; - -    if( ent->s.eType != ET_BUILDABLE ) -      continue; - -    if( ent->biteam == BIT_HUMANS && !ent->powered ) -      continue; - -    if( ent->s.modelindex == buildable && ent->spawned ) -      return qtrue; -  } - -  return qfalse; -} - - -/* -================ -G_itemFits - -Checks to see if an item fits in a specific area -================ -*/ -itemBuildError_t G_itemFits( gentity_t *ent, buildable_t buildable, int distance, vec3_t origin ) -{ -  vec3_t            angles; -  vec3_t            entity_origin, normal; -  vec3_t            mins, maxs; -  trace_t           tr1, tr2, tr3; -  int               i; -  itemBuildError_t  reason = IBE_NONE; -  gentity_t         *tempent; -  float             minNormal; -  qboolean          invert; -  int               contents; -  playerState_t     *ps = &ent->client->ps; - -  BG_FindBBoxForBuildable( buildable, mins, maxs ); - -  BG_PositionBuildableRelativeToPlayer( ps, mins, maxs, trap_Trace, entity_origin, angles, &tr1 ); - -  trap_Trace( &tr2, entity_origin, mins, maxs, entity_origin, ent->s.number, MASK_PLAYERSOLID ); -  trap_Trace( &tr3, ps->origin, NULL, NULL, entity_origin, ent->s.number, MASK_PLAYERSOLID ); - -  VectorCopy( entity_origin, origin ); - -  //this item does not fit here -  if( tr2.fraction < 1.0 || tr3.fraction < 1.0 ) -    return IBE_NOROOM; //NO other reason is allowed to override this - -  VectorCopy( tr1.plane.normal, normal ); -  minNormal = BG_FindMinNormalForBuildable( buildable ); -  invert = BG_FindInvertNormalForBuildable( buildable ); - -  //can we build at this angle? -  if( !( normal[ 2 ] >= minNormal || ( invert && normal[ 2 ] <= -minNormal ) ) ) -    return IBE_NORMAL; - -  if( tr1.entityNum != ENTITYNUM_WORLD ) -    return IBE_NORMAL; - -  //check there is enough room to spawn from (presuming this is a spawn) -  if( G_CheckSpawnPoint( -1, origin, normal, buildable, NULL ) != NULL ) -    return IBE_NORMAL; - -  contents = trap_PointContents( entity_origin, -1 ); - -  if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -  { -    //alien criteria - -    if( buildable == BA_A_HOVEL ) -    { -      vec3_t    builderMins, builderMaxs; - -      //this assumes the adv builder is the biggest thing that'll use the hovel -      BG_FindBBoxForClass( PCL_ALIEN_BUILDER0_UPG, builderMins, builderMaxs, NULL, NULL, NULL ); - -      if( APropHovel_Blocked( angles, origin, normal, ent ) ) -        reason = IBE_HOVELEXIT; -    } - -    //check there is creep near by for building on -    if( BG_FindCreepTestForBuildable( buildable ) ) -    { -      if( !isCreep( entity_origin ) ) -        reason = IBE_NOCREEP; -    } - -    //check permission to build here -    if( tr1.surfaceFlags & SURF_NOALIENBUILD || tr1.surfaceFlags & SURF_NOBUILD || -        contents & CONTENTS_NOALIENBUILD || contents & CONTENTS_NOBUILD ) -      reason = IBE_PERMISSION; - -    //look for a hivemind -    for ( i = 1, tempent = g_entities + i; i < level.num_entities; i++, tempent++ ) -    { -      if( tempent->s.eType != ET_BUILDABLE ) -        continue; -      if( tempent->s.modelindex == BA_A_OVERMIND && tempent->spawned ) -        break; -    } - -    //if none found... -    if( i >= level.num_entities && buildable != BA_A_OVERMIND ) -      reason = IBE_NOOVERMIND; - -    //can we only have one of these? -    if( BG_FindUniqueTestForBuildable( buildable ) ) -    { -      for ( i = 1, tempent = g_entities + i; i < level.num_entities; i++, tempent++ ) -      { -        if( tempent->s.eType != ET_BUILDABLE ) -          continue; - -        if( tempent->s.modelindex == buildable ) -        { -          switch( buildable ) -          { -            case BA_A_OVERMIND: -              reason = IBE_OVERMIND; -              break; - -            case BA_A_HOVEL: -              reason = IBE_HOVEL; -              break; - -            default: -              Com_Error( ERR_FATAL, "No reason for denying build of %d\n", buildable ); -              break; -          } - -          break; -        } -      } -    } - -    if( level.alienBuildPoints - BG_FindBuildPointsForBuildable( buildable ) < 0 ) -      reason = IBE_NOASSERT; -  } -  else if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -  { -    //human criteria -    if( !G_isPower( entity_origin ) ) -    { -      //tell player to build a repeater to provide power -      if( buildable != BA_H_REACTOR && buildable != BA_H_REPEATER ) -        reason = IBE_REPEATER; -    } - -    //this buildable requires a DCC -    if( BG_FindDCCTestForBuildable( buildable ) && !G_isDCC( ) ) -      reason = IBE_NODCC; - -    //check that there is a parent reactor when building a repeater -    if( buildable == BA_H_REPEATER ) -    { -      for ( i = 1, tempent = g_entities + i; i < level.num_entities; i++, tempent++ ) -      { -        if( tempent->s.eType != ET_BUILDABLE ) -          continue; - -        if( tempent->s.modelindex == BA_H_REACTOR ) -          break; -      } - -      if( i >= level.num_entities ) -      { -        //no reactor present - -        //check for other nearby repeaters -        for ( i = 1, tempent = g_entities + i; i < level.num_entities; i++, tempent++ ) -        { -          if( tempent->s.eType != ET_BUILDABLE ) -            continue; - -          if( tempent->s.modelindex == BA_H_REPEATER && -              Distance( tempent->s.origin, entity_origin ) < REPEATER_BASESIZE ) -          { -            reason = IBE_RPTWARN2; -            break; -          } -        } - -        if( reason == IBE_NONE ) -          reason = IBE_RPTWARN; -      } -      else if( G_isPower( entity_origin ) ) -        reason = IBE_RPTWARN2; -    } - -    //check permission to build here -    if( tr1.surfaceFlags & SURF_NOHUMANBUILD || tr1.surfaceFlags & SURF_NOBUILD || -        contents & CONTENTS_NOHUMANBUILD || contents & CONTENTS_NOBUILD ) -      reason = IBE_PERMISSION; - -    //can we only build one of these? -    if( BG_FindUniqueTestForBuildable( buildable ) ) -    { -      for ( i = 1, tempent = g_entities + i; i < level.num_entities; i++, tempent++ ) -      { -        if( tempent->s.eType != ET_BUILDABLE ) -          continue; - -        if( tempent->s.modelindex == BA_H_REACTOR ) -        { -          reason = IBE_REACTOR; -          break; -        } -      } -    } - -    if( level.humanBuildPoints - BG_FindBuildPointsForBuildable( buildable ) < 0 ) -      reason = IBE_NOPOWER; -  } - -  return reason; -} - - -/* -================ -G_buildItem - -Spawns a buildable -================ -*/ -gentity_t *G_buildItem( gentity_t *builder, buildable_t buildable, vec3_t origin, vec3_t angles ) -{ -  gentity_t *built; -  vec3_t    normal; - -  //spawn the buildable -  built = G_Spawn(); - -  built->s.eType = ET_BUILDABLE; - -  built->classname = BG_FindEntityNameForBuildable( buildable ); - -  built->s.modelindex = buildable; //so we can tell what this is on the client side -  built->biteam = built->s.modelindex2 = BG_FindTeamForBuildable( buildable ); - -  BG_FindBBoxForBuildable( buildable, built->r.mins, built->r.maxs ); -  built->health = 1; - -  built->splashDamage = BG_FindSplashDamageForBuildable( buildable ); -  built->splashRadius = BG_FindSplashRadiusForBuildable( buildable ); -  built->splashMethodOfDeath = BG_FindMODForBuildable( buildable ); - -  built->nextthink = BG_FindNextThinkForBuildable( buildable ); - -  built->takedamage = qtrue; -  built->spawned = qfalse; -  built->buildTime = built->s.time = level.time; - -  //things that vary for each buildable that aren't in the dbase -  switch( buildable ) -  { -    case BA_A_SPAWN: -      built->die = ASpawn_Die; -      built->think = ASpawn_Think; -      built->pain = ASpawn_Pain; -      break; - -    case BA_A_BARRICADE: -      built->die = ABarricade_Die; -      built->think = ABarricade_Think; -      built->pain = ABarricade_Pain; -      break; - -    case BA_A_BOOSTER: -      built->die = ABarricade_Die; -      built->think = ABarricade_Think; -      built->pain = ABarricade_Pain; -      built->touch = ABooster_Touch; -      break; - -    case BA_A_ACIDTUBE: -      built->die = ABarricade_Die; -      built->think = AAcidTube_Think; -      built->pain = ASpawn_Pain; -      break; - -    case BA_A_HIVE: -      built->die = ABarricade_Die; -      built->think = AHive_Think; -      built->pain = ASpawn_Pain; -      break; - -    case BA_A_TRAPPER: -      built->die = ABarricade_Die; -      built->think = ATrapper_Think; -      built->pain = ASpawn_Pain; -      break; - -    case BA_A_OVERMIND: -      built->die = ASpawn_Die; -      built->think = AOvermind_Think; -      built->pain = ASpawn_Pain; -      break; - -    case BA_A_HOVEL: -      built->die = AHovel_Die; -      built->use = AHovel_Use; -      built->think = AHovel_Think; -      built->pain = ASpawn_Pain; -      break; - -    case BA_H_SPAWN: -      built->die = HSpawn_Die; -      built->think = HSpawn_Think; -      break; - -    case BA_H_MGTURRET: -      built->die = HSpawn_Die; -      built->think = HMGTurret_Think; -      break; - -    case BA_H_TESLAGEN: -      built->die = HSpawn_Die; -      built->think = HTeslaGen_Think; -      break; - -    case BA_H_ARMOURY: -      built->think = HArmoury_Think; -      built->die = HSpawn_Die; -      built->use = HArmoury_Activate; -      break; - -    case BA_H_DCC: -      built->think = HDCC_Think; -      built->die = HSpawn_Die; -      break; - -    case BA_H_MEDISTAT: -      built->think = HMedistat_Think; -      built->die = HSpawn_Die; -      break; - -    case BA_H_REACTOR: -      built->think = HReactor_Think; -      built->die = HSpawn_Die; -      built->use = HRepeater_Use; -      built->powered = built->active = qtrue; -      break; - -    case BA_H_REPEATER: -      built->think = HRepeater_Think; -      built->die = HSpawn_Die; -      built->use = HRepeater_Use; -      built->count = -1; -      break; - -    default: -      //erk -      break; -  } - -  built->s.number = built - g_entities; -  built->r.contents = CONTENTS_BODY; -  built->clipmask = MASK_PLAYERSOLID; -  built->enemy = NULL; -  built->s.weapon = BG_FindProjTypeForBuildable( buildable ); - -  if( builder->client ) -    built->builtBy = builder->client->ps.clientNum; -  else -    built->builtBy = -1; - -  G_SetOrigin( built, origin ); -  VectorCopy( angles, built->s.angles ); -  built->s.angles[ PITCH ] = 0.0f; -  built->s.angles2[ YAW ] = angles[ YAW ]; -  built->s.pos.trType = BG_FindTrajectoryForBuildable( buildable ); -  built->s.pos.trTime = level.time; -  built->physicsBounce = BG_FindBounceForBuildable( buildable ); -  built->s.groundEntityNum = -1; - -  if( builder->client && builder->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBING ) -  { -    if( builder->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) -      VectorSet( normal, 0.0f, 0.0f, -1.0f ); -    else -      VectorCopy( builder->client->ps.grapplePoint, normal ); - -    //gently nudge the buildable onto the surface :) -    VectorScale( normal, -50.0f, built->s.pos.trDelta ); -  } -  else -    VectorSet( normal, 0.0f, 0.0f, 1.0f ); - -  built->s.generic1 = (int)( ( (float)built->health / -        (float)BG_FindHealthForBuildable( buildable ) ) * B_HEALTH_SCALE ); - -  if( built->s.generic1 < 0 ) -    built->s.generic1 = 0; - -  if( ( built->powered = findPower( built ) ) ) -    built->s.generic1 |= B_POWERED_TOGGLEBIT; - -  if( ( built->dcced = findDCC( built ) ) ) -    built->s.generic1 |= B_DCCED_TOGGLEBIT; - -  built->s.generic1 &= ~B_SPAWNED_TOGGLEBIT; - -  VectorCopy( normal, built->s.origin2 ); - -  G_AddEvent( built, EV_BUILD_CONSTRUCT, 0 ); - -  G_setIdleBuildableAnim( built, BG_FindAnimForBuildable( buildable ) ); - -  if( built->builtBy >= 0 ) -    G_setBuildableAnim( built, BANIM_CONSTRUCT1, qtrue ); - -  trap_LinkEntity( built ); - -  return built; -} - -/* -================= -G_ValidateBuild -================= -*/ -qboolean G_ValidateBuild( gentity_t *ent, buildable_t buildable ) -{ -  float         dist; -  vec3_t        origin; - -  dist = BG_FindBuildDistForClass( ent->client->ps.stats[ STAT_PCLASS ] ); - -  switch( G_itemFits( ent, buildable, dist, origin ) ) -  { -    case IBE_NONE: -      G_buildItem( ent, buildable, origin, ent->s.apos.trBase ); -      return qtrue; - -    case IBE_NOASSERT: -      G_TriggerMenu( ent->client->ps.clientNum, MN_A_NOASSERT ); -      return qfalse; - -    case IBE_NOOVERMIND: -      G_TriggerMenu( ent->client->ps.clientNum, MN_A_NOOVMND ); -      return qfalse; - -    case IBE_NOCREEP: -      G_TriggerMenu( ent->client->ps.clientNum, MN_A_NOCREEP ); -      return qfalse; - -    case IBE_OVERMIND: -      G_TriggerMenu( ent->client->ps.clientNum, MN_A_OVERMIND ); -      return qfalse; - -    case IBE_HOVEL: -      G_TriggerMenu( ent->client->ps.clientNum, MN_A_HOVEL ); -      return qfalse; - -    case IBE_HOVELEXIT: -      G_TriggerMenu( ent->client->ps.clientNum, MN_A_HOVEL_EXIT ); -      return qfalse; - -    case IBE_NORMAL: -      if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -        G_TriggerMenu( ent->client->ps.clientNum, MN_H_NORMAL ); -      else -        G_TriggerMenu( ent->client->ps.clientNum, MN_A_NORMAL ); -      return qfalse; - -    case IBE_PERMISSION: -      if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -        G_TriggerMenu( ent->client->ps.clientNum, MN_H_NORMAL ); -      else -        G_TriggerMenu( ent->client->ps.clientNum, MN_A_NORMAL ); -      return qfalse; - -    case IBE_REACTOR: -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_REACTOR ); -      return qfalse; - -    case IBE_REPEATER: -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_REPEATER ); -      return qfalse; - -    case IBE_NOROOM: -      if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -        G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOROOM ); -      else -        G_TriggerMenu( ent->client->ps.clientNum, MN_A_NOROOM ); -      return qfalse; - -    case IBE_NOPOWER: -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOPOWER ); -      return qfalse; - -    case IBE_NODCC: -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_NODCC ); -      return qfalse; - -    case IBE_SPWNWARN: -      G_TriggerMenu( ent->client->ps.clientNum, MN_A_SPWNWARN ); -      G_buildItem( ent, buildable, origin, ent->s.apos.trBase ); -      return qtrue; - -    case IBE_TNODEWARN: -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_TNODEWARN ); -      G_buildItem( ent, buildable, origin, ent->s.apos.trBase ); -      return qtrue; - -    case IBE_RPTWARN: -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_RPTWARN ); -      G_buildItem( ent, buildable, origin, ent->s.apos.trBase ); -      return qtrue; - -    case IBE_RPTWARN2: -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_RPTWARN2 ); -      return qfalse; - -    default: -      break; -  } - -  return qfalse; -} - -/* -================ -FinishSpawningBuildable - -Traces down to find where an item should rest, instead of letting them -free fall from their spawn points -================ -*/ -void FinishSpawningBuildable( gentity_t *ent ) -{ -  trace_t     tr; -  vec3_t      dest; -  gentity_t   *built; -  buildable_t buildable = ent->s.modelindex; - -  built = G_buildItem( ent, buildable, ent->s.pos.trBase, ent->s.angles ); -  G_FreeEntity( ent ); - -  built->takedamage = qtrue; -  built->spawned = qtrue; //map entities are already spawned -  built->health = BG_FindHealthForBuildable( buildable ); -  built->s.generic1 |= B_SPAWNED_TOGGLEBIT; - -  // drop to floor -  if( buildable != BA_NONE && BG_FindTrajectoryForBuildable( buildable ) == TR_BUOYANCY ) -    VectorSet( dest, built->s.origin[ 0 ], built->s.origin[ 1 ], built->s.origin[ 2 ] + 4096 ); -  else -    VectorSet( dest, built->s.origin[ 0 ], built->s.origin[ 1 ], built->s.origin[ 2 ] - 4096 ); - -  trap_Trace( &tr, built->s.origin, built->r.mins, built->r.maxs, dest, built->s.number, built->clipmask ); - -  if( tr.startsolid ) -  { -    G_Printf( S_COLOR_YELLOW "FinishSpawningBuildable: %s startsolid at %s\n", built->classname, vtos( built->s.origin ) ); -    G_FreeEntity( built ); -    return; -  } - -  //point items in the correct direction -  VectorCopy( tr.plane.normal, built->s.origin2 ); - -  // allow to ride movers -  built->s.groundEntityNum = tr.entityNum; - -  G_SetOrigin( built, tr.endpos ); - -  trap_LinkEntity( built ); -} - -/* -============ -G_SpawnBuildable - -Sets the clipping size and plants the object on the floor. - -Items can't be immediately dropped to floor, because they might -be on an entity that hasn't spawned yet. -============ -*/ -void G_SpawnBuildable( gentity_t *ent, buildable_t buildable ) -{ -  ent->s.modelindex = buildable; - -  // some movers spawn on the second frame, so delay item -  // spawns until the third frame so they can ride trains -  ent->nextthink = level.time + FRAMETIME * 2; -  ent->think = FinishSpawningBuildable; -} diff --git a/mod/src/game/g_client.c b/mod/src/game/g_client.c deleted file mode 100644 index e86439c4..00000000 --- a/mod/src/game/g_client.c +++ /dev/null @@ -1,1593 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -// g_client.c -- client functions that don't happen every frame - -static vec3_t playerMins = {-15, -15, -24}; -static vec3_t playerMaxs = {15, 15, 32}; - -/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 32) initial -potential spawning position for deathmatch games. -The first time a player enters the game, they will be at an 'initial' spot. -Targets will be fired when someone spawns in on them. -"nobots" will prevent bots from using this spot. -"nohumans" will prevent non-bots from using this spot. -*/ -void SP_info_player_deathmatch( gentity_t *ent ) -{ -  int   i; - -  G_SpawnInt( "nobots", "0", &i); - -  if( i ) -    ent->flags |= FL_NO_BOTS; - -  G_SpawnInt( "nohumans", "0", &i ); -  if( i ) -    ent->flags |= FL_NO_HUMANS; -} - -/*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 32) -equivelant to info_player_deathmatch -*/ -void SP_info_player_start( gentity_t *ent ) -{ -  ent->classname = "info_player_deathmatch"; -  SP_info_player_deathmatch( ent ); -} - -/*QUAKED info_player_intermission (1 0 1) (-16 -16 -24) (16 16 32) -The intermission will be viewed from this point.  Target an info_notnull for the view direction. -*/ -void SP_info_player_intermission( gentity_t *ent ) -{ -} - -/*QUAKED info_alien_intermission (1 0 1) (-16 -16 -24) (16 16 32) -The intermission will be viewed from this point.  Target an info_notnull for the view direction. -*/ -void SP_info_alien_intermission( gentity_t *ent ) -{ -} - -/*QUAKED info_human_intermission (1 0 1) (-16 -16 -24) (16 16 32) -The intermission will be viewed from this point.  Target an info_notnull for the view direction. -*/ -void SP_info_human_intermission( gentity_t *ent ) -{ -} - -/* -=============== -G_AddCreditToClient -=============== -*/ -void G_AddCreditToClient( gclient_t *client, short credit, qboolean cap ) -{ -  if( !client ) -    return; - -  //if we're already at the max and trying to add credit then stop -  if( cap ) -  { -    if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -    { -      if( client->ps.persistant[ PERS_CREDIT ] >= ALIEN_MAX_KILLS && -          credit > 0 ) -        return; -    } -    else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -    { -      if( client->ps.persistant[ PERS_CREDIT ] >= HUMAN_MAX_CREDITS && -          credit > 0 ) -        return; -    } -  } - -  client->ps.persistant[ PERS_CREDIT ] += credit; - -  if( cap ) -  { -    if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -    { -      if( client->ps.persistant[ PERS_CREDIT ] > ALIEN_MAX_KILLS ) -        client->ps.persistant[ PERS_CREDIT ] = ALIEN_MAX_KILLS; -    } -    else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -    { -      if( client->ps.persistant[ PERS_CREDIT ] > HUMAN_MAX_CREDITS ) -        client->ps.persistant[ PERS_CREDIT ] = HUMAN_MAX_CREDITS; -    } -  } - -  if( client->ps.persistant[ PERS_CREDIT ] < 0 ) -    client->ps.persistant[ PERS_CREDIT ] = 0; -} - - -/* -======================================================================= - -  SelectSpawnPoint - -======================================================================= -*/ - -/* -================ -SpotWouldTelefrag - -================ -*/ -qboolean SpotWouldTelefrag( gentity_t *spot ) -{ -  int       i, num; -  int       touch[ MAX_GENTITIES ]; -  gentity_t *hit; -  vec3_t    mins, maxs; - -  VectorAdd( spot->s.origin, playerMins, mins ); -  VectorAdd( spot->s.origin, playerMaxs, maxs ); -  num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES ); - -  for( i = 0; i < num; i++ ) -  { -    hit = &g_entities[ touch[ i ] ]; -    //if ( hit->client && hit->client->ps.stats[STAT_HEALTH] > 0 ) { -    if( hit->client ) -      return qtrue; -  } - -  return qfalse; -} - -/* -================ -SelectNearestDeathmatchSpawnPoint - -Find the spot that we DON'T want to use -================ -*/ -#define MAX_SPAWN_POINTS  128 -gentity_t *SelectNearestDeathmatchSpawnPoint( vec3_t from ) -{ -  gentity_t *spot; -  vec3_t    delta; -  float     dist, nearestDist; -  gentity_t *nearestSpot; - -  nearestDist = 999999; -  nearestSpot = NULL; -  spot = NULL; - -  while( (spot = G_Find( spot, FOFS( classname ), "info_player_deathmatch" ) ) != NULL ) -  { -    VectorSubtract( spot->s.origin, from, delta ); -    dist = VectorLength( delta ); - -    if( dist < nearestDist ) -    { -      nearestDist = dist; -      nearestSpot = spot; -    } -  } - -  return nearestSpot; -} - - -/* -================ -SelectRandomDeathmatchSpawnPoint - -go to a random point that doesn't telefrag -================ -*/ -#define MAX_SPAWN_POINTS  128 -gentity_t *SelectRandomDeathmatchSpawnPoint( void ) -{ -  gentity_t *spot; -  int       count; -  int       selection; -  gentity_t *spots[ MAX_SPAWN_POINTS ]; - -  count = 0; -  spot = NULL; - -  while( ( spot = G_Find( spot, FOFS( classname ), "info_player_deathmatch" ) ) != NULL ) -  { -    if( SpotWouldTelefrag( spot ) ) -      continue; - -    spots[ count ] = spot; -    count++; -  } - -  if( !count ) // no spots that won't telefrag -    return G_Find( NULL, FOFS( classname ), "info_player_deathmatch" ); - -  selection = rand( ) % count; -  return spots[ selection ]; -} - - -/* -=========== -SelectRandomFurthestSpawnPoint - -Chooses a player start, deathmatch start, etc -============ -*/ -gentity_t *SelectRandomFurthestSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles ) -{ -  gentity_t *spot; -  vec3_t    delta; -  float     dist; -  float     list_dist[ 64 ]; -  gentity_t *list_spot[ 64 ]; -  int       numSpots, rnd, i, j; - -  numSpots = 0; -  spot = NULL; - -  while( ( spot = G_Find( spot, FOFS( classname ), "info_player_deathmatch" ) ) != NULL ) -  { -    if( SpotWouldTelefrag( spot ) ) -      continue; - -    VectorSubtract( spot->s.origin, avoidPoint, delta ); -    dist = VectorLength( delta ); - -    for( i = 0; i < numSpots; i++ ) -    { -      if( dist > list_dist[ i ] ) -      { -        if( numSpots >= 64 ) -          numSpots = 64 - 1; - -        for( j = numSpots; j > i; j-- ) -        { -          list_dist[ j ] = list_dist[ j - 1 ]; -          list_spot[ j ] = list_spot[ j - 1 ]; -        } - -        list_dist[ i ] = dist; -        list_spot[ i ] = spot; -        numSpots++; - -        if( numSpots > 64 ) -          numSpots = 64; - -        break; -      } -    } - -    if( i >= numSpots && numSpots < 64 ) -    { -      list_dist[ numSpots ] = dist; -      list_spot[ numSpots ] = spot; -      numSpots++; -    } -  } - -  if( !numSpots ) -  { -    spot = G_Find( NULL, FOFS( classname ), "info_player_deathmatch" ); - -    if( !spot ) -      G_Error( "Couldn't find a spawn point" ); - -    VectorCopy( spot->s.origin, origin ); -    origin[ 2 ] += 9; -    VectorCopy( spot->s.angles, angles ); -    return spot; -  } - -  // select a random spot from the spawn points furthest away -  rnd = random( ) * ( numSpots / 2 ); - -  VectorCopy( list_spot[ rnd ]->s.origin, origin ); -  origin[ 2 ] += 9; -  VectorCopy( list_spot[ rnd ]->s.angles, angles ); - -  return list_spot[ rnd ]; -} - - -/* -================ -SelectAlienSpawnPoint - -go to a random point that doesn't telefrag -================ -*/ -gentity_t *SelectAlienSpawnPoint( vec3_t preference ) -{ -  gentity_t *spot; -  int       count; -  gentity_t *spots[ MAX_SPAWN_POINTS ]; - -  if( level.numAlienSpawns <= 0 ) -    return NULL; - -  count = 0; -  spot = NULL; - -  while( ( spot = G_Find( spot, FOFS( classname ), -    BG_FindEntityNameForBuildable( BA_A_SPAWN ) ) ) != NULL ) -  { -    if( !spot->spawned ) -      continue; - -    if( spot->health <= 0 ) -      continue; - -    if( !spot->s.groundEntityNum ) -      continue; - -    if( spot->clientSpawnTime > 0 ) -      continue; - -    if( G_CheckSpawnPoint( spot->s.number, spot->s.origin, -          spot->s.origin2, BA_A_SPAWN, NULL ) != NULL ) -      continue; - -    spots[ count ] = spot; -    count++; -  } - -  if( !count ) -    return NULL; - -  return G_ClosestEnt( preference, spots, count ); -} - - -/* -================ -SelectHumanSpawnPoint - -go to a random point that doesn't telefrag -================ -*/ -gentity_t *SelectHumanSpawnPoint( vec3_t preference ) -{ -  gentity_t *spot; -  int       count; -  gentity_t *spots[ MAX_SPAWN_POINTS ]; - -  if( level.numHumanSpawns <= 0 ) -    return NULL; - -  count = 0; -  spot = NULL; - -  while( ( spot = G_Find( spot, FOFS( classname ), -    BG_FindEntityNameForBuildable( BA_H_SPAWN ) ) ) != NULL ) -  { -    if( !spot->spawned ) -      continue; - -    if( spot->health <= 0 ) -      continue; - -    if( !spot->s.groundEntityNum ) -      continue; - -    if( spot->clientSpawnTime > 0 ) -      continue; - -    if( G_CheckSpawnPoint( spot->s.number, spot->s.origin, -          spot->s.origin2, BA_H_SPAWN, NULL ) != NULL ) -      continue; - -    spots[ count ] = spot; -    count++; -  } - -  if( !count ) -    return NULL; - -  return G_ClosestEnt( preference, spots, count ); -} - - -/* -=========== -SelectSpawnPoint - -Chooses a player start, deathmatch start, etc -============ -*/ -gentity_t *SelectSpawnPoint( vec3_t avoidPoint, vec3_t origin, vec3_t angles ) -{ -  return SelectRandomFurthestSpawnPoint( avoidPoint, origin, angles ); -} - - -/* -=========== -SelectTremulousSpawnPoint - -Chooses a player start, deathmatch start, etc -============ -*/ -gentity_t *SelectTremulousSpawnPoint( pTeam_t team, vec3_t preference, vec3_t origin, vec3_t angles ) -{ -  gentity_t *spot = NULL; - -  if( team == PTE_ALIENS ) -    spot = SelectAlienSpawnPoint( preference ); -  else if( team == PTE_HUMANS ) -    spot = SelectHumanSpawnPoint( preference ); - -  //no available spots -  if( !spot ) -    return NULL; - -  if( team == PTE_ALIENS ) -    G_CheckSpawnPoint( spot->s.number, spot->s.origin, spot->s.origin2, BA_A_SPAWN, origin ); -  else if( team == PTE_HUMANS ) -    G_CheckSpawnPoint( spot->s.number, spot->s.origin, spot->s.origin2, BA_H_SPAWN, origin ); - -  VectorCopy( spot->s.angles, angles ); -  angles[ ROLL ] = 0; - -  return spot; - -} - - -/* -=========== -SelectInitialSpawnPoint - -Try to find a spawn point marked 'initial', otherwise -use normal spawn selection. -============ -*/ -gentity_t *SelectInitialSpawnPoint( vec3_t origin, vec3_t angles ) -{ -  gentity_t *spot; - -  spot = NULL; -  while( ( spot = G_Find( spot, FOFS( classname ), "info_player_deathmatch" ) ) != NULL ) -  { -    if( spot->spawnflags & 1 ) -      break; -  } - -  if( !spot || SpotWouldTelefrag( spot ) ) -  { -    return SelectSpawnPoint( vec3_origin, origin, angles ); -  } - -  VectorCopy( spot->s.origin, origin ); -  origin[ 2 ] += 9; -  VectorCopy( spot->s.angles, angles ); - -  return spot; -} - -/* -=========== -SelectSpectatorSpawnPoint - -============ -*/ -gentity_t *SelectSpectatorSpawnPoint( vec3_t origin, vec3_t angles ) -{ -  FindIntermissionPoint( ); - -  VectorCopy( level.intermission_origin, origin ); -  VectorCopy( level.intermission_angle, angles ); - -  return NULL; -} - - -/* -=========== -SelectAlienLockSpawnPoint - -Try to find a spawn point for alien intermission otherwise -use normal intermission spawn. -============ -*/ -gentity_t *SelectAlienLockSpawnPoint( vec3_t origin, vec3_t angles ) -{ -  gentity_t *spot; - -  spot = NULL; -  spot = G_Find( spot, FOFS( classname ), "info_alien_intermission" ); - -  if( !spot ) -    return SelectSpectatorSpawnPoint( origin, angles ); - -  VectorCopy( spot->s.origin, origin ); -  VectorCopy( spot->s.angles, angles ); - -  return spot; -} - - -/* -=========== -SelectHumanLockSpawnPoint - -Try to find a spawn point for human intermission otherwise -use normal intermission spawn. -============ -*/ -gentity_t *SelectHumanLockSpawnPoint( vec3_t origin, vec3_t angles ) -{ -  gentity_t *spot; - -  spot = NULL; -  spot = G_Find( spot, FOFS( classname ), "info_human_intermission" ); - -  if( !spot ) -    return SelectSpectatorSpawnPoint( origin, angles ); - -  VectorCopy( spot->s.origin, origin ); -  VectorCopy( spot->s.angles, angles ); - -  return spot; -} - - -/* -======================================================================= - -BODYQUE - -======================================================================= -*/ - - -/* -============= -BodySink - -After sitting around for five seconds, fall into the ground and dissapear -============= -*/ -void BodySink( gentity_t *ent ) -{ -  //run on first BodySink call -  if( !ent->active ) -  { -    ent->active = qtrue; - -    //sinking bodies can't be infested -    ent->killedBy = ent->s.powerups = MAX_CLIENTS; -    ent->timestamp = level.time; -  } - -  if( level.time - ent->timestamp > 6500 ) -  { -    G_FreeEntity( ent ); -    return; -  } - -  ent->nextthink = level.time + 100; -  ent->s.pos.trBase[ 2 ] -= 1; -} - - -/* -============= -BodyFree - -After sitting around for a while the body becomes a freebie -============= -*/ -void BodyFree( gentity_t *ent ) -{ -  ent->killedBy = -1; - -  //if not claimed in the next minute destroy -  ent->think = BodySink; -  ent->nextthink = level.time + 60000; -} - - -/* -============= -SpawnCorpse - -A player is respawning, so make an entity that looks -just like the existing corpse to leave behind. -============= -*/ -void SpawnCorpse( gentity_t *ent ) -{ -  gentity_t   *body; -  int         contents; -  vec3_t      origin, dest; -  trace_t     tr; -  float       vDiff; - -  VectorCopy( ent->r.currentOrigin, origin ); - -  trap_UnlinkEntity( ent ); - -  // if client is in a nodrop area, don't leave the body -  contents = trap_PointContents( origin, -1 ); -  if( contents & CONTENTS_NODROP ) -    return; - -  body = G_Spawn( ); - -  VectorCopy( ent->s.apos.trBase, body->s.angles ); -  body->s.eFlags = EF_DEAD; -  body->s.eType = ET_CORPSE; -  body->s.number = body - g_entities; -  body->timestamp = level.time; -  body->s.event = 0; -  body->r.contents = CONTENTS_CORPSE; -  body->s.clientNum = ent->client->ps.stats[ STAT_PCLASS ]; -  body->nonSegModel = ent->client->ps.persistant[ PERS_STATE ] & PS_NONSEGMODEL; - -  if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -    body->classname = "humanCorpse"; -  else -    body->classname = "alienCorpse"; - -  body->s.powerups = MAX_CLIENTS; - -  body->think = BodySink; -  body->nextthink = level.time + 20000; - -  body->s.legsAnim = ent->s.legsAnim; - -  if( !body->nonSegModel ) -  { -    switch( body->s.legsAnim & ~ANIM_TOGGLEBIT ) -    { -      case BOTH_DEATH1: -      case BOTH_DEAD1: -        body->s.torsoAnim = body->s.legsAnim = BOTH_DEAD1; -        break; -      case BOTH_DEATH2: -      case BOTH_DEAD2: -        body->s.torsoAnim = body->s.legsAnim = BOTH_DEAD2; -        break; -      case BOTH_DEATH3: -      case BOTH_DEAD3: -      default: -        body->s.torsoAnim = body->s.legsAnim = BOTH_DEAD3; -        break; -    } -  } -  else -  { -    switch( body->s.legsAnim & ~ANIM_TOGGLEBIT ) -    { -      case NSPA_DEATH1: -      case NSPA_DEAD1: -        body->s.legsAnim = NSPA_DEAD1; -        break; -      case NSPA_DEATH2: -      case NSPA_DEAD2: -        body->s.legsAnim = NSPA_DEAD2; -        break; -      case NSPA_DEATH3: -      case NSPA_DEAD3: -      default: -        body->s.legsAnim = NSPA_DEAD3; -        break; -    } -  } - -  body->takedamage = qfalse; - -  body->health = ent->health = ent->client->ps.stats[ STAT_HEALTH ]; -  ent->health = 0; - -  //change body dimensions -  BG_FindBBoxForClass( ent->client->ps.stats[ STAT_PCLASS ], NULL, NULL, NULL, body->r.mins, body->r.maxs ); -  vDiff = body->r.mins[ 2 ] - ent->r.mins[ 2 ]; - -  //drop down to match the *model* origins of ent and body -  VectorSet( dest, origin[ 0 ], origin[ 1 ], origin[ 2 ] - vDiff ); -  trap_Trace( &tr, origin, body->r.mins, body->r.maxs, dest, body->s.number, body->clipmask ); -  VectorCopy( tr.endpos, origin ); - -  G_SetOrigin( body, origin ); -  VectorCopy( origin, body->s.origin ); -  body->s.pos.trType = TR_GRAVITY; -  body->s.pos.trTime = level.time; -  VectorCopy( ent->client->ps.velocity, body->s.pos.trDelta ); - -  VectorCopy ( body->s.pos.trBase, body->r.currentOrigin ); -  trap_LinkEntity( body ); -} - -//====================================================================== - - -/* -================== -SetClientViewAngle - -================== -*/ -void SetClientViewAngle( gentity_t *ent, vec3_t angle ) -{ -  int     i; - -  // set the delta angle -  for( i = 0; i < 3; i++ ) -  { -    int   cmdAngle; - -    cmdAngle = ANGLE2SHORT( angle[ i ] ); -    ent->client->ps.delta_angles[ i ] = cmdAngle - ent->client->pers.cmd.angles[ i ]; -  } - -  VectorCopy( angle, ent->s.angles ); -  VectorCopy( ent->s.angles, ent->client->ps.viewangles ); -} - -/* -================ -respawn -================ -*/ -void respawn( gentity_t *ent ) -{ -  SpawnCorpse( ent ); - -  //TA: Clients can't respawn - they must go thru the class cmd -  ClientSpawn( ent, NULL, NULL, NULL ); -} - -/* -================ -TeamCount - -Returns number of players on a team -================ -*/ -team_t TeamCount( int ignoreClientNum, int team ) -{ -  int   i; -  int   count = 0; - -  for( i = 0 ; i < level.maxclients ; i++ ) -  { -    if( i == ignoreClientNum ) -      continue; - -    if( level.clients[ i ].pers.connected == CON_DISCONNECTED ) -      continue; - -    if( level.clients[ i ].sess.sessionTeam == team ) -      count++; -  } - -  return count; -} - - -/* -=========== -ClientCheckName -============ -*/ -static void ClientCleanName( const char *in, char *out, int outSize ) -{ -  int   len, colorlessLen; -  char  ch; -  char  *p; -  int   spaces; - -  //save room for trailing null byte -  outSize--; - -  len = 0; -  colorlessLen = 0; -  p = out; -  *p = 0; -  spaces = 0; - -  while( 1 ) -  { -    ch = *in++; -    if( !ch ) -      break; - -    // don't allow leading spaces -    if( !*p && ch == ' ' ) -      continue; - -    // check colors -    if( ch == Q_COLOR_ESCAPE ) -    { -      // solo trailing carat is not a color prefix -      if( !*in ) -        break; - -      // don't allow black in a name, period -      if( ColorIndex( *in ) == 0 ) -      { -        in++; -        continue; -      } - -      // make sure room in dest for both chars -      if( len > outSize - 2 ) -        break; - -      *out++ = ch; -      *out++ = *in++; -      len += 2; -      continue; -    } - -    // don't allow too many consecutive spaces -    if( ch == ' ' ) -    { -      spaces++; -      if( spaces > 3 ) -        continue; -    } -    else -      spaces = 0; - -    if( len > outSize - 1 ) -      break; - -    *out++ = ch; -    colorlessLen++; -    len++; -  } - -  *out = 0; - -  // don't allow empty names -  if( *p == 0 || colorlessLen == 0 ) -    Q_strncpyz( p, "UnnamedPlayer", outSize ); -} - - -/* -====================== -G_NonSegModel - -Reads an animation.cfg to check for nonsegmentation -====================== -*/ -static qboolean G_NonSegModel( const char *filename ) -{ -  char          *text_p; -  int           len; -  char          *token; -  char          text[ 20000 ]; -  fileHandle_t  f; - -  // load the file -  len = trap_FS_FOpenFile( filename, &f, FS_READ ); -  if( !f ) -  { -    G_Printf( "File not found: %s\n", filename ); -    return qfalse; -  } - -  if( len <= 0 ) -    return qfalse; - -  if( len >= sizeof( text ) - 1 ) -  { -    G_Printf( "File %s too long\n", filename ); -    return qfalse; -  } - -  trap_FS_Read( text, len, f ); -  text[ len ] = 0; -  trap_FS_FCloseFile( f ); - -  // parse the text -  text_p = text; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( &text_p ); - -    //EOF -    if( !token[ 0 ] ) -      break; - -    if( !Q_stricmp( token, "nonsegmented" ) ) -      return qtrue; -  } - -  return qfalse; -} - -/* -=========== -ClientUserInfoChanged - -Called from ClientConnect when the player first connects and -directly by the server system when the player updates a userinfo variable. - -The game can override any of the settings and call trap_SetUserinfo -if desired. -============ -*/ -void ClientUserinfoChanged( int clientNum ) -{ -  gentity_t *ent; -  int       teamTask, teamLeader, health; -  char      *s; -  char      model[ MAX_QPATH ]; -  char      buffer[ MAX_QPATH ]; -  char      filename[ MAX_QPATH ]; -  char      oldname[ MAX_STRING_CHARS ]; -  gclient_t *client; -  char      c1[ MAX_INFO_STRING ]; -  char      c2[ MAX_INFO_STRING ]; -  char      redTeam[ MAX_INFO_STRING ]; -  char      blueTeam[ MAX_INFO_STRING ]; -  char      userinfo[ MAX_INFO_STRING ]; -  team_t    team; - -  ent = g_entities + clientNum; -  client = ent->client; - -  trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) ); - -  // check for malformed or illegal info strings -  if( !Info_Validate(userinfo) ) -    strcpy( userinfo, "\\name\\badinfo" ); - -  // check for local client -  s = Info_ValueForKey( userinfo, "ip" ); - -  if( !strcmp( s, "localhost" ) ) -    client->pers.localClient = qtrue; - -  // check the item prediction -  s = Info_ValueForKey( userinfo, "cg_predictItems" ); - -  if( !atoi( s ) ) -    client->pers.predictItemPickup = qfalse; -  else -    client->pers.predictItemPickup = qtrue; - -  // set name -  Q_strncpyz( oldname, client->pers.netname, sizeof( oldname ) ); -  s = Info_ValueForKey( userinfo, "name" ); -  ClientCleanName( s, client->pers.netname, sizeof( client->pers.netname ) ); - -  if( client->sess.sessionTeam == TEAM_SPECTATOR ) -  { -    if( client->sess.spectatorState == SPECTATOR_SCOREBOARD ) -      Q_strncpyz( client->pers.netname, "scoreboard", sizeof( client->pers.netname ) ); -  } - -  if( client->pers.connected == CON_CONNECTED ) -  { -    if( strcmp( oldname, client->pers.netname ) ) -    { -      G_SendCommandFromServer( -1, va( "print \"%s" S_COLOR_WHITE " renamed to %s\n\"", oldname, -        client->pers.netname ) ); -    } -  } - -  // set max health -  health = atoi( Info_ValueForKey( userinfo, "handicap" ) ); -  client->pers.maxHealth = health; - -  if( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) -    client->pers.maxHealth = 100; - -  //hack to force a client update if the config string does not change between spawning -  if( client->pers.classSelection == PCL_NONE ) -    client->pers.maxHealth = 0; - -  // set model -  if( client->ps.stats[ STAT_PCLASS ] == PCL_HUMAN && BG_InventoryContainsUpgrade( UP_BATTLESUIT, client->ps.stats ) ) -  { -    Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_FindModelNameForClass( PCL_HUMAN_BSUIT ), -                                              BG_FindSkinNameForClass( PCL_HUMAN_BSUIT ) ); -  } -  else if( client->pers.classSelection == PCL_NONE ) -  { -    //This looks hacky and frankly it is. The clientInfo string needs to hold different -    //model details to that of the spawning class or the info change will not be -    //registered and an axis appears instead of the player model. There is zero chance -    //the player can spawn with the battlesuit, hence this choice. -    Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_FindModelNameForClass( PCL_HUMAN_BSUIT ), -                                              BG_FindSkinNameForClass( PCL_HUMAN_BSUIT ) ); -  } -  else -  { -    Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_FindModelNameForClass( client->pers.classSelection ), -                                              BG_FindSkinNameForClass( client->pers.classSelection ) ); -  } -  Q_strncpyz( model, buffer, sizeof( model ) ); - -  //don't bother setting model type if spectating -  if( client->pers.classSelection != PCL_NONE ) -  { -    //model segmentation -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg", -                 BG_FindModelNameForClass( client->pers.classSelection ) ); - -    if( G_NonSegModel( filename ) ) -      client->ps.persistant[ PERS_STATE ] |= PS_NONSEGMODEL; -    else -      client->ps.persistant[ PERS_STATE ] &= ~PS_NONSEGMODEL; -  } - -  // wallwalk follow -  s = Info_ValueForKey( userinfo, "cg_wwFollow" ); - -  if( atoi( s ) ) -    client->ps.persistant[ PERS_STATE ] |= PS_WALLCLIMBINGFOLLOW; -  else -    client->ps.persistant[ PERS_STATE ] &= ~PS_WALLCLIMBINGFOLLOW; - -  // wallwalk toggle -  s = Info_ValueForKey( userinfo, "cg_wwToggle" ); - -  if( atoi( s ) ) -    client->ps.persistant[ PERS_STATE ] |= PS_WALLCLIMBINGTOGGLE; -  else -    client->ps.persistant[ PERS_STATE ] &= ~PS_WALLCLIMBINGTOGGLE; - -  // teamInfo -  s = Info_ValueForKey( userinfo, "teamoverlay" ); - -  if( ! *s || atoi( s ) != 0 ) -    client->pers.teamInfo = qtrue; -  else -    client->pers.teamInfo = qfalse; - -  // team task (0 = none, 1 = offence, 2 = defence) -  teamTask = atoi( Info_ValueForKey( userinfo, "teamtask" ) ); -  // team Leader (1 = leader, 0 is normal player) -  teamLeader = client->sess.teamLeader; - -  // colors -  strcpy( c1, Info_ValueForKey( userinfo, "color1" ) ); -  strcpy( c2, Info_ValueForKey( userinfo, "color2" ) ); -  strcpy( redTeam, "humans" ); -  strcpy( blueTeam, "aliens" ); - -  if( client->ps.pm_flags & PMF_FOLLOW ) -    team = PTE_NONE; -  else -    team = client->ps.stats[ STAT_PTEAM ]; - -  // send over a subset of the userinfo keys so other clients can -  // print scoreboards, display models, and play custom sounds -  s = va( "n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\g_redteam\\%s\\g_blueteam\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d", -    client->pers.netname, team, model, model, redTeam, blueTeam, c1, c2, -    client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask, teamLeader); - -  trap_SetConfigstring( CS_PLAYERS + clientNum, s ); - -  /*G_LogPrintf( "ClientUserinfoChanged: %i %s\n", clientNum, s );*/ -} - - -/* -=========== -ClientConnect - -Called when a player begins connecting to the server. -Called again for every map change or tournement restart. - -The session information will be valid after exit. - -Return NULL if the client should be allowed, otherwise return -a string with the reason for denial. - -Otherwise, the client will be sent the current gamestate -and will eventually get to ClientBegin. - -firstTime will be qtrue the very first time a client connects -to the server machine, but qfalse on map changes and tournement -restarts. -============ -*/ -char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) -{ -  char      *value; -  gclient_t *client; -  char      userinfo[ MAX_INFO_STRING ]; -  gentity_t *ent; - -  ent = &g_entities[ clientNum ]; - -  trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) ); - -  // IP filtering -  // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=500 -  // recommanding PB based IP / GUID banning, the builtin system is pretty limited -  // check to see if they are on the banned IP list -  value = Info_ValueForKey( userinfo, "ip" ); -  if( G_FilterPacket( value ) ) -    return "You are banned from this server."; - -  // check for a password -  value = Info_ValueForKey( userinfo, "password" ); - -  if( g_password.string[ 0 ] && Q_stricmp( g_password.string, "none" ) && -      strcmp( g_password.string, value ) != 0 ) -    return "Invalid password"; - -  // they can connect -  ent->client = level.clients + clientNum; -  client = ent->client; - -  memset( client, 0, sizeof(*client) ); - -  client->pers.connected = CON_CONNECTING; - -  // read or initialize the session data -  if( firstTime || level.newSession ) -    G_InitSessionData( client, userinfo ); - -  G_ReadSessionData( client ); - -  // get and distribute relevent paramters -  G_LogPrintf( "ClientConnect: %i\n", clientNum ); -  ClientUserinfoChanged( clientNum ); - -  // don't do the "xxx connected" messages if they were caried over from previous level -  if( firstTime ) -    G_SendCommandFromServer( -1, va( "print \"%s" S_COLOR_WHITE " connected\n\"", client->pers.netname ) ); - -  // count current clients and rank for scoreboard -  CalculateRanks( ); - -  return NULL; -} - -/* -=========== -ClientBegin - -called when a client has finished connecting, and is ready -to be placed into the level.  This will happen every level load, -and on transition between teams, but doesn't happen on respawns -============ -*/ -void ClientBegin( int clientNum ) -{ -  gentity_t *ent; -  gclient_t *client; -  int       flags; - -  ent = g_entities + clientNum; - -  client = level.clients + clientNum; - -  if( ent->r.linked ) -    trap_UnlinkEntity( ent ); - -  G_InitGentity( ent ); -  ent->touch = 0; -  ent->pain = 0; -  ent->client = client; - -  client->pers.connected = CON_CONNECTED; -  client->pers.enterTime = level.time; -  client->pers.teamState.state = TEAM_BEGIN; - -  // save eflags around this, because changing teams will -  // cause this to happen with a valid entity, and we -  // want to make sure the teleport bit is set right -  // so the viewpoint doesn't interpolate through the -  // world to the new position -  flags = client->ps.eFlags; -  memset( &client->ps, 0, sizeof( client->ps ) ); -  client->ps.eFlags = flags; - -  // locate ent at a spawn point - -  ClientSpawn( ent, NULL, NULL, NULL ); - -  G_InitCommandQueue( clientNum ); - -  G_SendCommandFromServer( -1, va( "print \"%s" S_COLOR_WHITE " entered the game\n\"", client->pers.netname ) ); - -  // request the clients PTR code -  G_SendCommandFromServer( ent - g_entities, "ptrcrequest" ); - -  G_LogPrintf( "ClientBegin: %i\n", clientNum ); - -  // count current clients and rank for scoreboard -  CalculateRanks( ); -} - -/* -=========== -ClientSpawn - -Called every time a client is placed fresh in the world: -after the first ClientBegin, and after each respawn -Initializes all non-persistant parts of playerState -============ -*/ -void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles ) -{ -  int                 index; -  vec3_t              spawn_origin, spawn_angles; -  gclient_t           *client; -  int                 i; -  clientPersistant_t  saved; -  clientSession_t     savedSess; -  int                 persistant[ MAX_PERSISTANT ]; -  gentity_t           *spawnPoint = NULL; -  int                 flags; -  int                 savedPing; -  int                 teamLocal; -  int                 eventSequence; -  char                userinfo[ MAX_INFO_STRING ]; -  vec3_t              up = { 0.0f, 0.0f, 1.0f }; -  int                 maxAmmo, maxClips; -  weapon_t            weapon; - - -  index = ent - g_entities; -  client = ent->client; - -  teamLocal = client->pers.teamSelection; - -  //TA: only start client if chosen a class and joined a team -  if( client->pers.classSelection == PCL_NONE && teamLocal == PTE_NONE ) -  { -    client->sess.sessionTeam = TEAM_SPECTATOR; -    client->sess.spectatorState = SPECTATOR_FREE; -  } -  else if( client->pers.classSelection == PCL_NONE ) -  { -    client->sess.sessionTeam = TEAM_SPECTATOR; -    client->sess.spectatorState = SPECTATOR_LOCKED; -  } - -  if( origin != NULL ) -    VectorCopy( origin, spawn_origin ); - -  if( angles != NULL ) -    VectorCopy( angles, spawn_angles ); - -  // find a spawn point -  // do it before setting health back up, so farthest -  // ranging doesn't count this client -  if( client->sess.sessionTeam == TEAM_SPECTATOR ) -  { -    if( teamLocal == PTE_NONE ) -      spawnPoint = SelectSpectatorSpawnPoint( spawn_origin, spawn_angles ); -    else if( teamLocal == PTE_ALIENS ) -      spawnPoint = SelectAlienLockSpawnPoint( spawn_origin, spawn_angles ); -    else if( teamLocal == PTE_HUMANS ) -      spawnPoint = SelectHumanLockSpawnPoint( spawn_origin, spawn_angles ); -  } -  else -  { -    if( spawn == NULL ) -    { -      G_Error( "ClientSpawn: spawn is NULL\n" ); -      return; -    } - -    spawnPoint = spawn; - -    if( ent != spawn ) -    { -      //start spawn animation on spawnPoint -      G_setBuildableAnim( spawnPoint, BANIM_SPAWN1, qtrue ); - -      if( spawnPoint->biteam == PTE_ALIENS ) -        spawnPoint->clientSpawnTime = ALIEN_SPAWN_REPEAT_TIME; -      else if( spawnPoint->biteam == PTE_HUMANS ) -        spawnPoint->clientSpawnTime = HUMAN_SPAWN_REPEAT_TIME; -    } -  } -  client->pers.teamState.state = TEAM_ACTIVE; - -  // toggle the teleport bit so the client knows to not lerp -  flags = ent->client->ps.eFlags & ( EF_TELEPORT_BIT | EF_VOTED | EF_TEAMVOTED ); -  flags ^= EF_TELEPORT_BIT; - -  // clear everything but the persistant data - -  saved = client->pers; -  savedSess = client->sess; -  savedPing = client->ps.ping; - -  for( i = 0; i < MAX_PERSISTANT; i++ ) -    persistant[ i ] = client->ps.persistant[ i ]; - -  eventSequence = client->ps.eventSequence; -  memset( client, 0, sizeof( *client ) ); - -  client->pers = saved; -  client->sess = savedSess; -  client->ps.ping = savedPing; -  client->lastkilled_client = -1; - -  for( i = 0; i < MAX_PERSISTANT; i++ ) -    client->ps.persistant[ i ] = persistant[ i ]; - -  client->ps.eventSequence = eventSequence; - -  // increment the spawncount so the client will detect the respawn -  client->ps.persistant[ PERS_SPAWN_COUNT ]++; -  client->ps.persistant[ PERS_TEAM ] = client->sess.sessionTeam; - -  client->airOutTime = level.time + 12000; - -  trap_GetUserinfo( index, userinfo, sizeof( userinfo ) ); -  client->ps.eFlags = flags; - -  //Com_Printf( "ent->client->pers->pclass = %i\n", ent->client->pers.classSelection ); - -  ent->s.groundEntityNum = ENTITYNUM_NONE; -  ent->client = &level.clients[ index ]; -  ent->takedamage = qtrue; -  ent->inuse = qtrue; -  ent->classname = "player"; -  ent->r.contents = CONTENTS_BODY; -  ent->clipmask = MASK_PLAYERSOLID; -  ent->die = player_die; -  ent->waterlevel = 0; -  ent->watertype = 0; -  ent->flags = 0; - -  //TA: calculate each client's acceleration -  ent->evaluateAcceleration = qtrue; - -  client->ps.stats[ STAT_WEAPONS ] = 0; -  client->ps.stats[ STAT_WEAPONS2 ] = 0; -  client->ps.stats[ STAT_SLOTS ] = 0; - -  client->ps.eFlags = flags; -  client->ps.clientNum = index; - -  BG_FindBBoxForClass( ent->client->pers.classSelection, ent->r.mins, ent->r.maxs, NULL, NULL, NULL ); - -  if( client->sess.sessionTeam != TEAM_SPECTATOR ) -    client->pers.maxHealth = client->ps.stats[ STAT_MAX_HEALTH ] = -      BG_FindHealthForClass( ent->client->pers.classSelection ); -  else -    client->pers.maxHealth = client->ps.stats[ STAT_MAX_HEALTH ] = 100; - -  // clear entity values -  if( ent->client->pers.classSelection == PCL_HUMAN ) -  { -    BG_AddWeaponToInventory( WP_BLASTER, client->ps.stats ); -    BG_AddUpgradeToInventory( UP_MEDKIT, client->ps.stats ); -    weapon = client->pers.humanItemSelection; -  } -  else if( client->sess.sessionTeam != TEAM_SPECTATOR ) -    weapon = BG_FindStartWeaponForClass( ent->client->pers.classSelection ); -  else -    weapon = WP_NONE; - -  BG_FindAmmoForWeapon( weapon, &maxAmmo, &maxClips ); -  BG_AddWeaponToInventory( weapon, client->ps.stats ); -  BG_PackAmmoArray( weapon, client->ps.ammo, client->ps.powerups, maxAmmo, maxClips ); - -  ent->client->ps.stats[ STAT_PCLASS ] = ent->client->pers.classSelection; -  ent->client->ps.stats[ STAT_PTEAM ] = ent->client->pers.teamSelection; - -  ent->client->ps.stats[ STAT_BUILDABLE ] = BA_NONE; -  ent->client->ps.stats[ STAT_STATE ] = 0; -  VectorSet( ent->client->ps.grapplePoint, 0.0f, 0.0f, 1.0f ); - -  // health will count down towards max_health -  ent->health = client->ps.stats[ STAT_HEALTH ] = client->ps.stats[ STAT_MAX_HEALTH ]; //* 1.25; - -  //if evolving scale health -  if( ent == spawn ) -  { -    ent->health *= ent->client->pers.evolveHealthFraction; -    client->ps.stats[ STAT_HEALTH ] *= ent->client->pers.evolveHealthFraction; -  } - -  //clear the credits array -  for( i = 0; i < MAX_CLIENTS; i++ ) -    ent->credits[ i ] = 0; - -  client->ps.stats[ STAT_STAMINA ] = MAX_STAMINA; - -  G_SetOrigin( ent, spawn_origin ); -  VectorCopy( spawn_origin, client->ps.origin ); - -#define UP_VEL  150.0f -#define F_VEL   50.0f - -  //give aliens some spawn velocity -  if( client->sess.sessionTeam != TEAM_SPECTATOR && -      client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -  { -    if( ent == spawn ) -    { -      //evolution particle system -      G_AddPredictableEvent( ent, EV_ALIEN_EVOLVE, DirToByte( up ) ); -    } -    else -    { -      spawn_angles[ YAW ] += 180.0f; -      AngleNormalize360( spawn_angles[ YAW ] ); - -      if( spawnPoint->s.origin2[ 2 ] > 0.0f ) -      { -        vec3_t  forward, dir; - -        AngleVectors( spawn_angles, forward, NULL, NULL ); -        VectorScale( forward, F_VEL, forward ); -        VectorAdd( spawnPoint->s.origin2, forward, dir ); -        VectorNormalize( dir ); - -        VectorScale( dir, UP_VEL, client->ps.velocity ); -      } - -      G_AddPredictableEvent( ent, EV_PLAYER_RESPAWN, 0 ); -    } -  } -  else if( client->sess.sessionTeam != TEAM_SPECTATOR && -           client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -  { -    spawn_angles[ YAW ] += 180.0f; -    AngleNormalize360( spawn_angles[ YAW ] ); -  } - -  // the respawned flag will be cleared after the attack and jump keys come up -  client->ps.pm_flags |= PMF_RESPAWNED; - -  trap_GetUsercmd( client - level.clients, &ent->client->pers.cmd ); -  SetClientViewAngle( ent, spawn_angles ); - -  if( !( client->sess.sessionTeam == TEAM_SPECTATOR ) ) -  { -    /*G_KillBox( ent );*/ //blame this if a newly spawned client gets stuck in another -    trap_LinkEntity( ent ); - -    // force the base weapon up -    client->ps.weapon = WP_NONE; -    client->ps.weaponstate = WEAPON_READY; -  } - -  // don't allow full run speed for a bit -  client->ps.pm_flags |= PMF_TIME_KNOCKBACK; -  client->ps.pm_time = 100; - -  client->respawnTime = level.time; -  client->lastKillTime = level.time; - -  client->inactivityTime = level.time + g_inactivity.integer * 1000; -  client->latched_buttons = 0; - -  // set default animations -  client->ps.torsoAnim = TORSO_STAND; -  client->ps.legsAnim = LEGS_IDLE; - -  if( level.intermissiontime ) -    MoveClientToIntermission( ent ); -  else -  { -    // fire the targets of the spawn point -    if( !spawn ) -      G_UseTargets( spawnPoint, ent ); - -    // select the highest weapon number available, after any -    // spawn given items have fired -    client->ps.weapon = 1; - -    for( i = WP_NUM_WEAPONS - 1; i > 0 ; i-- ) -    { -      if( BG_InventoryContainsWeapon( i, client->ps.stats ) ) -      { -        client->ps.weapon = i; -        break; -      } -    } -  } - -  // run a client frame to drop exactly to the floor, -  // initialize animations and other things -  client->ps.commandTime = level.time - 100; -  ent->client->pers.cmd.serverTime = level.time; -  ClientThink( ent-g_entities ); - -  // positively link the client, even if the command times are weird -  if( client->sess.sessionTeam != TEAM_SPECTATOR ) -  { -    BG_PlayerStateToEntityState( &client->ps, &ent->s, qtrue ); -    VectorCopy( ent->client->ps.origin, ent->r.currentOrigin ); -    trap_LinkEntity( ent ); -  } - -  //TA: must do this here so the number of active clients is calculated -  CalculateRanks( ); - -  // run the presend to set anything else -  ClientEndFrame( ent ); - -  // clear entity state values -  BG_PlayerStateToEntityState( &client->ps, &ent->s, qtrue ); -} - - -/* -=========== -ClientDisconnect - -Called when a player drops from the server. -Will not be called between levels. - -This should NOT be called directly by any game logic, -call trap_DropClient(), which will call this and do -server system housekeeping. -============ -*/ -void ClientDisconnect( int clientNum ) -{ -  gentity_t *ent; -  gentity_t *tent; -  int       i; - -  ent = g_entities + clientNum; - -  if( !ent->client ) -    return; - -  // stop any following clients -  for( i = 0; i < level.maxclients; i++ ) -  { -    if( level.clients[ i ].sess.sessionTeam == TEAM_SPECTATOR && -        level.clients[ i ].sess.spectatorState == SPECTATOR_FOLLOW && -        level.clients[ i ].sess.spectatorClient == clientNum ) -    { -      if( !G_FollowNewClient( &g_entities[ i ], 1 ) ) -        G_StopFollowing( &g_entities[ i ] ); -    } -  } - -  // send effect if they were completely connected -  if( ent->client->pers.connected == CON_CONNECTED && -      ent->client->sess.sessionTeam != TEAM_SPECTATOR ) -  { -    tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_OUT ); -    tent->s.clientNum = ent->s.clientNum; -  } - -  G_LogPrintf( "ClientDisconnect: %i\n", clientNum ); - -  trap_UnlinkEntity( ent ); -  ent->s.modelindex = 0; -  ent->inuse = qfalse; -  ent->classname = "disconnected"; -  ent->client->pers.connected = CON_DISCONNECTED; -  ent->client->ps.persistant[ PERS_TEAM ] = TEAM_FREE; -  ent->client->sess.sessionTeam = TEAM_FREE; - -  trap_SetConfigstring( CS_PLAYERS + clientNum, ""); - -  CalculateRanks( ); -} diff --git a/mod/src/game/g_cmds.c b/mod/src/game/g_cmds.c deleted file mode 100644 index 819fbb75..00000000 --- a/mod/src/game/g_cmds.c +++ /dev/null @@ -1,2305 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -/* -================== -G_SanitiseName - -Remove case and control characters from a player name -================== -*/ -void G_SanitiseName( char *in, char *out ) -{ -  while( *in ) -  { -    if( *in == 27 ) -    { -      in += 2;    // skip color code -      continue; -    } - -    if( *in < 32 ) -    { -      in++; -      continue; -    } - -    *out++ = tolower( *in++ ); -  } - -  *out = 0; -} - -/* -================== -G_ClientNumberFromString - -Returns a player number for either a number or name string -Returns -1 if invalid -================== -*/ -int G_ClientNumberFromString( gentity_t *to, char *s ) -{ -  gclient_t *cl; -  int       idnum; -  char      s2[ MAX_STRING_CHARS ]; -  char      n2[ MAX_STRING_CHARS ]; - -  // numeric values are just slot numbers -  if( s[ 0 ] >= '0' && s[ 0 ] <= '9' ) -  { -    idnum = atoi( s ); - -    if( idnum < 0 || idnum >= level.maxclients ) -    { -      G_SendCommandFromServer( to - g_entities, va( "print \"Bad client slot: %i\n\"", idnum ) ); -      return -1; -    } - -    cl = &level.clients[ idnum ]; - -    if( cl->pers.connected != CON_CONNECTED ) -    { -      G_SendCommandFromServer( to - g_entities, va( "print \"Client %i is not active\n\"", idnum ) ); -      return -1; -    } - -    return idnum; -  } - -  // check for a name match -  G_SanitiseName( s, s2 ); - -  for( idnum = 0, cl = level.clients; idnum < level.maxclients; idnum++, cl++ ) -  { -    if( cl->pers.connected != CON_CONNECTED ) -      continue; - -    G_SanitiseName( cl->pers.netname, n2 ); - -    if( !strcmp( n2, s2 ) ) -      return idnum; -  } - -  G_SendCommandFromServer( to - g_entities, va( "print \"User %s is not on the server\n\"", s ) ); -  return -1; -} - -/* -================== -ScoreboardMessage - -================== -*/ -void ScoreboardMessage( gentity_t *ent ) -{ -  char      entry[ 1024 ]; -  char      string[ 1400 ]; -  int       stringlength; -  int       i, j; -  gclient_t *cl; -  int       numSorted; -  weapon_t  weapon = WP_NONE; -  upgrade_t upgrade = UP_NONE; - -  // send the latest information on all clients -  string[ 0 ] = 0; -  stringlength = 0; - -  numSorted = level.numConnectedClients; - -  for( i = 0; i < numSorted; i++ ) -  { -    int   ping; - -    cl = &level.clients[ level.sortedClients[ i ] ]; - -    if( cl->pers.connected == CON_CONNECTING ) -      ping = -1; -    else -      ping = cl->ps.ping < 999 ? cl->ps.ping : 999; - -    if( cl->ps.stats[ STAT_HEALTH ] > 0 ) -    { -      weapon = cl->ps.weapon; - -      if( BG_InventoryContainsUpgrade( UP_BATTLESUIT, cl->ps.stats ) ) -        upgrade = UP_BATTLESUIT; -      else if( BG_InventoryContainsUpgrade( UP_JETPACK, cl->ps.stats ) ) -        upgrade = UP_JETPACK; -      else if( BG_InventoryContainsUpgrade( UP_BATTPACK, cl->ps.stats ) ) -        upgrade = UP_BATTPACK; -      else if( BG_InventoryContainsUpgrade( UP_HELMET, cl->ps.stats ) ) -        upgrade = UP_HELMET; -      else if( BG_InventoryContainsUpgrade( UP_LIGHTARMOUR, cl->ps.stats ) ) -        upgrade = UP_LIGHTARMOUR; -      else -        upgrade = UP_NONE; -    } -    else -    { -      weapon = WP_NONE; -      upgrade = UP_NONE; -    } - -    Com_sprintf( entry, sizeof( entry ), -      " %d %d %d %d %d %d", level.sortedClients[ i ], cl->ps.persistant[ PERS_SCORE ], -      ping, ( level.time - cl->pers.enterTime ) / 60000, weapon, upgrade ); - -    j = strlen( entry ); - -    if( stringlength + j > 1024 ) -      break; - -    strcpy( string + stringlength, entry ); -    stringlength += j; -  } - -  G_SendCommandFromServer( ent-g_entities, va( "scores %i %i %i%s", i, -    level.alienKills, level.humanKills, string ) ); -} - - -/* -================== -Cmd_Score_f - -Request current scoreboard information -================== -*/ -void Cmd_Score_f( gentity_t *ent ) -{ -  ScoreboardMessage( ent ); -} - - - -/* -================== -CheatsOk -================== -*/ -qboolean CheatsOk( gentity_t *ent ) -{ -  if( !g_cheats.integer ) -  { -    G_SendCommandFromServer( ent-g_entities, va( "print \"Cheats are not enabled on this server\n\"" ) ); -    return qfalse; -  } - -  if( ent->health <= 0 ) -  { -    G_SendCommandFromServer( ent-g_entities, va( "print \"You must be alive to use this command\n\"" ) ); -    return qfalse; -  } - -  return qtrue; -} - - -/* -================== -ConcatArgs -================== -*/ -char *ConcatArgs( int start ) -{ -  int         i, c, tlen; -  static char line[ MAX_STRING_CHARS ]; -  int         len; -  char        arg[ MAX_STRING_CHARS ]; - -  len = 0; -  c = trap_Argc( ); - -  for( i = start; i < c; i++ ) -  { -    trap_Argv( i, arg, sizeof( arg ) ); -    tlen = strlen( arg ); - -    if( len + tlen >= MAX_STRING_CHARS - 1 ) -      break; - -    memcpy( line + len, arg, tlen ); -    len += tlen; - -    if( i != c - 1 ) -    { -      line[ len ] = ' '; -      len++; -    } -  } - -  line[ len ] = 0; - -  return line; -} - - -/* -================== -Cmd_Give_f - -Give items to a client -================== -*/ -void Cmd_Give_f( gentity_t *ent ) -{ -  char      *name; -  qboolean  give_all; - -  if( !CheatsOk( ent ) ) -    return; - -  name = ConcatArgs( 1 ); - -  if( Q_stricmp( name, "all" ) == 0 ) -    give_all = qtrue; -  else -    give_all = qfalse; - -  if( give_all || Q_stricmp( name, "health" ) == 0 ) -  { -    ent->health = ent->client->ps.stats[ STAT_MAX_HEALTH ]; -    if( !give_all ) -      return; -  } - -  if( give_all || Q_stricmpn( name, "funds", 5 ) == 0 ) -  { -    int credits = atoi( name + 6 ); - -    if( !credits ) -      G_AddCreditToClient( ent->client, 1, qtrue ); -    else -      G_AddCreditToClient( ent->client, credits, qtrue ); - -    if( !give_all ) -      return; -  } -} - - -/* -================== -Cmd_God_f - -Sets client to godmode - -argv(0) god -================== -*/ -void Cmd_God_f( gentity_t *ent ) -{ -  char  *msg; - -  if( !CheatsOk( ent ) ) -    return; - -  ent->flags ^= FL_GODMODE; - -  if( !( ent->flags & FL_GODMODE ) ) -    msg = "godmode OFF\n"; -  else -    msg = "godmode ON\n"; - -  G_SendCommandFromServer( ent - g_entities, va( "print \"%s\"", msg ) ); -} - - -/* -================== -Cmd_Notarget_f - -Sets client to notarget - -argv(0) notarget -================== -*/ -void Cmd_Notarget_f( gentity_t *ent ) -{ -  char  *msg; - -  if( !CheatsOk( ent ) ) -    return; - -  ent->flags ^= FL_NOTARGET; - -  if( !( ent->flags & FL_NOTARGET ) ) -    msg = "notarget OFF\n"; -  else -    msg = "notarget ON\n"; - -  G_SendCommandFromServer( ent - g_entities, va( "print \"%s\"", msg ) ); -} - - -/* -================== -Cmd_Noclip_f - -argv(0) noclip -================== -*/ -void Cmd_Noclip_f( gentity_t *ent ) -{ -  char  *msg; - -  if( !CheatsOk( ent ) ) -    return; - -  if( ent->client->noclip ) -    msg = "noclip OFF\n"; -  else -    msg = "noclip ON\n"; - -  ent->client->noclip = !ent->client->noclip; - -  G_SendCommandFromServer( ent - g_entities, va( "print \"%s\"", msg ) ); -} - - -/* -================== -Cmd_LevelShot_f - -This is just to help generate the level pictures -for the menus.  It goes to the intermission immediately -and sends over a command to the client to resize the view, -hide the scoreboard, and take a special screenshot -================== -*/ -void Cmd_LevelShot_f( gentity_t *ent ) -{ -  if( !CheatsOk( ent ) ) -    return; - -  BeginIntermission( ); -  G_SendCommandFromServer( ent - g_entities, "clientLevelShot" ); -} - -/* -================= -Cmd_Kill_f -================= -*/ -void Cmd_Kill_f( gentity_t *ent ) -{ -  if( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) -    return; - -  if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_NONE ) -    return; - -  if( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) -    return; - -  if( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Leave the hovel first (use your destroy key)\n\"" ); -    return; -  } - -  if( ent->health <= 0 ) -    return; - -  if( g_cheats.integer ) -  { -    ent->flags &= ~FL_GODMODE; -    ent->client->ps.stats[ STAT_HEALTH ] = ent->health = 0; -    player_die( ent, ent, ent, 100000, MOD_SUICIDE ); -  } -  else -  { -    if( ent->suicideTime == 0 ) -    { -      G_SendCommandFromServer( ent-g_entities, "print \"You will suicide in 20 seconds\n\"" ); -      ent->suicideTime = level.time + 20000; -    } -    else if( ent->suicideTime > level.time ) -    { -      G_SendCommandFromServer( ent-g_entities, "print \"Suicide cancelled\n\"" ); -      ent->suicideTime = 0; -    } -  } -} - -/* -================= -G_ChangeTeam -================= -*/ -void G_ChangeTeam( gentity_t *ent, pTeam_t newTeam ) -{ -  pTeam_t oldTeam = ent->client->pers.teamSelection; - -  ent->client->pers.teamSelection = newTeam; - -  if( oldTeam != newTeam ) -  { -    //if the client is in a queue make sure they are removed from it before changing -    if( oldTeam == PTE_ALIENS ) -      G_RemoveFromSpawnQueue( &level.alienSpawnQueue, ent->client->ps.clientNum ); -    else if( oldTeam == PTE_HUMANS ) -      G_RemoveFromSpawnQueue( &level.humanSpawnQueue, ent->client->ps.clientNum ); - -    level.bankCredits[ ent->client->ps.clientNum ] = 0; -    ent->client->ps.persistant[ PERS_CREDIT ] = 0; -    ent->client->ps.persistant[ PERS_SCORE ] = 0; -    ent->client->pers.classSelection = PCL_NONE; -    ClientSpawn( ent, NULL, NULL, NULL ); -  } - -  ent->client->pers.joinedATeam = qtrue; - -  //update ClientInfo -  ClientUserinfoChanged( ent->client->ps.clientNum ); -} - -/* -================= -Cmd_Team_f -================= -*/ -void Cmd_Team_f( gentity_t *ent ) -{ -  pTeam_t team; -  char    s[ MAX_TOKEN_CHARS ]; - -  trap_Argv( 1, s, sizeof( s ) ); - -  if( !strlen( s ) ) -  { -    G_SendCommandFromServer( ent-g_entities, va("print \"team: %i\n\"", ent->client->pers.teamSelection ) ); -    return; -  } - -  if( !Q_stricmp( s, "spectate" ) ) -    team = PTE_NONE; -  else if( !Q_stricmp( s, "aliens" ) ) -  { -    if( g_teamForceBalance.integer && level.numAlienClients > level.numHumanClients ) -    { -      G_TriggerMenu( ent->client->ps.clientNum, MN_A_TEAMFULL ); -      return; -    } - -    team = PTE_ALIENS; -  } -  else if( !Q_stricmp( s, "humans" ) ) -  { -    if( g_teamForceBalance.integer && level.numHumanClients > level.numAlienClients ) -    { -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_TEAMFULL ); -      return; -    } - -    team = PTE_HUMANS; -  } -  else if( !Q_stricmp( s, "auto" ) ) -  { -    if( level.numHumanClients > level.numAlienClients ) -      team = PTE_ALIENS; -    else if( level.numHumanClients < level.numAlienClients ) -      team = PTE_HUMANS; -    else -      team = PTE_ALIENS + ( rand( ) % 2 ); -  } -  else -  { -    G_SendCommandFromServer( ent-g_entities, va( "print \"Unknown team: %s\n\"", s ) ); -    return; -  } - -  G_ChangeTeam( ent, team ); - -  if( team == PTE_ALIENS ) -    G_SendCommandFromServer( -1, va( "print \"%s" S_COLOR_WHITE " joined the aliens\n\"", ent->client->pers.netname ) ); -  else if( team == PTE_HUMANS ) -    G_SendCommandFromServer( -1, va( "print \"%s" S_COLOR_WHITE " joined the humans\n\"", ent->client->pers.netname ) ); -} - - -/* -================== -G_Say -================== -*/ -static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, const char *name, const char *message ) -{ -  if( !other ) -    return; - -  if( !other->inuse ) -    return; - -  if( !other->client ) -    return; - -  if( other->client->pers.connected != CON_CONNECTED ) -    return; - -  if( mode == SAY_TEAM && !OnSameTeam( ent, other ) ) -    return; - -  G_SendCommandFromServer( other-g_entities, va( "%s \"%s%c%c%s\"", -    mode == SAY_TEAM ? "tchat" : "chat", -    name, Q_COLOR_ESCAPE, color, message ) ); -} - -#define EC    "\x19" - -void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chatText ) -{ -  int     j; -  gentity_t *other; -  int     color; -  char    name[ 64 ]; -  // don't let text be too long for malicious reasons -  char    text[ MAX_SAY_TEXT ]; -  char    location[ 64 ]; - -  switch( mode ) -  { -    default: -    case SAY_ALL: -      G_LogPrintf( "say: %s: %s\n", ent->client->pers.netname, chatText ); -      Com_sprintf( name, sizeof( name ), "%s%c%c"EC": ", ent->client->pers.netname, -                   Q_COLOR_ESCAPE, COLOR_WHITE ); -      color = COLOR_GREEN; -      break; - -    case SAY_TEAM: -      G_LogPrintf( "sayteam: %s: %s\n", ent->client->pers.netname, chatText ); -      if( Team_GetLocationMsg( ent, location, sizeof( location ) ) ) -        Com_sprintf( name, sizeof( name ), EC"(%s%c%c"EC") (%s)"EC": ", -          ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE, location ); -      else -        Com_sprintf( name, sizeof( name ), EC"(%s%c%c"EC")"EC": ", -          ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); -      color = COLOR_CYAN; -      break; - -    case SAY_TELL: -      if( target && -          target->client->ps.stats[ STAT_PTEAM ] == ent->client->ps.stats[ STAT_PTEAM ] && -          Team_GetLocationMsg( ent, location, sizeof( location ) ) ) -        Com_sprintf( name, sizeof( name ), EC"[%s%c%c"EC"] (%s)"EC": ", -          ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE, location ); -      else -        Com_sprintf( name, sizeof( name ), EC"[%s%c%c"EC"]"EC": ", -          ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); -      color = COLOR_MAGENTA; -      break; -  } - -  Q_strncpyz( text, chatText, sizeof( text ) ); - -  if( target ) -  { -    G_SayTo( ent, target, mode, color, name, text ); -    return; -  } - -  // echo the text to the console -  if( g_dedicated.integer ) -    G_Printf( "%s%s\n", name, text); - -  // send it to all the apropriate clients -  for( j = 0; j < level.maxclients; j++ ) -  { -    other = &g_entities[ j ]; -    G_SayTo( ent, other, mode, color, name, text ); -  } -} - - -/* -================== -Cmd_Say_f -================== -*/ -static void Cmd_Say_f( gentity_t *ent, int mode, qboolean arg0 ) -{ -  char    *p; - -  if( trap_Argc( ) < 2 && !arg0 ) -    return; - -  if( arg0 ) -    p = ConcatArgs( 0 ); -  else -    p = ConcatArgs( 1 ); - -  G_Say( ent, NULL, mode, p ); -} - -/* -================== -Cmd_Tell_f -================== -*/ -static void Cmd_Tell_f( gentity_t *ent ) -{ -  int     targetNum; -  gentity_t *target; -  char    *p; -  char    arg[MAX_TOKEN_CHARS]; - -  if( trap_Argc( ) < 2 ) -    return; - -  trap_Argv( 1, arg, sizeof( arg ) ); -  targetNum = atoi( arg ); - -  if( targetNum < 0 || targetNum >= level.maxclients ) -    return; - -  target = &g_entities[ targetNum ]; -  if( !target || !target->inuse || !target->client ) -    return; - -  p = ConcatArgs( 2 ); - -  G_LogPrintf( "tell: %s to %s: %s\n", ent->client->pers.netname, target->client->pers.netname, p ); -  G_Say( ent, target, SAY_TELL, p ); -  // don't tell to the player self if it was already directed to this player -  // also don't send the chat back to a bot -  if( ent != target && !( ent->r.svFlags & SVF_BOT ) ) -    G_Say( ent, ent, SAY_TELL, p ); -} - -/* -================== -Cmd_Where_f -================== -*/ -void Cmd_Where_f( gentity_t *ent ) -{ -  G_SendCommandFromServer( ent-g_entities, va( "print \"%s\n\"", vtos( ent->s.origin ) ) ); -} - -/* -================== -Cmd_CallVote_f -================== -*/ -void Cmd_CallVote_f( gentity_t *ent ) -{ -  int   i; -  char  arg1[ MAX_STRING_TOKENS ]; -  char  arg2[ MAX_STRING_TOKENS ]; - -  if( !g_allowVote.integer ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Voting not allowed here\n\"" ); -    return; -  } - -  if( level.voteTime ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"A vote is already in progress\n\"" ); -    return; -  } - -  if( ent->client->pers.voteCount >= MAX_VOTE_COUNT ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"You have called the maximum number of votes\n\"" ); -    return; -  } - -  if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_NONE ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Not allowed to call a vote as spectator\n\"" ); -    return; -  } - -  // make sure it is a valid command to vote on -  trap_Argv( 1, arg1, sizeof( arg1 ) ); -  trap_Argv( 2, arg2, sizeof( arg2 ) ); - -  if( strchr( arg1, ';' ) || strchr( arg2, ';' ) ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Invalid vote string\n\"" ); -    return; -  } - -  if( !Q_stricmp( arg1, "map_restart" ) ) { } -  else if( !Q_stricmp( arg1, "nextmap" ) ) { } -  else if( !Q_stricmp( arg1, "map" ) ) { } -  else if( !Q_stricmp( arg1, "kick" ) ) { } -  else if( !Q_stricmp( arg1, "clientkick" ) ) { } -  else if( !Q_stricmp( arg1, "timelimit" ) ) { } -  else -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Invalid vote string\n\"" ); -    G_SendCommandFromServer( ent-g_entities, "print \"Vote commands are: map_restart, nextmap, map <mapname>, " -                                            "kick <player>, clientkick <clientnum>, " -                                            "timelimit <time>\n\"" ); -    return; -  } - -  // if there is still a vote to be executed -  if( level.voteExecuteTime ) -  { -    level.voteExecuteTime = 0; -    trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.voteString ) ); -  } - -  if( !Q_stricmp( arg1, "map" ) ) -  { -    // special case for map changes, we want to reset the nextmap setting -    // this allows a player to change maps, but not upset the map rotation -    char  s[ MAX_STRING_CHARS ]; - -    trap_Cvar_VariableStringBuffer( "nextmap", s, sizeof( s ) ); - -    if( *s ) -      Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s; set nextmap \"%s\"", arg1, arg2, s ); -    else -      Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s", arg1, arg2 ); - -    Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString ); -  } -  else if( !Q_stricmp( arg1, "nextmap" ) ) -  { -    char  s[ MAX_STRING_CHARS ]; - -    trap_Cvar_VariableStringBuffer( "nextmap", s, sizeof( s ) ); - -    if( !*s ) -    { -      G_SendCommandFromServer( ent-g_entities, "print \"nextmap not set\n\"" ); -      return; -    } - -    Com_sprintf( level.voteString, sizeof( level.voteString ), "vstr nextmap" ); -    Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString ); -  } -  else -  { -    Com_sprintf( level.voteString, sizeof( level.voteString ), "%s \"%s\"", arg1, arg2 ); -    Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString ); -  } - -  G_SendCommandFromServer( -1, va( "print \"%s called a vote\n\"", ent->client->pers.netname ) ); - -  // start the voting, the caller autoamtically votes yes -  level.voteTime = level.time; -  level.voteYes = 1; -  level.voteNo = 0; - -  for( i = 0 ; i < level.maxclients ; i++ ) -    level.clients[i].ps.eFlags &= ~EF_VOTED; - -  ent->client->ps.eFlags |= EF_VOTED; - -  trap_SetConfigstring( CS_VOTE_TIME, va( "%i", level.voteTime ) ); -  trap_SetConfigstring( CS_VOTE_STRING, level.voteDisplayString ); -  trap_SetConfigstring( CS_VOTE_YES, va( "%i", level.voteYes ) ); -  trap_SetConfigstring( CS_VOTE_NO, va( "%i", level.voteNo ) ); -} - -/* -================== -Cmd_Vote_f -================== -*/ -void Cmd_Vote_f( gentity_t *ent ) -{ -  char msg[ 64 ]; - -  if( !level.voteTime ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"No vote in progress\n\"" ); -    return; -  } - -  if( ent->client->ps.eFlags & EF_VOTED ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Vote already cast\n\"" ); -    return; -  } - -  if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_NONE ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Not allowed to vote as spectator\n\"" ); -    return; -  } - -  G_SendCommandFromServer( ent-g_entities, "print \"Vote cast\n\"" ); - -  ent->client->ps.eFlags |= EF_VOTED; - -  trap_Argv( 1, msg, sizeof( msg ) ); - -  if( msg[ 0 ] == 'y' || msg[ 1 ] == 'Y' || msg[ 1 ] == '1' ) -  { -    level.voteYes++; -    trap_SetConfigstring( CS_VOTE_YES, va( "%i", level.voteYes ) ); -  } -  else -  { -    level.voteNo++; -    trap_SetConfigstring( CS_VOTE_NO, va( "%i", level.voteNo ) ); -  } - -  // a majority will be determined in G_CheckVote, which will also account -  // for players entering or leaving -} - -/* -================== -Cmd_CallTeamVote_f -================== -*/ -void Cmd_CallTeamVote_f( gentity_t *ent ) -{ -  int   i, team, cs_offset; -  char  arg1[ MAX_STRING_TOKENS ]; -  char  arg2[ MAX_STRING_TOKENS ]; - -  team = ent->client->ps.stats[ STAT_PTEAM ]; - -  if( team == PTE_HUMANS ) -    cs_offset = 0; -  else if( team == PTE_ALIENS ) -    cs_offset = 1; -  else -    return; - -  if( !g_allowVote.integer ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Voting not allowed here\n\"" ); -    return; -  } - -  if( level.teamVoteTime[ cs_offset ] ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"A team vote is already in progress\n\"" ); -    return; -  } - -  if( ent->client->pers.teamVoteCount >= MAX_VOTE_COUNT ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"You have called the maximum number of team votes\n\"" ); -    return; -  } - -  if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_NONE ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Not allowed to call a vote as spectator\n\"" ); -    return; -  } - -  // make sure it is a valid command to vote on -  trap_Argv( 1, arg1, sizeof( arg1 ) ); -  trap_Argv( 2, arg2, sizeof( arg2 ) ); - -  if( strchr( arg1, ';' ) || strchr( arg2, ';' ) ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Invalid team vote string\n\"" ); -    return; -  } - -  if( !Q_stricmp( arg1, "teamkick" ) ) -  { -    char netname[ MAX_NETNAME ], kickee[ MAX_NETNAME ]; - -    Q_strncpyz( kickee, arg2, sizeof( kickee ) ); -    Q_CleanStr( kickee ); - -    for( i = 0; i < level.maxclients; i++ ) -    { -      if( level.clients[ i ].pers.connected == CON_DISCONNECTED ) -        continue; - -      if( level.clients[ i ].ps.stats[ STAT_PTEAM ] != team ) -        continue; - -      Q_strncpyz( netname, level.clients[ i ].pers.netname, sizeof( netname ) ); -      Q_CleanStr( netname ); - -      if( !Q_stricmp( netname, kickee ) ) -        break; -    } - -    if( i >= level.maxclients ) -    { -      G_SendCommandFromServer( ent-g_entities, va( "print \"%s is not a valid player on your team\n\"", arg2 ) ); -      return; -    } -  } -  else -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Invalid vote string\n\"" ); -    G_SendCommandFromServer( ent-g_entities, "print \"Team vote commands are: teamkick <player>\n\"" ); -    return; -  } - -  Com_sprintf( level.teamVoteString[ cs_offset ], -               sizeof( level.teamVoteString[ cs_offset ] ), "kick \"%s\"", arg2 ); - -  for( i = 0 ; i < level.maxclients ; i++ ) -  { -    if( level.clients[ i ].pers.connected == CON_DISCONNECTED ) -      continue; - -    if( level.clients[ i ].ps.stats[ STAT_PTEAM ] == team ) -      G_SendCommandFromServer( i, va("print \"%s called a team vote\n\"", ent->client->pers.netname ) ); -  } - -  // start the voting, the caller autoamtically votes yes -  level.teamVoteTime[ cs_offset ] = level.time; -  level.teamVoteYes[ cs_offset ] = 1; -  level.teamVoteNo[ cs_offset ] = 0; - -  for( i = 0 ; i < level.maxclients ; i++ ) -  { -    if( level.clients[ i ].ps.stats[ STAT_PTEAM ] == team ) -      level.clients[ i ].ps.eFlags &= ~EF_TEAMVOTED; -  } - -  ent->client->ps.eFlags |= EF_TEAMVOTED; - -  trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset, va( "%i", level.teamVoteTime[ cs_offset ] ) ); -  trap_SetConfigstring( CS_TEAMVOTE_STRING + cs_offset, level.teamVoteString[ cs_offset ] ); -  trap_SetConfigstring( CS_TEAMVOTE_YES + cs_offset, va( "%i", level.teamVoteYes[ cs_offset ] ) ); -  trap_SetConfigstring( CS_TEAMVOTE_NO + cs_offset, va( "%i", level.teamVoteNo[ cs_offset ] ) ); -} - - -/* -================== -Cmd_TeamVote_f -================== -*/ -void Cmd_TeamVote_f( gentity_t *ent ) -{ -  int     team, cs_offset; -  char    msg[ 64 ]; - -  team = ent->client->ps.stats[ STAT_PTEAM ]; -  if( team == PTE_HUMANS ) -    cs_offset = 0; -  else if( team == PTE_ALIENS ) -    cs_offset = 1; -  else -    return; - -  if( !level.teamVoteTime[ cs_offset ] ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"No team vote in progress\n\"" ); -    return; -  } - -  if( ent->client->ps.eFlags & EF_TEAMVOTED ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Team vote already cast\n\"" ); -    return; -  } - -  if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_NONE ) -  { -    G_SendCommandFromServer( ent-g_entities, "print \"Not allowed to vote as spectator\n\"" ); -    return; -  } - -  G_SendCommandFromServer( ent-g_entities, "print \"Team vote cast\n\"" ); - -  ent->client->ps.eFlags |= EF_TEAMVOTED; - -  trap_Argv( 1, msg, sizeof( msg ) ); - -  if( msg[ 0 ] == 'y' || msg[ 1 ] == 'Y' || msg[ 1 ] == '1' ) -  { -    level.teamVoteYes[ cs_offset ]++; -    trap_SetConfigstring( CS_TEAMVOTE_YES + cs_offset, va( "%i", level.teamVoteYes[ cs_offset ] ) ); -  } -  else -  { -    level.teamVoteNo[ cs_offset ]++; -    trap_SetConfigstring( CS_TEAMVOTE_NO + cs_offset, va( "%i", level.teamVoteNo[ cs_offset ] ) ); -  } - -  // a majority will be determined in TeamCheckVote, which will also account -  // for players entering or leaving -} - - -/* -================= -Cmd_SetViewpos_f -================= -*/ -void Cmd_SetViewpos_f( gentity_t *ent ) -{ -  vec3_t  origin, angles; -  char    buffer[ MAX_TOKEN_CHARS ]; -  int     i; - -  if( !g_cheats.integer ) -  { -    G_SendCommandFromServer( ent-g_entities, va( "print \"Cheats are not enabled on this server\n\"" ) ); -    return; -  } - -  if( trap_Argc( ) != 5 ) -  { -    G_SendCommandFromServer( ent-g_entities, va( "print \"usage: setviewpos x y z yaw\n\"" ) ); -    return; -  } - -  VectorClear( angles ); - -  for( i = 0 ; i < 3 ; i++ ) -  { -    trap_Argv( i + 1, buffer, sizeof( buffer ) ); -    origin[ i ] = atof( buffer ); -  } - -  trap_Argv( 4, buffer, sizeof( buffer ) ); -  angles[ YAW ] = atof( buffer ); - -  TeleportPlayer( ent, origin, angles ); -} - -#define EVOLVE_TRACE_HEIGHT 128.0f -#define AS_OVER_RT3         ((ALIENSENSE_RANGE*0.5f)/M_ROOT3) - -/* -================= -Cmd_Class_f -================= -*/ -void Cmd_Class_f( gentity_t *ent ) -{ -  char      s[ MAX_TOKEN_CHARS ]; -  int       clientNum; -  int       i; -  trace_t   tr, tr2; -  vec3_t    infestOrigin; -  int       allowedClasses[ PCL_NUM_CLASSES ]; -  int       numClasses = 0; -  pClass_t  currentClass = ent->client->ps.stats[ STAT_PCLASS ]; - -  int       numLevels; -  vec3_t    fromMins, fromMaxs, toMins, toMaxs; -  vec3_t    temp; - -  int       entityList[ MAX_GENTITIES ]; -  vec3_t    range = { AS_OVER_RT3, AS_OVER_RT3, AS_OVER_RT3 }; -  vec3_t    mins, maxs; -  int       num; -  gentity_t *other; - -  if( ent->client->ps.stats[ STAT_HEALTH ] <= 0 ) -    return; - -  clientNum = ent->client - level.clients; -  trap_Argv( 1, s, sizeof( s ) ); - -  if( G_ClassIsAllowed( PCL_ALIEN_BUILDER0 ) ) -    allowedClasses[ numClasses++ ] = PCL_ALIEN_BUILDER0; - -  if( G_ClassIsAllowed( PCL_ALIEN_BUILDER0_UPG ) && -      BG_FindStagesForClass( PCL_ALIEN_BUILDER0_UPG, g_alienStage.integer ) ) -    allowedClasses[ numClasses++ ] = PCL_ALIEN_BUILDER0_UPG; - -  if( G_ClassIsAllowed( PCL_ALIEN_LEVEL0 ) ) -    allowedClasses[ numClasses++ ] = PCL_ALIEN_LEVEL0; - -  if( ent->client->pers.teamSelection == PTE_ALIENS && -      !( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) && -      !( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) && -      !( ent->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBING ) && -      !( ent->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) ) -  { -    //if we are not currently spectating, we are attempting evolution -    if( currentClass != PCL_NONE ) -    { -      //check there are no humans nearby -      VectorAdd( ent->client->ps.origin, range, maxs ); -      VectorSubtract( ent->client->ps.origin, range, mins ); - -      num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -      for( i = 0; i < num; i++ ) -      { -        other = &g_entities[ entityList[ i ] ]; - -        if( ( other->client && other->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) || -            ( other->s.eType == ET_BUILDABLE && other->biteam == BIT_HUMANS ) ) -        { -          ent->client->pers.classSelection = PCL_NONE; -          G_TriggerMenu( clientNum, MN_A_TOOCLOSE ); -          return; -        } -      } - -      if( !level.overmindPresent ) -      { -        ent->client->pers.classSelection = PCL_NONE; -        G_TriggerMenu( clientNum, MN_A_NOOVMND_EVOLVE ); -        return; -      } - -      //guard against selling the HBUILD weapons exploit -      if( ( currentClass == PCL_ALIEN_BUILDER0 || -            currentClass == PCL_ALIEN_BUILDER0_UPG ) && -          ent->client->ps.stats[ STAT_MISC ] > 0 ) -      { -        G_SendCommandFromServer( ent-g_entities, va( "print \"Cannot evolve until build timer expires\n\"" ) ); -        return; -      } - -      //evolve now -      ent->client->pers.classSelection = BG_FindClassNumForName( s ); - -      if( ent->client->pers.classSelection == PCL_NONE ) -      { -        G_SendCommandFromServer( ent-g_entities, va( "print \"Unknown class\n\"" ) ); -        return; -      } - -      numLevels = BG_ClassCanEvolveFromTo( currentClass, -                                           ent->client->pers.classSelection, -                                           (short)ent->client->ps.persistant[ PERS_CREDIT ], 0 ); - -      BG_FindBBoxForClass( currentClass, -                           fromMins, fromMaxs, NULL, NULL, NULL ); -      BG_FindBBoxForClass( ent->client->pers.classSelection, -                           toMins, toMaxs, NULL, NULL, NULL ); - -      VectorCopy( ent->s.pos.trBase, infestOrigin ); - -      infestOrigin[ 2 ] += ( fabs( toMins[ 2 ] ) - fabs( fromMins[ 2 ] ) ) + 1.0f; -      VectorCopy( infestOrigin, temp ); -      temp[ 2 ] += EVOLVE_TRACE_HEIGHT; - -      //compute a place up in the air to start the real trace -      trap_Trace( &tr, infestOrigin, toMins, toMaxs, temp, ent->s.number, MASK_SHOT ); -      VectorCopy( infestOrigin, temp ); -      temp[ 2 ] += ( EVOLVE_TRACE_HEIGHT * tr.fraction ) - 1.0f; - -      //trace down to the ground so that we can evolve on slopes -      trap_Trace( &tr, temp, toMins, toMaxs, infestOrigin, ent->s.number, MASK_SHOT ); -      VectorCopy( tr.endpos, infestOrigin ); - -      //make REALLY sure -      trap_Trace( &tr2, ent->s.pos.trBase, NULL, NULL, infestOrigin, ent->s.number, MASK_SHOT ); - -      //check there is room to evolve -      if( !tr.startsolid && tr2.fraction == 1.0f ) -      { -        //...check we can evolve to that class -        if( numLevels >= 0 && -            BG_FindStagesForClass( ent->client->pers.classSelection, g_alienStage.integer ) &&  -            G_ClassIsAllowed( ent->client->pers.classSelection ) ) -        { -          ent->client->pers.evolveHealthFraction = (float)ent->client->ps.stats[ STAT_HEALTH ] / -            (float)BG_FindHealthForClass( currentClass ); - -          if( ent->client->pers.evolveHealthFraction < 0.0f ) -            ent->client->pers.evolveHealthFraction = 0.0f; -          else if( ent->client->pers.evolveHealthFraction > 1.0f ) -            ent->client->pers.evolveHealthFraction = 1.0f; - -          //remove credit -          G_AddCreditToClient( ent->client, -(short)numLevels, qtrue ); - -          ClientUserinfoChanged( clientNum ); -          VectorCopy( infestOrigin, ent->s.pos.trBase ); -          ClientSpawn( ent, ent, ent->s.pos.trBase, ent->s.apos.trBase ); -          return; -        } -        else -        { -          ent->client->pers.classSelection = PCL_NONE; -          G_SendCommandFromServer( ent-g_entities, -               va( "print \"You cannot evolve from your current class\n\"" ) ); -          return; -        } -      } -      else -      { -        ent->client->pers.classSelection = PCL_NONE; -        G_TriggerMenu( clientNum, MN_A_NOEROOM ); -        return; -      } -    } -    else -    { -      //spawning from an egg -      ent->client->pers.classSelection = -        ent->client->ps.stats[ STAT_PCLASS ] = BG_FindClassNumForName( s ); - -      if( ent->client->pers.classSelection != PCL_NONE ) -      { -        for( i = 0; i < numClasses; i++ ) -        { -          if( allowedClasses[ i ] == ent->client->pers.classSelection && -              BG_FindStagesForClass( ent->client->pers.classSelection, g_alienStage.integer ) && -              G_ClassIsAllowed( ent->client->pers.classSelection ) ) -          { -            G_PushSpawnQueue( &level.alienSpawnQueue, clientNum ); -            return; -          } -        } - -        ent->client->pers.classSelection = PCL_NONE; -        G_SendCommandFromServer( ent-g_entities, va( "print \"You cannot spawn as this class\n\"" ) ); -      } -      else -      { -        G_SendCommandFromServer( ent-g_entities, va( "print \"Unknown class\n\"" ) ); -        return; -      } -    } -  } -  else if( ent->client->pers.teamSelection == PTE_HUMANS ) -  { -    //humans cannot use this command whilst alive -    if( ent->client->pers.classSelection != PCL_NONE ) -    { -      G_SendCommandFromServer( ent-g_entities, va( "print \"You must be dead to use the class command\n\"" ) ); -      return; -    } - -    ent->client->pers.classSelection = -      ent->client->ps.stats[ STAT_PCLASS ] = PCL_HUMAN; - -    //set the item to spawn with -    if( !Q_stricmp( s, BG_FindNameForWeapon( WP_MACHINEGUN ) ) && G_WeaponIsAllowed( WP_MACHINEGUN ) ) -      ent->client->pers.humanItemSelection = WP_MACHINEGUN; -    else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD ) ) && G_WeaponIsAllowed( WP_HBUILD ) ) -      ent->client->pers.humanItemSelection = WP_HBUILD; -    else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD2 ) ) && G_WeaponIsAllowed( WP_HBUILD2 ) && -        BG_FindStagesForWeapon( WP_HBUILD2, g_humanStage.integer ) ) -      ent->client->pers.humanItemSelection = WP_HBUILD2; -    else -    { -      ent->client->pers.classSelection = PCL_NONE; -      G_SendCommandFromServer( ent-g_entities, va( "print \"Unknown starting item\n\"" ) ); -      return; -    } - -    G_PushSpawnQueue( &level.humanSpawnQueue, clientNum ); -  } -  else if( ent->client->pers.teamSelection == PTE_NONE ) -  { -    //can't use this command unless on a team -    ent->client->pers.classSelection = PCL_NONE; -    ent->client->sess.sessionTeam = TEAM_FREE; -    ClientSpawn( ent, NULL, NULL, NULL ); -    G_SendCommandFromServer( ent-g_entities, va( "print \"Join a team first\n\"" ) ); -  } -} - - -/* -================= -Cmd_Destroy_f -================= -*/ -void Cmd_Destroy_f( gentity_t *ent, qboolean deconstruct ) -{ -  vec3_t      forward, end; -  trace_t     tr; -  gentity_t   *traceEnt; - -  if( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) -    G_Damage( ent->client->hovel, ent, ent, forward, ent->s.origin, 10000, 0, MOD_SUICIDE ); - -  if( !( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) ) -  { -    AngleVectors( ent->client->ps.viewangles, forward, NULL, NULL ); -    VectorMA( ent->client->ps.origin, 100, forward, end ); - -    trap_Trace( &tr, ent->client->ps.origin, NULL, NULL, end, ent->s.number, MASK_PLAYERSOLID ); -    traceEnt = &g_entities[ tr.entityNum ]; - -    if( tr.fraction < 1.0f && -        ( traceEnt->s.eType == ET_BUILDABLE ) && -        ( traceEnt->biteam == ent->client->pers.teamSelection ) && -        ( ( ent->client->ps.weapon >= WP_ABUILD ) && -          ( ent->client->ps.weapon <= WP_HBUILD ) ) ) -    { -      if( ent->client->ps.stats[ STAT_MISC ] > 0 ) -      { -        G_AddEvent( ent, EV_BUILD_DELAY, ent->client->ps.clientNum ); -        return; -      } - -      if( !deconstruct ) -        G_Damage( traceEnt, ent, ent, forward, tr.endpos, 10000, 0, MOD_SUICIDE ); -      else -        G_FreeEntity( traceEnt ); - -      ent->client->ps.stats[ STAT_MISC ] += -        BG_FindBuildDelayForWeapon( ent->s.weapon ) >> 2; -    } -  } -} - - -/* -================= -Cmd_ActivateItem_f - -Activate an item -================= -*/ -void Cmd_ActivateItem_f( gentity_t *ent ) -{ -  char  s[ MAX_TOKEN_CHARS ]; -  int   upgrade, weapon; - -  trap_Argv( 1, s, sizeof( s ) ); -  upgrade = BG_FindUpgradeNumForName( s ); -  weapon = BG_FindWeaponNumForName( s ); - -  if( ent->client->pers.teamSelection != PTE_HUMANS ) -    return; - -  if( upgrade != UP_NONE && BG_InventoryContainsUpgrade( upgrade, ent->client->ps.stats ) ) -    BG_ActivateUpgrade( upgrade, ent->client->ps.stats ); -  else if( weapon != WP_NONE && BG_InventoryContainsWeapon( weapon, ent->client->ps.stats ) ) -    G_ForceWeaponChange( ent, weapon ); -  else -    G_SendCommandFromServer( ent-g_entities, va( "print \"You don't have the %s\n\"", s ) ); -} - - -/* -================= -Cmd_DeActivateItem_f - -Deactivate an item -================= -*/ -void Cmd_DeActivateItem_f( gentity_t *ent ) -{ -  char  s[ MAX_TOKEN_CHARS ]; -  int   upgrade; - -  trap_Argv( 1, s, sizeof( s ) ); -  upgrade = BG_FindUpgradeNumForName( s ); - -  if( ent->client->pers.teamSelection != PTE_HUMANS ) -    return; - -  if( BG_InventoryContainsUpgrade( upgrade, ent->client->ps.stats ) ) -    BG_DeactivateUpgrade( upgrade, ent->client->ps.stats ); -  else -    G_SendCommandFromServer( ent-g_entities, va( "print \"You don't have the %s\n\"", s ) ); -} - - -/* -================= -Cmd_ToggleItem_f -================= -*/ -void Cmd_ToggleItem_f( gentity_t *ent ) -{ -  char  s[ MAX_TOKEN_CHARS ]; -  int   upgrade, weapon, i; - -  trap_Argv( 1, s, sizeof( s ) ); -  upgrade = BG_FindUpgradeNumForName( s ); -  weapon = BG_FindWeaponNumForName( s ); - -  if( ent->client->pers.teamSelection != PTE_HUMANS ) -    return; - -  if( weapon != WP_NONE ) -  { -    //special case to allow switching between -    //the blaster and the primary weapon - -    if( ent->client->ps.weapon != WP_BLASTER ) -      weapon = WP_BLASTER; -    else -    { -      //find a held weapon which isn't the blaster -      for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) -      { -        if( i == WP_BLASTER ) -          continue; - -        if( BG_InventoryContainsWeapon( i, ent->client->ps.stats ) ) -        { -          weapon = i; -          break; -        } -      } - -      if( i == WP_NUM_WEAPONS ) -        weapon = WP_BLASTER; -    } - -    G_ForceWeaponChange( ent, weapon ); -  } -  else if( BG_InventoryContainsUpgrade( upgrade, ent->client->ps.stats ) ) -  { -    if( BG_UpgradeIsActive( upgrade, ent->client->ps.stats ) ) -      BG_DeactivateUpgrade( upgrade, ent->client->ps.stats ); -    else -      BG_ActivateUpgrade( upgrade, ent->client->ps.stats ); -  } -  else -    G_SendCommandFromServer( ent-g_entities, va( "print \"You don't have the %s\n\"", s ) ); -} - -/* -================= -Cmd_Buy_f -================= -*/ -void Cmd_Buy_f( gentity_t *ent ) -{ -  char      s[ MAX_TOKEN_CHARS ]; -  int       i; -  int       weapon, upgrade, numItems = 0; -  int       maxAmmo, maxClips; -  qboolean  buyingEnergyAmmo = qfalse; - -  for( i = UP_NONE; i < UP_NUM_UPGRADES; i++ ) -  { -    if( BG_InventoryContainsUpgrade( i, ent->client->ps.stats ) ) -      numItems++; -  } - -  for( i = WP_NONE; i < WP_NUM_WEAPONS; i++ ) -  { -    if( BG_InventoryContainsWeapon( i, ent->client->ps.stats ) ) -      numItems++; -  } - -  trap_Argv( 1, s, sizeof( s ) ); - -  //aliens don't buy stuff -  if( ent->client->pers.teamSelection != PTE_HUMANS ) -    return; - -  weapon = BG_FindWeaponNumForName( s ); -  upgrade = BG_FindUpgradeNumForName( s ); - -  //special case to keep norf happy -  if( weapon == WP_NONE && upgrade == UP_AMMO ) -    buyingEnergyAmmo = BG_FindUsesEnergyForWeapon( ent->client->ps.weapon ); - -  if( buyingEnergyAmmo ) -  { -    //no armoury nearby -    if( ( !G_BuildableRange( ent->client->ps.origin, 100, BA_H_REACTOR ) && -        !G_BuildableRange( ent->client->ps.origin, 100, BA_H_REPEATER ) ) ) -    { -      G_SendCommandFromServer( ent-g_entities, va( "print \"You must be near a reactor or repeater\n\"" ) ); -      return; -    } -  } -  else -  { -    //no armoury nearby -    if( !G_BuildableRange( ent->client->ps.origin, 100, BA_H_ARMOURY ) ) -    { -      G_SendCommandFromServer( ent-g_entities, va( "print \"You must be near a powered armoury\n\"" ) ); -      return; -    } -  } - -  if( weapon != WP_NONE ) -  { -    //already got this? -    if( BG_InventoryContainsWeapon( weapon, ent->client->ps.stats ) ) -    { -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_ITEMHELD ); -      return; -    } - -    //can afford this? -    if( BG_FindPriceForWeapon( weapon ) > (short)ent->client->ps.persistant[ PERS_CREDIT ] ) -    { -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOFUNDS ); -      return; -    } - -    //have space to carry this? -    if( BG_FindSlotsForWeapon( weapon ) & ent->client->ps.stats[ STAT_SLOTS ] ) -    { -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOSLOTS ); -      return; -    } - -    if( BG_FindTeamForWeapon( weapon ) != WUT_HUMANS ) -    { -      //shouldn't need a fancy dialog -      G_SendCommandFromServer( ent-g_entities, va( "print \"You can't buy alien items\n\"" ) ); -      return; -    } - -    //are we /allowed/ to buy this? -    if( !BG_FindPurchasableForWeapon( weapon ) ) -    { -      G_SendCommandFromServer( ent-g_entities, va( "print \"You can't buy this item\n\"" ) ); -      return; -    } - -    //are we /allowed/ to buy this? -    if( !BG_FindStagesForWeapon( weapon, g_humanStage.integer ) || !G_WeaponIsAllowed( weapon ) ) -    { -      G_SendCommandFromServer( ent-g_entities, va( "print \"You can't buy this item\n\"" ) ); -      return; -    } - -    //add to inventory -    BG_AddWeaponToInventory( weapon, ent->client->ps.stats ); -    BG_FindAmmoForWeapon( weapon, &maxAmmo, &maxClips ); - -    if( BG_FindUsesEnergyForWeapon( weapon ) && -        BG_InventoryContainsUpgrade( UP_BATTPACK, ent->client->ps.stats ) ) -      maxAmmo = (int)( (float)maxAmmo * BATTPACK_MODIFIER ); - -    BG_PackAmmoArray( weapon, ent->client->ps.ammo, ent->client->ps.powerups, -                      maxAmmo, maxClips ); - -    G_ForceWeaponChange( ent, weapon ); - -    //set build delay/pounce etc to 0 -    ent->client->ps.stats[ STAT_MISC ] = 0; - -    //subtract from funds -    G_AddCreditToClient( ent->client, -(short)BG_FindPriceForWeapon( weapon ), qfalse ); -  } -  else if( upgrade != UP_NONE ) -  { -    //already got this? -    if( BG_InventoryContainsUpgrade( upgrade, ent->client->ps.stats ) ) -    { -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_ITEMHELD ); -      return; -    } - -    //can afford this? -    if( BG_FindPriceForUpgrade( upgrade ) > (short)ent->client->ps.persistant[ PERS_CREDIT ] ) -    { -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOFUNDS ); -      return; -    } - -    //have space to carry this? -    if( BG_FindSlotsForUpgrade( upgrade ) & ent->client->ps.stats[ STAT_SLOTS ] ) -    { -      G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOSLOTS ); -      return; -    } - -    if( BG_FindTeamForUpgrade( upgrade ) != WUT_HUMANS ) -    { -      //shouldn't need a fancy dialog -      G_SendCommandFromServer( ent-g_entities, va( "print \"You can't buy alien items\n\"" ) ); -      return; -    } - -    //are we /allowed/ to buy this? -    if( !BG_FindPurchasableForUpgrade( upgrade ) ) -    { -      G_SendCommandFromServer( ent-g_entities, va( "print \"You can't buy this item\n\"" ) ); -      return; -    } - -    //are we /allowed/ to buy this? -    if( !BG_FindStagesForUpgrade( upgrade, g_humanStage.integer ) || !G_UpgradeIsAllowed( upgrade ) ) -    { -      G_SendCommandFromServer( ent-g_entities, va( "print \"You can't buy this item\n\"" ) ); -      return; -    } - -    if( upgrade == UP_AMMO ) -      G_GiveClientMaxAmmo( ent, buyingEnergyAmmo ); -    else -    { -      //add to inventory -      BG_AddUpgradeToInventory( upgrade, ent->client->ps.stats ); -    } - -    if( upgrade == UP_BATTPACK ) -      G_GiveClientMaxAmmo( ent, qtrue ); - -    //subtract from funds -    G_AddCreditToClient( ent->client, -(short)BG_FindPriceForUpgrade( upgrade ), qfalse ); -  } -  else -  { -    G_SendCommandFromServer( ent-g_entities, va( "print \"Unknown item\n\"" ) ); -  } - -  if( trap_Argc( ) >= 2 ) -  { -    trap_Argv( 2, s, sizeof( s ) ); - -    //retrigger the armoury menu -    if( !Q_stricmp( s, "retrigger" ) ) -      ent->client->retriggerArmouryMenu = level.framenum + RAM_FRAMES; -  } - -  //update ClientInfo -  ClientUserinfoChanged( ent->client->ps.clientNum ); -} - - -/* -================= -Cmd_Sell_f -================= -*/ -void Cmd_Sell_f( gentity_t *ent ) -{ -  char      s[ MAX_TOKEN_CHARS ]; -  int       i; -  int       weapon, upgrade; - -  trap_Argv( 1, s, sizeof( s ) ); - -  //aliens don't sell stuff -  if( ent->client->pers.teamSelection != PTE_HUMANS ) -    return; - -  //no armoury nearby -  if( !G_BuildableRange( ent->client->ps.origin, 100, BA_H_ARMOURY ) ) -  { -    G_SendCommandFromServer( ent-g_entities, va( "print \"You must be near a powered armoury\n\"" ) ); -    return; -  } - -  weapon = BG_FindWeaponNumForName( s ); -  upgrade = BG_FindUpgradeNumForName( s ); - -  if( weapon != WP_NONE ) -  { -    //are we /allowed/ to sell this? -    if( !BG_FindPurchasableForWeapon( weapon ) ) -    { -      G_SendCommandFromServer( ent-g_entities, va( "print \"You can't sell this weapon\n\"" ) ); -      return; -    } - -    //remove weapon if carried -    if( BG_InventoryContainsWeapon( weapon, ent->client->ps.stats ) ) -    { -      //guard against selling the HBUILD weapons exploit -      if( ( weapon == WP_HBUILD || weapon == WP_HBUILD2 ) && -          ent->client->ps.stats[ STAT_MISC ] > 0 ) -      { -        G_SendCommandFromServer( ent-g_entities, va( "print \"Cannot sell until build timer expires\n\"" ) ); -        return; -      } - -      BG_RemoveWeaponFromInventory( weapon, ent->client->ps.stats ); - -      //add to funds -      G_AddCreditToClient( ent->client, (short)BG_FindPriceForWeapon( weapon ), qfalse ); -    } - -    //if we have this weapon selected, force a new selection -    if( weapon == ent->client->ps.weapon ) -      G_ForceWeaponChange( ent, WP_NONE ); -  } -  else if( upgrade != UP_NONE ) -  { -    //are we /allowed/ to sell this? -    if( !BG_FindPurchasableForUpgrade( upgrade ) ) -    { -      G_SendCommandFromServer( ent-g_entities, va( "print \"You can't sell this item\n\"" ) ); -      return; -    } -    //remove upgrade if carried -    if( BG_InventoryContainsUpgrade( upgrade, ent->client->ps.stats ) ) -    { -      BG_RemoveUpgradeFromInventory( upgrade, ent->client->ps.stats ); - -      if( upgrade == UP_BATTPACK ) -        G_GiveClientMaxAmmo( ent, qtrue ); - -      //add to funds -      G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( upgrade ), qfalse ); -    } -  } -  else if( !Q_stricmp( s, "weapons" ) ) -  { -    for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) -    { -      //guard against selling the HBUILD weapons exploit -      if( ( i == WP_HBUILD || i == WP_HBUILD2 ) && -          ent->client->ps.stats[ STAT_MISC ] > 0 ) -      { -        G_SendCommandFromServer( ent-g_entities, va( "print \"Cannot sell until build timer expires\n\"" ) ); -        continue; -      } - -      if( BG_InventoryContainsWeapon( i, ent->client->ps.stats ) && -          BG_FindPurchasableForWeapon( i ) ) -      { -        BG_RemoveWeaponFromInventory( i, ent->client->ps.stats ); - -        //add to funds -        G_AddCreditToClient( ent->client, (short)BG_FindPriceForWeapon( i ), qfalse ); -      } - -      //if we have this weapon selected, force a new selection -      if( i == ent->client->ps.weapon ) -        G_ForceWeaponChange( ent, WP_NONE ); -    } -  } -  else if( !Q_stricmp( s, "upgrades" ) ) -  { -    for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -    { -      //remove upgrade if carried -      if( BG_InventoryContainsUpgrade( i, ent->client->ps.stats ) && -          BG_FindPurchasableForUpgrade( i ) ) -      { -        BG_RemoveUpgradeFromInventory( i, ent->client->ps.stats ); - -        if( i == UP_BATTPACK ) -        { -          int j; - -          //remove energy -          for( j = WP_NONE; j < WP_NUM_WEAPONS; j++ ) -          { -            if( BG_InventoryContainsWeapon( j, ent->client->ps.stats ) && -                BG_FindUsesEnergyForWeapon( j ) && -                !BG_FindInfinteAmmoForWeapon( j ) ) -            { -              BG_PackAmmoArray( j, ent->client->ps.ammo, ent->client->ps.powerups, 0, 0 ); -            } -          } -        } - -        //add to funds -        G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( i ), qfalse ); -      } -    } -  } -  else -    G_SendCommandFromServer( ent-g_entities, va( "print \"Unknown item\n\"" ) ); - -  if( trap_Argc( ) >= 2 ) -  { -    trap_Argv( 2, s, sizeof( s ) ); - -    //retrigger the armoury menu -    if( !Q_stricmp( s, "retrigger" ) ) -      ent->client->retriggerArmouryMenu = level.framenum + RAM_FRAMES; -  } - -  //update ClientInfo -  ClientUserinfoChanged( ent->client->ps.clientNum ); -} - - -/* -================= -Cmd_Build_f -================= -*/ -void Cmd_Build_f( gentity_t *ent ) -{ -  char          s[ MAX_TOKEN_CHARS ]; -  buildable_t   buildable; -  float         dist; -  vec3_t        origin; -  pTeam_t       team; - -  trap_Argv( 1, s, sizeof( s ) ); - -  buildable = BG_FindBuildNumForName( s ); -  team = ent->client->ps.stats[ STAT_PTEAM ]; - -  if( buildable != BA_NONE && -      ( ( 1 << ent->client->ps.weapon ) & BG_FindBuildWeaponForBuildable( buildable ) ) && -      !( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) && -      !( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) && -      G_BuildableIsAllowed( buildable ) && -      ( ( team == PTE_ALIENS && BG_FindStagesForBuildable( buildable, g_alienStage.integer ) ) || -        ( team == PTE_HUMANS && BG_FindStagesForBuildable( buildable, g_humanStage.integer ) ) ) ) -  { -    dist = BG_FindBuildDistForClass( ent->client->ps.stats[ STAT_PCLASS ] ); - -    //these are the errors displayed when the builder first selects something to use -    switch( G_itemFits( ent, buildable, dist, origin ) ) -    { -      case IBE_NONE: -      case IBE_TNODEWARN: -      case IBE_RPTWARN: -      case IBE_RPTWARN2: -      case IBE_SPWNWARN: -      case IBE_NOROOM: -      case IBE_NORMAL: -      case IBE_HOVELEXIT: -        ent->client->ps.stats[ STAT_BUILDABLE ] = ( buildable | SB_VALID_TOGGLEBIT ); -        break; - -      case IBE_NOASSERT: -        G_TriggerMenu( ent->client->ps.clientNum, MN_A_NOASSERT ); -        break; - -      case IBE_NOOVERMIND: -        G_TriggerMenu( ent->client->ps.clientNum, MN_A_NOOVMND ); -        break; - -      case IBE_OVERMIND: -        G_TriggerMenu( ent->client->ps.clientNum, MN_A_OVERMIND ); -        break; - -      case IBE_REACTOR: -        G_TriggerMenu( ent->client->ps.clientNum, MN_H_REACTOR ); -        break; - -      case IBE_REPEATER: -        G_TriggerMenu( ent->client->ps.clientNum, MN_H_REPEATER ); -        break; - -      case IBE_NOPOWER: -        G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOPOWER ); -        break; - -      case IBE_NOCREEP: -        G_TriggerMenu( ent->client->ps.clientNum, MN_A_NOCREEP ); -        break; - -      case IBE_NODCC: -        G_TriggerMenu( ent->client->ps.clientNum, MN_H_NODCC ); -        break; - -      default: -        break; -    } -  } -  else -    G_SendCommandFromServer( ent-g_entities, va( "print \"Cannot build this item\n\"" ) ); -} - - -/* -================= -Cmd_Boost_f -================= -*/ -void Cmd_Boost_f( gentity_t *ent ) -{ -  if( BG_InventoryContainsUpgrade( UP_JETPACK, ent->client->ps.stats ) && -      BG_UpgradeIsActive( UP_JETPACK, ent->client->ps.stats ) ) -    return; - -  if( ent->client->pers.cmd.buttons & BUTTON_WALKING ) -    return; - -  if( ( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) && -      ( ent->client->ps.stats[ STAT_STAMINA ] > 0 ) ) -    ent->client->ps.stats[ STAT_STATE ] |= SS_SPEEDBOOST; -} - -/* -================= -Cmd_Reload_f -================= -*/ -void Cmd_Reload_f( gentity_t *ent ) -{ -  if( ent->client->ps.weaponstate != WEAPON_RELOADING ) -    ent->client->ps.pm_flags |= PMF_WEAPON_RELOAD; -} - -/* -================= -G_StopFollowing - -If the client being followed leaves the game, or you just want to drop -to free floating spectator mode -================= -*/ -void G_StopFollowing( gentity_t *ent ) -{ -  ent->client->ps.persistant[ PERS_TEAM ] = TEAM_SPECTATOR; -  ent->client->sess.sessionTeam = TEAM_SPECTATOR; -  ent->client->sess.spectatorState = SPECTATOR_FREE; -  ent->client->sess.spectatorClient = -1; -  ent->client->ps.pm_flags &= ~PMF_FOLLOW; -  ent->client->ps.stats[ STAT_PTEAM ] = PTE_NONE; - -  ent->client->ps.stats[ STAT_STATE ] &= ~SS_WALLCLIMBING; -  ent->client->ps.stats[ STAT_STATE ] &= ~SS_WALLCLIMBINGCEILING; -  ent->client->ps.eFlags &= ~EF_WALLCLIMB; -  ent->client->ps.viewangles[ PITCH ] = 0.0f; - -  ent->r.svFlags &= ~SVF_BOT; -  ent->client->ps.clientNum = ent - g_entities; - -  CalculateRanks( ); -} - -/* -================= -G_FollowNewClient - -This was a really nice, elegant function. Then I fucked it up. -================= -*/ -qboolean G_FollowNewClient( gentity_t *ent, int dir ) -{ -  int       clientnum = ent->client->sess.spectatorClient; -  int       original = clientnum; -  qboolean  selectAny = qfalse; - -  if( dir > 1 ) -    dir = 1; -  else if( dir < -1 ) -    dir = -1; -  else if( dir == 0 ) -    return qtrue; - -  if( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) -    return qfalse; - -  // select any if no target exists -  if( clientnum < 0 || clientnum >= level.maxclients ) -  { -    clientnum = original = 0; -    selectAny = qtrue; -  } - -  do -  { -    clientnum += dir; - -    if( clientnum >= level.maxclients ) -      clientnum = 0; - -    if( clientnum < 0 ) -      clientnum = level.maxclients - 1; - -    // avoid selecting existing follow target -    if( clientnum == original && !selectAny ) -      continue; //effectively break; - -    // can't follow self -    if( &level.clients[ clientnum ] == ent->client ) -      continue; - -    // can only follow connected clients -    if( level.clients[ clientnum ].pers.connected != CON_CONNECTED ) -      continue; - -    // can't follow another spectator -    if( level.clients[ clientnum ].sess.sessionTeam == TEAM_SPECTATOR ) -      continue; - -    // this is good, we can use it -    ent->client->sess.spectatorClient = clientnum; -    ent->client->sess.spectatorState = SPECTATOR_FOLLOW; -    return qtrue; - -  } while( clientnum != original ); - -  return qfalse; -} - -/* -================= -Cmd_Follow_f -================= -*/ -void Cmd_Follow_f( gentity_t *ent, qboolean toggle ) -{ -  int   i; -  char  arg[ MAX_TOKEN_CHARS ]; - -  if( trap_Argc( ) != 2 || toggle ) -  { -    if( ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) -      G_StopFollowing( ent ); -    else if( ent->client->sess.spectatorState == SPECTATOR_FREE ) -      G_FollowNewClient( ent, 1 ); -  } -  else if( ent->client->sess.spectatorState == SPECTATOR_FREE ) -  { -    trap_Argv( 1, arg, sizeof( arg ) ); -    i = G_ClientNumberFromString( ent, arg ); - -    if( i == -1 ) -      return; - -    // can't follow self -    if( &level.clients[ i ] == ent->client ) -      return; - -    // can't follow another spectator -    if( level.clients[ i ].sess.sessionTeam == TEAM_SPECTATOR ) -      return; - -    // first set them to spectator -    if( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) -      return; - -    ent->client->sess.spectatorState = SPECTATOR_FOLLOW; -    ent->client->sess.spectatorClient = i; -  } -} - -/* -================= -Cmd_FollowCycle_f -================= -*/ -void Cmd_FollowCycle_f( gentity_t *ent, int dir ) -{ -  // won't work unless spectating -  if( ent->client->sess.spectatorState == SPECTATOR_NOT ) -    return; - -  if( dir != 1 && dir != -1 ) -    G_Error( "Cmd_FollowCycle_f: bad dir %i", dir ); - -  G_FollowNewClient( ent, dir ); -} - -/* -================= -Cmd_PTRCVerify_f - -Check a PTR code is valid -================= -*/ -void Cmd_PTRCVerify_f( gentity_t *ent ) -{ -  connectionRecord_t  *connection; -  char                s[ MAX_TOKEN_CHARS ] = { 0 }; -  int                 code; - -  trap_Argv( 1, s, sizeof( s ) ); - -  if( !strlen( s ) ) -    return; - -  code = atoi( s ); - -  if( G_VerifyPTRC( code ) ) -  { -    connection = G_FindConnectionForCode( code ); - -    // valid code -    if( connection->clientTeam != PTE_NONE ) -      G_SendCommandFromServer( ent->client->ps.clientNum, "ptrcconfirm" ); - -    // restore mapping -    ent->client->pers.connection = connection; -  } -  else -  { -    // invalid code -- generate a new one -    connection = G_GenerateNewConnection( ent->client ); - -    if( connection ) -    { -      G_SendCommandFromServer( ent->client->ps.clientNum, -        va( "ptrcissue %d", connection->ptrCode ) ); -    } -  } -} - -/* -================= -Cmd_PTRCRestore_f - -Restore against a PTR code -================= -*/ -void Cmd_PTRCRestore_f( gentity_t *ent ) -{ -  char                s[ MAX_TOKEN_CHARS ] = { 0 }; -  int                 code; -  connectionRecord_t  *connection; - -  trap_Argv( 1, s, sizeof( s ) ); - -  if( !strlen( s ) ) -    return; - -  code = atoi( s ); - -  if( G_VerifyPTRC( code ) ) -  { -    if( ent->client->pers.joinedATeam ) -    { -      G_SendCommandFromServer( ent - g_entities, -        "print \"You cannot use a PTR code after joining a team\n\"" ); -    } -    else -    { -      // valid code -      connection = G_FindConnectionForCode( code ); - -      if( connection ) -      { -        // set the correct team -        G_ChangeTeam( ent, connection->clientTeam ); - -        // set the correct credit -        ent->client->ps.persistant[ PERS_CREDIT ] = 0; -        G_AddCreditToClient( ent->client, connection->clientCredit, qtrue ); -      } -    } -  } -  else -  { -    G_SendCommandFromServer( ent - g_entities, -      va( "print \"\"%d\" is not a valid PTR code\n\"", code ) ); -  } -} - -/* -================= -Cmd_Test_f -================= -*/ -void Cmd_Test_f( gentity_t *ent ) -{ -  if( !CheatsOk( ent ) ) -    return; - -/*  ent->client->ps.stats[ STAT_STATE ] |= SS_POISONCLOUDED; -  ent->client->lastPoisonCloudedTime = level.time; -  ent->client->lastPoisonCloudedClient = ent; -  G_SendCommandFromServer( ent->client->ps.clientNum, "poisoncloud" );*/ - -/*  ent->client->ps.stats[ STAT_STATE ] |= SS_POISONED; -  ent->client->lastPoisonTime = level.time; -  ent->client->lastPoisonClient = ent;*/ -} - - -/* -================= -ClientCommand -================= -*/ -void ClientCommand( int clientNum ) -{ -  gentity_t *ent; -  char      cmd[ MAX_TOKEN_CHARS ]; - -  ent = g_entities + clientNum; -  if( !ent->client ) -    return;   // not fully in game yet - -  trap_Argv( 0, cmd, sizeof( cmd ) ); - -  if( Q_stricmp( cmd, "say" ) == 0 ) -  { -    Cmd_Say_f( ent, SAY_ALL, qfalse ); -    return; -  } - -  if( Q_stricmp( cmd, "say_team" ) == 0 ) -  { -    Cmd_Say_f( ent, SAY_TEAM, qfalse ); -    return; -  } - -  if( Q_stricmp( cmd, "tell" ) == 0 ) -  { -    Cmd_Tell_f( ent ); -    return; -  } - -  if( Q_stricmp( cmd, "score" ) == 0 ) -  { -    Cmd_Score_f( ent ); -    return; -  } - -  // ignore all other commands when at intermission -  if( level.intermissiontime ) -    return; - -  if( Q_stricmp( cmd, "give" ) == 0 ) -    Cmd_Give_f( ent ); -  else if( Q_stricmp( cmd, "god" ) == 0 ) -    Cmd_God_f( ent ); -  else if( Q_stricmp( cmd, "notarget" ) == 0 ) -    Cmd_Notarget_f( ent ); -  else if( Q_stricmp( cmd, "noclip" ) == 0 ) -    Cmd_Noclip_f( ent ); -  else if( Q_stricmp( cmd, "kill" ) == 0 ) -    Cmd_Kill_f( ent ); -  else if( Q_stricmp( cmd, "levelshot" ) == 0 ) -    Cmd_LevelShot_f( ent ); -  else if( Q_stricmp( cmd, "team" ) == 0 ) -    Cmd_Team_f( ent ); -  else if( Q_stricmp( cmd, "class" ) == 0 ) -    Cmd_Class_f( ent ); -  else if( Q_stricmp( cmd, "build" ) == 0 ) -    Cmd_Build_f( ent ); -  else if( Q_stricmp( cmd, "buy" ) == 0 ) -    Cmd_Buy_f( ent ); -  else if( Q_stricmp( cmd, "sell" ) == 0 ) -    Cmd_Sell_f( ent ); -  else if( Q_stricmp( cmd, "itemact" ) == 0 ) -    Cmd_ActivateItem_f( ent ); -  else if( Q_stricmp( cmd, "itemdeact" ) == 0 ) -    Cmd_DeActivateItem_f( ent ); -  else if( Q_stricmp( cmd, "itemtoggle" ) == 0 ) -    Cmd_ToggleItem_f( ent ); -  else if( Q_stricmp( cmd, "destroy" ) == 0 ) -    Cmd_Destroy_f( ent, qfalse ); -  else if( Q_stricmp( cmd, "deconstruct" ) == 0 ) -    Cmd_Destroy_f( ent, qtrue ); -  else if( Q_stricmp( cmd, "reload" ) == 0 ) -    Cmd_Reload_f( ent ); -  else if( Q_stricmp( cmd, "boost" ) == 0 ) -    Cmd_Boost_f( ent ); -  else if( Q_stricmp( cmd, "where" ) == 0 ) -    Cmd_Where_f( ent ); -  else if( Q_stricmp( cmd, "callvote" ) == 0 ) -    Cmd_CallVote_f( ent ); -  else if( Q_stricmp( cmd, "vote" ) == 0 ) -    Cmd_Vote_f( ent ); -  else if( Q_stricmp( cmd, "callteamvote" ) == 0 ) -    Cmd_CallTeamVote_f( ent ); -  else if( Q_stricmp( cmd, "follow" ) == 0 ) -    Cmd_Follow_f( ent, qfalse ); -  else if( Q_stricmp (cmd, "follownext") == 0) -    Cmd_FollowCycle_f( ent, 1 ); -  else if( Q_stricmp( cmd, "followprev" ) == 0 ) -    Cmd_FollowCycle_f( ent, -1 ); -  else if( Q_stricmp( cmd, "teamvote" ) == 0 ) -    Cmd_TeamVote_f( ent ); -  else if( Q_stricmp( cmd, "setviewpos" ) == 0 ) -    Cmd_SetViewpos_f( ent ); -  else if( Q_stricmp( cmd, "ptrcverify" ) == 0 ) -    Cmd_PTRCVerify_f( ent ); -  else if( Q_stricmp( cmd, "ptrcrestore" ) == 0 ) -    Cmd_PTRCRestore_f( ent ); -  else if( Q_stricmp( cmd, "test" ) == 0 ) -    Cmd_Test_f( ent ); -  else -    G_SendCommandFromServer( clientNum, va( "print \"unknown cmd %s\n\"", cmd ) ); -} diff --git a/mod/src/game/g_combat.c b/mod/src/game/g_combat.c deleted file mode 100644 index d98f74c3..00000000 --- a/mod/src/game/g_combat.c +++ /dev/null @@ -1,1322 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// g_combat.c - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -damageRegion_t  g_damageRegions[ PCL_NUM_CLASSES ][ MAX_LOCDAMAGE_REGIONS ]; -int             g_numDamageRegions[ PCL_NUM_CLASSES ]; - -armourRegion_t  g_armourRegions[ UP_NUM_UPGRADES ][ MAX_ARMOUR_REGIONS ]; -int             g_numArmourRegions[ UP_NUM_UPGRADES ]; - -/* -============ -AddScore - -Adds score to both the client and his team -============ -*/ -void AddScore( gentity_t *ent, int score ) -{ -  if( !ent->client ) -    return; - -  // no scoring during pre-match warmup -  if( level.warmupTime ) -    return; - -  ent->client->ps.persistant[ PERS_SCORE ] += score; -  CalculateRanks( ); -} - -/* -================== -LookAtKiller -================== -*/ -void LookAtKiller( gentity_t *self, gentity_t *inflictor, gentity_t *attacker ) -{ -  vec3_t    dir; - -  if ( attacker && attacker != self ) -    VectorSubtract( attacker->s.pos.trBase, self->s.pos.trBase, dir ); -  else if( inflictor && inflictor != self ) -    VectorSubtract( inflictor->s.pos.trBase, self->s.pos.trBase, dir ); -  else -  { -    self->client->ps.stats[ STAT_VIEWLOCK ] = self->s.angles[ YAW ]; -    return; -  } - -  self->client->ps.stats[ STAT_VIEWLOCK ] = vectoyaw( dir ); -} - -// these are just for logging, the client prints its own messages -char *modNames[ ] = -{ -  "MOD_UNKNOWN", -  "MOD_SHOTGUN", -  "MOD_BLASTER", -  "MOD_PAINSAW", -  "MOD_MACHINEGUN", -  "MOD_CHAINGUN", -  "MOD_PRIFLE", -  "MOD_MDRIVER", -  "MOD_LASGUN", -  "MOD_LCANNON", -  "MOD_LCANNON_SPLASH", -  "MOD_FLAMER", -  "MOD_FLAMER_SPLASH", -  "MOD_GRENADE", -  "MOD_WATER", -  "MOD_SLIME", -  "MOD_LAVA", -  "MOD_CRUSH", -  "MOD_TELEFRAG", -  "MOD_FALLING", -  "MOD_SUICIDE", -  "MOD_TARGET_LASER", -  "MOD_TRIGGER_HURT", - -  "MOD_ABUILDER_CLAW", -  "MOD_LEVEL0_BITE", -  "MOD_LEVEL1_CLAW", -  "MOD_LEVEL1_PCLOUD", -  "MOD_LEVEL3_CLAW", -  "MOD_LEVEL3_POUNCE", -  "MOD_LEVEL3_BOUNCEBALL", -  "MOD_LEVEL2_CLAW", -  "MOD_LEVEL2_ZAP", -  "MOD_LEVEL4_CLAW", -  "MOD_LEVEL4_CHARGE", - -  "MOD_SLOWBLOB", -  "MOD_POISON", -  "MOD_SWARM", - -  "MOD_HSPAWN", -  "MOD_TESLAGEN", -  "MOD_MGTURRET", -  "MOD_REACTOR", - -  "MOD_ASPAWN", -  "MOD_ATUBE", -  "MOD_OVERMIND" -}; - -/* -================== -player_die -================== -*/ -void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) -{ -  gentity_t *ent; -  int       anim; -  int       killer; -  int       i, j; -  char      *killerName, *obit; -  float     totalDamage = 0.0f; -  gentity_t *player; - - -  if( self->client->ps.pm_type == PM_DEAD ) -    return; - -  if( level.intermissiontime ) -    return; - -  // stop any following clients -  for( i = 0; i < level.maxclients; i++ ) -  { -    if( level.clients[ i ].sess.sessionTeam == TEAM_SPECTATOR && -        level.clients[ i ].sess.spectatorState == SPECTATOR_FOLLOW && -        level.clients[ i ].sess.spectatorClient == self->client->ps.clientNum ) -    { -      if( !G_FollowNewClient( &g_entities[ i ], 1 ) ) -        G_StopFollowing( &g_entities[ i ] ); -    } -  } - -  self->client->ps.pm_type = PM_DEAD; -  self->suicideTime = 0; - -  if( attacker ) -  { -    killer = attacker->s.number; - -    if( attacker->client ) -      killerName = attacker->client->pers.netname; -    else -      killerName = "<non-client>"; -  } -  else -  { -    killer = ENTITYNUM_WORLD; -    killerName = "<world>"; -  } - -  if( killer < 0 || killer >= MAX_CLIENTS ) -  { -    killer = ENTITYNUM_WORLD; -    killerName = "<world>"; -  } - -  if( meansOfDeath < 0 || meansOfDeath >= sizeof( modNames ) / sizeof( modNames[0] ) ) -    obit = "<bad obituary>"; -  else -    obit = modNames[ meansOfDeath ]; - -  G_LogPrintf("Kill: %i %i %i: %s killed %s by %s\n", -    killer, self->s.number, meansOfDeath, killerName, -    self->client->pers.netname, obit ); - -  //TA: close any menus the client has open -  G_CloseMenus( self->client->ps.clientNum ); - -  //TA: deactivate all upgrades -  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -    BG_DeactivateUpgrade( i, self->client->ps.stats ); - -  // broadcast the death event to everyone -  ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY ); -  ent->s.eventParm = meansOfDeath; -  ent->s.otherEntityNum = self->s.number; -  ent->s.otherEntityNum2 = killer; -  ent->r.svFlags = SVF_BROADCAST; // send to everyone - -  self->enemy = attacker; - -  self->client->ps.persistant[ PERS_KILLED ]++; - -  if( attacker && attacker->client ) -  { -    attacker->client->lastkilled_client = self->s.number; - -    if( attacker == self || OnSameTeam( self, attacker ) ) -    { -      AddScore( attacker, -1 ); - -      //punish team kills and suicides -      if( attacker->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -        G_AddCreditToClient( attacker->client, -1, qtrue ); -      else if( attacker->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -        G_AddCreditToClient( attacker->client, -ASPAWN_VALUE, qtrue ); -    } -    else -    { -      AddScore( attacker, 1 ); - -      attacker->client->lastKillTime = level.time; -    } -  } -  else if( attacker->s.eType != ET_BUILDABLE ) -    AddScore( self, -1 ); - -  //total up all the damage done by every client -  for( i = 0; i < MAX_CLIENTS; i++ ) -    totalDamage += (float)self->credits[ i ]; - -  // if players did more than DAMAGE_FRACTION_FOR_KILL increment the stage counters -  if( totalDamage >= ( self->client->ps.stats[ STAT_MAX_HEALTH ] * DAMAGE_FRACTION_FOR_KILL ) ) -  { -    if( self->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -      trap_Cvar_Set( "g_alienKills", va( "%d", g_alienKills.integer + 1 ) ); -    else if( self->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -      trap_Cvar_Set( "g_humanKills", va( "%d", g_humanKills.integer + 1 ) ); -  } - -  if( totalDamage > 0.0f ) -  { -    if( self->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -    { -      //nice simple happy bouncy human land -      float classValue = BG_FindValueOfClass( self->client->ps.stats[ STAT_PCLASS ] ); - -      for( i = 0; i < MAX_CLIENTS; i++ ) -      { -        player = g_entities + i; - -        if( !player->client ) -          continue; - -        if( player->client->ps.stats[ STAT_PTEAM ] != PTE_HUMANS ) -          continue; - -        if( !self->credits[ i ] ) -          continue; - -        //add credit -        G_AddCreditToClient( player->client, -            (int)( classValue * ( (float)self->credits[ i ] / totalDamage ) ), qtrue ); -      } -    } -    else if( self->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -    { -      //horribly complex nasty alien land -      float humanValue = BG_GetValueOfHuman( &self->client->ps ); -      int   frags; -      int   unclaimedFrags = (int)humanValue; - -      for( i = 0; i < MAX_CLIENTS; i++ ) -      { -        player = g_entities + i; - -        if( !player->client ) -          continue; - -        if( player->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS ) -          continue; - -        //this client did no damage -        if( !self->credits[ i ] ) -          continue; - -        //nothing left to claim -        if( !unclaimedFrags ) -          break; - -        frags = (int)floor( humanValue * ( (float)self->credits[ i ] / totalDamage ) ); - -        if( frags > 0 ) -        { -          //add kills -          G_AddCreditToClient( player->client, frags, qtrue ); - -          //can't revist this account later -          self->credits[ i ] = 0; - -          //reduce frags left to be claimed -          unclaimedFrags -= frags; -        } -      } - -      //there are frags still to be claimed -      if( unclaimedFrags ) -      { -        //the clients remaining at this point do not -        //have enough credit to claim even one frag -        //so simply give the top <unclaimedFrags> clients -        //a frag each - -        for( i = 0; i < unclaimedFrags; i++ ) -        { -          int maximum = 0; -          int topClient = 0; - -          for( j = 0; j < MAX_CLIENTS; j++ ) -          { -            //this client did no damage -            if( !self->credits[ j ] ) -              continue; - -            if( self->credits[ j ] > maximum ) -            { -              maximum = self->credits[ j ]; -              topClient = j; -            } -          } - -          if( maximum > 0 ) -          { -            player = g_entities + topClient; - -            //add kills -            G_AddCreditToClient( player->client, 1, qtrue ); - -            //can't revist this account again -            self->credits[ topClient ] = 0; -          } -        } -      } -    } -  } - -  Cmd_Score_f( self );    // show scores - -  // send updated scores to any clients that are following this one, -  // or they would get stale scoreboards -  for( i = 0 ; i < level.maxclients ; i++ ) -  { -    gclient_t *client; - -    client = &level.clients[ i ]; -    if( client->pers.connected != CON_CONNECTED ) -      continue; - -    if( client->sess.sessionTeam != TEAM_SPECTATOR ) -      continue; - -    if( client->sess.spectatorClient == self->s.number ) -      Cmd_Score_f( g_entities + i ); -  } - -  self->client->pers.classSelection = PCL_NONE; //TA: reset the classtype -  VectorCopy( self->s.origin, self->client->pers.lastDeathLocation ); - -  self->takedamage = qfalse; // can still be gibbed - -  self->s.weapon = WP_NONE; -  self->r.contents = CONTENTS_CORPSE; - -  self->s.angles[ PITCH ] = 0; -  self->s.angles[ ROLL ] = 0; -  self->s.angles[ YAW ] = self->s.apos.trBase[ YAW ]; -  LookAtKiller( self, inflictor, attacker ); - -  VectorCopy( self->s.angles, self->client->ps.viewangles ); - -  self->s.loopSound = 0; - -  self->r.maxs[ 2 ] = -8; - -  // don't allow respawn until the death anim is done -  // g_forcerespawn may force spawning at some later time -  self->client->respawnTime = level.time + 1700; - -  // remove powerups -  memset( self->client->ps.powerups, 0, sizeof( self->client->ps.powerups ) ); - -  { -    // normal death -    static int i; - -    if( !( self->client->ps.persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -    { -      switch( i ) -      { -        case 0: -          anim = BOTH_DEATH1; -          break; -        case 1: -          anim = BOTH_DEATH2; -          break; -        case 2: -        default: -          anim = BOTH_DEATH3; -          break; -      } -    } -    else -    { -      switch( i ) -      { -        case 0: -          anim = NSPA_DEATH1; -          break; -        case 1: -          anim = NSPA_DEATH2; -          break; -        case 2: -        default: -          anim = NSPA_DEATH3; -          break; -      } -    } - -    self->client->ps.legsAnim = -      ( ( self->client->ps.legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim; - -    if( !( self->client->ps.persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) -    { -      self->client->ps.torsoAnim = -        ( ( self->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim; -    } - -    G_AddEvent( self, EV_DEATH1 + i, killer ); - -    // globally cycle through the different death animations -    i = ( i + 1 ) % 3; -  } - -  trap_LinkEntity( self ); -} - - -////////TA: locdamage - -/* -=============== -G_ParseArmourScript -=============== -*/ -void G_ParseArmourScript( char *buf, int upgrade ) -{ -  char  *token; -  int   count; - -  count = 0; - -  while( 1 ) -  { -    token = COM_Parse( &buf ); - -    if( !token[0] ) -      break; - -    if( strcmp( token, "{" ) ) -    { -      G_Printf( "Missing { in armour file\n" ); -      break; -    } - -    if( count == MAX_ARMOUR_REGIONS ) -    { -      G_Printf( "Max armour regions exceeded in locdamage file\n" ); -      break; -    } - -    //default -    g_armourRegions[ upgrade ][ count ].minHeight = 0.0; -    g_armourRegions[ upgrade ][ count ].maxHeight = 1.0; -    g_armourRegions[ upgrade ][ count ].minAngle = 0; -    g_armourRegions[ upgrade ][ count ].maxAngle = 360; -    g_armourRegions[ upgrade ][ count ].modifier = 1.0; -    g_armourRegions[ upgrade ][ count ].crouch = qfalse; - -    while( 1 ) -    { -      token = COM_ParseExt( &buf, qtrue ); - -      if( !token[0] ) -      { -        G_Printf( "Unexpected end of armour file\n" ); -        break; -      } - -      if( !Q_stricmp( token, "}" ) ) -      { -        break; -      } -      else if( !strcmp( token, "minHeight" ) ) -      { -        token = COM_ParseExt( &buf, qfalse ); - -        if ( !token[0] ) -          strcpy( token, "0" ); - -        g_armourRegions[ upgrade ][ count ].minHeight = atof( token ); -      } -      else if( !strcmp( token, "maxHeight" ) ) -      { -        token = COM_ParseExt( &buf, qfalse ); - -        if ( !token[0] ) -          strcpy( token, "100" ); - -        g_armourRegions[ upgrade ][ count ].maxHeight = atof( token ); -      } -      else if( !strcmp( token, "minAngle" ) ) -      { -        token = COM_ParseExt( &buf, qfalse ); - -        if ( !token[0] ) -          strcpy( token, "0" ); - -        g_armourRegions[ upgrade ][ count ].minAngle = atoi( token ); -      } -      else if( !strcmp( token, "maxAngle" ) ) -      { -        token = COM_ParseExt( &buf, qfalse ); - -        if ( !token[0] ) -          strcpy( token, "360" ); - -        g_armourRegions[ upgrade ][ count ].maxAngle = atoi( token ); -      } -      else if( !strcmp( token, "modifier" ) ) -      { -        token = COM_ParseExt( &buf, qfalse ); - -        if ( !token[0] ) -          strcpy( token, "1.0" ); - -        g_armourRegions[ upgrade ][ count ].modifier = atof( token ); -      } -      else if( !strcmp( token, "crouch" ) ) -      { -        g_armourRegions[ upgrade ][ count ].crouch = qtrue; -      } -    } - -    g_numArmourRegions[ upgrade ]++; -    count++; -  } -} - - -/* -=============== -G_ParseDmgScript -=============== -*/ -void G_ParseDmgScript( char *buf, int class ) -{ -  char  *token; -  int   count; - -  count = 0; - -  while( 1 ) -  { -    token = COM_Parse( &buf ); - -    if( !token[0] ) -      break; - -    if( strcmp( token, "{" ) ) -    { -      G_Printf( "Missing { in locdamage file\n" ); -      break; -    } - -    if( count == MAX_LOCDAMAGE_REGIONS ) -    { -      G_Printf( "Max damage regions exceeded in locdamage file\n" ); -      break; -    } - -    //default -    g_damageRegions[ class ][ count ].minHeight = 0.0; -    g_damageRegions[ class ][ count ].maxHeight = 1.0; -    g_damageRegions[ class ][ count ].minAngle = 0; -    g_damageRegions[ class ][ count ].maxAngle = 360; -    g_damageRegions[ class ][ count ].modifier = 1.0; -    g_damageRegions[ class ][ count ].crouch = qfalse; - -    while( 1 ) -    { -      token = COM_ParseExt( &buf, qtrue ); - -      if( !token[0] ) -      { -        G_Printf( "Unexpected end of locdamage file\n" ); -        break; -      } - -      if( !Q_stricmp( token, "}" ) ) -      { -        break; -      } -      else if( !strcmp( token, "minHeight" ) ) -      { -        token = COM_ParseExt( &buf, qfalse ); - -        if ( !token[0] ) -          strcpy( token, "0" ); - -        g_damageRegions[ class ][ count ].minHeight = atof( token ); -      } -      else if( !strcmp( token, "maxHeight" ) ) -      { -        token = COM_ParseExt( &buf, qfalse ); - -        if ( !token[0] ) -          strcpy( token, "100" ); - -        g_damageRegions[ class ][ count ].maxHeight = atof( token ); -      } -      else if( !strcmp( token, "minAngle" ) ) -      { -        token = COM_ParseExt( &buf, qfalse ); - -        if ( !token[0] ) -          strcpy( token, "0" ); - -        g_damageRegions[ class ][ count ].minAngle = atoi( token ); -      } -      else if( !strcmp( token, "maxAngle" ) ) -      { -        token = COM_ParseExt( &buf, qfalse ); - -        if ( !token[0] ) -          strcpy( token, "360" ); - -        g_damageRegions[ class ][ count ].maxAngle = atoi( token ); -      } -      else if( !strcmp( token, "modifier" ) ) -      { -        token = COM_ParseExt( &buf, qfalse ); - -        if ( !token[0] ) -          strcpy( token, "1.0" ); - -        g_damageRegions[ class ][ count ].modifier = atof( token ); -      } -      else if( !strcmp( token, "crouch" ) ) -      { -        g_damageRegions[ class ][ count ].crouch = qtrue; -      } -    } - -    g_numDamageRegions[ class ]++; -    count++; -  } -} - - -/* -============ -G_CalcDamageModifier -============ -*/ -static float G_CalcDamageModifier( vec3_t point, gentity_t *targ, gentity_t *attacker, int class, int dflags ) -{ -  vec3_t  bulletPath; -  vec3_t  bulletAngle; -  vec3_t  pMINUSfloor, floor, normal; - -  float   clientHeight, hitRelative, hitRatio; -  int     bulletRotation, clientRotation, hitRotation; -  float   modifier = 1.0f; -  int     i, j; - -  if( point == NULL ) -    return 1.0f; - -  clientHeight = targ->r.maxs[ 2 ] - targ->r.mins[ 2 ]; - -  if( targ->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBING ) -    VectorCopy( targ->client->ps.grapplePoint, normal ); -  else -    VectorSet( normal, 0, 0, 1 ); - -  VectorMA( targ->r.currentOrigin, targ->r.mins[ 2 ], normal, floor ); -  VectorSubtract( point, floor, pMINUSfloor ); - -  hitRelative = DotProduct( normal, pMINUSfloor ) / VectorLength( normal ); - -  if( hitRelative < 0.0f ) -    hitRelative = 0.0f; - -  if( hitRelative > clientHeight ) -    hitRelative = clientHeight; - -  hitRatio = hitRelative / clientHeight; - -  VectorSubtract( targ->r.currentOrigin, point, bulletPath ); -  vectoangles( bulletPath, bulletAngle ); - -  clientRotation = targ->client->ps.viewangles[ YAW ]; -  bulletRotation = bulletAngle[ YAW ]; - -  hitRotation = abs( clientRotation - bulletRotation ); - -  hitRotation = hitRotation % 360; // Keep it in the 0-359 range - -  if( dflags & DAMAGE_NO_LOCDAMAGE ) -  { -    for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -    { -      float totalModifier = 0.0f; -      float averageModifier = 1.0f; - -      //average all of this upgrade's armour regions together -      if( BG_InventoryContainsUpgrade( i, targ->client->ps.stats ) ) -      { -        for( j = 0; j < g_numArmourRegions[ i ]; j++ ) -          totalModifier += g_armourRegions[ i ][ j ].modifier; - -        if( g_numArmourRegions[ i ] ) -          averageModifier = totalModifier / g_numArmourRegions[ i ]; -        else -          averageModifier = 1.0f; -      } - -      modifier *= averageModifier; -    } -  } -  else -  { -    for( i = 0; i < g_numDamageRegions[ class ]; i++ ) -    { -      qboolean rotationBound; - -      if( g_damageRegions[ class ][ i ].minAngle > -          g_damageRegions[ class ][ i ].maxAngle ) -      { -        rotationBound = ( hitRotation >= g_damageRegions[ class ][ i ].minAngle && -                          hitRotation <= 360 ) || ( hitRotation >= 0 && -                          hitRotation <= g_damageRegions[ class ][ i ].maxAngle ); -      } -      else -      { -        rotationBound = ( hitRotation >= g_damageRegions[ class ][ i ].minAngle && -                          hitRotation <= g_damageRegions[ class ][ i ].maxAngle ); -      } - -      if( rotationBound && -          hitRatio >= g_damageRegions[ class ][ i ].minHeight && -          hitRatio <= g_damageRegions[ class ][ i ].maxHeight && -          ( g_damageRegions[ class ][ i ].crouch == -            ( targ->client->ps.pm_flags & PMF_DUCKED ) ) ) -        modifier *= g_damageRegions[ class ][ i ].modifier; -    } - -    for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -    { -      if( BG_InventoryContainsUpgrade( i, targ->client->ps.stats ) ) -      { -        for( j = 0; j < g_numArmourRegions[ i ]; j++ ) -        { -          qboolean rotationBound; - -          if( g_armourRegions[ i ][ j ].minAngle > -              g_armourRegions[ i ][ j ].maxAngle ) -          { -            rotationBound = ( hitRotation >= g_armourRegions[ i ][ j ].minAngle && -                              hitRotation <= 360 ) || ( hitRotation >= 0 && -                              hitRotation <= g_armourRegions[ i ][ j ].maxAngle ); -          } -          else -          { -            rotationBound = ( hitRotation >= g_armourRegions[ i ][ j ].minAngle && -                              hitRotation <= g_armourRegions[ i ][ j ].maxAngle ); -          } - -          if( rotationBound && -              hitRatio >= g_armourRegions[ i ][ j ].minHeight && -              hitRatio <= g_armourRegions[ i ][ j ].maxHeight && -              ( g_armourRegions[ i ][ j ].crouch == -                ( targ->client->ps.pm_flags & PMF_DUCKED ) ) ) -            modifier *= g_armourRegions[ i ][ j ].modifier; -        } -      } -    } -  } - -  return modifier; -} - - -/* -============ -G_InitDamageLocations -============ -*/ -void G_InitDamageLocations( void ) -{ -  char          *modelName; -  char          filename[ MAX_QPATH ]; -  int           i; -  int           len; -  fileHandle_t  fileHandle; -  char          buffer[ MAX_LOCDAMAGE_TEXT ]; - -  for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ ) -  { -    modelName = BG_FindModelNameForClass( i ); -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/locdamage.cfg", modelName ); - -    len = trap_FS_FOpenFile( filename, &fileHandle, FS_READ ); -    if ( !fileHandle ) -    { -      G_Printf( va( S_COLOR_RED "file not found: %s\n", filename ) ); -      continue; -    } - -    if( len >= MAX_LOCDAMAGE_TEXT ) -    { -      G_Printf( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_LOCDAMAGE_TEXT ) ); -      trap_FS_FCloseFile( fileHandle ); -      continue; -    } - -    trap_FS_Read( buffer, len, fileHandle ); -    buffer[len] = 0; -    trap_FS_FCloseFile( fileHandle ); - -    G_ParseDmgScript( buffer, i ); -  } - -  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -  { -    modelName = BG_FindNameForUpgrade( i ); -    Com_sprintf( filename, sizeof( filename ), "armour/%s.armour", modelName ); - -    len = trap_FS_FOpenFile( filename, &fileHandle, FS_READ ); - -    //no file - no parsage -    if ( !fileHandle ) -      continue; - -    if( len >= MAX_LOCDAMAGE_TEXT ) -    { -      G_Printf( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_LOCDAMAGE_TEXT ) ); -      trap_FS_FCloseFile( fileHandle ); -      continue; -    } - -    trap_FS_Read( buffer, len, fileHandle ); -    buffer[len] = 0; -    trap_FS_FCloseFile( fileHandle ); - -    G_ParseArmourScript( buffer, i ); -  } -} - -////////TA: locdamage - - -/* -============ -T_Damage - -targ    entity that is being damaged -inflictor entity that is causing the damage -attacker  entity that caused the inflictor to damage targ -  example: targ=monster, inflictor=rocket, attacker=player - -dir     direction of the attack for knockback -point   point at which the damage is being inflicted, used for headshots -damage    amount of damage being inflicted -knockback force to be applied against targ as a result of the damage - -inflictor, attacker, dir, and point can be NULL for environmental effects - -dflags    these flags are used to control how T_Damage works -  DAMAGE_RADIUS     damage was indirect (from a nearby explosion) -  DAMAGE_NO_ARMOR     armor does not protect from this damage -  DAMAGE_NO_KNOCKBACK   do not affect velocity, just view angles -  DAMAGE_NO_PROTECTION  kills godmode, armor, everything -============ -*/ - -//TA: team is the team that is immune to this damage -void G_SelectiveDamage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, -         vec3_t dir, vec3_t point, int damage, int dflags, int mod, int team ) -{ -  if( targ->client && ( team != targ->client->ps.stats[ STAT_PTEAM ] ) ) -    G_Damage( targ, inflictor, attacker, dir, point, damage, dflags, mod ); -} - -void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, -         vec3_t dir, vec3_t point, int damage, int dflags, int mod ) -{ -  gclient_t *client; -  int     take; -  int     save; -  int     asave = 0; -  int     knockback; - -  if( !targ->takedamage ) -    return; - -  // the intermission has allready been qualified for, so don't -  // allow any extra scoring -  if( level.intermissionQueued ) -    return; - -  if( !inflictor ) -    inflictor = &g_entities[ ENTITYNUM_WORLD ]; - -  if( !attacker ) -    attacker = &g_entities[ ENTITYNUM_WORLD ]; - -  // shootable doors / buttons don't actually have any health -  if( targ->s.eType == ET_MOVER ) -  { -    if( targ->use && ( targ->moverState == MOVER_POS1 || -                       targ->moverState == ROTATOR_POS1 ) ) -      targ->use( targ, inflictor, attacker ); - -    return; -  } - -  client = targ->client; - -  if( client ) -  { -    if( client->noclip ) -      return; -  } - -  if( !dir ) -    dflags |= DAMAGE_NO_KNOCKBACK; -  else -    VectorNormalize( dir ); - -  knockback = damage; - -  // silly hack to give norf his knockbacking teslas -  if( !strcmp( inflictor->classname, "team_human_tesla" ) ) -    knockback *= 4; - -  if( targ->client ) -  { -    knockback = (int)( (float)knockback * -      BG_FindKnockbackScaleForClass( targ->client->ps.stats[ STAT_PCLASS ] ) ); -  } - -  if( knockback > 200 ) -    knockback = 200; - -  if( targ->flags & FL_NO_KNOCKBACK ) -    knockback = 0; - -  if( dflags & DAMAGE_NO_KNOCKBACK ) -    knockback = 0; - -  // figure momentum add, even if the damage won't be taken -  if( knockback && targ->client ) -  { -    vec3_t  kvel; -    float   mass; - -    mass = 200; - -    VectorScale( dir, g_knockback.value * (float)knockback / mass, kvel ); -    VectorAdd( targ->client->ps.velocity, kvel, targ->client->ps.velocity ); - -    // set the timer so that the other client can't cancel -    // out the movement immediately -    if( !targ->client->ps.pm_time ) -    { -      int   t; - -      t = knockback * 2; -      if( t < 50 ) -        t = 50; - -      if( t > 200 ) -        t = 200; - -      targ->client->ps.pm_time = t; -      targ->client->ps.pm_flags |= PMF_TIME_KNOCKBACK; -    } -  } - -  // check for completely getting out of the damage -  if( !( dflags & DAMAGE_NO_PROTECTION ) ) -  { - -    // if TF_NO_FRIENDLY_FIRE is set, don't do damage to the target -    // if the attacker was on the same team -    if( targ != attacker && OnSameTeam( targ, attacker ) ) -    { -      if( !g_friendlyFire.integer ) -        return; -    } - -    // check for godmode -    if ( targ->flags & FL_GODMODE ) -      return; -  } - -  // add to the attacker's hit counter -  if( attacker->client && targ != attacker && targ->health > 0 -      && targ->s.eType != ET_MISSILE -      && targ->s.eType != ET_GENERAL ) -  { -    if( OnSameTeam( targ, attacker ) ) -      attacker->client->ps.persistant[ PERS_HITS ]--; -    else -      attacker->client->ps.persistant[ PERS_HITS ]++; -  } - -  take = damage; -  save = 0; - -  // add to the damage inflicted on a player this frame -  // the total will be turned into screen blends and view angle kicks -  // at the end of the frame -  if( client ) -  { -    if( attacker ) -      client->ps.persistant[ PERS_ATTACKER ] = attacker->s.number; -    else -      client->ps.persistant[ PERS_ATTACKER ] = ENTITYNUM_WORLD; - -    client->damage_armor += asave; -    client->damage_blood += take; -    client->damage_knockback += knockback; - -    if( dir ) -    { -      VectorCopy ( dir, client->damage_from ); -      client->damage_fromWorld = qfalse; -    } -    else -    { -      VectorCopy ( targ->r.currentOrigin, client->damage_from ); -      client->damage_fromWorld = qtrue; -    } - -    // set the last client who damaged the target -    targ->client->lasthurt_client = attacker->s.number; -    targ->client->lasthurt_mod = mod; -    take = (int)( (float)take * G_CalcDamageModifier( point, targ, attacker, -                                                      client->ps.stats[ STAT_PCLASS ], dflags ) ); - -    //if boosted poison every attack -    if( attacker->client && attacker->client->ps.stats[ STAT_STATE ] & SS_BOOSTED ) -    { -      if( !( targ->client->ps.stats[ STAT_STATE ] & SS_POISONED ) && -          !BG_InventoryContainsUpgrade( UP_BATTLESUIT, targ->client->ps.stats ) && -          mod != MOD_LEVEL2_ZAP && -          targ->client->poisonImmunityTime < level.time ) -      { -        targ->client->ps.stats[ STAT_STATE ] |= SS_POISONED; -        targ->client->lastPoisonTime = level.time; -        targ->client->lastPoisonClient = attacker; -      } -    } -  } - -  if( take < 1 ) -    take = 1; - -  if( g_debugDamage.integer ) -  { -    G_Printf( "%i: client:%i health:%i damage:%i armor:%i\n", level.time, targ->s.number, -      targ->health, take, asave ); -  } - -  // do the damage -  if( take ) -  { -    targ->health = targ->health - take; - -    if( targ->client ) -      targ->client->ps.stats[ STAT_HEALTH ] = targ->health; - -    targ->lastDamageTime = level.time; - -    //TA: add to the attackers "account" on the target -    if( targ->client && attacker->client ) -    { -      if( attacker != targ && !OnSameTeam( targ, attacker ) ) -        targ->credits[ attacker->client->ps.clientNum ] += take; -    } - -    if( targ->health <= 0 ) -    { -      if( client ) -        targ->flags |= FL_NO_KNOCKBACK; - -      if( targ->health < -999 ) -        targ->health = -999; - -      targ->enemy = attacker; -      targ->die( targ, inflictor, attacker, take, mod ); -      return; -    } -    else if( targ->pain ) -      targ->pain( targ, attacker, take ); -  } -} - - -/* -============ -CanDamage - -Returns qtrue if the inflictor can directly damage the target.  Used for -explosions and melee attacks. -============ -*/ -qboolean CanDamage( gentity_t *targ, vec3_t origin ) -{ -  vec3_t  dest; -  trace_t tr; -  vec3_t  midpoint; - -  // use the midpoint of the bounds instead of the origin, because -  // bmodels may have their origin is 0,0,0 -  VectorAdd( targ->r.absmin, targ->r.absmax, midpoint ); -  VectorScale( midpoint, 0.5, midpoint ); - -  VectorCopy( midpoint, dest ); -  trap_Trace( &tr, origin, vec3_origin, vec3_origin, dest, ENTITYNUM_NONE, MASK_SOLID ); -  if( tr.fraction == 1.0  || tr.entityNum == targ->s.number ) -    return qtrue; - -  // this should probably check in the plane of projection, -  // rather than in world coordinate, and also include Z -  VectorCopy( midpoint, dest ); -  dest[ 0 ] += 15.0; -  dest[ 1 ] += 15.0; -  trap_Trace( &tr, origin, vec3_origin, vec3_origin, dest, ENTITYNUM_NONE, MASK_SOLID ); -  if( tr.fraction == 1.0 ) -    return qtrue; - -  VectorCopy( midpoint, dest ); -  dest[ 0 ] += 15.0; -  dest[ 1 ] -= 15.0; -  trap_Trace( &tr, origin, vec3_origin, vec3_origin, dest, ENTITYNUM_NONE, MASK_SOLID ); -  if( tr.fraction == 1.0 ) -    return qtrue; - -  VectorCopy( midpoint, dest ); -  dest[ 0 ] -= 15.0; -  dest[ 1 ] += 15.0; -  trap_Trace( &tr, origin, vec3_origin, vec3_origin, dest, ENTITYNUM_NONE, MASK_SOLID ); -  if( tr.fraction == 1.0 ) -    return qtrue; - -  VectorCopy( midpoint, dest ); -  dest[ 0 ] -= 15.0; -  dest[ 1 ] -= 15.0; -  trap_Trace( &tr, origin, vec3_origin, vec3_origin, dest, ENTITYNUM_NONE, MASK_SOLID ); -  if( tr.fraction == 1.0 ) -    return qtrue; - -  return qfalse; -} - - -//TA: -/* -============ -G_SelectiveRadiusDamage -============ -*/ -qboolean G_SelectiveRadiusDamage( vec3_t origin, gentity_t *attacker, float damage, -                                  float radius, gentity_t *ignore, int mod, int team ) -{ -  float     points, dist; -  gentity_t *ent; -  int       entityList[ MAX_GENTITIES ]; -  int       numListedEntities; -  vec3_t    mins, maxs; -  vec3_t    v; -  vec3_t    dir; -  int       i, e; -  qboolean  hitClient = qfalse; - -  if( radius < 1 ) -    radius = 1; - -  for( i = 0; i < 3; i++ ) -  { -    mins[ i ] = origin[ i ] - radius; -    maxs[ i ] = origin[ i ] + radius; -  } - -  numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); - -  for( e = 0; e < numListedEntities; e++ ) -  { -    ent = &g_entities[ entityList[ e ] ]; - -    if( ent == ignore ) -      continue; - -    if( !ent->takedamage ) -      continue; - -    // find the distance from the edge of the bounding box -    for( i = 0 ; i < 3 ; i++ ) -    { -      if( origin[ i ] < ent->r.absmin[ i ] ) -        v[ i ] = ent->r.absmin[ i ] - origin[ i ]; -      else if( origin[ i ] > ent->r.absmax[ i ] ) -        v[ i ] = origin[ i ] - ent->r.absmax[ i ]; -      else -        v[ i ] = 0; -    } - -    dist = VectorLength( v ); -    if( dist >= radius ) -      continue; - -    points = damage * ( 1.0 - dist / radius ); - -    if( CanDamage( ent, origin ) ) -    { -      VectorSubtract( ent->r.currentOrigin, origin, dir ); -      // push the center of mass higher than the origin so players -      // get knocked into the air more -      dir[ 2 ] += 24; -      G_SelectiveDamage( ent, NULL, attacker, dir, origin, -          (int)points, DAMAGE_RADIUS|DAMAGE_NO_LOCDAMAGE, mod, team ); -    } -  } - -  return hitClient; -} - - -/* -============ -G_RadiusDamage -============ -*/ -qboolean G_RadiusDamage( vec3_t origin, gentity_t *attacker, float damage, -                         float radius, gentity_t *ignore, int mod ) -{ -  float     points, dist; -  gentity_t *ent; -  int       entityList[ MAX_GENTITIES ]; -  int       numListedEntities; -  vec3_t    mins, maxs; -  vec3_t    v; -  vec3_t    dir; -  int       i, e; -  qboolean  hitClient = qfalse; - -  if( radius < 1 ) -    radius = 1; - -  for( i = 0; i < 3; i++ ) -  { -    mins[ i ] = origin[ i ] - radius; -    maxs[ i ] = origin[ i ] + radius; -  } - -  numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); - -  for( e = 0; e < numListedEntities; e++ ) -  { -    ent = &g_entities[ entityList[ e ] ]; - -    if( ent == ignore ) -      continue; - -    if( !ent->takedamage ) -      continue; - -    // find the distance from the edge of the bounding box -    for( i = 0; i < 3; i++ ) -    { -      if( origin[ i ] < ent->r.absmin[ i ] ) -        v[ i ] = ent->r.absmin[ i ] - origin[ i ]; -      else if( origin[ i ] > ent->r.absmax[ i ] ) -        v[ i ] = origin[ i ] - ent->r.absmax[ i ]; -      else -        v[ i ] = 0; -    } - -    dist = VectorLength( v ); -    if( dist >= radius ) -      continue; - -    points = damage * ( 1.0 - dist / radius ); - -    if( CanDamage( ent, origin ) ) -    { -      VectorSubtract( ent->r.currentOrigin, origin, dir ); -      // push the center of mass higher than the origin so players -      // get knocked into the air more -      dir[ 2 ] += 24; -      G_Damage( ent, NULL, attacker, dir, origin, -          (int)points, DAMAGE_RADIUS|DAMAGE_NO_LOCDAMAGE, mod ); -    } -  } - -  return hitClient; -} diff --git a/mod/src/game/g_local.h b/mod/src/game/g_local.h deleted file mode 100644 index 57e1934a..00000000 --- a/mod/src/game/g_local.h +++ /dev/null @@ -1,1139 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// g_local.h -- local definitions for game module - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "q_shared.h" -#include "bg_public.h" -#include "g_public.h" - -//================================================================== - -// the "gameversion" client command will print this plus compile date -#define GAMEVERSION "tremulous" - -#define INFINITE      1000000 - -#define FRAMETIME     100         // msec -#define CARNAGE_REWARD_TIME 3000 -#define REWARD_SPRITE_TIME  2000 - -#define INTERMISSION_DELAY_TIME 1000 -#define SP_INTERMISSION_DELAY_TIME 5000 - -// gentity->flags -#define FL_GODMODE        0x00000010 -#define FL_NOTARGET       0x00000020 -#define FL_TEAMSLAVE      0x00000400  // not the first on the team -#define FL_NO_KNOCKBACK   0x00000800 -#define FL_DROPPED_ITEM   0x00001000 -#define FL_NO_BOTS        0x00002000  // spawn point not for bot use -#define FL_NO_HUMANS      0x00004000  // spawn point just for bots -#define FL_FORCE_GESTURE  0x00008000  // spawn point just for bots - -// movers are things like doors, plats, buttons, etc -typedef enum -{ -  MOVER_POS1, -  MOVER_POS2, -  MOVER_1TO2, -  MOVER_2TO1, - -  ROTATOR_POS1, -  ROTATOR_POS2, -  ROTATOR_1TO2, -  ROTATOR_2TO1, - -  MODEL_POS1, -  MODEL_POS2, -  MODEL_1TO2, -  MODEL_2TO1 -} moverState_t; - -#define SP_PODIUM_MODEL   "models/mapobjects/podium/podium4.md3" - -//============================================================================ - -typedef struct gentity_s gentity_t; -typedef struct gclient_s gclient_t; - -struct gentity_s -{ -  entityState_t     s;        // communicated by server to clients -  entityShared_t    r;        // shared by both the server system and game - -  // DO NOT MODIFY ANYTHING ABOVE THIS, THE SERVER -  // EXPECTS THE FIELDS IN THAT ORDER! -  //================================ - -  struct gclient_s  *client;        // NULL if not a client - -  qboolean          inuse; - -  char              *classname;     // set in QuakeEd -  int               spawnflags;     // set in QuakeEd - -  qboolean          neverFree;      // if true, FreeEntity will only unlink -                                    // bodyque uses this - -  int               flags;          // FL_* variables - -  char              *model; -  char              *model2; -  int               freetime;       // level.time when the object was freed - -  int               eventTime;      // events will be cleared EVENT_VALID_MSEC after set -  qboolean          freeAfterEvent; -  qboolean          unlinkAfterEvent; - -  qboolean          physicsObject;  // if true, it can be pushed by movers and fall off edges -                                    // all game items are physicsObjects, -  float             physicsBounce;  // 1.0 = continuous bounce, 0.0 = no bounce -  int               clipmask;       // brushes with this content value will be collided against -                                    // when moving.  items and corpses do not collide against -                                    // players, for instance - -  // movers -  moverState_t      moverState; -  int               soundPos1; -  int               sound1to2; -  int               sound2to1; -  int               soundPos2; -  int               soundLoop; -  gentity_t         *parent; -  gentity_t         *nextTrain; -  gentity_t         *prevTrain; -  vec3_t            pos1, pos2; -  float             rotatorAngle; -  gentity_t         *clipBrush;   //TA: clipping brush for model doors - -  char              *message; - -  int               timestamp;      // body queue sinking, etc - -  float             angle;          // set in editor, -1 = up, -2 = down -  char              *target; -  char              *targetname; -  char              *team; -  char              *targetShaderName; -  char              *targetShaderNewName; -  gentity_t         *target_ent; - -  float             speed; -  float             lastSpeed;  //TA: used by trains that have been restarted -  vec3_t            movedir; - -  //TA: acceleration evaluation -  qboolean          evaluateAcceleration; -  vec3_t            oldVelocity; -  vec3_t            acceleration; -  vec3_t            oldAccel; -  vec3_t            jerk; - -  int               nextthink; -  void              (*think)( gentity_t *self ); -  void              (*reached)( gentity_t *self );  // movers call this when hitting endpoint -  void              (*blocked)( gentity_t *self, gentity_t *other ); -  void              (*touch)( gentity_t *self, gentity_t *other, trace_t *trace ); -  void              (*use)( gentity_t *self, gentity_t *other, gentity_t *activator ); -  void              (*pain)( gentity_t *self, gentity_t *attacker, int damage ); -  void              (*die)( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ); - -  int               pain_debounce_time; -  int               fly_sound_debounce_time;  // wind tunnel -  int               last_move_time; - -  int               health; -  int               lastHealth; //TA: currently only used for overmind - -  qboolean          takedamage; - -  int               damage; -  int               splashDamage; // quad will increase this without increasing radius -  int               splashRadius; -  int               methodOfDeath; -  int               splashMethodOfDeath; -  int               chargeRepeat; - -  int               count; - -  gentity_t         *chain; -  gentity_t         *enemy; -  gentity_t         *activator; -  gentity_t         *teamchain;   // next entity in team -  gentity_t         *teammaster;  // master of the team - -  int               watertype; -  int               waterlevel; - -  int               noise_index; - -  // timing variables -  float             wait; -  float             random; - -  pTeam_t           stageTeam; -  stage_t           stageStage; - -  int               biteam;       //TA: buildable item team -  gentity_t         *parentNode;  //TA: for creep and defence/spawn dependencies -  qboolean          active;       //TA: for power repeater, but could be useful elsewhere -  qboolean          powered;      //TA: for human buildables -  int               builtBy;      //TA: clientNum of person that built this -  gentity_t         *dccNode;     //TA: controlling dcc -  gentity_t         *overmindNode;//TA: controlling overmind -  qboolean          dcced;        //TA: controlled by a dcc or not? -  qboolean          spawned;      //TA: whether or not this buildable has finished spawning -  int               buildTime;    //TA: when this buildable was built -  int               time1000;     //TA: timer evaluated every second -  int               overmindAttackTimer; -  int               overmindDyingTimer; -  int               overmindSpawnsTimer; -  int               nextPhysicsTime; //TA: buildables don't need to check what they're sitting on -                                     //    every single frame.. so only do it periodically -  int               clientSpawnTime; //TA: the time until this spawn can spawn a client -  qboolean          lev1Grabbed;      //TA: for turrets interacting with lev1s -  int               lev1GrabTime;     //TA: for turrets interacting with lev1s - -  int               credits[ MAX_CLIENTS ]; //TA: human credits for each client -  qboolean          creditsHash[ MAX_CLIENTS ]; //TA: track who has claimed credit -  int               killedBy;                   //TA: clientNum of killer - -  gentity_t         *targeted;    //TA: true if the player is currently a valid target of a turret -  vec3_t            turretAim;    //TA: aim vector for turrets - -  vec4_t            animation;    //TA: animated map objects - -  gentity_t         *builder;     //TA: occupant of this hovel - -  qboolean          nonSegModel;  //TA: this entity uses a nonsegmented player model - -  buildable_t       bTriggers[ BA_NUM_BUILDABLES ]; //TA: which buildables are triggers -  pClass_t          cTriggers[ PCL_NUM_CLASSES ];   //TA: which classes are triggers -  weapon_t          wTriggers[ WP_NUM_WEAPONS ];    //TA: which weapons are triggers -  upgrade_t         uTriggers[ UP_NUM_UPGRADES ];   //TA: which upgrades are triggers - -  int               triggerGravity;                 //TA: gravity for this trigger - -  int               suicideTime;  //TA: when the client will suicide - -  int               lastDamageTime; -}; - -typedef enum -{ -  CON_DISCONNECTED, -  CON_CONNECTING, -  CON_CONNECTED -} clientConnected_t; - -typedef enum -{ -  SPECTATOR_NOT, -  SPECTATOR_FREE, -  SPECTATOR_LOCKED, -  SPECTATOR_FOLLOW, -  SPECTATOR_SCOREBOARD -} spectatorState_t; - -typedef enum -{ -  TEAM_BEGIN,   // Beginning a team game, spawn at base -  TEAM_ACTIVE   // Now actively playing -} playerTeamStateState_t; - -typedef struct -{ -  playerTeamStateState_t  state; - -  int     location; - -  int     captures; -  int     basedefense; -  int     carrierdefense; -  int     flagrecovery; -  int     fragcarrier; -  int     assists; - -  float   lasthurtcarrier; -  float   lastreturnedflag; -  float   flagsince; -  float   lastfraggedcarrier; -} playerTeamState_t; - -// the auto following clients don't follow a specific client -// number, but instead follow the first two active players -#define FOLLOW_ACTIVE1  -1 -#define FOLLOW_ACTIVE2  -2 - -// client data that stays across multiple levels or tournament restarts -// this is achieved by writing all the data to cvar strings at game shutdown -// time and reading them back at connection time.  Anything added here -// MUST be dealt with in G_InitSessionData() / G_ReadSessionData() / G_WriteSessionData() -typedef struct -{ -  team_t            sessionTeam; -  int               spectatorTime;    // for determining next-in-line to play -  spectatorState_t  spectatorState; -  int               spectatorClient;  // for chasecam and follow mode -  int               wins, losses;     // tournament stats -  qboolean          teamLeader;       // true when this client is a team leader -} clientSession_t; - -#define MAX_NETNAME       36 -#define MAX_VOTE_COUNT    3 - -// data to store details of clients that have abnormally disconnected -typedef struct connectionRecord_s -{ -  int       clientNum; -  pTeam_t   clientTeam; -  int       clientCredit; - -  int       ptrCode; -} connectionRecord_t; - -// client data that stays across multiple respawns, but is cleared -// on each level change or team change at ClientBegin() -typedef struct -{ -  clientConnected_t   connected; -  usercmd_t           cmd;                // we would lose angles if not persistant -  qboolean            localClient;        // true if "ip" info key is "localhost" -  qboolean            initialSpawn;       // the first spawn should be at a cool location -  qboolean            predictItemPickup;  // based on cg_predictItems userinfo -  qboolean            pmoveFixed;         // -  char                netname[ MAX_NETNAME ]; -  int                 maxHealth;          // for handicapping -  int                 enterTime;          // level.time the client entered the game -  playerTeamState_t   teamState;          // status in teamplay games -  int                 voteCount;          // to prevent people from constantly calling votes -  int                 teamVoteCount;      // to prevent people from constantly calling votes -  qboolean            teamInfo;           // send team overlay updates? - -  pClass_t            classSelection;     //TA: player class (copied to ent->client->ps.stats[ STAT_PCLASS ] once spawned) -  float               evolveHealthFraction; -  weapon_t            humanItemSelection; //TA: humans have a starting item -  pTeam_t             teamSelection;      //TA: player team (copied to ps.stats[ STAT_PTEAM ]) - -  qboolean            joinedATeam;        //TA: used to tell when a PTR code is valid -  connectionRecord_t  *connection; - -  vec3_t              lastDeathLocation; -} clientPersistant_t; - -// this structure is cleared on each ClientSpawn(), -// except for 'client->pers' and 'client->sess' -struct gclient_s -{ -  // ps MUST be the first element, because the server expects it -  playerState_t       ps;       // communicated by server to clients - -  // the rest of the structure is private to game -  clientPersistant_t  pers; -  clientSession_t     sess; - -  qboolean            readyToExit;    // wishes to leave the intermission - -  qboolean            noclip; - -  int                 lastCmdTime;    // level.time of last usercmd_t, for EF_CONNECTION -                                      // we can't just use pers.lastCommand.time, because -                                      // of the g_sycronousclients case -  int                 buttons; -  int                 oldbuttons; -  int                 latched_buttons; - -  vec3_t              oldOrigin; - -  // sum up damage over an entire frame, so -  // shotgun blasts give a single big kick -  int                 damage_armor;     // damage absorbed by armor -  int                 damage_blood;     // damage taken out of health -  int                 damage_knockback; // impact damage -  vec3_t              damage_from;      // origin for vector calculation -  qboolean            damage_fromWorld; // if true, don't use the damage_from vector - -  // -  int                 lastkilled_client;// last client that this client killed -  int                 lasthurt_client;  // last client that damaged this client -  int                 lasthurt_mod;     // type of damage the client did - -  // timers -  int                 respawnTime;      // can respawn when time > this, force after g_forcerespwan -  int                 inactivityTime;   // kick players when time > this -  qboolean            inactivityWarning;// qtrue if the five seoond warning has been given -  int                 rewardTime;       // clear the EF_AWARD_IMPRESSIVE, etc when time > this - -  int                 airOutTime; - -  int                 lastKillTime;     // for multiple kill rewards - -  qboolean            fireHeld;         // used for hook -  qboolean            fire2Held;        // used for alt fire -  gentity_t           *hook;            // grapple hook if out - -  int                 switchTeamTime;   // time the player switched teams - -  // timeResidual is used to handle events that happen every second -  // like health / armor countdowns and regeneration -  //TA: two timers, one every 100 msecs, another every sec -  int                 time100; -  int                 time1000; -  int                 time10000; - -  char                *areabits; - -  gentity_t           *hovel;      //TA: body that is being infested. must be persistant - -  int                 lastPoisonTime; -  int                 poisonImmunityTime; -  gentity_t           *lastPoisonClient; -  int                 lastPoisonCloudedTime; -  gentity_t           *lastPoisonCloudedClient; -  int                 grabExpiryTime; -  int                 lastLockTime; -  int                 lastSlowTime; -  int                 lastBoostedTime; -  int                 lastMedKitTime; -  int                 medKitHealthToRestore; -  int                 medKitIncrementTime; -  int                 lastCreepSlowTime; //TA: time until creep can be removed - -  int                 pouncePayload;    //TA: amount of damage pounce attack will do -  qboolean            allowedToPounce; - -  qboolean            charging; - -  vec3_t              hovelOrigin;      //TA: player origin before entering hovel - -  int                 lastFlameBall;    //TA: s.number of the last flame ball fired - -#define RAM_FRAMES  1                       //TA: number of frames to wait before retriggering -  int                 retriggerArmouryMenu; //TA: frame number to retrigger the armoury menu -}; - - -typedef struct spawnQueue_s -{ -  int clients[ MAX_CLIENTS ]; - -  int front, back; -} spawnQueue_t; - -#define QUEUE_PLUS1(x)  (((x)+1)%MAX_CLIENTS) -#define QUEUE_MINUS1(x) (((x)+MAX_CLIENTS-1)%MAX_CLIENTS) - -void      G_InitSpawnQueue( spawnQueue_t *sq ); -int       G_GetSpawnQueueLength( spawnQueue_t *sq ); -int       G_PopSpawnQueue( spawnQueue_t *sq ); -int       G_PeekSpawnQueue( spawnQueue_t *sq ); -void      G_PushSpawnQueue( spawnQueue_t *sq, int clientNum ); -qboolean  G_RemoveFromSpawnQueue( spawnQueue_t *sq, int clientNum ); -int       G_GetPosInSpawnQueue( spawnQueue_t *sq, int clientNum ); - - -#define MAX_LOCDAMAGE_TEXT    8192 -#define MAX_LOCDAMAGE_REGIONS 16 - -//TA: store locational damage regions -typedef struct damageRegion_s -{ -  float     minHeight, maxHeight; -  int       minAngle, maxAngle; - -  float     modifier; - -  qboolean  crouch; -} damageRegion_t; - -#define MAX_ARMOUR_TEXT    8192 -#define MAX_ARMOUR_REGIONS 16 - -//TA: store locational armour regions -typedef struct armourRegion_s -{ -  float     minHeight, maxHeight; -  int       minAngle, maxAngle; - -  float     modifier; - -  qboolean  crouch; -} armourRegion_t; - -// -// this structure is cleared as each map is entered -// -#define MAX_SPAWN_VARS      64 -#define MAX_SPAWN_VARS_CHARS  4096 - -typedef struct -{ -  struct gclient_s  *clients;   // [maxclients] - -  struct gentity_s  *gentities; -  int               gentitySize; -  int               num_entities;   // current number, <= MAX_GENTITIES - -  int               warmupTime;     // restart match at this time - -  fileHandle_t      logFile; - -  // store latched cvars here that we want to get at often -  int               maxclients; - -  int               framenum; -  int               time;                         // in msec -  int               previousTime;                 // so movers can back up when blocked - -  int               startTime;                    // level.time the map was started - -  int               teamScores[ TEAM_NUM_TEAMS ]; -  int               lastTeamLocationTime;         // last time of client team location update - -  qboolean          newSession;                   // don't use any old session data, because -                                                  // we changed gametype - -  qboolean          restarted;                    // waiting for a map_restart to fire - -  int               numConnectedClients; -  int               numNonSpectatorClients;       // includes connecting clients -  int               numPlayingClients;            // connected, non-spectators -  int               sortedClients[MAX_CLIENTS];   // sorted by score -  int               follow1, follow2;             // clientNums for auto-follow spectators - -  int               snd_fry;                      // sound index for standing in lava - -  int               warmupModificationCount;      // for detecting if g_warmup is changed - -  // voting state -  char              voteString[MAX_STRING_CHARS]; -  char              voteDisplayString[MAX_STRING_CHARS]; -  int               voteTime;                     // level.time vote was called -  int               voteExecuteTime;              // time the vote is executed -  int               voteYes; -  int               voteNo; -  int               numVotingClients;             // set by CalculateRanks - -  // team voting state -  char              teamVoteString[ 2 ][ MAX_STRING_CHARS ]; -  int               teamVoteTime[ 2 ];            // level.time vote was called -  int               teamVoteYes[ 2 ]; -  int               teamVoteNo[ 2 ]; -  int               numteamVotingClients[ 2 ];    // set by CalculateRanks - -  // spawn variables -  qboolean          spawning;                     // the G_Spawn*() functions are valid -  int               numSpawnVars; -  char              *spawnVars[ MAX_SPAWN_VARS ][ 2 ];  // key / value pairs -  int               numSpawnVarChars; -  char              spawnVarChars[ MAX_SPAWN_VARS_CHARS ]; - -  // intermission state -  int               intermissionQueued;           // intermission was qualified, but -                                                  // wait INTERMISSION_DELAY_TIME before -                                                  // actually going there so the last -                                                  // frag can be watched.  Disable future -                                                  // kills during this delay -  int               intermissiontime;             // time the intermission was started -  char              *changemap; -  qboolean          readyToExit;                  // at least one client wants to exit -  int               exitTime; -  vec3_t            intermission_origin;          // also used for spectator spawns -  vec3_t            intermission_angle; - -  qboolean          locationLinked;               // target_locations get linked -  gentity_t         *locationHead;                // head of the location list - -  //TA: extra stuff: -  int               numAlienSpawns; -  int               numHumanSpawns; - -  int               numAlienClients; -  int               numHumanClients; - -  float             averageNumAlienClients; -  int               numAlienSamples; -  float             averageNumHumanClients; -  int               numHumanSamples; - -  int               numLiveAlienClients; -  int               numLiveHumanClients; - -  int               alienBuildPoints; -  int               humanBuildPoints; -  int               humanBuildPointsPowered; - -  int               bankCredits[ MAX_CLIENTS ];   //global credits storage - -  int               alienKills; -  int               humanKills; - -  qboolean          reactorPresent; -  qboolean          overmindPresent; - -  int               humanBaseAttackTimer; - -  pTeam_t           lastWin; - -  spawnQueue_t      alienSpawnQueue; -  spawnQueue_t      humanSpawnQueue; - -  int               alienStage2Time; -  int               alienStage3Time; -  int               humanStage2Time; -  int               humanStage3Time; - -  qboolean          uncondAlienWin; -  qboolean          uncondHumanWin; -} level_locals_t; - -// -// g_spawn.c -// -qboolean  G_SpawnString( const char *key, const char *defaultString, char **out ); -// spawn string returns a temporary reference, you must CopyString() if you want to keep it -qboolean  G_SpawnFloat( const char *key, const char *defaultString, float *out ); -qboolean  G_SpawnInt( const char *key, const char *defaultString, int *out ); -qboolean  G_SpawnVector( const char *key, const char *defaultString, float *out ); -void      G_SpawnEntitiesFromString( void ); -char      *G_NewString( const char *string ); - -// -// g_cmds.c -// -void      Cmd_Score_f( gentity_t *ent ); -void      G_StopFollowing( gentity_t *ent ); -qboolean  G_FollowNewClient( gentity_t *ent, int dir ); -void      Cmd_Follow_f( gentity_t *ent, qboolean toggle ); - -// -// g_physics.c -// -void G_Physics( gentity_t *ent, int msec ); - -// -// g_buildable.c -// - -#define MAX_ALIEN_BBOX  25 - -typedef enum -{ -  IBE_NONE, - -  IBE_NOOVERMIND, -  IBE_OVERMIND, -  IBE_NOASSERT, -  IBE_SPWNWARN, -  IBE_NOCREEP, -  IBE_HOVEL, -  IBE_HOVELEXIT, - -  IBE_REACTOR, -  IBE_REPEATER, -  IBE_TNODEWARN, -  IBE_RPTWARN, -  IBE_RPTWARN2, -  IBE_NOPOWER, -  IBE_NODCC, - -  IBE_NORMAL, -  IBE_NOROOM, -  IBE_PERMISSION, - -  IBE_MAXERRORS -} itemBuildError_t; - -qboolean          AHovel_Blocked( gentity_t *hovel, gentity_t *player, qboolean provideExit ); -gentity_t         *G_CheckSpawnPoint( int spawnNum, vec3_t origin, vec3_t normal, -                    buildable_t spawn, vec3_t spawnOrigin ); - -qboolean          G_isPower( vec3_t origin ); -qboolean          G_isDCC( void ); -qboolean          G_isOvermind( void ); - -void              G_BuildableThink( gentity_t *ent, int msec ); -qboolean          G_BuildableRange( vec3_t origin, float r, buildable_t buildable ); -itemBuildError_t  G_itemFits( gentity_t *ent, buildable_t buildable, int distance, vec3_t origin ); -gentity_t         *G_buildItem( gentity_t *builder, buildable_t buildable, vec3_t origin, vec3_t angles ); -qboolean          G_ValidateBuild( gentity_t *ent, buildable_t buildable ); -void              G_setBuildableAnim( gentity_t *ent, buildableAnimNumber_t anim, qboolean force ); -void              G_setIdleBuildableAnim( gentity_t *ent, buildableAnimNumber_t anim ); -void              G_SpawnBuildable(gentity_t *ent, buildable_t buildable); -void              FinishSpawningBuildable( gentity_t *ent ); - -// -// g_utils.c -// -int         G_ParticleSystemIndex( char *name ); -int         G_ShaderIndex( char *name ); -int         G_ModelIndex( char *name ); -int         G_SoundIndex( char *name ); -void        G_TeamCommand( pTeam_t team, char *cmd ); -void        G_KillBox (gentity_t *ent); -gentity_t   *G_Find (gentity_t *from, int fieldofs, const char *match); -gentity_t   *G_PickTarget (char *targetname); -void        G_UseTargets (gentity_t *ent, gentity_t *activator); -void        G_SetMovedir ( vec3_t angles, vec3_t movedir); - -void        G_InitGentity( gentity_t *e ); -gentity_t   *G_Spawn( void ); -gentity_t   *G_TempEntity( vec3_t origin, int event ); -void        G_Sound( gentity_t *ent, int channel, int soundIndex ); -void        G_FreeEntity( gentity_t *e ); -qboolean    G_EntitiesFree( void ); - -void        G_TouchTriggers( gentity_t *ent ); -void        G_TouchSolids( gentity_t *ent ); - -float       *tv( float x, float y, float z ); -char        *vtos( const vec3_t v ); - -float       vectoyaw( const vec3_t vec ); - -void        G_AddPredictableEvent( gentity_t *ent, int event, int eventParm ); -void        G_AddEvent( gentity_t *ent, int event, int eventParm ); -void        G_BroadcastEvent( int event, int eventParm ); -void        G_SetOrigin( gentity_t *ent, vec3_t origin ); -void        AddRemap(const char *oldShader, const char *newShader, float timeOffset); -const char  *BuildShaderStateConfig( void ); - - -#define MAX_QUEUE_COMMANDS  64 //should be MAX_RELIABLE_COMMANDS/server.h - -typedef struct commandQueueElement_s -{ -  qboolean                      used; -  struct commandQueueElement_s  *next; -  char                          command[ MAX_TOKEN_CHARS ]; -} commandQueueElement_t; - -typedef struct commandQueue_s -{ -  int                   nextCommandTime; //next time that the queue can be popped - -  int                   numElements; -  commandQueueElement_t *front; -  commandQueueElement_t *back; - -  commandQueueElement_t pool[ MAX_QUEUE_COMMANDS ]; -} commandQueue_t; - -qboolean    G_ClientIsLagging( gclient_t *client ); -void        G_ProcessCommandQueues( void ); -void        G_SendCommandFromServer( int clientNum, const char *cmd ); -void        G_InitCommandQueue( int clientNum ); - -void        G_TriggerMenu( int clientNum, dynMenu_t menu ); -void        G_CloseMenus( int clientNum ); - -qboolean    G_Visible( gentity_t *ent1, gentity_t *ent2 ); -gentity_t   *G_ClosestEnt( vec3_t origin, gentity_t **entities, int numEntities ); - -// -// g_combat.c -// -qboolean  CanDamage( gentity_t *targ, vec3_t origin ); -void      G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, -                    vec3_t dir, vec3_t point, int damage, int dflags, int mod ); -void      G_SelectiveDamage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, vec3_t dir, -                             vec3_t point, int damage, int dflags, int mod, int team ); -qboolean  G_RadiusDamage( vec3_t origin, gentity_t *attacker, float damage, float radius, -                          gentity_t *ignore, int mod ); -qboolean  G_SelectiveRadiusDamage( vec3_t origin, gentity_t *attacker, float damage, float radius, -                                   gentity_t *ignore, int mod, int team ); -void      body_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ); -void      AddScore( gentity_t *ent, int score ); - -//TA: -void      G_InitDamageLocations( void ); - -// damage flags -#define DAMAGE_RADIUS         0x00000001  // damage was indirect -#define DAMAGE_NO_ARMOR       0x00000002  // armour does not protect from this damage -#define DAMAGE_NO_KNOCKBACK   0x00000004  // do not affect velocity, just view angles -#define DAMAGE_NO_PROTECTION  0x00000008  // armor, shields, invulnerability, and godmode have no effect -#define DAMAGE_NO_LOCDAMAGE   0x00000010  // do not apply locational damage - -// -// g_missile.c -// -void      G_RunMissile( gentity_t *ent ); - -gentity_t *fire_flamer( gentity_t *self, vec3_t start, vec3_t aimdir ); -gentity_t *fire_blaster( gentity_t *self, vec3_t start, vec3_t dir ); -gentity_t *fire_pulseRifle( gentity_t *self, vec3_t start, vec3_t dir ); -gentity_t *fire_luciferCannon( gentity_t *self, vec3_t start, vec3_t dir, int damage, int radius ); -gentity_t *fire_lockblob( gentity_t *self, vec3_t start, vec3_t dir ); -gentity_t *fire_paraLockBlob( gentity_t *self, vec3_t start, vec3_t dir ); -gentity_t *fire_slowBlob( gentity_t *self, vec3_t start, vec3_t dir ); -gentity_t *fire_bounceBall( gentity_t *self, vec3_t start, vec3_t dir ); -gentity_t *fire_hive( gentity_t *self, vec3_t start, vec3_t dir ); -gentity_t *launch_grenade( gentity_t *self, vec3_t start, vec3_t dir ); - - -// -// g_mover.c -// -void G_RunMover( gentity_t *ent ); -void Touch_DoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace ); -void manualTriggerSpectator( gentity_t *trigger, gentity_t *player ); - -// -// g_trigger.c -// -void trigger_teleporter_touch( gentity_t *self, gentity_t *other, trace_t *trace ); -void G_Checktrigger_stages( pTeam_t team, stage_t stage ); - - -// -// g_misc.c -// -void TeleportPlayer( gentity_t *player, vec3_t origin, vec3_t angles ); -void ShineTorch( gentity_t *self ); - -// -// g_weapon.c -// - -#define MAX_ZAP_TARGETS LEVEL2_AREAZAP_MAX_TARGETS - -typedef struct zap_s -{ -  qboolean      used; - -  gentity_t     *creator; -  gentity_t     *targets[ MAX_ZAP_TARGETS ]; -  int           numTargets; - -  int           timeToLive; - -  gentity_t     *effectChannel; -} zap_t; - -void      G_ForceWeaponChange( gentity_t *ent, weapon_t weapon ); -void      G_GiveClientMaxAmmo( gentity_t *ent, qboolean buyingEnergyAmmo ); -void      CalcMuzzlePoint( gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint ); -void      SnapVectorTowards( vec3_t v, vec3_t to ); -qboolean  CheckVenomAttack( gentity_t *ent ); -void      CheckGrabAttack( gentity_t *ent ); -qboolean  CheckPounceAttack( gentity_t *ent ); -void      ChargeAttack( gentity_t *ent, gentity_t *victim ); -void      G_UpdateZaps( int msec ); - - -// -// g_client.c -// -void      G_AddCreditToClient( gclient_t *client, short credit, qboolean cap ); -team_t    TeamCount( int ignoreClientNum, int team ); -void      SetClientViewAngle( gentity_t *ent, vec3_t angle ); -gentity_t *SelectTremulousSpawnPoint( pTeam_t team, vec3_t preference, vec3_t origin, vec3_t angles ); -gentity_t *SelectSpawnPoint( vec3_t avoidPoint, vec3_t origin, vec3_t angles ); -void      SpawnCorpse( gentity_t *ent ); -void      respawn( gentity_t *ent ); -void      BeginIntermission( void ); -void      ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles ); -void      player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ); -qboolean  SpotWouldTelefrag( gentity_t *spot ); - -// -// g_svcmds.c -// -qboolean  ConsoleCommand( void ); -void      G_ProcessIPBans( void ); -qboolean  G_FilterPacket( char *from ); - -// -// g_weapon.c -// -void FireWeapon( gentity_t *ent ); -void FireWeapon2( gentity_t *ent ); -void FireWeapon3( gentity_t *ent ); - -// -// g_cmds.c -// - -// -// g_main.c -// -void ScoreboardMessage( gentity_t *client ); -void MoveClientToIntermission( gentity_t *client ); -void CalculateRanks( void ); -void FindIntermissionPoint( void ); -void G_RunThink( gentity_t *ent ); -void QDECL G_LogPrintf( const char *fmt, ... ); -void SendScoreboardMessageToAllClients( void ); -void QDECL G_Printf( const char *fmt, ... ); -void QDECL G_Error( const char *fmt, ... ); - -qboolean G_WeaponIsAllowed( weapon_t weapon ); -qboolean G_UpgradeIsAllowed( upgrade_t upgrade ); -qboolean G_ClassIsAllowed( pClass_t class ); -qboolean G_BuildableIsAllowed( buildable_t buildable ); - -// -// g_client.c -// -char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ); -void ClientUserinfoChanged( int clientNum ); -void ClientDisconnect( int clientNum ); -void ClientBegin( int clientNum ); -void ClientCommand( int clientNum ); - -// -// g_active.c -// -void ClientThink( int clientNum ); -void ClientEndFrame( gentity_t *ent ); -void G_RunClient( gentity_t *ent ); - -// -// g_team.c -// -qboolean  OnSameTeam( gentity_t *ent1, gentity_t *ent2 ); -gentity_t *Team_GetLocation( gentity_t *ent ); -qboolean  Team_GetLocationMsg( gentity_t *ent, char *loc, int loclen ); -void      TeamplayInfoMessage( gentity_t *ent ); -void      CheckTeamStatus( void ); - -// -// g_mem.c -// -void *G_Alloc( int size ); -void G_InitMemory( void ); -void G_Free( void *ptr ); -void G_DefragmentMemory( void ); -void Svcmd_GameMem_f( void ); - -// -// g_session.c -// -void G_ReadSessionData( gclient_t *client ); -void G_InitSessionData( gclient_t *client, char *userinfo ); -void G_WriteSessionData( void ); - -// -// g_maprotation.c -// -#define MAX_MAP_ROTATIONS       16 -#define MAX_MAP_ROTATION_MAPS   64 -#define MAX_MAP_COMMANDS        16 -#define MAX_MAP_ROTATION_CONDS  4 - -#define NOT_ROTATING          -1 - -typedef enum -{ -  MCV_ERR, -  MCV_RANDOM, -  MCV_NUMCLIENTS, -  MCV_LASTWIN -} mapConditionVariable_t; - -typedef enum -{ -  MCO_LT, -  MCO_EQ, -  MCO_GT -} mapConditionOperator_t; - -typedef enum -{ -  MCT_ERR, -  MCT_MAP, -  MCT_ROTATION -} mapConditionType_t; - -typedef struct mapRotationCondition_s -{ -  char                    dest[ MAX_QPATH ]; - -  qboolean                unconditional; - -  mapConditionVariable_t  lhs; -  mapConditionOperator_t  op; - -  int                     numClients; -  pTeam_t                 lastWin; -} mapRotationCondition_t; - -typedef struct mapRotationEntry_s -{ -  char                    name[ MAX_QPATH ]; - -  char                    postCmds[ MAX_QPATH ][ MAX_MAP_COMMANDS ]; -  int                     numCmds; - -  mapRotationCondition_t  conditions[ MAX_MAP_ROTATION_CONDS ]; -  int                     numConditions; -} mapRotationEntry_t; - -typedef struct mapRotation_s -{ -  char                name[ MAX_QPATH ]; - -  mapRotationEntry_t  maps[ MAX_MAP_ROTATION_MAPS ]; -  int                 numMaps; -  int                 currentMap; -} mapRotation_t; - -typedef struct mapRotations_s -{ -  mapRotation_t   rotations[ MAX_MAP_ROTATIONS ]; -  int             numRotations; -} mapRotations_t; - -void      G_PrintRotations( void ); -qboolean  G_AdvanceMapRotation( void ); -qboolean  G_StartMapRotation( char *name, qboolean changeMap ); -void      G_StopMapRotation( void ); -qboolean  G_MapRotationActive( void ); -void      G_InitMapRotations( void ); - -// -// g_ptr.c -// -void                G_UpdatePTRConnection( gclient_t *client ); -connectionRecord_t  *G_GenerateNewConnection( gclient_t *client ); -qboolean            G_VerifyPTRC( int code ); -void                G_ResetPTRConnections( void ); -connectionRecord_t  *G_FindConnectionForCode( int code ); -void                G_DeletePTRConnection( connectionRecord_t *connection ); - - -//some maxs -#define MAX_FILEPATH      144 - -extern  level_locals_t  level; -extern  gentity_t       g_entities[ MAX_GENTITIES ]; - -#define FOFS(x) ((int)&(((gentity_t *)0)->x)) - -extern  vmCvar_t  g_dedicated; -extern  vmCvar_t  g_cheats; -extern  vmCvar_t  g_maxclients;     // allow this many total, including spectators -extern  vmCvar_t  g_maxGameClients;   // allow this many active -extern  vmCvar_t  g_restarted; -extern  vmCvar_t  g_minCommandPeriod; - -extern  vmCvar_t  g_timelimit; -extern  vmCvar_t  g_suddenDeathTime; -extern  vmCvar_t  g_friendlyFire; -extern  vmCvar_t  g_password; -extern  vmCvar_t  g_needpass; -extern  vmCvar_t  g_gravity; -extern  vmCvar_t  g_speed; -extern  vmCvar_t  g_knockback; -extern  vmCvar_t  g_quadfactor; -extern  vmCvar_t  g_forcerespawn; -extern  vmCvar_t  g_inactivity; -extern  vmCvar_t  g_debugMove; -extern  vmCvar_t  g_debugAlloc; -extern  vmCvar_t  g_debugDamage; -extern  vmCvar_t  g_weaponRespawn; -extern  vmCvar_t  g_weaponTeamRespawn; -extern  vmCvar_t  g_synchronousClients; -extern  vmCvar_t  g_motd; -extern  vmCvar_t  g_warmup; -extern  vmCvar_t  g_doWarmup; -extern  vmCvar_t  g_blood; -extern  vmCvar_t  g_allowVote; -extern  vmCvar_t  g_teamAutoJoin; -extern  vmCvar_t  g_teamForceBalance; -extern  vmCvar_t  g_banIPs; -extern  vmCvar_t  g_filterBan; -extern  vmCvar_t  g_smoothClients; -extern  vmCvar_t  pmove_fixed; -extern  vmCvar_t  pmove_msec; -extern  vmCvar_t  g_rankings; -extern  vmCvar_t  g_enableDust; -extern  vmCvar_t  g_enableBreath; -extern  vmCvar_t  g_singlePlayer; - -extern  vmCvar_t  g_humanBuildPoints; -extern  vmCvar_t  g_alienBuildPoints; -extern  vmCvar_t  g_humanStage; -extern  vmCvar_t  g_humanKills; -extern  vmCvar_t  g_humanMaxStage; -extern  vmCvar_t  g_humanStage2Threshold; -extern  vmCvar_t  g_humanStage3Threshold; -extern  vmCvar_t  g_alienStage; -extern  vmCvar_t  g_alienKills; -extern  vmCvar_t  g_alienMaxStage; -extern  vmCvar_t  g_alienStage2Threshold; -extern  vmCvar_t  g_alienStage3Threshold; - -extern  vmCvar_t  g_disabledEquipment; -extern  vmCvar_t  g_disabledClasses; -extern  vmCvar_t  g_disabledBuildables; - -extern  vmCvar_t  g_debugMapRotation; -extern  vmCvar_t  g_currentMapRotation; -extern  vmCvar_t  g_currentMap; -extern  vmCvar_t  g_initialMapRotation; - -void      trap_Printf( const char *fmt ); -void      trap_Error( const char *fmt ); -int       trap_Milliseconds( void ); -int       trap_Argc( void ); -void      trap_Argv( int n, char *buffer, int bufferLength ); -void      trap_Args( char *buffer, int bufferLength ); -int       trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode ); -void      trap_FS_Read( void *buffer, int len, fileHandle_t f ); -void      trap_FS_Write( const void *buffer, int len, fileHandle_t f ); -void      trap_FS_FCloseFile( fileHandle_t f ); -int       trap_FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize ); -int       trap_FS_Seek( fileHandle_t f, long offset, int origin ); // fsOrigin_t -void      trap_SendConsoleCommand( int exec_when, const char *text ); -void      trap_Cvar_Register( vmCvar_t *cvar, const char *var_name, const char *value, int flags ); -void      trap_Cvar_Update( vmCvar_t *cvar ); -void      trap_Cvar_Set( const char *var_name, const char *value ); -int       trap_Cvar_VariableIntegerValue( const char *var_name ); -float     trap_Cvar_VariableValue( const char *var_name ); -void      trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ); -void      trap_LocateGameData( gentity_t *gEnts, int numGEntities, int sizeofGEntity_t, -                               playerState_t *gameClients, int sizeofGameClient ); -void      trap_DropClient( int clientNum, const char *reason ); -void      trap_SendServerCommand( int clientNum, const char *text ); -void      trap_SetConfigstring( int num, const char *string ); -void      trap_GetConfigstring( int num, char *buffer, int bufferSize ); -void      trap_GetUserinfo( int num, char *buffer, int bufferSize ); -void      trap_SetUserinfo( int num, const char *buffer ); -void      trap_GetServerinfo( char *buffer, int bufferSize ); -void      trap_SetBrushModel( gentity_t *ent, const char *name ); -void      trap_Trace( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, -                      const vec3_t end, int passEntityNum, int contentmask ); -int       trap_PointContents( const vec3_t point, int passEntityNum ); -qboolean  trap_InPVS( const vec3_t p1, const vec3_t p2 ); -qboolean  trap_InPVSIgnorePortals( const vec3_t p1, const vec3_t p2 ); -void      trap_AdjustAreaPortalState( gentity_t *ent, qboolean open ); -qboolean  trap_AreasConnected( int area1, int area2 ); -void      trap_LinkEntity( gentity_t *ent ); -void      trap_UnlinkEntity( gentity_t *ent ); -int       trap_EntitiesInBox( const vec3_t mins, const vec3_t maxs, int *entityList, int maxcount ); -qboolean  trap_EntityContact( const vec3_t mins, const vec3_t maxs, const gentity_t *ent ); -int       trap_BotAllocateClient( void ); -void      trap_BotFreeClient( int clientNum ); -void      trap_GetUsercmd( int clientNum, usercmd_t *cmd ); -qboolean  trap_GetEntityToken( char *buffer, int bufferSize ); - -int       trap_DebugPolygonCreate(int color, int numPoints, vec3_t *points); -void      trap_DebugPolygonDelete(int id); - -void      trap_SnapVector( float *v ); - diff --git a/mod/src/game/g_main.c b/mod/src/game/g_main.c deleted file mode 100644 index 22ff74f7..00000000 --- a/mod/src/game/g_main.c +++ /dev/null @@ -1,2207 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -level_locals_t  level; - -typedef struct -{ -  vmCvar_t  *vmCvar; -  char    *cvarName; -  char    *defaultString; -  int     cvarFlags; -  int     modificationCount;  // for tracking changes -  qboolean  trackChange;  // track this variable, and announce if changed -  qboolean teamShader;        // track and if changed, update shader state -} cvarTable_t; - -gentity_t   g_entities[ MAX_GENTITIES ]; -gclient_t   g_clients[ MAX_CLIENTS ]; - -vmCvar_t  g_fraglimit; -vmCvar_t  g_timelimit; -vmCvar_t  g_suddenDeathTime; -vmCvar_t  g_capturelimit; -vmCvar_t  g_friendlyFire; -vmCvar_t  g_password; -vmCvar_t  g_needpass; -vmCvar_t  g_maxclients; -vmCvar_t  g_maxGameClients; -vmCvar_t  g_dedicated; -vmCvar_t  g_speed; -vmCvar_t  g_gravity; -vmCvar_t  g_cheats; -vmCvar_t  g_knockback; -vmCvar_t  g_quadfactor; -vmCvar_t  g_forcerespawn; -vmCvar_t  g_inactivity; -vmCvar_t  g_debugMove; -vmCvar_t  g_debugDamage; -vmCvar_t  g_debugAlloc; -vmCvar_t  g_weaponRespawn; -vmCvar_t  g_weaponTeamRespawn; -vmCvar_t  g_motd; -vmCvar_t  g_synchronousClients; -vmCvar_t  g_warmup; -vmCvar_t  g_doWarmup; -vmCvar_t  g_restarted; -vmCvar_t  g_logFile; -vmCvar_t  g_logFileSync; -vmCvar_t  g_blood; -vmCvar_t  g_podiumDist; -vmCvar_t  g_podiumDrop; -vmCvar_t  g_allowVote; -vmCvar_t  g_teamAutoJoin; -vmCvar_t  g_teamForceBalance; -vmCvar_t  g_banIPs; -vmCvar_t  g_filterBan; -vmCvar_t  g_smoothClients; -vmCvar_t  pmove_fixed; -vmCvar_t  pmove_msec; -vmCvar_t  g_rankings; -vmCvar_t  g_listEntity; -vmCvar_t  g_minCommandPeriod; - -//TA -vmCvar_t  g_humanBuildPoints; -vmCvar_t  g_alienBuildPoints; -vmCvar_t  g_humanStage; -vmCvar_t  g_humanKills; -vmCvar_t  g_humanMaxStage; -vmCvar_t  g_humanStage2Threshold; -vmCvar_t  g_humanStage3Threshold; -vmCvar_t  g_alienStage; -vmCvar_t  g_alienKills; -vmCvar_t  g_alienMaxStage; -vmCvar_t  g_alienStage2Threshold; -vmCvar_t  g_alienStage3Threshold; - -vmCvar_t  g_disabledEquipment; -vmCvar_t  g_disabledClasses; -vmCvar_t  g_disabledBuildables; - -vmCvar_t  g_debugMapRotation; -vmCvar_t  g_currentMapRotation; -vmCvar_t  g_currentMap; -vmCvar_t  g_initialMapRotation; - -static cvarTable_t   gameCvarTable[ ] = -{ -  // don't override the cheat state set by the system -  { &g_cheats, "sv_cheats", "", 0, 0, qfalse }, - -  // noset vars -  { NULL, "gamename", GAMEVERSION , CVAR_SERVERINFO | CVAR_ROM, 0, qfalse  }, -  { NULL, "gamedate", __DATE__ , CVAR_ROM, 0, qfalse  }, -  { &g_restarted, "g_restarted", "0", CVAR_ROM, 0, qfalse  }, -  { NULL, "sv_mapname", "", CVAR_SERVERINFO | CVAR_ROM, 0, qfalse  }, - -  // latched vars - -  { &g_maxclients, "sv_maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE, 0, qfalse  }, -  { &g_maxGameClients, "g_maxGameClients", "0", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE, 0, qfalse  }, - -  // change anytime vars -  { &g_timelimit, "timelimit", "0", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue }, -  { &g_suddenDeathTime, "g_suddenDeathTime", "0", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue }, - -  { &g_synchronousClients, "g_synchronousClients", "0", CVAR_SYSTEMINFO, 0, qfalse  }, - -  { &g_friendlyFire, "g_friendlyFire", "0", CVAR_ARCHIVE, 0, qtrue  }, - -  { &g_teamAutoJoin, "g_teamAutoJoin", "0", CVAR_ARCHIVE  }, -  { &g_teamForceBalance, "g_teamForceBalance", "0", CVAR_ARCHIVE  }, - -  { &g_warmup, "g_warmup", "20", CVAR_ARCHIVE, 0, qtrue  }, -  { &g_doWarmup, "g_doWarmup", "0", 0, 0, qtrue  }, -  { &g_logFile, "g_logFile", "games.log", CVAR_ARCHIVE, 0, qfalse  }, -  { &g_logFileSync, "g_logFileSync", "0", CVAR_ARCHIVE, 0, qfalse  }, - -  { &g_password, "g_password", "", CVAR_USERINFO, 0, qfalse  }, - -  { &g_banIPs, "g_banIPs", "", CVAR_ARCHIVE, 0, qfalse  }, -  { &g_filterBan, "g_filterBan", "1", CVAR_ARCHIVE, 0, qfalse  }, - -  { &g_needpass, "g_needpass", "0", CVAR_SERVERINFO | CVAR_ROM, 0, qfalse }, - -  { &g_dedicated, "dedicated", "0", 0, 0, qfalse  }, - -  { &g_speed, "g_speed", "320", 0, 0, qtrue  }, -  { &g_gravity, "g_gravity", "800", 0, 0, qtrue  }, -  { &g_knockback, "g_knockback", "1000", 0, 0, qtrue  }, -  { &g_quadfactor, "g_quadfactor", "3", 0, 0, qtrue  }, -  { &g_weaponRespawn, "g_weaponrespawn", "5", 0, 0, qtrue  }, -  { &g_weaponTeamRespawn, "g_weaponTeamRespawn", "30", 0, 0, qtrue }, -  { &g_forcerespawn, "g_forcerespawn", "20", 0, 0, qtrue }, -  { &g_inactivity, "g_inactivity", "0", 0, 0, qtrue }, -  { &g_debugMove, "g_debugMove", "0", 0, 0, qfalse }, -  { &g_debugDamage, "g_debugDamage", "0", 0, 0, qfalse }, -  { &g_debugAlloc, "g_debugAlloc", "0", 0, 0, qfalse }, -  { &g_motd, "g_motd", "", 0, 0, qfalse }, -  { &g_blood, "com_blood", "1", 0, 0, qfalse }, - -  { &g_podiumDist, "g_podiumDist", "80", 0, 0, qfalse }, -  { &g_podiumDrop, "g_podiumDrop", "70", 0, 0, qfalse }, - -  { &g_allowVote, "g_allowVote", "1", CVAR_ARCHIVE, 0, qfalse }, -  { &g_listEntity, "g_listEntity", "0", 0, 0, qfalse }, -  { &g_minCommandPeriod, "g_minCommandPeriod", "500", 0, 0, qfalse}, - -  { &g_smoothClients, "g_smoothClients", "1", 0, 0, qfalse}, -  { &pmove_fixed, "pmove_fixed", "0", CVAR_SYSTEMINFO, 0, qfalse}, -  { &pmove_msec, "pmove_msec", "8", CVAR_SYSTEMINFO, 0, qfalse}, - -  { &g_humanBuildPoints, "g_humanBuildPoints", "100", 0, 0, qfalse  }, -  { &g_alienBuildPoints, "g_alienBuildPoints", "100", 0, 0, qfalse  }, -  { &g_humanStage, "g_humanStage", "0", 0, 0, qfalse  }, -  { &g_humanKills, "g_humanKills", "0", 0, 0, qfalse  }, -  { &g_humanMaxStage, "g_humanMaxStage", "2", 0, 0, qfalse  }, -  { &g_humanStage2Threshold, "g_humanStage2Threshold", "20", 0, 0, qfalse  }, -  { &g_humanStage3Threshold, "g_humanStage3Threshold", "40", 0, 0, qfalse  }, -  { &g_alienStage, "g_alienStage", "0", 0, 0, qfalse  }, -  { &g_alienKills, "g_alienKills", "0", 0, 0, qfalse  }, -  { &g_alienMaxStage, "g_alienMaxStage", "2", 0, 0, qfalse  }, -  { &g_alienStage2Threshold, "g_alienStage2Threshold", "20", 0, 0, qfalse  }, -  { &g_alienStage3Threshold, "g_alienStage3Threshold", "40", 0, 0, qfalse  }, - -  { &g_disabledEquipment, "g_disabledEquipment", "", CVAR_ROM, 0, qfalse  }, -  { &g_disabledClasses, "g_disabledClasses", "", CVAR_ROM, 0, qfalse  }, -  { &g_disabledBuildables, "g_disabledBuildables", "", CVAR_ROM, 0, qfalse  }, - -  { &g_debugMapRotation, "g_debugMapRotation", "0", 0, 0, qfalse  }, -  { &g_currentMapRotation, "g_currentMapRotation", "-1", 0, 0, qfalse  }, // -1 = NOT_ROTATING -  { &g_currentMap, "g_currentMap", "0", 0, 0, qfalse  }, -  { &g_initialMapRotation, "g_initialMapRotation", "", CVAR_ARCHIVE, 0, qfalse  }, - -  { &g_rankings, "g_rankings", "0", 0, 0, qfalse} -}; - -static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[ 0 ] ); - - -void G_InitGame( int levelTime, int randomSeed, int restart ); -void G_RunFrame( int levelTime ); -void G_ShutdownGame( int restart ); -void CheckExitRules( void ); - -void G_CountSpawns( void ); -void G_CalculateBuildPoints( void ); - -/* -================ -vmMain - -This is the only way control passes into the module. -This must be the very first function compiled into the .q3vm file -================ -*/ -long vmMain( long command, long arg0, long arg1, long arg2, long arg3, long arg4, -                           long arg5, long arg6, long arg7, long arg8, long arg9, -                           long arg10, long arg11 ) -{ -  switch( command ) -  { -    case GAME_INIT: -      G_InitGame( arg0, arg1, arg2 ); -      return 0; - -    case GAME_SHUTDOWN: -      G_ShutdownGame( arg0 ); -      return 0; - -    case GAME_CLIENT_CONNECT: -      return (long)ClientConnect( arg0, arg1, arg2 ); - -    case GAME_CLIENT_THINK: -      ClientThink( arg0 ); -      return 0; - -    case GAME_CLIENT_USERINFO_CHANGED: -      ClientUserinfoChanged( arg0 ); -      return 0; - -    case GAME_CLIENT_DISCONNECT: -      ClientDisconnect( arg0 ); -      return 0; - -    case GAME_CLIENT_BEGIN: -      ClientBegin( arg0 ); -      return 0; - -    case GAME_CLIENT_COMMAND: -      ClientCommand( arg0 ); -      return 0; - -    case GAME_RUN_FRAME: -      G_RunFrame( arg0 ); -      return 0; - -    case GAME_CONSOLE_COMMAND: -      return ConsoleCommand( ); -  } - -  return -1; -} - - -void QDECL G_Printf( const char *fmt, ... ) -{ -  va_list argptr; -  char    text[ 1024 ]; -  char    clientText[ 1048 ]; - -  va_start( argptr, fmt ); -  vsprintf( text, fmt, argptr ); -  va_end( argptr ); - -  if( !g_dedicated.integer ) -  { -    Com_sprintf( clientText, 1048, "gprintf \"%s\"", text ); -    G_SendCommandFromServer( -1, clientText ); -  } - -  trap_Printf( text ); -} - -void QDECL G_Error( const char *fmt, ... ) -{ -  va_list argptr; -  char    text[ 1024 ]; - -  va_start( argptr, fmt ); -  vsprintf( text, fmt, argptr ); -  va_end( argptr ); - -  trap_Error( text ); -} - -/* -================ -G_FindTeams - -Chain together all entities with a matching team field. -Entity teams are used for item groups and multi-entity mover groups. - -All but the first will have the FL_TEAMSLAVE flag set and teammaster field set -All but the last will have the teamchain field set to the next one -================ -*/ -void G_FindTeams( void ) -{ -  gentity_t *e, *e2; -  int       i, j; -  int       c, c2; - -  c = 0; -  c2 = 0; - -  for( i = 1, e = g_entities+i; i < level.num_entities; i++, e++ ) -  { -    if( !e->inuse ) -      continue; - -    if( !e->team ) -      continue; - -    if( e->flags & FL_TEAMSLAVE ) -      continue; - -    e->teammaster = e; -    c++; -    c2++; - -    for( j = i + 1, e2 = e + 1; j < level.num_entities; j++, e2++ ) -    { -      if( !e2->inuse ) -        continue; - -      if( !e2->team ) -        continue; - -      if( e2->flags & FL_TEAMSLAVE ) -        continue; - -      if( !strcmp( e->team, e2->team ) ) -      { -        c2++; -        e2->teamchain = e->teamchain; -        e->teamchain = e2; -        e2->teammaster = e; -        e2->flags |= FL_TEAMSLAVE; - -        // make sure that targets only point at the master -        if( e2->targetname ) -        { -          e->targetname = e2->targetname; -          e2->targetname = NULL; -        } -      } -    } -  } - -  G_Printf( "%i teams with %i entities\n", c, c2 ); -} - -void G_RemapTeamShaders( ) -{ -} - - -/* -================= -G_RegisterCvars -================= -*/ -void G_RegisterCvars( void ) -{ -  int         i; -  cvarTable_t *cv; -  qboolean    remapped = qfalse; - -  for( i = 0, cv = gameCvarTable; i < gameCvarTableSize; i++, cv++ ) -  { -    trap_Cvar_Register( cv->vmCvar, cv->cvarName, -      cv->defaultString, cv->cvarFlags ); - -    if( cv->vmCvar ) -      cv->modificationCount = cv->vmCvar->modificationCount; - -    if( cv->teamShader ) -      remapped = qtrue; -  } - -  if( remapped ) -    G_RemapTeamShaders( ); - -  // check some things -  level.warmupModificationCount = g_warmup.modificationCount; -} - -/* -================= -G_UpdateCvars -================= -*/ -void G_UpdateCvars( void ) -{ -  int         i; -  cvarTable_t *cv; -  qboolean    remapped = qfalse; - -  for( i = 0, cv = gameCvarTable; i < gameCvarTableSize; i++, cv++ ) -  { -    if( cv->vmCvar ) -    { -      trap_Cvar_Update( cv->vmCvar ); - -      if( cv->modificationCount != cv->vmCvar->modificationCount ) -      { -        cv->modificationCount = cv->vmCvar->modificationCount; - -        if( cv->trackChange ) -          G_SendCommandFromServer( -1, va( "print \"Server: %s changed to %s\n\"", -            cv->cvarName, cv->vmCvar->string ) ); - -        if( cv->teamShader ) -          remapped = qtrue; -      } -    } -  } - -  if( remapped ) -    G_RemapTeamShaders( ); -} - - -/* -=============== -G_GenerateParticleFileList - -Make a list of particle files for each client to parse since fsr -the client does not have trap_FS_GetFileList -=============== -*/ -static void G_GenerateParticleFileList( void ) -{ -  int   i, numFiles, fileLen; -  char  fileList[ MAX_PARTICLE_FILES * MAX_QPATH ]; -  char  fileName[ MAX_QPATH ]; -  char  *filePtr; - -  numFiles = trap_FS_GetFileList( "scripts", ".particle", fileList, MAX_PARTICLE_FILES * MAX_QPATH ); -  filePtr = fileList; - -  for( i = 0; i < numFiles; i++, filePtr += fileLen + 1 ) -  { -    fileLen = strlen( filePtr ); -    strcpy( fileName, "scripts/" ); -    strcat( fileName, filePtr ); -    trap_SetConfigstring( CS_PARTICLE_FILES + i, fileName ); -  } -} - -typedef struct gameElements_s -{ -  buildable_t       buildables[ BA_NUM_BUILDABLES ]; -  pClass_t          classes[ PCL_NUM_CLASSES ]; -  weapon_t          weapons[ WP_NUM_WEAPONS ]; -  upgrade_t         upgrades[ UP_NUM_UPGRADES ]; -} gameElements_t; - -static gameElements_t disabledGameElements; - -/* -============ -G_InitAllowedGameElements -============ -*/ -static void G_InitAllowedGameElements( void ) -{ -  BG_ParseCSVEquipmentList( g_disabledEquipment.string, -      disabledGameElements.weapons, WP_NUM_WEAPONS, -      disabledGameElements.upgrades, UP_NUM_UPGRADES ); - -  BG_ParseCSVClassList( g_disabledClasses.string, -      disabledGameElements.classes, PCL_NUM_CLASSES ); - -  BG_ParseCSVBuildableList( g_disabledBuildables.string, -      disabledGameElements.buildables, BA_NUM_BUILDABLES ); -} - -/* -============ -G_WeaponIsAllowed -============ -*/ -qboolean G_WeaponIsAllowed( weapon_t weapon ) -{ -  int i; - -  for( i = 0; i < WP_NUM_WEAPONS && -      disabledGameElements.weapons[ i ] != WP_NONE; i++ ) -  { -    if( disabledGameElements.weapons[ i ] == weapon ) -      return qfalse; -  } - -  return qtrue; -} - -/* -============ -G_UpgradeIsAllowed -============ -*/ -qboolean G_UpgradeIsAllowed( upgrade_t upgrade ) -{ -  int i; - -  for( i = 0; i < UP_NUM_UPGRADES && -      disabledGameElements.upgrades[ i ] != UP_NONE; i++ ) -  { -    if( disabledGameElements.upgrades[ i ] == upgrade ) -      return qfalse; -  } - -  return qtrue; -} - -/* -============ -G_ClassIsAllowed -============ -*/ -qboolean G_ClassIsAllowed( pClass_t class ) -{ -  int i; - -  for( i = 0; i < PCL_NUM_CLASSES && -      disabledGameElements.classes[ i ] != PCL_NONE; i++ ) -  { -    if( disabledGameElements.classes[ i ] == class ) -      return qfalse; -  } - -  return qtrue; -} - -/* -============ -G_BuildableIsAllowed -============ -*/ -qboolean G_BuildableIsAllowed( buildable_t buildable ) -{ -  int i; - -  for( i = 0; i < BA_NUM_BUILDABLES && -      disabledGameElements.buildables[ i ] != BA_NONE; i++ ) -  { -    if( disabledGameElements.buildables[ i ] == buildable ) -      return qfalse; -  } - -  return qtrue; -} - -/* -============ -G_InitGame - -============ -*/ -void G_InitGame( int levelTime, int randomSeed, int restart ) -{ -  int i; - -  srand( randomSeed ); - -  G_RegisterCvars( ); - -  //TA: moved after G_RegisterCvars since G_Printf -  //    now depends on the value of g_dedicated -  G_Printf( "------- Game Initialization -------\n" ); -  G_Printf( "gamename: %s\n", GAMEVERSION ); -  G_Printf( "gamedate: %s\n", __DATE__ ); - -  G_ProcessIPBans( ); - -  G_InitMemory( ); - -  // set some level globals -  memset( &level, 0, sizeof( level ) ); -  level.time = levelTime; -  level.startTime = levelTime; - -  level.snd_fry = G_SoundIndex( "sound/player/fry.wav" ); // FIXME standing in lava / slime - -  if( g_logFile.string[ 0 ] ) -  { -    if( g_logFileSync.integer ) -      trap_FS_FOpenFile( g_logFile.string, &level.logFile, FS_APPEND_SYNC ); -    else -      trap_FS_FOpenFile( g_logFile.string, &level.logFile, FS_APPEND ); - -    if( !level.logFile ) -      G_Printf( "WARNING: Couldn't open logfile: %s\n", g_logFile.string ); -    else -    { -      char serverinfo[ MAX_INFO_STRING ]; - -      trap_GetServerinfo( serverinfo, sizeof( serverinfo ) ); - -      G_LogPrintf( "------------------------------------------------------------\n" ); -      G_LogPrintf( "InitGame: %s\n", serverinfo ); -    } -  } -  else -    G_Printf( "Not logging to disk\n" ); - -  // initialize all entities for this game -  memset( g_entities, 0, MAX_GENTITIES * sizeof( g_entities[ 0 ] ) ); -  level.gentities = g_entities; - -  // initialize all clients for this game -  level.maxclients = g_maxclients.integer; -  memset( g_clients, 0, MAX_CLIENTS * sizeof( g_clients[ 0 ] ) ); -  level.clients = g_clients; - -  // set client fields on player ents -  for( i = 0; i < level.maxclients; i++ ) -    g_entities[ i ].client = level.clients + i; - -  // always leave room for the max number of clients, -  // even if they aren't all used, so numbers inside that -  // range are NEVER anything but clients -  level.num_entities = MAX_CLIENTS; - -  // let the server system know where the entites are -  trap_LocateGameData( level.gentities, level.num_entities, sizeof( gentity_t ), -    &level.clients[ 0 ].ps, sizeof( level.clients[ 0 ] ) ); - -  trap_SetConfigstring( CS_INTERMISSION, "0" ); - -  // parse the key/value pairs and spawn gentities -  G_SpawnEntitiesFromString( ); - -  // the map might disable some things -  G_InitAllowedGameElements( ); - -  // general initialization -  G_FindTeams( ); - -  //TA: -  BG_InitClassOverrides( ); -  BG_InitBuildableOverrides( ); -  G_InitDamageLocations( ); -  G_GenerateParticleFileList( ); -  G_InitMapRotations( ); -  G_InitSpawnQueue( &level.alienSpawnQueue ); -  G_InitSpawnQueue( &level.humanSpawnQueue ); - -  if( g_debugMapRotation.integer ) -    G_PrintRotations( ); - -  //reset stages -  trap_Cvar_Set( "g_alienStage", va( "%d", S1 ) ); -  trap_Cvar_Set( "g_humanStage", va( "%d", S1 ) ); -  trap_Cvar_Set( "g_alienKills", 0 ); -  trap_Cvar_Set( "g_humanKills", 0 ); - -  G_Printf( "-----------------------------------\n" ); - -  G_RemapTeamShaders( ); - -  //TA: so the server counts the spawns without a client attached -  G_CountSpawns( ); - -  G_ResetPTRConnections( ); -} - - - -/* -================= -G_ShutdownGame -================= -*/ -void G_ShutdownGame( int restart ) -{ -  G_Printf( "==== ShutdownGame ====\n" ); - -  if( level.logFile ) -  { -    G_LogPrintf( "ShutdownGame:\n" ); -    G_LogPrintf( "------------------------------------------------------------\n" ); -    trap_FS_FCloseFile( level.logFile ); -  } - -  // write all the client session data so we can get it back -  G_WriteSessionData( ); -} - - - -//=================================================================== - -void QDECL Com_Error( int level, const char *error, ... ) -{ -  va_list argptr; -  char    text[ 1024 ]; - -  va_start( argptr, error ); -  vsprintf( text, error, argptr ); -  va_end( argptr ); - -  G_Error( "%s", text ); -} - -void QDECL Com_Printf( const char *msg, ... ) -{ -  va_list argptr; -  char    text[ 1024 ]; - -  va_start( argptr, msg ); -  vsprintf( text, msg, argptr ); -  va_end( argptr ); - -  G_Printf( "%s", text ); -} - -/* -======================================================================== - -PLAYER COUNTING / SCORE SORTING - -======================================================================== -*/ - - -/* -============= -SortRanks - -============= -*/ -int QDECL SortRanks( const void *a, const void *b ) -{ -  gclient_t *ca, *cb; - -  ca = &level.clients[ *(int *)a ]; -  cb = &level.clients[ *(int *)b ]; - -  // then sort by score -  if( ca->ps.persistant[ PERS_SCORE ] > cb->ps.persistant[ PERS_SCORE ] ) -    return -1; -  else if( ca->ps.persistant[ PERS_SCORE ] < cb->ps.persistant[ PERS_SCORE ] ) -    return 1; -  else -    return 0; -} - -/* -============ -G_InitSpawnQueue - -Initialise a spawn queue -============ -*/ -void G_InitSpawnQueue( spawnQueue_t *sq ) -{ -  int i; - -  sq->back = sq->front = 0; -  sq->back = QUEUE_MINUS1( sq->back ); - -  //0 is a valid clientNum, so use something else -  for( i = 0; i < MAX_CLIENTS; i++ ) -    sq->clients[ i ] = -1; -} - -/* -============ -G_GetSpawnQueueLength - -Return tha length of a spawn queue -============ -*/ -int G_GetSpawnQueueLength( spawnQueue_t *sq ) -{ -  int length = sq->back - sq->front + 1; - -  while( length < 0 ) -    length += MAX_CLIENTS; - -  while( length >= MAX_CLIENTS ) -    length -= MAX_CLIENTS; - -  return length; -} - -/* -============ -G_PopSpawnQueue - -Remove from front element from a spawn queue -============ -*/ -int G_PopSpawnQueue( spawnQueue_t *sq ) -{ -  int clientNum = sq->clients[ sq->front ]; - -  if( G_GetSpawnQueueLength( sq ) > 0 ) -  { -    sq->clients[ sq->front ] = -1; -    sq->front = QUEUE_PLUS1( sq->front ); -    g_entities[ clientNum ].client->ps.pm_flags &= ~PMF_QUEUED; - -    return clientNum; -  } -  else -    return -1; -} - -/* -============ -G_PeekSpawnQueue - -Look at front element from a spawn queue -============ -*/ -int G_PeekSpawnQueue( spawnQueue_t *sq ) -{ -  return sq->clients[ sq->front ]; -} - -/* -============ -G_PushSpawnQueue - -Add an element to the back of the spawn queue -============ -*/ -void G_PushSpawnQueue( spawnQueue_t *sq, int clientNum ) -{ -  sq->back = QUEUE_PLUS1( sq->back ); -  sq->clients[ sq->back ] = clientNum; - -  g_entities[ clientNum ].client->ps.pm_flags |= PMF_QUEUED; -} - -/* -============ -G_RemoveFromSpawnQueue - -remove a specific client from a spawn queue -============ -*/ -qboolean G_RemoveFromSpawnQueue( spawnQueue_t *sq, int clientNum ) -{ -  int i = sq->front; - -  if( G_GetSpawnQueueLength( sq ) ) -  { -    do -    { -      if( sq->clients[ i ] == clientNum ) -      { -        //and this kids is why it would have -        //been better to use an LL for internal -        //representation -        do -        { -          sq->clients[ i ] = sq->clients[ QUEUE_PLUS1( i ) ]; - -          i = QUEUE_PLUS1( i ); -        } while( i != QUEUE_PLUS1( sq->back ) ); - -        sq->back = QUEUE_MINUS1( sq->back ); -        g_entities[ clientNum ].client->ps.pm_flags &= ~PMF_QUEUED; - -        return qtrue; -      } - -      i = QUEUE_PLUS1( i ); -    } while( i != QUEUE_PLUS1( sq->back ) ); -  } - -  return qfalse; -} - -/* -============ -G_GetPosInSpawnQueue - -Get the position of a client in a spawn queue -============ -*/ -int G_GetPosInSpawnQueue( spawnQueue_t *sq, int clientNum ) -{ -  int i = sq->front; - -  if( G_GetSpawnQueueLength( sq ) ) -  { -    do -    { -      if( sq->clients[ i ] == clientNum ) -      { -        if( i < sq->front ) -          return i + MAX_CLIENTS - sq->front; -        else -          return i - sq->front; -      } - -      i = QUEUE_PLUS1( i ); -    } while( i != QUEUE_PLUS1( sq->back ) ); -  } - -  return -1; -} - -/* -============ -G_PrintSpawnQueue - -Print the contents of a spawn queue -============ -*/ -void G_PrintSpawnQueue( spawnQueue_t *sq ) -{ -  int i = sq->front; -  int length = G_GetSpawnQueueLength( sq ); - -  G_Printf( "l:%d f:%d b:%d    :", length, sq->front, sq->back ); - -  if( length > 0 ) -  { -    do -    { -      if( sq->clients[ i ] == -1 ) -        G_Printf( "*:" ); -      else -        G_Printf( "%d:", sq->clients[ i ] ); - -      i = QUEUE_PLUS1( i ); -    } while( i != QUEUE_PLUS1( sq->back ) ); -  } - -  G_Printf( "\n" ); -} - -/* -============ -G_SpawnClients - -Spawn queued clients -============ -*/ -void G_SpawnClients( pTeam_t team ) -{ -  int           clientNum; -  gentity_t     *ent, *spawn; -  vec3_t        spawn_origin, spawn_angles; -  spawnQueue_t  *sq = NULL; -  int           numSpawns = 0; - -  if( team == PTE_ALIENS ) -  { -    sq = &level.alienSpawnQueue; -    numSpawns = level.numAlienSpawns; -  } -  else if( team == PTE_HUMANS ) -  { -    sq = &level.humanSpawnQueue; -    numSpawns = level.numHumanSpawns; -  } - -  if( G_GetSpawnQueueLength( sq ) > 0 && numSpawns > 0 ) -  { -    clientNum = G_PeekSpawnQueue( sq ); -    ent = &g_entities[ clientNum ]; - -    if( ( spawn = SelectTremulousSpawnPoint( team, -            ent->client->pers.lastDeathLocation, -            spawn_origin, spawn_angles ) ) ) -    { -      clientNum = G_PopSpawnQueue( sq ); - -      if( clientNum < 0 ) -        return; - -      ent = &g_entities[ clientNum ]; - -      ent->client->sess.sessionTeam = TEAM_FREE; -      ClientUserinfoChanged( clientNum ); -      ClientSpawn( ent, spawn, spawn_origin, spawn_angles ); -    } -  } -} - -/* -============ -G_CountSpawns - -Counts the number of spawns for each team -============ -*/ -void G_CountSpawns( void ) -{ -  int i; -  gentity_t *ent; - -  level.numAlienSpawns = 0; -  level.numHumanSpawns = 0; - -  for( i = 1, ent = g_entities + i ; i < level.num_entities ; i++, ent++ ) -  { -    if( !ent->inuse ) -      continue; - -    if( ent->s.modelindex == BA_A_SPAWN && ent->health > 0 ) -      level.numAlienSpawns++; - -    if( ent->s.modelindex == BA_H_SPAWN && ent->health > 0 ) -      level.numHumanSpawns++; -  } - -  //let the client know how many spawns there are -  trap_SetConfigstring( CS_SPAWNS, va( "%d %d", -        level.numAlienSpawns, level.numHumanSpawns ) ); -} - - -#define PLAYER_COUNT_MOD 5.0f - -/* -============ -G_CalculateBuildPoints - -Recalculate the quantity of building points available to the teams -============ -*/ -void G_CalculateBuildPoints( void ) -{ -  int         i; -  buildable_t buildable; -  gentity_t   *ent; -  int         localHTP = g_humanBuildPoints.integer, -              localATP = g_alienBuildPoints.integer; - -  if( g_suddenDeathTime.integer && !level.warmupTime && -    ( level.time - level.startTime >= g_suddenDeathTime.integer * 60000 ) ) -  { -    localHTP = 0; -    localATP = 0; -  } -  else -  { -    localHTP = g_humanBuildPoints.integer; -    localATP = g_alienBuildPoints.integer; -  } - -  level.humanBuildPoints = level.humanBuildPointsPowered = localHTP; -  level.alienBuildPoints = localATP; - -  level.reactorPresent = qfalse; -  level.overmindPresent = qfalse; - -  for( i = 1, ent = g_entities + i ; i < level.num_entities ; i++, ent++ ) -  { -    if( !ent->inuse ) -      continue; - -    if( ent->s.eType != ET_BUILDABLE ) -      continue; - -    buildable = ent->s.modelindex; - -    if( buildable != BA_NONE ) -    { -      if( buildable == BA_H_REACTOR && ent->spawned && ent->health > 0 ) -        level.reactorPresent = qtrue; - -      if( buildable == BA_A_OVERMIND && ent->spawned && ent->health > 0 ) -        level.overmindPresent = qtrue; - -      if( BG_FindTeamForBuildable( buildable ) == BIT_HUMANS ) -      { -        level.humanBuildPoints -= BG_FindBuildPointsForBuildable( buildable ); - -        if( ent->powered ) -          level.humanBuildPointsPowered -= BG_FindBuildPointsForBuildable( buildable ); -      } -      else -      { -        level.alienBuildPoints -= BG_FindBuildPointsForBuildable( buildable ); -      } -    } -  } - -  if( level.humanBuildPoints < 0 ) -  { -    localHTP -= level.humanBuildPoints; -    level.humanBuildPointsPowered -= level.humanBuildPoints; -    level.humanBuildPoints = 0; -  } - -  if( level.alienBuildPoints < 0 ) -  { -    localATP -= level.alienBuildPoints; -    level.alienBuildPoints = 0; -  } - -  trap_SetConfigstring( CS_BUILDPOINTS, -                        va( "%d %d %d %d %d", level.alienBuildPoints, -                                              localATP, -                                              level.humanBuildPoints, -                                              localHTP, -                                              level.humanBuildPointsPowered ) ); - -  //may as well pump the stages here too -  { -    float alienPlayerCountMod = level.averageNumAlienClients / PLAYER_COUNT_MOD; -    float humanPlayerCountMod = level.averageNumHumanClients / PLAYER_COUNT_MOD; -    int   alienNextStageThreshold, humanNextStageThreshold; - -    if( alienPlayerCountMod < 0.1f ) -      alienPlayerCountMod = 0.1f; - -    if( humanPlayerCountMod < 0.1f ) -      humanPlayerCountMod = 0.1f; - -    if( g_alienStage.integer == S1 && g_alienMaxStage.integer > S1 ) -      alienNextStageThreshold = (int)( ceil( (float)g_alienStage2Threshold.integer * alienPlayerCountMod ) ); -    else if( g_alienStage.integer == S2 && g_alienMaxStage.integer > S2 ) -      alienNextStageThreshold = (int)( ceil( (float)g_alienStage3Threshold.integer * alienPlayerCountMod ) ); -    else -      alienNextStageThreshold = -1; - -    if( g_humanStage.integer == S1 && g_humanMaxStage.integer > S1 ) -      humanNextStageThreshold = (int)( ceil( (float)g_humanStage2Threshold.integer * humanPlayerCountMod ) ); -    else if( g_humanStage.integer == S2 && g_humanMaxStage.integer > S2 ) -      humanNextStageThreshold = (int)( ceil( (float)g_humanStage3Threshold.integer * humanPlayerCountMod ) ); -    else -      humanNextStageThreshold = -1; - -    trap_SetConfigstring( CS_STAGES, va( "%d %d %d %d %d %d", -          g_alienStage.integer, g_humanStage.integer, -          g_alienKills.integer, g_humanKills.integer, -          alienNextStageThreshold, humanNextStageThreshold ) ); -  } -} - -/* -============ -G_CalculateStages -============ -*/ -void G_CalculateStages( void ) -{ -  float alienPlayerCountMod = level.averageNumAlienClients / PLAYER_COUNT_MOD; -  float humanPlayerCountMod = level.averageNumHumanClients / PLAYER_COUNT_MOD; - -  if( alienPlayerCountMod < 0.1f ) -    alienPlayerCountMod = 0.1f; - -  if( humanPlayerCountMod < 0.1f ) -    humanPlayerCountMod = 0.1f; - -  if( g_alienKills.integer >= -      (int)( ceil( (float)g_alienStage2Threshold.integer * alienPlayerCountMod ) ) && -      g_alienStage.integer == S1 && g_alienMaxStage.integer > S1 ) -  { -    G_Checktrigger_stages( PTE_ALIENS, S2 ); -    trap_Cvar_Set( "g_alienStage", va( "%d", S2 ) ); -    level.alienStage2Time = level.time; -  } - -  if( g_alienKills.integer >= -      (int)( ceil( (float)g_alienStage3Threshold.integer * alienPlayerCountMod ) ) && -      g_alienStage.integer == S2 && g_alienMaxStage.integer > S2 ) -  { -    G_Checktrigger_stages( PTE_ALIENS, S3 ); -    trap_Cvar_Set( "g_alienStage", va( "%d", S3 ) ); -    level.alienStage3Time = level.time; -  } - -  if( g_humanKills.integer >= -      (int)( ceil( (float)g_humanStage2Threshold.integer * humanPlayerCountMod ) ) && -      g_humanStage.integer == S1 && g_humanMaxStage.integer > S1 ) -  { -    G_Checktrigger_stages( PTE_HUMANS, S2 ); -    trap_Cvar_Set( "g_humanStage", va( "%d", S2 ) ); -    level.humanStage2Time = level.time; -  } - -  if( g_humanKills.integer >= -      (int)( ceil( (float)g_humanStage3Threshold.integer * humanPlayerCountMod ) ) && -      g_humanStage.integer == S2 && g_humanMaxStage.integer > S2 ) -  { -    G_Checktrigger_stages( PTE_HUMANS, S3 ); -    trap_Cvar_Set( "g_humanStage", va( "%d", S3 ) ); -    level.humanStage3Time = level.time; -  } -} - -/* -============ -CalculateAvgPlayers - -Calculates the average number of players playing this game -============ -*/ -void G_CalculateAvgPlayers( void ) -{ -  //there are no clients or only spectators connected, so -  //reset the number of samples in order to avoid the situation -  //where the average tends to 0 -  if( !level.numAlienClients ) -  { -    level.numAlienSamples = 0; -    trap_Cvar_Set( "g_alienKills", "0" ); -  } - -  if( !level.numHumanClients ) -  { -    level.numHumanSamples = 0; -    trap_Cvar_Set( "g_humanKills", "0" ); -  } - -  //calculate average number of clients for stats -  level.averageNumAlienClients = -    ( ( level.averageNumAlienClients * level.numAlienSamples ) -      + level.numAlienClients ) / -    (float)( level.numAlienSamples + 1 ); -  level.numAlienSamples++; - -  level.averageNumHumanClients = -    ( ( level.averageNumHumanClients * level.numHumanSamples ) -      + level.numHumanClients ) / -    (float)( level.numHumanSamples + 1 ); -  level.numHumanSamples++; -} - -/* -============ -CalculateRanks - -Recalculates the score ranks of all players -This will be called on every client connect, begin, disconnect, death, -and team change. -============ -*/ -void CalculateRanks( void ) -{ -  int       i; -  int       rank; -  int       score; -  int       newScore; -  gclient_t *cl; - -  level.follow1 = -1; -  level.follow2 = -1; -  level.numConnectedClients = 0; -  level.numNonSpectatorClients = 0; -  level.numPlayingClients = 0; -  level.numVotingClients = 0;   // don't count bots -  level.numAlienClients = 0; -  level.numHumanClients = 0; -  level.numLiveAlienClients = 0; -  level.numLiveHumanClients = 0; - -  for( i = 0; i < TEAM_NUM_TEAMS; i++ ) -    level.numteamVotingClients[ i ] = 0; - -  for( i = 0; i < level.maxclients; i++ ) -  { -    if ( level.clients[ i ].pers.connected != CON_DISCONNECTED ) -    { -      level.sortedClients[ level.numConnectedClients ] = i; -      level.numConnectedClients++; - -      if( !( level.clients[ i ].ps.pm_flags & PMF_FOLLOW ) ) -      { -        //so we know when the game ends and for team leveling -        if( level.clients[ i ].ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -        { -          level.numAlienClients++; -          if( level.clients[ i ].sess.sessionTeam != TEAM_SPECTATOR ) -            level.numLiveAlienClients++; -        } - -        if( level.clients[ i ].ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -        { -          level.numHumanClients++; -          if( level.clients[ i ].sess.sessionTeam != TEAM_SPECTATOR ) -            level.numLiveHumanClients++; -        } -      } - -      if( level.clients[ i ].sess.sessionTeam != TEAM_SPECTATOR ) -      { -        level.numNonSpectatorClients++; - -        // decide if this should be auto-followed -        if( level.clients[ i ].pers.connected == CON_CONNECTED ) -        { -          level.numPlayingClients++; -          if( !(g_entities[ i ].r.svFlags & SVF_BOT) ) -            level.numVotingClients++; - -          if( level.clients[ i ].ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -            level.numteamVotingClients[ 0 ]++; -          else if( level.clients[ i ].ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -            level.numteamVotingClients[ 1 ]++; - -          if( level.follow1 == -1 ) -            level.follow1 = i; -          else if( level.follow2 == -1 ) -            level.follow2 = i; -        } - -      } -    } -  } - -  qsort( level.sortedClients, level.numConnectedClients, -    sizeof( level.sortedClients[ 0 ] ), SortRanks ); - -  // set the rank value for all clients that are connected and not spectators -  rank = -1; -  score = 0; -  for( i = 0;  i < level.numPlayingClients; i++ ) -  { -    cl = &level.clients[ level.sortedClients[ i ] ]; -    newScore = cl->ps.persistant[ PERS_SCORE ]; - -    if( i == 0 || newScore != score ) -    { -      rank = i; -      // assume we aren't tied until the next client is checked -      level.clients[ level.sortedClients[ i ] ].ps.persistant[ PERS_RANK ] = rank; -    } -    else -    { -      // we are tied with the previous client -      level.clients[ level.sortedClients[ i - 1 ] ].ps.persistant[ PERS_RANK ] = rank; -      level.clients[ level.sortedClients[ i ] ].ps.persistant[ PERS_RANK ] = rank; -    } - -    score = newScore; -  } - -  // set the CS_SCORES1/2 configstrings, which will be visible to everyone -  if( level.numConnectedClients == 0 ) -  { -    trap_SetConfigstring( CS_SCORES1, va( "%i", SCORE_NOT_PRESENT ) ); -    trap_SetConfigstring( CS_SCORES2, va( "%i", SCORE_NOT_PRESENT ) ); -  } -  else if( level.numConnectedClients == 1 ) -  { -    trap_SetConfigstring( CS_SCORES1, va( "%i", -          level.clients[ level.sortedClients[ 0 ] ].ps.persistant[ PERS_SCORE ] ) ); -    trap_SetConfigstring( CS_SCORES2, va( "%i", SCORE_NOT_PRESENT ) ); -  } -  else -  { -    trap_SetConfigstring( CS_SCORES1, va( "%i", -          level.clients[ level.sortedClients[ 0 ] ].ps.persistant[ PERS_SCORE ] ) ); -    trap_SetConfigstring( CS_SCORES2, va( "%i", -          level.clients[ level.sortedClients[ 1 ] ].ps.persistant[ PERS_SCORE ] ) ); -  } - -  // see if it is time to end the level -  CheckExitRules( ); - -  // if we are at the intermission, send the new info to everyone -  if( level.intermissiontime ) -    SendScoreboardMessageToAllClients( ); -} - - -/* -======================================================================== - -MAP CHANGING - -======================================================================== -*/ - -/* -======================== -SendScoreboardMessageToAllClients - -Do this at BeginIntermission time and whenever ranks are recalculated -due to enters/exits/forced team changes -======================== -*/ -void SendScoreboardMessageToAllClients( void ) -{ -  int   i; - -  for( i = 0; i < level.maxclients; i++ ) -  { -    if( level.clients[ i ].pers.connected == CON_CONNECTED ) -      ScoreboardMessage( g_entities + i ); -  } -} - -/* -======================== -MoveClientToIntermission - -When the intermission starts, this will be called for all players. -If a new client connects, this will be called after the spawn function. -======================== -*/ -void MoveClientToIntermission( gentity_t *ent ) -{ -  // take out of follow mode if needed -  if( ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) -    G_StopFollowing( ent ); - -  // move to the spot -  VectorCopy( level.intermission_origin, ent->s.origin ); -  VectorCopy( level.intermission_origin, ent->client->ps.origin ); -  VectorCopy( level.intermission_angle, ent->client->ps.viewangles ); -  ent->client->ps.pm_type = PM_INTERMISSION; - -  // clean up powerup info -  memset( ent->client->ps.powerups, 0, sizeof( ent->client->ps.powerups ) ); - -  ent->client->ps.eFlags = 0; -  ent->s.eFlags = 0; -  ent->s.eType = ET_GENERAL; -  ent->s.modelindex = 0; -  ent->s.loopSound = 0; -  ent->s.event = 0; -  ent->r.contents = 0; -} - -/* -================== -FindIntermissionPoint - -This is also used for spectator spawns -================== -*/ -void FindIntermissionPoint( void ) -{ -  gentity_t *ent, *target; -  vec3_t    dir; - -  // find the intermission spot -  ent = G_Find( NULL, FOFS( classname ), "info_player_intermission" ); - -  if( !ent ) -  { // the map creator forgot to put in an intermission point... -    SelectSpawnPoint( vec3_origin, level.intermission_origin, level.intermission_angle ); -  } -  else -  { -    VectorCopy( ent->s.origin, level.intermission_origin ); -    VectorCopy( ent->s.angles, level.intermission_angle ); -    // if it has a target, look towards it -    if( ent->target ) -    { -      target = G_PickTarget( ent->target ); - -      if( target ) -      { -        VectorSubtract( target->s.origin, level.intermission_origin, dir ); -        vectoangles( dir, level.intermission_angle ); -      } -    } -  } - -} - -/* -================== -BeginIntermission -================== -*/ -void BeginIntermission( void ) -{ -  int     i; -  gentity_t *client; - -  if( level.intermissiontime ) -    return;   // already active - -  level.intermissiontime = level.time; -  FindIntermissionPoint( ); - -  // move all clients to the intermission point -  for( i = 0; i < level.maxclients; i++ ) -  { -    client = g_entities + i; - -    if( !client->inuse ) -      continue; - -    // respawn if dead -    if( client->health <= 0 ) -      respawn(client); - -    MoveClientToIntermission( client ); -  } - -  // send the current scoring to all clients -  SendScoreboardMessageToAllClients( ); -} - - -/* -============= -ExitLevel - -When the intermission has been exited, the server is either killed -or moved to a new level based on the "nextmap" cvar - -============= -*/ -void ExitLevel( void ) -{ -  int       i; -  gclient_t *cl; - -  if( G_MapRotationActive( ) ) -    G_AdvanceMapRotation( ); -  else -    trap_SendConsoleCommand( EXEC_APPEND, "vstr nextmap\n" ); - -  level.changemap = NULL; -  level.intermissiontime = 0; - -  // reset all the scores so we don't enter the intermission again -  for( i = 0; i < g_maxclients.integer; i++ ) -  { -    cl = level.clients + i; -    if( cl->pers.connected != CON_CONNECTED ) -      continue; - -    cl->ps.persistant[ PERS_SCORE ] = 0; -  } - -  // we need to do this here before chaning to CON_CONNECTING -  G_WriteSessionData( ); - -  // change all client states to connecting, so the early players into the -  // next level will know the others aren't done reconnecting -  for( i = 0; i < g_maxclients.integer; i++ ) -  { -    if( level.clients[ i ].pers.connected == CON_CONNECTED ) -      level.clients[ i ].pers.connected = CON_CONNECTING; -  } - -} - -/* -================= -G_LogPrintf - -Print to the logfile with a time stamp if it is open -================= -*/ -void QDECL G_LogPrintf( const char *fmt, ... ) -{ -  va_list argptr; -  char    string[ 1024 ]; -  int     min, tens, sec; - -  sec = level.time / 1000; - -  min = sec / 60; -  sec -= min * 60; -  tens = sec / 10; -  sec -= tens * 10; - -  Com_sprintf( string, sizeof( string ), "%3i:%i%i ", min, tens, sec ); - -  va_start( argptr, fmt ); -  vsprintf( string +7 , fmt,argptr ); -  va_end( argptr ); - -  if( g_dedicated.integer ) -    G_Printf( "%s", string + 7 ); - -  if( !level.logFile ) -    return; - -  trap_FS_Write( string, strlen( string ), level.logFile ); -} - -/* -================ -LogExit - -Append information about this game to the log file -================ -*/ -void LogExit( const char *string ) -{ -  int         i, numSorted; -  gclient_t   *cl; -  gentity_t   *ent; - -  G_LogPrintf( "Exit: %s\n", string ); - -  level.intermissionQueued = level.time; - -  // this will keep the clients from playing any voice sounds -  // that will get cut off when the queued intermission starts -  trap_SetConfigstring( CS_INTERMISSION, "1" ); - -  // don't send more than 32 scores (FIXME?) -  numSorted = level.numConnectedClients; -  if( numSorted > 32 ) -    numSorted = 32; - -  for( i = 0; i < numSorted; i++ ) -  { -    int   ping; - -    cl = &level.clients[ level.sortedClients[ i ] ]; - -    if( cl->ps.stats[ STAT_PTEAM ] == PTE_NONE ) -      continue; - -    if( cl->pers.connected == CON_CONNECTING ) -      continue; - -    ping = cl->ps.ping < 999 ? cl->ps.ping : 999; - -    G_LogPrintf( "score: %i  ping: %i  client: %i %s\n", -      cl->ps.persistant[ PERS_SCORE ], ping, level.sortedClients[ i ], -      cl->pers.netname ); - -  } - -  for( i = 1, ent = g_entities + i ; i < level.num_entities ; i++, ent++ ) -  { -    if( !ent->inuse ) -      continue; - -    if( !Q_stricmp( ent->classname, "trigger_win" ) ) -    { -      if( level.lastWin == ent->stageTeam ) -        ent->use( ent, ent, ent ); -    } -  } -} - - -/* -================= -CheckIntermissionExit - -The level will stay at the intermission for a minimum of 5 seconds -If all players wish to continue, the level will then exit. -If one or more players have not acknowledged the continue, the game will -wait 10 seconds before going on. -================= -*/ -void CheckIntermissionExit( void ) -{ -  int       ready, notReady, numPlayers; -  int       i; -  gclient_t *cl; -  int       readyMask; - -  //if no clients are connected, just exit -  if( !level.numConnectedClients ) -  { -    ExitLevel( ); -    return; -  } - -  // see which players are ready -  ready = 0; -  notReady = 0; -  readyMask = 0; -  numPlayers = 0; -  for( i = 0; i < g_maxclients.integer; i++ ) -  { -    cl = level.clients + i; -    if( cl->pers.connected != CON_CONNECTED ) -      continue; - -    if( cl->ps.stats[ STAT_PTEAM ] == PTE_NONE ) -      continue; - -    if( g_entities[ cl->ps.clientNum ].r.svFlags & SVF_BOT ) -      continue; - -    if( cl->readyToExit ) -    { -      ready++; -      if( i < 16 ) -        readyMask |= 1 << i; -    } -    else -      notReady++; - -    numPlayers++; -  } - -  trap_SetConfigstring( CS_CLIENTS_READY, va( "%d", readyMask ) ); - -  // never exit in less than five seconds -  if( level.time < level.intermissiontime + 5000 ) -    return; - -  // if nobody wants to go, clear timer -  if( !ready && numPlayers ) -  { -    level.readyToExit = qfalse; -    return; -  } - -  // if everyone wants to go, go now -  if( !notReady ) -  { -    ExitLevel( ); -    return; -  } - -  // the first person to ready starts the thirty second timeout -  if( !level.readyToExit ) -  { -    level.readyToExit = qtrue; -    level.exitTime = level.time; -  } - -  // if we have waited thirty seconds since at least one player -  // wanted to exit, go ahead -  if( level.time < level.exitTime + 30000 ) -    return; - -  ExitLevel( ); -} - -/* -============= -ScoreIsTied -============= -*/ -qboolean ScoreIsTied( void ) -{ -  int   a, b; - -  if( level.numPlayingClients < 2 ) -    return qfalse; - -  a = level.clients[ level.sortedClients[ 0 ] ].ps.persistant[ PERS_SCORE ]; -  b = level.clients[ level.sortedClients[ 1 ] ].ps.persistant[ PERS_SCORE ]; - -  return a == b; -} - -/* -================= -CheckExitRules - -There will be a delay between the time the exit is qualified for -and the time everyone is moved to the intermission spot, so you -can see the last frag. -================= -*/ -void CheckExitRules( void ) -{ -  char      s[ MAX_STRING_CHARS ]; - -  trap_Cvar_VariableStringBuffer( "mapname", s, sizeof( s ) ); - -  // if at the intermission, wait for all non-bots to -  // signal ready, then go to next level -  if( level.intermissiontime ) -  { -    CheckIntermissionExit( ); -    return; -  } - -  if( level.intermissionQueued ) -  { -    if( level.time - level.intermissionQueued >= INTERMISSION_DELAY_TIME ) -    { -      level.intermissionQueued = 0; -      BeginIntermission( ); -    } - -    return; -  } - -  if( g_timelimit.integer && !level.warmupTime ) -  { -    if( level.time - level.startTime >= g_timelimit.integer * 60000 ) -    { -      G_SendCommandFromServer( -1, "print \"Timelimit hit\n\"" ); - -      G_LogPrintf( "STATS T:L A:%f H:%f M:%s D:%d AS:%d AS2T:%d AS3T:%d HS:%d HS2T:%d HS3T:%d\n", -          level.averageNumAlienClients, level.averageNumHumanClients, -          s, level.time - level.startTime, -          g_alienStage.integer, -          level.alienStage2Time - level.startTime, level.alienStage3Time - level.startTime, -          g_humanStage.integer, -          level.humanStage2Time - level.startTime, level.humanStage3Time - level.startTime ); - -      level.lastWin = PTE_NONE; -      LogExit( "Timelimit hit." ); -      return; -    } -  } - -  //TA: end the game on these conditions -  if( level.uncondHumanWin || -      ( ( level.time > level.startTime + 1000 ) && -        ( level.numAlienSpawns == 0 ) && -        ( level.numLiveAlienClients == 0 ) ) ) -  { -    //humans win -    level.lastWin = PTE_HUMANS; -    G_SendCommandFromServer( -1, "print \"Humans win\n\""); - -    G_LogPrintf( "STATS T:H A:%f H:%f M:%s D:%d AS:%d AS2T:%d AS3T:%d HS:%d HS2T:%d HS3T:%d\n", -        level.averageNumAlienClients, level.averageNumHumanClients, -        s, level.time - level.startTime, -        g_alienStage.integer, -        level.alienStage2Time - level.startTime, level.alienStage3Time - level.startTime, -        g_humanStage.integer, -        level.humanStage2Time - level.startTime, level.humanStage3Time - level.startTime ); - -    LogExit( "Humans win." ); -    return; -  } -  else if( level.uncondAlienWin || -           ( ( level.time > level.startTime + 1000 ) && -             ( level.numHumanSpawns == 0 ) && -             ( level.numLiveHumanClients == 0 ) ) ) -  { -    //aliens win -    level.lastWin = PTE_ALIENS; -    G_SendCommandFromServer( -1, "print \"Aliens win\n\""); - -    G_LogPrintf( "STATS T:A A:%f H:%f M:%s D:%d AS:%d AS2T:%d AS3T:%d HS:%d HS2T:%d HS3T:%d\n", -        level.averageNumAlienClients, level.averageNumHumanClients, -        s, level.time - level.startTime, -        g_alienStage.integer, -        level.alienStage2Time - level.startTime, level.alienStage3Time - level.startTime, -        g_humanStage.integer, -        level.humanStage2Time - level.startTime, level.humanStage3Time - level.startTime ); - -    LogExit( "Aliens win." ); -    return; -  } - -  if( level.numPlayingClients < 2 ) -    return; -} - - - -/* -======================================================================== - -FUNCTIONS CALLED EVERY FRAME - -======================================================================== -*/ - - -/* -================== -CheckVote -================== -*/ -void CheckVote( void ) -{ -  if( level.voteExecuteTime && level.voteExecuteTime < level.time ) -  { -    level.voteExecuteTime = 0; - -    //SUPAR HAK -    if( !Q_stricmp( level.voteString, "vstr nextmap" ) ) -    { -      level.lastWin = PTE_NONE; -      LogExit( "Vote for next map." ); -    } -    else -      trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.voteString ) ); -  } - -  if( !level.voteTime ) -    return; - -  if( level.time - level.voteTime >= VOTE_TIME ) -  { -    if( level.voteYes > level.voteNo ) -    { -      // execute the command, then remove the vote -      G_SendCommandFromServer( -1, "print \"Vote passed\n\"" ); -      level.voteExecuteTime = level.time + 3000; -    } -    else -    { -      // same behavior as a timeout -      G_SendCommandFromServer( -1, "print \"Vote failed\n\"" ); -    } -  } -  else -  { -    if( level.voteYes > level.numConnectedClients / 2 ) -    { -      // execute the command, then remove the vote -      G_SendCommandFromServer( -1, "print \"Vote passed\n\"" ); -      level.voteExecuteTime = level.time + 3000; -    } -    else if( level.voteNo >= level.numConnectedClients / 2 ) -    { -      // same behavior as a timeout -      G_SendCommandFromServer( -1, "print \"Vote failed\n\"" ); -    } -    else -    { -      // still waiting for a majority -      return; -    } -  } - -  level.voteTime = 0; -  trap_SetConfigstring( CS_VOTE_TIME, "" ); -} - - -/* -================== -CheckTeamVote -================== -*/ -void CheckTeamVote( int team ) -{ -  int cs_offset; - -  if ( team == PTE_HUMANS ) -    cs_offset = 0; -  else if ( team == PTE_ALIENS ) -    cs_offset = 1; -  else -    return; - -  if( !level.teamVoteTime[ cs_offset ] ) -    return; - -  if( level.time - level.teamVoteTime[ cs_offset ] >= VOTE_TIME ) -  { -    G_SendCommandFromServer( -1, "print \"Team vote failed\n\"" ); -  } -  else -  { -    if( level.teamVoteYes[ cs_offset ] > level.numteamVotingClients[ cs_offset ] / 2 ) -    { -      // execute the command, then remove the vote -      G_SendCommandFromServer( -1, "print \"Team vote passed\n\"" ); -      // -      trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.teamVoteString[ cs_offset ] ) ); -    } -    else if( level.teamVoteNo[ cs_offset ] >= level.numteamVotingClients[ cs_offset ] / 2 ) -    { -      // same behavior as a timeout -      G_SendCommandFromServer( -1, "print \"Team vote failed\n\"" ); -    } -    else -    { -      // still waiting for a majority -      return; -    } -  } - -  level.teamVoteTime[ cs_offset ] = 0; -  trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset, "" ); -} - - -/* -================== -CheckCvars -================== -*/ -void CheckCvars( void ) -{ -  static int lastMod = -1; - -  if( g_password.modificationCount != lastMod ) -  { -    lastMod = g_password.modificationCount; - -    if( *g_password.string && Q_stricmp( g_password.string, "none" ) ) -      trap_Cvar_Set( "g_needpass", "1" ); -    else -      trap_Cvar_Set( "g_needpass", "0" ); -  } -} - -/* -============= -G_RunThink - -Runs thinking code for this frame if necessary -============= -*/ -void G_RunThink( gentity_t *ent ) -{ -  float thinktime; - -  thinktime = ent->nextthink; -  if( thinktime <= 0 ) -    return; - -  if( thinktime > level.time ) -    return; - -  ent->nextthink = 0; -  if( !ent->think ) -    G_Error( "NULL ent->think" ); - -  ent->think( ent ); -} - -/* -============= -G_EvaluateAcceleration - -Calculates the acceleration for an entity -============= -*/ -void G_EvaluateAcceleration( gentity_t *ent, int msec ) -{ -  vec3_t  deltaVelocity; -  vec3_t  deltaAccel; - -  VectorSubtract( ent->s.pos.trDelta, ent->oldVelocity, deltaVelocity ); -  VectorScale( deltaVelocity, 1.0f / (float)msec, ent->acceleration ); - -  VectorSubtract( ent->acceleration, ent->oldAccel, deltaAccel ); -  VectorScale( deltaAccel, 1.0f / (float)msec, ent->jerk ); - -  VectorCopy( ent->s.pos.trDelta, ent->oldVelocity ); -  VectorCopy( ent->acceleration, ent->oldAccel ); -} - -/* -================ -G_RunFrame - -Advances the non-player objects in the world -================ -*/ -void G_RunFrame( int levelTime ) -{ -  int       i; -  gentity_t *ent; -  int       msec; -  int       start, end; - -  // if we are waiting for the level to restart, do nothing -  if( level.restarted ) -    return; - -  level.framenum++; -  level.previousTime = level.time; -  level.time = levelTime; -  msec = level.time - level.previousTime; - -  //TA: seed the rng -  srand( level.framenum ); - -  // get any cvar changes -  G_UpdateCvars( ); - -  // -  // go through all allocated objects -  // -  start = trap_Milliseconds( ); -  ent = &g_entities[ 0 ]; - -  for( i = 0; i < level.num_entities; i++, ent++ ) -  { -    if( !ent->inuse ) -      continue; - -    // clear events that are too old -    if( level.time - ent->eventTime > EVENT_VALID_MSEC ) -    { -      if( ent->s.event ) -      { -        ent->s.event = 0; // &= EV_EVENT_BITS; -        if ( ent->client ) -        { -          ent->client->ps.externalEvent = 0; -          //ent->client->ps.events[0] = 0; -          //ent->client->ps.events[1] = 0; -        } -      } - -      if( ent->freeAfterEvent ) -      { -        // tempEntities or dropped items completely go away after their event -        G_FreeEntity( ent ); -        continue; -      } -      else if( ent->unlinkAfterEvent ) -      { -        // items that will respawn will hide themselves after their pickup event -        ent->unlinkAfterEvent = qfalse; -        trap_UnlinkEntity( ent ); -      } -    } - -    // temporary entities don't think -    if( ent->freeAfterEvent ) -      continue; - -    //TA: calculate the acceleration of this entity -    if( ent->evaluateAcceleration ) -      G_EvaluateAcceleration( ent, msec ); - -    if( !ent->r.linked && ent->neverFree ) -      continue; - -    if( ent->s.eType == ET_MISSILE ) -    { -      G_RunMissile( ent ); -      continue; -    } - -    if( ent->s.eType == ET_BUILDABLE ) -    { -      G_BuildableThink( ent, msec ); -      continue; -    } - -    if( ent->s.eType == ET_CORPSE || ent->physicsObject ) -    { -      G_Physics( ent, msec ); -      continue; -    } - -    if( ent->s.eType == ET_MOVER ) -    { -      G_RunMover( ent ); -      continue; -    } - -    if( i < MAX_CLIENTS ) -    { -      G_RunClient( ent ); -      continue; -    } - -    G_RunThink( ent ); -  } -  end = trap_Milliseconds(); - -  start = trap_Milliseconds(); - -  // perform final fixups on the players -  ent = &g_entities[ 0 ]; - -  for( i = 0; i < level.maxclients; i++, ent++ ) -  { -    if( ent->inuse ) -      ClientEndFrame( ent ); -  } - -  end = trap_Milliseconds(); - -  //TA: -  G_CountSpawns( ); -  G_CalculateBuildPoints( ); -  G_CalculateStages( ); -  G_SpawnClients( PTE_ALIENS ); -  G_SpawnClients( PTE_HUMANS ); -  G_CalculateAvgPlayers( ); -  G_UpdateZaps( msec ); - -  //send any pending commands -  G_ProcessCommandQueues( ); - -  // see if it is time to end the level -  CheckExitRules( ); - -  // update to team status? -  CheckTeamStatus( ); - -  // cancel vote if timed out -  CheckVote( ); - -  // check team votes -  CheckTeamVote( PTE_HUMANS ); -  CheckTeamVote( PTE_ALIENS ); - -  // for tracking changes -  CheckCvars( ); - -  if( g_listEntity.integer ) -  { -    for( i = 0; i < MAX_GENTITIES; i++ ) -      G_Printf( "%4i: %s\n", i, g_entities[ i ].classname ); - -    trap_Cvar_Set( "g_listEntity", "0" ); -  } -} - diff --git a/mod/src/game/g_maprotation.c b/mod/src/game/g_maprotation.c deleted file mode 100644 index fb98c4a8..00000000 --- a/mod/src/game/g_maprotation.c +++ /dev/null @@ -1,709 +0,0 @@ -// g_maprotation.c -- the map rotation system - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -static mapRotations_t mapRotations; - -/* -=============== -G_ParseCommandSection - -Parse a map rotation command section -=============== -*/ -static qboolean G_ParseMapCommandSection( mapRotationEntry_t *mre, char **text_p ) -{ -  char *token; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( text_p ); - -    if( !token ) -      break; - -    if( !Q_stricmp( token, "" ) ) -      return qfalse; - -    if( !Q_stricmp( token, "}" ) ) -      return qtrue; //reached the end of this command section - -    Q_strncpyz( mre->postCmds[ mre->numCmds ], token, sizeof( mre->postCmds[ 0 ] ) ); -    Q_strcat( mre->postCmds[ mre->numCmds ], sizeof( mre->postCmds[ 0 ] ), " " ); - -    token = COM_ParseExt( text_p, qfalse ); - -    while( token && token[ 0 ] != 0 ) -    { -      Q_strcat( mre->postCmds[ mre->numCmds ], sizeof( mre->postCmds[ 0 ] ), token ); -      Q_strcat( mre->postCmds[ mre->numCmds ], sizeof( mre->postCmds[ 0 ] ), " " ); -      token = COM_ParseExt( text_p, qfalse ); -    } - -    if( mre->numCmds == MAX_MAP_COMMANDS ) -    { -      G_Printf( S_COLOR_RED "ERROR: maximum number of map commands (%d) reached\n", -                MAX_MAP_COMMANDS ); -      return qfalse; -    } -    else -      mre->numCmds++; -  } - -  return qfalse; -} - -/* -=============== -G_ParseMapRotation - -Parse a map rotation section -=============== -*/ -static qboolean G_ParseMapRotation( mapRotation_t *mr, char **text_p ) -{ -  char                    *token; -  qboolean                mnSet = qfalse; -  mapRotationEntry_t      *mre = NULL; -  mapRotationCondition_t  *mrc; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( text_p ); - -    if( !token ) -      break; - -    if( !Q_stricmp( token, "" ) ) -      return qfalse; - -    if( !Q_stricmp( token, "{" ) ) -    { -      if( !mnSet ) -      { -        G_Printf( S_COLOR_RED "ERROR: map settings section with no name\n" ); -        return qfalse; -      } - -      if( !G_ParseMapCommandSection( mre, text_p ) ) -      { -        G_Printf( S_COLOR_RED "ERROR: failed to parse map command section\n" ); -        return qfalse; -      } - -      mnSet = qfalse; -      continue; -    } -    else if( !Q_stricmp( token, "goto" ) ) -    { -      token = COM_Parse( text_p ); - -      if( !token ) -        break; - -      mrc = &mre->conditions[ mre->numConditions ]; -      mrc->unconditional = qtrue; -      Q_strncpyz( mrc->dest, token, sizeof( mrc->dest ) ); - -      if( mre->numConditions == MAX_MAP_ROTATION_CONDS ) -      { -        G_Printf( S_COLOR_RED "ERROR: maximum number of conditions for one map (%d) reached\n", -                  MAX_MAP_ROTATION_CONDS ); -        return qfalse; -      } -      else -        mre->numConditions++; - -      continue; -    } -    else if( !Q_stricmp( token, "if" ) ) -    { -      token = COM_Parse( text_p ); - -      if( !token ) -        break; - -      mrc = &mre->conditions[ mre->numConditions ]; - -      if( !Q_stricmp( token, "numClients" ) ) -      { -        mrc->lhs = MCV_NUMCLIENTS; - -        token = COM_Parse( text_p ); - -        if( !token ) -          break; - -        if( !Q_stricmp( token, "<" ) ) -          mrc->op = MCO_LT; -        else if( !Q_stricmp( token, ">" ) ) -          mrc->op = MCO_GT; -        else if( !Q_stricmp( token, "=" ) ) -          mrc->op = MCO_EQ; -        else -        { -          G_Printf( S_COLOR_RED "ERROR: invalid operator in expression: %s\n", token ); -          return qfalse; -        } - -        token = COM_Parse( text_p ); - -        if( !token ) -          break; - -        mrc->numClients = atoi( token ); -      } -      else if( !Q_stricmp( token, "lastWin" ) ) -      { -        mrc->lhs = MCV_LASTWIN; - -        token = COM_Parse( text_p ); - -        if( !token ) -          break; - -        if( !Q_stricmp( token, "aliens" ) ) -          mrc->lastWin = PTE_ALIENS; -        else if( !Q_stricmp( token, "humans" ) ) -          mrc->lastWin = PTE_HUMANS; -        else -        { -          G_Printf( S_COLOR_RED "ERROR: invalid right hand side in expression: %s\n", token ); -          return qfalse; -        } -      } -      else if( !Q_stricmp( token, "random" ) ) -        mrc->lhs = MCV_RANDOM; -      else -      { -        G_Printf( S_COLOR_RED "ERROR: invalid left hand side in expression: %s\n", token ); -        return qfalse; -      } - -      token = COM_Parse( text_p ); - -      if( !token ) -        break; - -      mrc->unconditional = qfalse; -      Q_strncpyz( mrc->dest, token, sizeof( mrc->dest ) ); - -      if( mre->numConditions == MAX_MAP_ROTATION_CONDS ) -      { -        G_Printf( S_COLOR_RED "ERROR: maximum number of conditions for one map (%d) reached\n", -                  MAX_MAP_ROTATION_CONDS ); -        return qfalse; -      } -      else -        mre->numConditions++; - -      continue; -    } -    else if( !Q_stricmp( token, "}" ) ) -      return qtrue; //reached the end of this map rotation - -    mre = &mr->maps[ mr->numMaps ]; - -    if( mr->numMaps == MAX_MAP_ROTATION_MAPS ) -    { -      G_Printf( S_COLOR_RED "ERROR: maximum number of maps in one rotation (%d) reached\n", -                MAX_MAP_ROTATION_MAPS ); -      return qfalse; -    } -    else -      mr->numMaps++; - -    Q_strncpyz( mre->name, token, sizeof( mre->name ) ); -    mnSet = qtrue; -  } - -  return qfalse; -} - -/* -=============== -G_ParseMapRotationFile - -Load the map rotations from a map rotation file -=============== -*/ -static qboolean G_ParseMapRotationFile( const char *fileName ) -{ -  char          *text_p; -  int           i; -  int           len; -  char          *token; -  char          text[ 20000 ]; -  char          mrName[ MAX_QPATH ]; -  qboolean      mrNameSet = qfalse; -  fileHandle_t  f; - -  // load the file -  len = trap_FS_FOpenFile( fileName, &f, FS_READ ); -  if( len <= 0 ) -    return qfalse; - -  if( len >= sizeof( text ) - 1 ) -  { -    G_Printf( S_COLOR_RED "ERROR: map rotation file %s too long\n", fileName ); -    return qfalse; -  } - -  trap_FS_Read( text, len, f ); -  text[ len ] = 0; -  trap_FS_FCloseFile( f ); - -  // parse the text -  text_p = text; - -  // read optional parameters -  while( 1 ) -  { -    token = COM_Parse( &text_p ); - -    if( !token ) -      break; - -    if( !Q_stricmp( token, "" ) ) -      break; - -    if( !Q_stricmp( token, "{" ) ) -    { -      if( mrNameSet ) -      { -        //check for name space clashes -        for( i = 0; i < mapRotations.numRotations; i++ ) -        { -          if( !Q_stricmp( mapRotations.rotations[ i ].name, mrName ) ) -          { -            G_Printf( S_COLOR_RED "ERROR: a map rotation is already named %s\n", mrName ); -            return qfalse; -          } -        } - -        Q_strncpyz( mapRotations.rotations[ mapRotations.numRotations ].name, mrName, MAX_QPATH ); - -        if( !G_ParseMapRotation( &mapRotations.rotations[ mapRotations.numRotations ], &text_p ) ) -        { -          G_Printf( S_COLOR_RED "ERROR: %s: failed to parse map rotation %s\n", fileName, mrName ); -          return qfalse; -        } - -        //start parsing particle systems again -        mrNameSet = qfalse; - -        if( mapRotations.numRotations == MAX_MAP_ROTATIONS ) -        { -          G_Printf( S_COLOR_RED "ERROR: maximum number of map rotations (%d) reached\n", -                    MAX_MAP_ROTATIONS ); -          return qfalse; -        } -        else -          mapRotations.numRotations++; - -        continue; -      } -      else -      { -        G_Printf( S_COLOR_RED "ERROR: unamed map rotation\n" ); -        return qfalse; -      } -    } - -    if( !mrNameSet ) -    { -      Q_strncpyz( mrName, token, sizeof( mrName ) ); -      mrNameSet = qtrue; -    } -    else -    { -      G_Printf( S_COLOR_RED "ERROR: map rotation already named\n" ); -      return qfalse; -    } -  } - -  return qtrue; -} - -/* -=============== -G_PrintRotations - -Print the parsed map rotations -=============== -*/ -void G_PrintRotations( void ) -{ -  int i, j, k; - -  G_Printf( "Map rotations as parsed:\n\n" ); - -  for( i = 0; i < mapRotations.numRotations; i++ ) -  { -    G_Printf( "rotation: %s\n{\n", mapRotations.rotations[ i ].name ); - -    for( j = 0; j < mapRotations.rotations[ i ].numMaps; j++ ) -    { -      G_Printf( "  map: %s\n  {\n", mapRotations.rotations[ i ].maps[ j ].name ); - -      for( k = 0; k < mapRotations.rotations[ i ].maps[ j ].numCmds; k++ ) -      { -        G_Printf( "    command: %s\n", -                  mapRotations.rotations[ i ].maps[ j ].postCmds[ k ] ); -      } - -      G_Printf( "  }\n" ); - -      for( k = 0; k < mapRotations.rotations[ i ].maps[ j ].numConditions; k++ ) -      { -        G_Printf( "  conditional: %s\n", -                  mapRotations.rotations[ i ].maps[ j ].conditions[ k ].dest ); -      } - -    } - -    G_Printf( "}\n" ); -  } - -  G_Printf( "Total memory used: %d bytes\n", sizeof( mapRotations ) ); -} - -/* -=============== -G_GetCurrentMapArray - -Fill a static array with the current map of each rotation -=============== -*/ -static int *G_GetCurrentMapArray( void ) -{ -  static int  currentMap[ MAX_MAP_ROTATIONS ]; -  int         i = 0; -  char        text[ MAX_MAP_ROTATIONS * 2 ]; -  char        *text_p, *token; - -  Q_strncpyz( text, g_currentMap.string, sizeof( text ) ); - -  text_p = text; - -  while( 1 ) -  { -    token = COM_Parse( &text_p ); - -    if( !token ) -      break; - -    if( !Q_stricmp( token, "" ) ) -      break; - -    currentMap[ i++ ] = atoi( token ); -  } - -  return currentMap; -} - -/* -=============== -G_SetCurrentMap - -Set the current map in some rotation -=============== -*/ -static void G_SetCurrentMap( int currentMap, int rotation ) -{ -  char  text[ MAX_MAP_ROTATIONS * 2 ] = { 0 }; -  int   *p = G_GetCurrentMapArray( ); -  int   i; - -  p[ rotation ] = currentMap; - -  for( i = 0; i < mapRotations.numRotations; i++ ) -    Q_strcat( text, sizeof( text ), va( "%d ", p[ i ] ) ); - -  trap_Cvar_Set( "g_currentMap", text ); -  trap_Cvar_Update( &g_currentMap ); -} - -/* -=============== -G_GetCurrentMap - -Return the current map in some rotation -=============== -*/ -static int G_GetCurrentMap( int rotation ) -{ -  int   *p = G_GetCurrentMapArray( ); - -  return p[ rotation ]; -} - -/* -=============== -G_IssueMapChange - -Send commands to the server to actually change the map -=============== -*/ -static void G_IssueMapChange( int rotation ) -{ -  int   i; -  int   map = G_GetCurrentMap( rotation ); -  char  cmd[ MAX_TOKEN_CHARS ]; - -  trap_SendConsoleCommand( EXEC_APPEND, va( "map %s\n", -    mapRotations.rotations[ rotation ].maps[ map ].name ) ); - -  for( i = 0; i < mapRotations.rotations[ rotation ].maps[ map ].numCmds; i++ ) -  { -    Q_strncpyz( cmd, mapRotations.rotations[ rotation ].maps[ map ].postCmds[ i ], -                sizeof( cmd ) ); -    Q_strcat( cmd, sizeof( cmd ), "\n" ); -    trap_SendConsoleCommand( EXEC_APPEND, cmd ); -  } -} - -/* -=============== -G_ResolveConditionDestination - -Resolve the destination of some condition -=============== -*/ -static mapConditionType_t G_ResolveConditionDestination( int *n, char *name ) -{ -  int i; - -  //search the current rotation first... -  for( i = 0; i < mapRotations.rotations[ g_currentMapRotation.integer ].numMaps; i++ ) -  { -    if( !Q_stricmp( mapRotations.rotations[ g_currentMapRotation.integer ].maps[ i ].name, name ) ) -    { -      *n = i; -      return MCT_MAP; -    } -  } - -  //...then search the rotation names -  for( i = 0; i < mapRotations.numRotations; i++ ) -  { -    if( !Q_stricmp( mapRotations.rotations[ i ].name, name ) ) -    { -      *n = i; -      return MCT_ROTATION; -    } -  } - -  //this should probably be prevented by a 2nd pass at compile time -  //but i'm lazy (FIXME) -  return MCT_ERR; -} - -/* -=============== -G_EvaluateMapCondition - -Evaluate a map condition -=============== -*/ -static qboolean G_EvaluateMapCondition( mapRotationCondition_t *mrc ) -{ -  switch( mrc->lhs ) -  { -    case MCV_RANDOM: -      return rand( ) & 1; -      break; - -    case MCV_NUMCLIENTS: -      switch( mrc->op ) -      { -        case MCO_LT: -          return level.numConnectedClients < mrc->numClients; -          break; - -        case MCO_GT: -          return level.numConnectedClients > mrc->numClients; -          break; - -        case MCO_EQ: -          return level.numConnectedClients == mrc->numClients; -          break; -      } -      break; - -    case MCV_LASTWIN: -      return level.lastWin == mrc->lastWin; -      break; - -    default: -    case MCV_ERR: -      G_Printf( S_COLOR_RED "ERROR: malformed map switch condition\n" ); -      break; -  } - -  return qfalse; -} - -/* -=============== -G_AdvanceMapRotation - -Increment the current map rotation -=============== -*/ -qboolean G_AdvanceMapRotation( void ) -{ -  mapRotation_t           *mr; -  mapRotationEntry_t      *mre; -  mapRotationCondition_t  *mrc; -  int                     currentRotation, currentMap, nextMap; -  int                     i, n; -  mapConditionType_t      mct; - -  if( ( currentRotation = g_currentMapRotation.integer ) == NOT_ROTATING ) -    return qfalse; - -  currentMap = G_GetCurrentMap( currentRotation ); - -  mr = &mapRotations.rotations[ currentRotation ]; -  mre = &mr->maps[ currentMap ]; -  nextMap = ( currentMap + 1 ) % mr->numMaps; - -  for( i = 0; i < mre->numConditions; i++ ) -  { -    mrc = &mre->conditions[ i ]; - -    if( mrc->unconditional || G_EvaluateMapCondition( mrc ) ) -    { -      mct = G_ResolveConditionDestination( &n, mrc->dest ); - -      switch( mct ) -      { -        case MCT_MAP: -          nextMap = n; -          break; - -        case MCT_ROTATION: -          G_StartMapRotation( mrc->dest, qtrue ); -          return qtrue; -          break; - -        default: -        case MCT_ERR: -          G_Printf( S_COLOR_YELLOW "WARNING: map switch destination could not be resolved: %s\n", -                    mrc->dest ); -          break; -      } -    } -  } - -  G_SetCurrentMap( nextMap, currentRotation ); -  G_IssueMapChange( currentRotation ); - -  return qtrue; -} - -/* -=============== -G_StartMapRotation - -Switch to a new map rotation -=============== -*/ -qboolean G_StartMapRotation( char *name, qboolean changeMap ) -{ -  int i; - -  for( i = 0; i < mapRotations.numRotations; i++ ) -  { -    if( !Q_stricmp( mapRotations.rotations[ i ].name, name ) ) -    { -      trap_Cvar_Set( "g_currentMapRotation", va( "%d", i ) ); -      trap_Cvar_Update( &g_currentMapRotation ); - -      if( changeMap ) -        G_IssueMapChange( i ); -      break; -    } -  } - -  if( i == mapRotations.numRotations ) -    return qfalse; -  else -    return qtrue; -} - -/* -=============== -G_StopMapRotation - -Stop the current map rotation -=============== -*/ -void G_StopMapRotation( void ) -{ -  trap_Cvar_Set( "g_currentMapRotation", va( "%d", NOT_ROTATING ) ); -  trap_Cvar_Update( &g_currentMapRotation ); -} - -/* -=============== -G_MapRotationActive - -Test if any map rotation is currently active -=============== -*/ -qboolean G_MapRotationActive( void ) -{ -  return ( g_currentMapRotation.integer != NOT_ROTATING ); -} - -/* -=============== -G_InitMapRotations - -Load and intialise the map rotations -=============== -*/ -void G_InitMapRotations( void ) -{ -  const char    *fileName = "maprotation.cfg"; -  fileHandle_t  f; - -  //load the file if it exists -  if( trap_FS_FOpenFile( fileName, &f, FS_READ ) > 0 ) -  { -    trap_FS_FCloseFile( f ); - -    if( !G_ParseMapRotationFile( fileName ) ) -      G_Printf( S_COLOR_RED "ERROR: failed to parse %s file\n", fileName ); -  } -  else -    G_Printf( "%s file not found.\n", fileName ); - -  if( g_currentMapRotation.integer == NOT_ROTATING ) -  { -    if( g_initialMapRotation.string[ 0 ] != 0 ) -    { -      G_StartMapRotation( g_initialMapRotation.string, qfalse ); - -      trap_Cvar_Set( "g_initialMapRotation", "" ); -      trap_Cvar_Update( &g_initialMapRotation ); -    } -  } -} diff --git a/mod/src/game/g_mem.c b/mod/src/game/g_mem.c deleted file mode 100644 index 2f3ed5c7..00000000 --- a/mod/src/game/g_mem.c +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// -// g_mem.c -// -// Golliwog: All rewritten to allow deallocation - - -#include "g_local.h" - -#define POOLSIZE    (256 * 1024) -#define  FREEMEMCOOKIE  ((int)0xDEADBE3F)  // Any unlikely to be used value -#define  ROUNDBITS    31          // Round to 32 bytes - -struct freememnode -{ -  // Size of ROUNDBITS -  int cookie, size;        // Size includes node (obviously) -  struct freememnode *prev, *next; -}; - -static char    memoryPool[POOLSIZE]; -static struct freememnode *freehead; -static int    freemem; - -void *G_Alloc( int size ) -{ -  // Find a free block and allocate. -  // Does two passes, attempts to fill same-sized free slot first. - -  struct freememnode *fmn, *prev, *next, *smallest; -  int allocsize, smallestsize; -  char *endptr; -  int *ptr; - -  allocsize = ( size + sizeof(int) + ROUNDBITS ) & ~ROUNDBITS;    // Round to 32-byte boundary -  ptr = NULL; - -  smallest = NULL; -  smallestsize = POOLSIZE + 1;    // Guaranteed not to miss any slots :) -  for( fmn = freehead; fmn; fmn = fmn->next ) -  { -    if( fmn->cookie != FREEMEMCOOKIE ) -      G_Error( "G_Alloc: Memory corruption detected!\n" ); - -    if( fmn->size >= allocsize ) -    { -      // We've got a block -      if( fmn->size == allocsize ) -      { -        // Same size, just remove - -        prev = fmn->prev; -        next = fmn->next; -        if( prev ) -          prev->next = next;      // Point previous node to next -        if( next ) -          next->prev = prev;      // Point next node to previous -        if( fmn == freehead ) -          freehead = next;      // Set head pointer to next -        ptr = (int *) fmn; -        break;              // Stop the loop, this is fine -      } -      else -      { -        // Keep track of the smallest free slot -        if( fmn->size < smallestsize ) -        { -          smallest = fmn; -          smallestsize = fmn->size; -        } -      } -    } -  } - -  if( !ptr && smallest ) -  { -    // We found a slot big enough -    smallest->size -= allocsize; -    endptr = (char *) smallest + smallest->size; -    ptr = (int *) endptr; -  } - -  if( ptr ) -  { -    freemem -= allocsize; -    if( g_debugAlloc.integer ) -      G_Printf( "G_Alloc of %i bytes (%i left)\n", allocsize, freemem ); -    memset( ptr, 0, allocsize ); -    *ptr++ = allocsize;        // Store a copy of size for deallocation -    return( (void *) ptr ); -  } - -  G_Error( "G_Alloc: failed on allocation of %i bytes\n", size ); -  return( NULL ); -} - -void G_Free( void *ptr ) -{ -  // Release allocated memory, add it to the free list. - -  struct freememnode *fmn; -  char *freeend; -  int *freeptr; - -  freeptr = ptr; -  freeptr--; - -  freemem += *freeptr; -  if( g_debugAlloc.integer ) -    G_Printf( "G_Free of %i bytes (%i left)\n", *freeptr, freemem ); - -  for( fmn = freehead; fmn; fmn = fmn->next ) -  { -    freeend = ((char *) fmn) + fmn->size; -    if( freeend == (char *) freeptr ) -    { -      // Released block can be merged to an existing node - -      fmn->size += *freeptr;    // Add size of node. -      return; -    } -  } -  // No merging, add to head of list - -  fmn = (struct freememnode *) freeptr; -  fmn->size = *freeptr;        // Set this first to avoid corrupting *freeptr -  fmn->cookie = FREEMEMCOOKIE; -  fmn->prev = NULL; -  fmn->next = freehead; -  freehead->prev = fmn; -  freehead = fmn; -} - -void G_InitMemory( void ) -{ -  // Set up the initial node - -  freehead = (struct freememnode *)memoryPool; -  freehead->cookie = FREEMEMCOOKIE; -  freehead->size = POOLSIZE; -  freehead->next = NULL; -  freehead->prev = NULL; -  freemem = sizeof( memoryPool ); -} - -void G_DefragmentMemory( void ) -{ -  // If there's a frenzy of deallocation and we want to -  // allocate something big, this is useful. Otherwise... -  // not much use. - -  struct freememnode *startfmn, *endfmn, *fmn; - -  for( startfmn = freehead; startfmn; ) -  { -    endfmn = (struct freememnode *)(((char *) startfmn) + startfmn->size); -    for( fmn = freehead; fmn; ) -    { -      if( fmn->cookie != FREEMEMCOOKIE ) -        G_Error( "G_DefragmentMemory: Memory corruption detected!\n" ); - -      if( fmn == endfmn ) -      { -        // We can add fmn onto startfmn. - -        if( fmn->prev ) -          fmn->prev->next = fmn->next; -        if( fmn->next ) -        { -          if( !(fmn->next->prev = fmn->prev) ) -            freehead = fmn->next;  // We're removing the head node -        } -        startfmn->size += fmn->size; -        memset( fmn, 0, sizeof(struct freememnode) );  // A redundant call, really. - -        startfmn = freehead; -        endfmn = fmn = NULL;        // Break out of current loop -      } -      else -        fmn = fmn->next; -    } - -    if( endfmn ) -      startfmn = startfmn->next;    // endfmn acts as a 'restart' flag here -  } -} - -void Svcmd_GameMem_f( void ) -{ -  // Give a breakdown of memory - -  struct freememnode *fmn; - -  G_Printf( "Game memory status: %i out of %i bytes allocated\n", POOLSIZE - freemem, POOLSIZE ); - -  for( fmn = freehead; fmn; fmn = fmn->next ) -    G_Printf( "  %dd: %d bytes free.\n", fmn, fmn->size ); -  G_Printf( "Status complete.\n" ); -} - diff --git a/mod/src/game/g_misc.c b/mod/src/game/g_misc.c deleted file mode 100644 index 4bcb387f..00000000 --- a/mod/src/game/g_misc.c +++ /dev/null @@ -1,411 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// g_misc.c - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - - -/*QUAKED func_group (0 0 0) ? -Used to group brushes together just for editor convenience.  They are turned into normal brushes by the utilities. -*/ - - -/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4) -Used as a positional target for calculations in the utilities (spotlights, etc), but removed during gameplay. -*/ -void SP_info_null( gentity_t *self ) -{ -  G_FreeEntity( self ); -} - - -/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4) -Used as a positional target for in-game calculation, like jumppad targets. -target_position does the same thing -*/ -void SP_info_notnull( gentity_t *self ) -{ -  G_SetOrigin( self, self->s.origin ); -} - - -/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) linear -Non-displayed light. -"light" overrides the default 300 intensity. -Linear checbox gives linear falloff instead of inverse square -Lights pointed at a target will be spotlights. -"radius" overrides the default 64 unit radius of a spotlight at the target point. -*/ -void SP_light( gentity_t *self ) -{ -  G_FreeEntity( self ); -} - - - -/* -================================================================================= - -TELEPORTERS - -================================================================================= -*/ - -void TeleportPlayer( gentity_t *player, vec3_t origin, vec3_t angles ) -{ -  // unlink to make sure it can't possibly interfere with G_KillBox -  trap_UnlinkEntity( player ); - -  VectorCopy( origin, player->client->ps.origin ); -  player->client->ps.origin[ 2 ] += 1; - -  // spit the player out -  AngleVectors( angles, player->client->ps.velocity, NULL, NULL ); -  VectorScale( player->client->ps.velocity, 400, player->client->ps.velocity ); -  player->client->ps.pm_time = 160;   // hold time -  player->client->ps.pm_flags |= PMF_TIME_KNOCKBACK; - -  // toggle the teleport bit so the client knows to not lerp -  player->client->ps.eFlags ^= EF_TELEPORT_BIT; - -  // set angles -  SetClientViewAngle( player, angles ); - -  // kill anything at the destination -  if( player->client->sess.sessionTeam != TEAM_SPECTATOR ) -    G_KillBox( player ); - -  // save results of pmove -  BG_PlayerStateToEntityState( &player->client->ps, &player->s, qtrue ); - -  // use the precise origin for linking -  VectorCopy( player->client->ps.origin, player->r.currentOrigin ); - -  if( player->client->sess.sessionTeam != TEAM_SPECTATOR ) -    trap_LinkEntity (player); -} - - -/*QUAKED misc_teleporter_dest (1 0 0) (-32 -32 -24) (32 32 -16) -Point teleporters at these. -Now that we don't have teleport destination pads, this is just -an info_notnull -*/ -void SP_misc_teleporter_dest( gentity_t *ent ) -{ -} - - -//=========================================================== - -/*QUAKED misc_model (1 0 0) (-16 -16 -16) (16 16 16) -"model"   arbitrary .md3 file to display -*/ -void SP_misc_model( gentity_t *ent ) -{ -#if 0 -  ent->s.modelindex = G_ModelIndex( ent->model ); -  VectorSet (ent->mins, -16, -16, -16); -  VectorSet (ent->maxs, 16, 16, 16); -  trap_LinkEntity (ent); - -  G_SetOrigin( ent, ent->s.origin ); -  VectorCopy( ent->s.angles, ent->s.apos.trBase ); -#else -  G_FreeEntity( ent ); -#endif -} - -//=========================================================== - -void locateCamera( gentity_t *ent ) -{ -  vec3_t    dir; -  gentity_t *target; -  gentity_t *owner; - -  owner = G_PickTarget( ent->target ); -  if( !owner ) -  { -    G_Printf( "Couldn't find target for misc_partal_surface\n" ); -    G_FreeEntity( ent ); -    return; -  } -  ent->r.ownerNum = owner->s.number; - -  // frame holds the rotate speed -  if( owner->spawnflags & 1 ) -    ent->s.frame = 25; -  else if( owner->spawnflags & 2 ) -    ent->s.frame = 75; - -  // swing camera ? -  if( owner->spawnflags & 4 ) -  { -    // set to 0 for no rotation at all -    ent->s.powerups = 0; -  } -  else -    ent->s.powerups = 1; - -  // clientNum holds the rotate offset -  ent->s.clientNum = owner->s.clientNum; - -  VectorCopy( owner->s.origin, ent->s.origin2 ); - -  // see if the portal_camera has a target -  target = G_PickTarget( owner->target ); -  if( target ) -  { -    VectorSubtract( target->s.origin, owner->s.origin, dir ); -    VectorNormalize( dir ); -  } -  else -    G_SetMovedir( owner->s.angles, dir ); - -  ent->s.eventParm = DirToByte( dir ); -} - -/*QUAKED misc_portal_surface (0 0 1) (-8 -8 -8) (8 8 8) -The portal surface nearest this entity will show a view from the targeted misc_portal_camera, or a mirror view if untargeted. -This must be within 64 world units of the surface! -*/ -void SP_misc_portal_surface( gentity_t *ent ) -{ -  VectorClear( ent->r.mins ); -  VectorClear( ent->r.maxs ); -  trap_LinkEntity( ent ); - -  ent->r.svFlags = SVF_PORTAL; -  ent->s.eType = ET_PORTAL; - -  if( !ent->target ) -  { -    VectorCopy( ent->s.origin, ent->s.origin2 ); -  } -  else -  { -    ent->think = locateCamera; -    ent->nextthink = level.time + 100; -  } -} - -/*QUAKED misc_portal_camera (0 0 1) (-8 -8 -8) (8 8 8) slowrotate fastrotate noswing - -The target for a misc_portal_director.  You can set either angles or target another entity to determine the direction of view. -"roll" an angle modifier to orient the camera around the target vector; -*/ -void SP_misc_portal_camera( gentity_t *ent ) -{ -  float roll; - -  VectorClear( ent->r.mins ); -  VectorClear( ent->r.maxs ); -  trap_LinkEntity( ent ); - -  G_SpawnFloat( "roll", "0", &roll ); - -  ent->s.clientNum = roll / 360.0f * 256; -} - -/* -====================================================================== - -  NEAT EFFECTS AND STUFF FOR TREMULOUS - -====================================================================== -*/ - -/* -=============== -SP_use_particle_system - -Use function for particle_system -=============== -*/ -void SP_use_particle_system( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  //toggle EF_NODRAW -  self->s.eFlags ^= EF_NODRAW; -} - -/* -=============== -SP_spawn_particle_system - -Spawn function for particle system -=============== -*/ -void SP_misc_particle_system( gentity_t *self ) -{ -  char  *s; - -  G_SetOrigin( self, self->s.origin ); - -  G_SpawnString( "psName", "", &s ); - -  //add the particle system to the client precache list -  self->s.modelindex = G_ParticleSystemIndex( s ); - -  if( self->spawnflags & 1 ) -    self->s.eFlags |= EF_NODRAW; - -  self->use = SP_use_particle_system; -  self->s.eType = ET_PARTICLE_SYSTEM; -  trap_LinkEntity( self ); -} - -/* -=============== -SP_use_anim_model - -Use function for anim model -=============== -*/ -void SP_use_anim_model( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  if( self->spawnflags & 1 ) -  { -    //if spawnflag 1 is set -    //toggle EF_NODRAW -    if( self->s.eFlags & EF_NODRAW ) -      self->s.eFlags &= ~EF_NODRAW; -    else -      self->s.eFlags |= EF_NODRAW; -  } -  else -  { -    //if the animation loops then toggle the animation -    //toggle EF_MOVER_STOP -    if( self->s.eFlags & EF_MOVER_STOP ) -      self->s.eFlags &= ~EF_MOVER_STOP; -    else -      self->s.eFlags |= EF_MOVER_STOP; -  } -} - -/* -=============== -SP_misc_anim_model - -Spawn function for anim model -=============== -*/ -void SP_misc_anim_model( gentity_t *self ) -{ -  self->s.powerups  = (int)self->animation[ 0 ]; -  self->s.weapon    = (int)self->animation[ 1 ]; -  self->s.torsoAnim = (int)self->animation[ 2 ]; -  self->s.legsAnim  = (int)self->animation[ 3 ]; - -  self->s.angles2[ 0 ] = self->pos2[ 0 ]; - -  //add the model to the client precache list -  self->s.modelindex = G_ModelIndex( self->model ); - -  self->use = SP_use_anim_model; - -  self->s.eType = ET_ANIMMAPOBJ; - -  trap_LinkEntity( self ); -} - -/* -=============== -SP_use_light_flare - -Use function for light flare -=============== -*/ -void SP_use_light_flare( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  self->s.eFlags ^= EF_NODRAW; -} - -/* -=============== -findEmptySpot - -Finds an empty spot radius units from origin -============== -*/ -static void findEmptySpot( vec3_t origin, float radius, vec3_t spot ) -{ -  int     i, j, k; -  vec3_t  delta, test, total; -  trace_t tr; - -  VectorClear( total ); - -  //54(!) traces to test for empty spots -  for( i = -1; i <= 1; i++ ) -  { -    for( j = -1; j <= 1; j++ ) -    { -      for( k = -1; k <= 1; k++ ) -      { -        VectorSet( delta, ( i * radius ), -                          ( j * radius ), -                          ( k * radius ) ); - -        VectorAdd( origin, delta, test ); - -        trap_Trace( &tr, test, NULL, NULL, test, -1, MASK_SOLID ); - -        if( !tr.allsolid ) -        { -          trap_Trace( &tr, test, NULL, NULL, origin, -1, MASK_SOLID ); -          VectorScale( delta, tr.fraction, delta ); -          VectorAdd( total, delta, total ); -        } -      } -    } -  } - -  VectorNormalize( total ); -  VectorScale( total, radius, total ); -  VectorAdd( origin, total, spot ); -} - -/* -=============== -SP_misc_light_flare - -Spawn function for light flare -=============== -*/ -void SP_misc_light_flare( gentity_t *self ) -{ -  self->s.eType = ET_LIGHTFLARE; -  self->s.modelindex = G_ShaderIndex( self->targetShaderName ); -  VectorCopy( self->pos2, self->s.origin2 ); - -  //try to find a spot near to the flare which is empty. This -  //is used to facilitate visibility testing -  findEmptySpot( self->s.origin, 8.0f, self->s.angles2 ); - -  self->use = SP_use_light_flare; - -  G_SpawnFloat( "speed", "200", &self->speed ); -  self->s.time = self->speed; - -  G_SpawnInt( "mindist", "0", &self->s.generic1 ); - -  if( self->spawnflags & 1 ) -    self->s.eFlags |= EF_NODRAW; - -  trap_LinkEntity( self ); -} diff --git a/mod/src/game/g_missile.c b/mod/src/game/g_missile.c deleted file mode 100644 index 4f019f41..00000000 --- a/mod/src/game/g_missile.c +++ /dev/null @@ -1,803 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -#define MISSILE_PRESTEP_TIME  50 - -/* -================ -G_BounceMissile - -================ -*/ -void G_BounceMissile( gentity_t *ent, trace_t *trace ) -{ -  vec3_t  velocity; -  float dot; -  int   hitTime; - -  // reflect the velocity on the trace plane -  hitTime = level.previousTime + ( level.time - level.previousTime ) * trace->fraction; -  BG_EvaluateTrajectoryDelta( &ent->s.pos, hitTime, velocity ); -  dot = DotProduct( velocity, trace->plane.normal ); -  VectorMA( velocity, -2 * dot, trace->plane.normal, ent->s.pos.trDelta ); - -  if( ent->s.eFlags & EF_BOUNCE_HALF ) -  { -    VectorScale( ent->s.pos.trDelta, 0.65, ent->s.pos.trDelta ); -    // check for stop -    if( trace->plane.normal[ 2 ] > 0.2 && VectorLength( ent->s.pos.trDelta ) < 40 ) -    { -      G_SetOrigin( ent, trace->endpos ); -      return; -    } -  } - -  VectorAdd( ent->r.currentOrigin, trace->plane.normal, ent->r.currentOrigin ); -  VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase ); -  ent->s.pos.trTime = level.time; -} - - -/* -================ -G_ExplodeMissile - -Explode a missile without an impact -================ -*/ -void G_ExplodeMissile( gentity_t *ent ) -{ -  vec3_t    dir; -  vec3_t    origin; - -  BG_EvaluateTrajectory( &ent->s.pos, level.time, origin ); -  SnapVector( origin ); -  G_SetOrigin( ent, origin ); - -  // we don't have a valid direction, so just point straight up -  dir[ 0 ] = dir[ 1 ] = 0; -  dir[ 2 ] = 1; - -  ent->s.eType = ET_GENERAL; - -  //TA: tired... can't be fucked... hack -  if( ent->s.weapon != WP_LOCKBLOB_LAUNCHER && -      ent->s.weapon != WP_FLAMER ) -    G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) ); - -  ent->freeAfterEvent = qtrue; - -  // splash damage -  if( ent->splashDamage ) -    G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, -                    ent->splashRadius, ent, ent->splashMethodOfDeath ); - -  trap_LinkEntity( ent ); -} - -void AHive_ReturnToHive( gentity_t *self ); - -/* -================ -G_MissileImpact - -================ -*/ -void G_MissileImpact( gentity_t *ent, trace_t *trace ) -{ -  gentity_t   *other, *attacker; -  qboolean    returnAfterDamage = qfalse; -  vec3_t      dir; - -  other = &g_entities[ trace->entityNum ]; -  attacker = &g_entities[ ent->r.ownerNum ]; - -  // check for bounce -  if( !other->takedamage && -      ( ent->s.eFlags & ( EF_BOUNCE | EF_BOUNCE_HALF ) ) ) -  { -    G_BounceMissile( ent, trace ); - -    //only play a sound if requested -    if( !( ent->s.eFlags & EF_NO_BOUNCE_SOUND ) ) -      G_AddEvent( ent, EV_GRENADE_BOUNCE, 0 ); - -    return; -  } - -  if( !strcmp( ent->classname, "grenade" ) ) -  { -    //grenade doesn't explode on impact -    G_BounceMissile( ent, trace ); - -    //only play a sound if requested -    if( !( ent->s.eFlags & EF_NO_BOUNCE_SOUND ) ) -      G_AddEvent( ent, EV_GRENADE_BOUNCE, 0 ); - -    return; -  } -  else if( !strcmp( ent->classname, "lockblob" ) ) -  { -    if( other->client && other->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -    { -      other->client->ps.stats[ STAT_STATE ] |= SS_BLOBLOCKED; -      other->client->lastLockTime = level.time; -      AngleVectors( other->client->ps.viewangles, dir, NULL, NULL ); -      other->client->ps.stats[ STAT_VIEWLOCK ] = DirToByte( dir ); -    } -  } -  else if( !strcmp( ent->classname, "slowblob" ) ) -  { -    if( other->client && other->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -    { -      other->client->ps.stats[ STAT_STATE ] |= SS_SLOWLOCKED; -      other->client->lastSlowTime = level.time; -      AngleVectors( other->client->ps.viewangles, dir, NULL, NULL ); -      other->client->ps.stats[ STAT_VIEWLOCK ] = DirToByte( dir ); -    } -  } -  else if( !strcmp( ent->classname, "hive" ) ) -  { -    if( other->s.eType == ET_BUILDABLE && other->s.modelindex == BA_A_HIVE ) -    { -      if( !ent->parent ) -        G_Printf( S_COLOR_YELLOW "WARNING: hive entity has no parent in G_MissileImpact\n" ); -      else -        ent->parent->active = qfalse; - -      G_FreeEntity( ent ); -      return; -    } -    else -    { -      //prevent collision with the client when returning -      ent->r.ownerNum = other->s.number; - -      ent->think = AHive_ReturnToHive; -      ent->nextthink = level.time + FRAMETIME; - -      //only damage humans -      if( other->client && other->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -        returnAfterDamage = qtrue; -      else -        return; -    } -  } - -  // impact damage -  if( other->takedamage ) -  { -    // FIXME: wrong damage direction? -    if( ent->damage ) -    { -      vec3_t  velocity; - -      BG_EvaluateTrajectoryDelta( &ent->s.pos, level.time, velocity ); -      if( VectorLength( velocity ) == 0 ) -        velocity[ 2 ] = 1;  // stepped on a grenade - -      G_Damage( other, ent, attacker, velocity, ent->s.origin, ent->damage, -        0, ent->methodOfDeath ); -    } -  } - -  if( returnAfterDamage ) -    return; - -  // is it cheaper in bandwidth to just remove this ent and create a new -  // one, rather than changing the missile into the explosion? - -  if( other->takedamage && other->client ) -  { -    G_AddEvent( ent, EV_MISSILE_HIT, DirToByte( trace->plane.normal ) ); -    ent->s.otherEntityNum = other->s.number; -  } -  else if( trace->surfaceFlags & SURF_METALSTEPS ) -    G_AddEvent( ent, EV_MISSILE_MISS_METAL, DirToByte( trace->plane.normal ) ); -  else -    G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( trace->plane.normal ) ); - -  ent->freeAfterEvent = qtrue; - -  // change over to a normal entity right at the point of impact -  ent->s.eType = ET_GENERAL; - -  SnapVectorTowards( trace->endpos, ent->s.pos.trBase );  // save net bandwidth - -  G_SetOrigin( ent, trace->endpos ); - -  // splash damage (doesn't apply to person directly hit) -  if( ent->splashDamage ) -    G_RadiusDamage( trace->endpos, ent->parent, ent->splashDamage, ent->splashRadius, -                    other, ent->splashMethodOfDeath ); - -  trap_LinkEntity( ent ); -} - - -/* -================ -G_RunMissile - -================ -*/ -void G_RunMissile( gentity_t *ent ) -{ -  vec3_t    origin; -  trace_t   tr; -  int     passent; - -  // get current position -  BG_EvaluateTrajectory( &ent->s.pos, level.time, origin ); - -  // ignore interactions with the missile owner -  passent = ent->r.ownerNum; - -  // trace a line from the previous position to the current position -  trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, passent, ent->clipmask ); - -  if( tr.startsolid || tr.allsolid ) -  { -    // make sure the tr.entityNum is set to the entity we're stuck in -    trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, ent->r.currentOrigin, passent, ent->clipmask ); -    tr.fraction = 0; -  } -  else -    VectorCopy( tr.endpos, ent->r.currentOrigin ); - -  ent->r.contents = CONTENTS_SOLID; //trick trap_LinkEntity into... -  trap_LinkEntity( ent ); -  ent->r.contents = 0; //...encoding bbox information - -  if( tr.fraction != 1 ) -  { -    // never explode or bounce on sky -    if( tr.surfaceFlags & SURF_NOIMPACT ) -    { -      // If grapple, reset owner -      if( ent->parent && ent->parent->client && ent->parent->client->hook == ent ) -        ent->parent->client->hook = NULL; - -      G_FreeEntity( ent ); -      return; -    } - -    G_MissileImpact( ent, &tr ); -    if( ent->s.eType != ET_MISSILE ) -      return;   // exploded -  } - -  // check think function after bouncing -  G_RunThink( ent ); -} - - -//============================================================================= - -/* -================= -fire_flamer - -================= -*/ -gentity_t *fire_flamer( gentity_t *self, vec3_t start, vec3_t dir ) -{ -  gentity_t *bolt; -  vec3_t    pvel; - -  VectorNormalize (dir); - -  bolt = G_Spawn(); -  bolt->classname = "flame"; -  bolt->nextthink = level.time + FLAMER_LIFETIME; -  bolt->think = G_ExplodeMissile; -  bolt->s.eType = ET_MISSILE; -  bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; -  bolt->s.weapon = WP_FLAMER; -  bolt->s.generic1 = self->s.generic1; //weaponMode -  bolt->r.ownerNum = self->s.number; -  bolt->parent = self; -  bolt->damage = FLAMER_DMG; -  bolt->splashDamage = FLAMER_DMG; -  bolt->splashRadius = FLAMER_RADIUS; -  bolt->methodOfDeath = MOD_FLAMER; -  bolt->splashMethodOfDeath = MOD_FLAMER_SPLASH; -  bolt->clipmask = MASK_SHOT; -  bolt->target_ent = NULL; -  bolt->r.mins[ 0 ] = bolt->r.mins[ 1 ] = bolt->r.mins[ 2 ] = -15.0f; -  bolt->r.maxs[ 0 ] = bolt->r.maxs[ 1 ] = bolt->r.maxs[ 2 ] = 15.0f; - -  bolt->s.pos.trType = TR_LINEAR; -  bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit on the very first frame -  VectorCopy( start, bolt->s.pos.trBase ); -  VectorScale( self->client->ps.velocity, FLAMER_LAG, pvel ); -  VectorMA( pvel, FLAMER_SPEED, dir, bolt->s.pos.trDelta ); -  SnapVector( bolt->s.pos.trDelta );      // save net bandwidth - -  VectorCopy( start, bolt->r.currentOrigin ); - -  return bolt; -} - -//============================================================================= - -/* -================= -fire_blaster - -================= -*/ -gentity_t *fire_blaster( gentity_t *self, vec3_t start, vec3_t dir ) -{ -  gentity_t *bolt; - -  VectorNormalize (dir); - -  bolt = G_Spawn(); -  bolt->classname = "blaster"; -  bolt->nextthink = level.time + 10000; -  bolt->think = G_ExplodeMissile; -  bolt->s.eType = ET_MISSILE; -  bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; -  bolt->s.weapon = WP_BLASTER; -  bolt->s.generic1 = self->s.generic1; //weaponMode -  bolt->r.ownerNum = self->s.number; -  bolt->parent = self; -  bolt->damage = BLASTER_DMG; -  bolt->splashDamage = 0; -  bolt->splashRadius = 0; -  bolt->methodOfDeath = MOD_BLASTER; -  bolt->splashMethodOfDeath = MOD_BLASTER; -  bolt->clipmask = MASK_SHOT; -  bolt->target_ent = NULL; - -  bolt->s.pos.trType = TR_LINEAR; -  bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit on the very first frame -  VectorCopy( start, bolt->s.pos.trBase ); -  VectorScale( dir, BLASTER_SPEED, bolt->s.pos.trDelta ); -  SnapVector( bolt->s.pos.trDelta );      // save net bandwidth - -  VectorCopy( start, bolt->r.currentOrigin ); - -  return bolt; -} - -//============================================================================= - -/* -================= -fire_pulseRifle - -================= -*/ -gentity_t *fire_pulseRifle( gentity_t *self, vec3_t start, vec3_t dir ) -{ -  gentity_t *bolt; - -  VectorNormalize (dir); - -  bolt = G_Spawn(); -  bolt->classname = "pulse"; -  bolt->nextthink = level.time + 10000; -  bolt->think = G_ExplodeMissile; -  bolt->s.eType = ET_MISSILE; -  bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; -  bolt->s.weapon = WP_PULSE_RIFLE; -  bolt->s.generic1 = self->s.generic1; //weaponMode -  bolt->r.ownerNum = self->s.number; -  bolt->parent = self; -  bolt->damage = PRIFLE_DMG; -  bolt->splashDamage = 0; -  bolt->splashRadius = 0; -  bolt->methodOfDeath = MOD_PRIFLE; -  bolt->splashMethodOfDeath = MOD_PRIFLE; -  bolt->clipmask = MASK_SHOT; -  bolt->target_ent = NULL; - -  bolt->s.pos.trType = TR_LINEAR; -  bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit on the very first frame -  VectorCopy( start, bolt->s.pos.trBase ); -  VectorScale( dir, PRIFLE_SPEED, bolt->s.pos.trDelta ); -  SnapVector( bolt->s.pos.trDelta );      // save net bandwidth - -  VectorCopy( start, bolt->r.currentOrigin ); - -  return bolt; -} - -//============================================================================= - -/* -================= -fire_luciferCannon - -================= -*/ -gentity_t *fire_luciferCannon( gentity_t *self, vec3_t start, vec3_t dir, int damage, int radius ) -{ -  gentity_t *bolt; -  int localDamage = (int)( ceil( ( (float)damage / -                                   (float)LCANNON_TOTAL_CHARGE ) * (float)LCANNON_DAMAGE ) ); - -  VectorNormalize( dir ); - -  bolt = G_Spawn( ); -  bolt->classname = "lcannon"; - -  if( damage == LCANNON_TOTAL_CHARGE ) -    bolt->nextthink = level.time; -  else -    bolt->nextthink = level.time + 10000; - -  bolt->think = G_ExplodeMissile; -  bolt->s.eType = ET_MISSILE; -  bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; -  bolt->s.weapon = WP_LUCIFER_CANNON; -  bolt->s.generic1 = self->s.generic1; //weaponMode -  bolt->r.ownerNum = self->s.number; -  bolt->parent = self; -  bolt->damage = localDamage; -  bolt->splashDamage = localDamage / 2; -  bolt->splashRadius = radius; -  bolt->methodOfDeath = MOD_LCANNON; -  bolt->splashMethodOfDeath = MOD_LCANNON_SPLASH; -  bolt->clipmask = MASK_SHOT; -  bolt->target_ent = NULL; - -  bolt->s.pos.trType = TR_LINEAR; -  bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit on the very first frame -  VectorCopy( start, bolt->s.pos.trBase ); -  VectorScale( dir, LCANNON_SPEED, bolt->s.pos.trDelta ); -  SnapVector( bolt->s.pos.trDelta );      // save net bandwidth - -  VectorCopy( start, bolt->r.currentOrigin ); - -  return bolt; -} - -/* -================= -launch_grenade - -================= -*/ -gentity_t *launch_grenade( gentity_t *self, vec3_t start, vec3_t dir ) -{ -  gentity_t *bolt; - -  VectorNormalize( dir ); - -  bolt = G_Spawn( ); -  bolt->classname = "grenade"; -  bolt->nextthink = level.time + 5000; -  bolt->think = G_ExplodeMissile; -  bolt->s.eType = ET_MISSILE; -  bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; -  bolt->s.weapon = WP_GRENADE; -  bolt->s.eFlags = EF_BOUNCE_HALF; -  bolt->s.generic1 = WPM_PRIMARY; //weaponMode -  bolt->r.ownerNum = self->s.number; -  bolt->parent = self; -  bolt->damage = GRENADE_DAMAGE; -  bolt->splashDamage = GRENADE_DAMAGE; -  bolt->splashRadius = GRENADE_RANGE; -  bolt->methodOfDeath = MOD_GRENADE; -  bolt->splashMethodOfDeath = MOD_GRENADE; -  bolt->clipmask = MASK_SHOT; -  bolt->target_ent = NULL; -  bolt->r.mins[ 0 ] = bolt->r.mins[ 1 ] = bolt->r.mins[ 2 ] = -3.0f; -  bolt->r.maxs[ 0 ] = bolt->r.maxs[ 1 ] = bolt->r.maxs[ 2 ] = 3.0f; -  bolt->s.time = level.time; - -  bolt->s.pos.trType = TR_GRAVITY; -  bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit on the very first frame -  VectorCopy( start, bolt->s.pos.trBase ); -  VectorScale( dir, GRENADE_SPEED, bolt->s.pos.trDelta ); -  SnapVector( bolt->s.pos.trDelta );      // save net bandwidth - -  VectorCopy( start, bolt->r.currentOrigin ); - -  return bolt; -} -//============================================================================= - -/* -================ -AHive_ReturnToHive - -Adjust the trajectory to point towards the hive -================ -*/ -void AHive_ReturnToHive( gentity_t *self ) -{ -  vec3_t  dir; -  trace_t tr; - -  if( !self->parent ) -  { -    G_Printf( S_COLOR_YELLOW "WARNING: AHive_ReturnToHive called with no self->parent\n" ); -    return; -  } - -  trap_UnlinkEntity( self->parent ); -  trap_Trace( &tr, self->r.currentOrigin, self->r.mins, self->r.maxs, -              self->parent->r.currentOrigin, self->r.ownerNum, self->clipmask ); -  trap_LinkEntity( self->parent ); - -  if( tr.fraction < 1.0f ) -  { -    //if can't see hive then disperse -    VectorCopy( self->r.currentOrigin, self->s.pos.trBase ); -    self->s.pos.trType = TR_STATIONARY; -    self->s.pos.trTime = level.time; - -    self->think = G_ExplodeMissile; -    self->nextthink = level.time + 2000; -    self->parent->active = qfalse; //allow the parent to start again -  } -  else -  { -    VectorSubtract( self->parent->r.currentOrigin, self->r.currentOrigin, dir ); -    VectorNormalize( dir ); - -    //change direction towards the hive -    VectorScale( dir, HIVE_SPEED, self->s.pos.trDelta ); -    SnapVector( self->s.pos.trDelta );      // save net bandwidth -    VectorCopy( self->r.currentOrigin, self->s.pos.trBase ); -    self->s.pos.trTime = level.time; - -    self->think = G_ExplodeMissile; -    self->nextthink = level.time + 15000; -  } -} - -/* -================ -AHive_SearchAndDestroy - -Adjust the trajectory to point towards the target -================ -*/ -void AHive_SearchAndDestroy( gentity_t *self ) -{ -  vec3_t dir; -  trace_t tr; - -  trap_Trace( &tr, self->r.currentOrigin, self->r.mins, self->r.maxs, -              self->target_ent->r.currentOrigin, self->r.ownerNum, self->clipmask ); - -  //if there is no LOS or the parent hive is too far away or the target is dead, return -  if( tr.entityNum == ENTITYNUM_WORLD || -      Distance( self->r.currentOrigin, self->parent->r.currentOrigin ) > ( HIVE_RANGE * 5 ) || -      self->target_ent->health <= 0 ) -  { -    self->r.ownerNum = ENTITYNUM_WORLD; - -    self->think = AHive_ReturnToHive; -    self->nextthink = level.time + FRAMETIME; -  } -  else -  { -    VectorSubtract( self->target_ent->r.currentOrigin, self->r.currentOrigin, dir ); -    VectorNormalize( dir ); - -    //change direction towards the player -    VectorScale( dir, HIVE_SPEED, self->s.pos.trDelta ); -    SnapVector( self->s.pos.trDelta );      // save net bandwidth -    VectorCopy( self->r.currentOrigin, self->s.pos.trBase ); -    self->s.pos.trTime = level.time; - -    self->nextthink = level.time + HIVE_DIR_CHANGE_PERIOD; -  } -} - -/* -================= -fire_hive -================= -*/ -gentity_t *fire_hive( gentity_t *self, vec3_t start, vec3_t dir ) -{ -  gentity_t *bolt; - -  VectorNormalize ( dir ); - -  bolt = G_Spawn( ); -  bolt->classname = "hive"; -  bolt->nextthink = level.time + HIVE_DIR_CHANGE_PERIOD; -  bolt->think = AHive_SearchAndDestroy; -  bolt->s.eType = ET_MISSILE; -  bolt->s.eFlags |= EF_BOUNCE|EF_NO_BOUNCE_SOUND; -  bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; -  bolt->s.weapon = WP_HIVE; -  bolt->s.generic1 = WPM_PRIMARY; //weaponMode -  bolt->r.ownerNum = self->s.number; -  bolt->parent = self; -  bolt->damage = HIVE_DMG; -  bolt->splashDamage = 0; -  bolt->splashRadius = 0; -  bolt->methodOfDeath = MOD_SWARM; -  bolt->clipmask = MASK_SHOT; -  bolt->target_ent = self->target_ent; - -  bolt->s.pos.trType = TR_LINEAR; -  bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit on the very first frame -  VectorCopy( start, bolt->s.pos.trBase ); -  VectorScale( dir, HIVE_SPEED, bolt->s.pos.trDelta ); -  SnapVector( bolt->s.pos.trDelta );      // save net bandwidth -  VectorCopy( start, bolt->r.currentOrigin ); - -  return bolt; -} - -//============================================================================= - -/* -================= -fire_lockblob -================= -*/ -gentity_t *fire_lockblob( gentity_t *self, vec3_t start, vec3_t dir ) -{ -  gentity_t *bolt; - -  VectorNormalize ( dir ); - -  bolt = G_Spawn( ); -  bolt->classname = "lockblob"; -  bolt->nextthink = level.time + 15000; -  bolt->think = G_ExplodeMissile; -  bolt->s.eType = ET_MISSILE; -  bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; -  bolt->s.weapon = WP_LOCKBLOB_LAUNCHER; -  bolt->s.generic1 = WPM_PRIMARY; //weaponMode -  bolt->r.ownerNum = self->s.number; -  bolt->parent = self; -  bolt->damage = 0; -  bolt->splashDamage = 0; -  bolt->splashRadius = 0; -  bolt->methodOfDeath = MOD_UNKNOWN; //doesn't do damage so will never kill -  bolt->clipmask = MASK_SHOT; -  bolt->target_ent = NULL; - -  bolt->s.pos.trType = TR_LINEAR; -  bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit on the very first frame -  VectorCopy( start, bolt->s.pos.trBase ); -  VectorScale( dir, 500, bolt->s.pos.trDelta ); -  SnapVector( bolt->s.pos.trDelta );      // save net bandwidth -  VectorCopy( start, bolt->r.currentOrigin ); - -  return bolt; -} - -/* -================= -fire_slowBlob -================= -*/ -gentity_t *fire_slowBlob( gentity_t *self, vec3_t start, vec3_t dir ) -{ -  gentity_t *bolt; - -  VectorNormalize ( dir ); - -  bolt = G_Spawn( ); -  bolt->classname = "slowblob"; -  bolt->nextthink = level.time + 15000; -  bolt->think = G_ExplodeMissile; -  bolt->s.eType = ET_MISSILE; -  bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; -  bolt->s.weapon = WP_ABUILD2; -  bolt->s.generic1 = self->s.generic1; //weaponMode -  bolt->r.ownerNum = self->s.number; -  bolt->parent = self; -  bolt->damage = ABUILDER_BLOB_DMG; -  bolt->splashDamage = 0; -  bolt->splashRadius = 0; -  bolt->methodOfDeath = MOD_SLOWBLOB; -  bolt->splashMethodOfDeath = MOD_SLOWBLOB; -  bolt->clipmask = MASK_SHOT; -  bolt->target_ent = NULL; - -  bolt->s.pos.trType = TR_GRAVITY; -  bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit on the very first frame -  VectorCopy( start, bolt->s.pos.trBase ); -  VectorScale( dir, ABUILDER_BLOB_SPEED, bolt->s.pos.trDelta ); -  SnapVector( bolt->s.pos.trDelta );      // save net bandwidth -  VectorCopy( start, bolt->r.currentOrigin ); - -  return bolt; -} - -/* -================= -fire_paraLockBlob -================= -*/ -gentity_t *fire_paraLockBlob( gentity_t *self, vec3_t start, vec3_t dir ) -{ -  gentity_t *bolt; - -  VectorNormalize ( dir ); - -  bolt = G_Spawn( ); -  bolt->classname = "lockblob"; -  bolt->nextthink = level.time + 15000; -  bolt->think = G_ExplodeMissile; -  bolt->s.eType = ET_MISSILE; -  bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; -  bolt->s.weapon = WP_LOCKBLOB_LAUNCHER; -  bolt->s.generic1 = self->s.generic1; //weaponMode -  bolt->r.ownerNum = self->s.number; -  bolt->parent = self; -  bolt->damage = 0; -  bolt->splashDamage = 0; -  bolt->splashRadius = 0; -  bolt->clipmask = MASK_SHOT; -  bolt->target_ent = NULL; - -  bolt->s.pos.trType = TR_GRAVITY; -  bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit on the very first frame -  VectorCopy( start, bolt->s.pos.trBase ); -  VectorScale( dir, LOCKBLOB_SPEED, bolt->s.pos.trDelta ); -  SnapVector( bolt->s.pos.trDelta );      // save net bandwidth -  VectorCopy( start, bolt->r.currentOrigin ); - -  return bolt; -} - -/* -================= -fire_bounceBall -================= -*/ -gentity_t *fire_bounceBall( gentity_t *self, vec3_t start, vec3_t dir ) -{ -  gentity_t *bolt; - -  VectorNormalize ( dir ); - -  bolt = G_Spawn( ); -  bolt->classname = "bounceball"; -  bolt->nextthink = level.time + 3000; -  bolt->think = G_ExplodeMissile; -  bolt->s.eType = ET_MISSILE; -  bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; -  bolt->s.weapon = WP_ALEVEL3_UPG; -  bolt->s.generic1 = self->s.generic1; //weaponMode -  bolt->r.ownerNum = self->s.number; -  bolt->parent = self; -  bolt->damage = LEVEL3_BOUNCEBALL_DMG; -  bolt->splashDamage = 0; -  bolt->splashRadius = 0; -  bolt->methodOfDeath = MOD_LEVEL3_BOUNCEBALL; -  bolt->splashMethodOfDeath = MOD_LEVEL3_BOUNCEBALL; -  bolt->clipmask = MASK_SHOT; -  bolt->target_ent = NULL; - -  bolt->s.pos.trType = TR_GRAVITY; -  bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit on the very first frame -  VectorCopy( start, bolt->s.pos.trBase ); -  VectorScale( dir, LEVEL3_BOUNCEBALL_SPEED, bolt->s.pos.trDelta ); -  SnapVector( bolt->s.pos.trDelta );      // save net bandwidth -  VectorCopy( start, bolt->r.currentOrigin ); -  /*bolt->s.eFlags |= EF_BOUNCE;*/ - -  return bolt; -} - diff --git a/mod/src/game/g_mover.c b/mod/src/game/g_mover.c deleted file mode 100644 index c3879b5b..00000000 --- a/mod/src/game/g_mover.c +++ /dev/null @@ -1,2468 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - - - -/* -=============================================================================== - -PUSHMOVE - -=============================================================================== -*/ - -void MatchTeam( gentity_t *teamLeader, int moverState, int time ); - -typedef struct -{ -  gentity_t *ent; -  vec3_t  origin; -  vec3_t  angles; -  float deltayaw; -} pushed_t; - -pushed_t  pushed[ MAX_GENTITIES ], *pushed_p; - - -/* -============ -G_TestEntityPosition - -============ -*/ -gentity_t *G_TestEntityPosition( gentity_t *ent ) -{ -  trace_t tr; -  int   mask; - -  if( ent->clipmask ) -    mask = ent->clipmask; -  else -    mask = MASK_SOLID; - -  if( ent->client ) -    trap_Trace( &tr, ent->client->ps.origin, ent->r.mins, ent->r.maxs, ent->client->ps.origin, ent->s.number, mask ); -  else -    trap_Trace( &tr, ent->s.pos.trBase, ent->r.mins, ent->r.maxs, ent->s.pos.trBase, ent->s.number, mask ); - -  if( tr.startsolid ) -    return &g_entities[ tr.entityNum ]; - -  return NULL; -} - -/* -================ -G_CreateRotationMatrix -================ -*/ -void G_CreateRotationMatrix( vec3_t angles, vec3_t matrix[ 3 ] ) -{ -  AngleVectors( angles, matrix[ 0 ], matrix[ 1 ], matrix[ 2 ] ); -  VectorInverse( matrix[ 1 ] ); -} - -/* -================ -G_TransposeMatrix -================ -*/ -void G_TransposeMatrix( vec3_t matrix[ 3 ], vec3_t transpose[ 3 ] ) -{ -  int i, j; - -  for( i = 0; i < 3; i++ ) -  { -    for( j = 0; j < 3; j++ ) -    { -      transpose[ i ][ j ] = matrix[ j ][ i ]; -    } -  } -} - -/* -================ -G_RotatePoint -================ -*/ -void G_RotatePoint( vec3_t point, vec3_t matrix[ 3 ] ) -{ -  vec3_t tvec; - -  VectorCopy( point, tvec ); -  point[ 0 ] = DotProduct( matrix[ 0 ], tvec ); -  point[ 1 ] = DotProduct( matrix[ 1 ], tvec ); -  point[ 2 ] = DotProduct( matrix[ 2 ], tvec ); -} - -/* -================== -G_TryPushingEntity - -Returns qfalse if the move is blocked -================== -*/ -qboolean G_TryPushingEntity( gentity_t *check, gentity_t *pusher, vec3_t move, vec3_t amove ) -{ -  vec3_t    matrix[ 3 ], transpose[ 3 ]; -  vec3_t    org, org2, move2; -  gentity_t *block; - -  // EF_MOVER_STOP will just stop when contacting another entity -  // instead of pushing it, but entities can still ride on top of it -  if( ( pusher->s.eFlags & EF_MOVER_STOP ) && -      check->s.groundEntityNum != pusher->s.number ) -    return qfalse; - -  //don't try to move buildables unless standing on a mover -  if( check->s.eType == ET_BUILDABLE && -      check->s.groundEntityNum != pusher->s.number ) -    return qfalse; - -  // save off the old position -  if( pushed_p > &pushed[ MAX_GENTITIES ] ) -    G_Error( "pushed_p > &pushed[MAX_GENTITIES]" ); - -  pushed_p->ent = check; -  VectorCopy( check->s.pos.trBase, pushed_p->origin ); -  VectorCopy( check->s.apos.trBase, pushed_p->angles ); - -  if( check->client ) -  { -    pushed_p->deltayaw = check->client->ps.delta_angles[ YAW ]; -    VectorCopy( check->client->ps.origin, pushed_p->origin ); -  } -  pushed_p++; - -  // try moving the contacted entity -  // figure movement due to the pusher's amove -  G_CreateRotationMatrix( amove, transpose ); -  G_TransposeMatrix( transpose, matrix ); - -  if( check->client ) -    VectorSubtract( check->client->ps.origin, pusher->r.currentOrigin, org ); -  else -    VectorSubtract( check->s.pos.trBase, pusher->r.currentOrigin, org ); - -  VectorCopy( org, org2 ); -  G_RotatePoint( org2, matrix ); -  VectorSubtract( org2, org, move2 ); -  // add movement -  VectorAdd( check->s.pos.trBase, move, check->s.pos.trBase ); -  VectorAdd( check->s.pos.trBase, move2, check->s.pos.trBase ); - -  if( check->client ) -  { -    VectorAdd( check->client->ps.origin, move, check->client->ps.origin ); -    VectorAdd( check->client->ps.origin, move2, check->client->ps.origin ); -    // make sure the client's view rotates when on a rotating mover -    check->client->ps.delta_angles[ YAW ] += ANGLE2SHORT( amove[ YAW ] ); -  } - -  // may have pushed them off an edge -  if( check->s.groundEntityNum != pusher->s.number ) -    check->s.groundEntityNum = -1; - -  block = G_TestEntityPosition( check ); - -  if( !block ) -  { -    // pushed ok -    if( check->client ) -      VectorCopy( check->client->ps.origin, check->r.currentOrigin ); -    else -      VectorCopy( check->s.pos.trBase, check->r.currentOrigin ); - -    trap_LinkEntity( check ); -    return qtrue; -  } - -  // if it is ok to leave in the old position, do it -  // this is only relevent for riding entities, not pushed -  // Sliding trapdoors can cause this. -  VectorCopy( ( pushed_p - 1 )->origin, check->s.pos.trBase ); - -  if( check->client ) -    VectorCopy( ( pushed_p - 1 )->origin, check->client->ps.origin ); - -  VectorCopy( ( pushed_p - 1 )->angles, check->s.apos.trBase ); -  block = G_TestEntityPosition( check ); - -  if( !block ) -  { -    check->s.groundEntityNum = -1; -    pushed_p--; -    return qtrue; -  } - -  // blocked -  return qfalse; -} - - -/* -============ -G_MoverPush - -Objects need to be moved back on a failed push, -otherwise riders would continue to slide. -If qfalse is returned, *obstacle will be the blocking entity -============ -*/ -qboolean G_MoverPush( gentity_t *pusher, vec3_t move, vec3_t amove, gentity_t **obstacle ) -{ -  int       i, e; -  gentity_t *check; -  vec3_t    mins, maxs; -  pushed_t  *p; -  int       entityList[ MAX_GENTITIES ]; -  int       listedEntities; -  vec3_t    totalMins, totalMaxs; - -  *obstacle = NULL; - - -  // mins/maxs are the bounds at the destination -  // totalMins / totalMaxs are the bounds for the entire move -  if( pusher->r.currentAngles[ 0 ] || pusher->r.currentAngles[ 1 ] || pusher->r.currentAngles[ 2 ] -    || amove[ 0 ] || amove[ 1 ] || amove[ 2 ] ) -  { -    float   radius; - -    radius = RadiusFromBounds( pusher->r.mins, pusher->r.maxs ); - -    for( i = 0 ; i < 3 ; i++ ) -    { -      mins[ i ] = pusher->r.currentOrigin[ i ] + move[ i ] - radius; -      maxs[ i ] = pusher->r.currentOrigin[ i ] + move[ i ] + radius; -      totalMins[ i ] = mins[ i ] - move[ i ]; -      totalMaxs[ i ] = maxs[ i ] - move[ i ]; -    } -  } -  else -  { -    for( i = 0; i < 3; i++ ) -    { -      mins[ i ] = pusher->r.absmin[ i ] + move[ i ]; -      maxs[ i ] = pusher->r.absmax[ i ] + move[ i ]; -    } - -    VectorCopy( pusher->r.absmin, totalMins ); -    VectorCopy( pusher->r.absmax, totalMaxs ); -    for( i = 0; i < 3; i++ ) -    { -      if( move[ i ] > 0 ) -        totalMaxs[ i ] += move[ i ]; -      else -        totalMins[ i ] += move[ i ]; -    } -  } - -  // unlink the pusher so we don't get it in the entityList -  trap_UnlinkEntity( pusher ); - -  listedEntities = trap_EntitiesInBox( totalMins, totalMaxs, entityList, MAX_GENTITIES ); - -  // move the pusher to it's final position -  VectorAdd( pusher->r.currentOrigin, move, pusher->r.currentOrigin ); -  VectorAdd( pusher->r.currentAngles, amove, pusher->r.currentAngles ); -  trap_LinkEntity( pusher ); - -  // see if any solid entities are inside the final position -  for( e = 0 ; e < listedEntities ; e++ ) -  { -    check = &g_entities[ entityList[ e ] ]; - -    // only push items and players -    if( check->s.eType != ET_ITEM && check->s.eType != ET_BUILDABLE && -        check->s.eType != ET_CORPSE && check->s.eType != ET_PLAYER && -        !check->physicsObject ) -      continue; - -    // if the entity is standing on the pusher, it will definitely be moved -    if( check->s.groundEntityNum != pusher->s.number ) -    { -      // see if the ent needs to be tested -      if( check->r.absmin[ 0 ] >= maxs[ 0 ] -       || check->r.absmin[ 1 ] >= maxs[ 1 ] -       || check->r.absmin[ 2 ] >= maxs[ 2 ] -       || check->r.absmax[ 0 ] <= mins[ 0 ] -       || check->r.absmax[ 1 ] <= mins[ 1 ] -       || check->r.absmax[ 2 ] <= mins[ 2 ] ) -        continue; - -      // see if the ent's bbox is inside the pusher's final position -      // this does allow a fast moving object to pass through a thin entity... -      if( !G_TestEntityPosition( check ) ) -        continue; -    } - -    // the entity needs to be pushed -    if( G_TryPushingEntity( check, pusher, move, amove ) ) -      continue; - -    // the move was blocked an entity - -    // bobbing entities are instant-kill and never get blocked -    if( pusher->s.pos.trType == TR_SINE || pusher->s.apos.trType == TR_SINE ) -    { -      G_Damage( check, pusher, pusher, NULL, NULL, 99999, 0, MOD_CRUSH ); -      continue; -    } - - -    // save off the obstacle so we can call the block function (crush, etc) -    *obstacle = check; - -    // move back any entities we already moved -    // go backwards, so if the same entity was pushed -    // twice, it goes back to the original position -    for( p = pushed_p - 1; p >= pushed; p-- ) -    { -      VectorCopy( p->origin, p->ent->s.pos.trBase ); -      VectorCopy( p->angles, p->ent->s.apos.trBase ); - -      if( p->ent->client ) -      { -        p->ent->client->ps.delta_angles[ YAW ] = p->deltayaw; -        VectorCopy( p->origin, p->ent->client->ps.origin ); -      } - -      trap_LinkEntity( p->ent ); -    } - -    return qfalse; -  } - -  return qtrue; -} - - -/* -================= -G_MoverTeam -================= -*/ -void G_MoverTeam( gentity_t *ent ) -{ -  vec3_t    move, amove; -  gentity_t *part, *obstacle; -  vec3_t    origin, angles; - -  obstacle = NULL; - -  // make sure all team slaves can move before commiting -  // any moves or calling any think functions -  // if the move is blocked, all moved objects will be backed out -  pushed_p = pushed; -  for( part = ent; part; part = part->teamchain ) -  { -    // get current position -    BG_EvaluateTrajectory( &part->s.pos, level.time, origin ); -    BG_EvaluateTrajectory( &part->s.apos, level.time, angles ); -    VectorSubtract( origin, part->r.currentOrigin, move ); -    VectorSubtract( angles, part->r.currentAngles, amove ); -    if( !G_MoverPush( part, move, amove, &obstacle ) ) -      break;  // move was blocked -  } - -  if( part ) -  { -    // go back to the previous position -    for( part = ent; part; part = part->teamchain ) -    { -      part->s.pos.trTime += level.time - level.previousTime; -      part->s.apos.trTime += level.time - level.previousTime; -      BG_EvaluateTrajectory( &part->s.pos, level.time, part->r.currentOrigin ); -      BG_EvaluateTrajectory( &part->s.apos, level.time, part->r.currentAngles ); -      trap_LinkEntity( part ); -    } - -    // if the pusher has a "blocked" function, call it -    if( ent->blocked ) -      ent->blocked( ent, obstacle ); - -    return; -  } - -  // the move succeeded -  for( part = ent; part; part = part->teamchain ) -  { -    // call the reached function if time is at or past end point -    if( part->s.pos.trType == TR_LINEAR_STOP ) -    { -      if( level.time >= part->s.pos.trTime + part->s.pos.trDuration ) -      { -        if( part->reached ) -          part->reached( part ); -      } -    } -    if ( part->s.apos.trType == TR_LINEAR_STOP ) { -      if ( level.time >= part->s.apos.trTime + part->s.apos.trDuration ) { -        if ( part->reached ) { -          part->reached( part ); -        } -      } -    } -  } -} - -/* -================ -G_RunMover - -================ -*/ -void G_RunMover( gentity_t *ent ) -{ -  // if not a team captain, don't do anything, because -  // the captain will handle everything -  if( ent->flags & FL_TEAMSLAVE ) -    return; - -  // if stationary at one of the positions, don't move anything -  if( ( ent->s.pos.trType != TR_STATIONARY || ent->s.apos.trType != TR_STATIONARY ) && -      ent->moverState < MODEL_POS1 ) //yuck yuck hack -    G_MoverTeam( ent ); - -  // check think function -  G_RunThink( ent ); -} - -/* -============================================================================ - -GENERAL MOVERS - -Doors, plats, and buttons are all binary (two position) movers -Pos1 is "at rest", pos2 is "activated" -============================================================================ -*/ - -/* -=============== -SetMoverState -=============== -*/ -void SetMoverState( gentity_t *ent, moverState_t moverState, int time ) -{ -  vec3_t delta; -  float  f; - -  ent->moverState = moverState; - -  ent->s.pos.trTime = time; -  ent->s.apos.trTime = time; - -  switch( moverState ) -  { -    case MOVER_POS1: -      VectorCopy( ent->pos1, ent->s.pos.trBase ); -      ent->s.pos.trType = TR_STATIONARY; -      break; - -    case MOVER_POS2: -      VectorCopy( ent->pos2, ent->s.pos.trBase ); -      ent->s.pos.trType = TR_STATIONARY; -      break; - -    case MOVER_1TO2: -      VectorCopy( ent->pos1, ent->s.pos.trBase ); -      VectorSubtract( ent->pos2, ent->pos1, delta ); -      f = 1000.0 / ent->s.pos.trDuration; -      VectorScale( delta, f, ent->s.pos.trDelta ); -      ent->s.pos.trType = TR_LINEAR_STOP; -      break; - -    case MOVER_2TO1: -      VectorCopy( ent->pos2, ent->s.pos.trBase ); -      VectorSubtract( ent->pos1, ent->pos2, delta ); -      f = 1000.0 / ent->s.pos.trDuration; -      VectorScale( delta, f, ent->s.pos.trDelta ); -      ent->s.pos.trType = TR_LINEAR_STOP; -      break; - -    case ROTATOR_POS1: -      VectorCopy( ent->pos1, ent->s.apos.trBase ); -      ent->s.apos.trType = TR_STATIONARY; -      break; - -    case ROTATOR_POS2: -      VectorCopy( ent->pos2, ent->s.apos.trBase ); -      ent->s.apos.trType = TR_STATIONARY; -      break; - -    case ROTATOR_1TO2: -      VectorCopy( ent->pos1, ent->s.apos.trBase ); -      VectorSubtract( ent->pos2, ent->pos1, delta ); -      f = 1000.0 / ent->s.apos.trDuration; -      VectorScale( delta, f, ent->s.apos.trDelta ); -      ent->s.apos.trType = TR_LINEAR_STOP; -      break; - -    case ROTATOR_2TO1: -      VectorCopy( ent->pos2, ent->s.apos.trBase ); -      VectorSubtract( ent->pos1, ent->pos2, delta ); -      f = 1000.0 / ent->s.apos.trDuration; -      VectorScale( delta, f, ent->s.apos.trDelta ); -      ent->s.apos.trType = TR_LINEAR_STOP; -      break; - -    case MODEL_POS1: -      break; - -    case MODEL_POS2: -      break; - -    default: -      break; -  } - -  if( moverState >= MOVER_POS1 && moverState <= MOVER_2TO1 ) -    BG_EvaluateTrajectory( &ent->s.pos, level.time, ent->r.currentOrigin ); - -  if( moverState >= ROTATOR_POS1 && moverState <= ROTATOR_2TO1 ) -    BG_EvaluateTrajectory( &ent->s.apos, level.time, ent->r.currentAngles ); - -  trap_LinkEntity( ent ); -} - -/* -================ -MatchTeam - -All entities in a mover team will move from pos1 to pos2 -in the same amount of time -================ -*/ -void MatchTeam( gentity_t *teamLeader, int moverState, int time ) -{ -  gentity_t   *slave; - -  for( slave = teamLeader; slave; slave = slave->teamchain ) -    SetMoverState( slave, moverState, time ); -} - - - -/* -================ -ReturnToPos1 -================ -*/ -void ReturnToPos1( gentity_t *ent ) -{ -  MatchTeam( ent, MOVER_2TO1, level.time ); - -  // looping sound -  ent->s.loopSound = ent->soundLoop; - -  // starting sound -  if( ent->sound2to1 ) -    G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound2to1 ); -} - - -/* -================ -ReturnToApos1 -================ -*/ -void ReturnToApos1( gentity_t *ent ) -{ -  MatchTeam( ent, ROTATOR_2TO1, level.time ); - -  // looping sound -  ent->s.loopSound = ent->soundLoop; - -  // starting sound -  if( ent->sound2to1 ) -    G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound2to1 ); -} - - -/* -================ -Think_ClosedModelDoor -================ -*/ -void Think_ClosedModelDoor( gentity_t *ent ) -{ -  // play sound -  if( ent->soundPos1 ) -    G_AddEvent( ent, EV_GENERAL_SOUND, ent->soundPos1 ); - -  // close areaportals -  if( ent->teammaster == ent || !ent->teammaster ) -    trap_AdjustAreaPortalState( ent, qfalse ); - -  ent->moverState = MODEL_POS1; -} - - -/* -================ -Think_CloseModelDoor -================ -*/ -void Think_CloseModelDoor( gentity_t *ent ) -{ -  int       entityList[ MAX_GENTITIES ]; -  int       numEntities, i; -  gentity_t *clipBrush = ent->clipBrush; -  gentity_t *check; -  qboolean  canClose = qtrue; - -  numEntities = trap_EntitiesInBox( clipBrush->r.absmin, clipBrush->r.absmax, entityList, MAX_GENTITIES ); - -  //set brush solid -  trap_LinkEntity( ent->clipBrush ); - -  //see if any solid entities are inside the door -  for( i = 0; i < numEntities; i++ ) -  { -    check = &g_entities[ entityList[ i ] ]; - -    //only test items and players -    if( check->s.eType != ET_ITEM && check->s.eType != ET_BUILDABLE && -        check->s.eType != ET_CORPSE && check->s.eType != ET_PLAYER && -        !check->physicsObject ) -      continue; - -    //test is this entity collides with this door -    if( G_TestEntityPosition( check ) ) -      canClose = qfalse; -  } - -  //something is blocking this door -  if( !canClose ) -  { -    //set brush non-solid -    trap_UnlinkEntity( ent->clipBrush ); - -    ent->nextthink = level.time + ent->wait; -    return; -  } - -  //toggle door state -  ent->s.legsAnim = qfalse; - -  // play sound -  if( ent->sound2to1 ) -    G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound2to1 ); - -  ent->moverState = MODEL_2TO1; - -  ent->think = Think_ClosedModelDoor; -  ent->nextthink = level.time + ent->speed; -} - - -/* -================ -Think_OpenModelDoor -================ -*/ -void Think_OpenModelDoor( gentity_t *ent ) -{ -  //set brush non-solid -  trap_UnlinkEntity( ent->clipBrush ); - -  // looping sound -  ent->s.loopSound = ent->soundLoop; - -  // starting sound -  if( ent->soundPos2 ) -    G_AddEvent( ent, EV_GENERAL_SOUND, ent->soundPos2 ); - -  ent->moverState = MODEL_POS2; - -  // return to pos1 after a delay -  ent->think = Think_CloseModelDoor; -  ent->nextthink = level.time + ent->wait; - -  // fire targets -  if( !ent->activator ) -    ent->activator = ent; - -  G_UseTargets( ent, ent->activator ); -} - - -/* -================ -Reached_BinaryMover -================ -*/ -void Reached_BinaryMover( gentity_t *ent ) -{ -  // stop the looping sound -  ent->s.loopSound = ent->soundLoop; - -  if( ent->moverState == MOVER_1TO2 ) -  { -    // reached pos2 -    SetMoverState( ent, MOVER_POS2, level.time ); - -    // play sound -    if( ent->soundPos2 ) -      G_AddEvent( ent, EV_GENERAL_SOUND, ent->soundPos2 ); - -    // return to pos1 after a delay -    ent->think = ReturnToPos1; -    ent->nextthink = level.time + ent->wait; - -    // fire targets -    if( !ent->activator ) -      ent->activator = ent; - -    G_UseTargets( ent, ent->activator ); -  } -  else if( ent->moverState == MOVER_2TO1 ) -  { -    // reached pos1 -    SetMoverState( ent, MOVER_POS1, level.time ); - -    // play sound -    if( ent->soundPos1 ) -      G_AddEvent( ent, EV_GENERAL_SOUND, ent->soundPos1 ); - -    // close areaportals -    if( ent->teammaster == ent || !ent->teammaster ) -      trap_AdjustAreaPortalState( ent, qfalse ); -  } -  else if( ent->moverState == ROTATOR_1TO2 ) -  { -    // reached pos2 -    SetMoverState( ent, ROTATOR_POS2, level.time ); - -    // play sound -    if( ent->soundPos2 ) -      G_AddEvent( ent, EV_GENERAL_SOUND, ent->soundPos2 ); - -    // return to apos1 after a delay -    ent->think = ReturnToApos1; -    ent->nextthink = level.time + ent->wait; - -    // fire targets -    if( !ent->activator ) -      ent->activator = ent; - -    G_UseTargets( ent, ent->activator ); -  } -  else if( ent->moverState == ROTATOR_2TO1 ) -  { -    // reached pos1 -    SetMoverState( ent, ROTATOR_POS1, level.time ); - -    // play sound -    if( ent->soundPos1 ) -      G_AddEvent( ent, EV_GENERAL_SOUND, ent->soundPos1 ); - -    // close areaportals -    if( ent->teammaster == ent || !ent->teammaster ) -      trap_AdjustAreaPortalState( ent, qfalse ); -  } -  else -    G_Error( "Reached_BinaryMover: bad moverState" ); -} - - -/* -================ -Use_BinaryMover -================ -*/ -void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  int   total; -  int   partial; - -  // if this is a non-client-usable door return -  if( ent->targetname && other && other->client ) -    return; - -  // only the master should be used -  if( ent->flags & FL_TEAMSLAVE ) -  { -    Use_BinaryMover( ent->teammaster, other, activator ); -    return; -  } - -  ent->activator = activator; - -  if( ent->moverState == MOVER_POS1 ) -  { -    // start moving 50 msec later, becase if this was player -    // triggered, level.time hasn't been advanced yet -    MatchTeam( ent, MOVER_1TO2, level.time + 50 ); - -    // starting sound -    if( ent->sound1to2 ) -      G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 ); - -    // looping sound -    ent->s.loopSound = ent->soundLoop; - -    // open areaportal -    if( ent->teammaster == ent || !ent->teammaster ) -      trap_AdjustAreaPortalState( ent, qtrue ); -  } -  else if( ent->moverState == MOVER_POS2 ) -  { -    // if all the way up, just delay before coming down -    ent->nextthink = level.time + ent->wait; -  } -  else if( ent->moverState == MOVER_2TO1 ) -  { -    // only partway down before reversing -    total = ent->s.pos.trDuration; -    partial = level.time - ent->s.pos.trTime; - -    if( partial > total ) -      partial = total; - -    MatchTeam( ent, MOVER_1TO2, level.time - ( total - partial ) ); - -    if( ent->sound1to2 ) -      G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 ); -  } -  else if( ent->moverState == MOVER_1TO2 ) -  { -    // only partway up before reversing -    total = ent->s.pos.trDuration; -    partial = level.time - ent->s.pos.trTime; - -    if( partial > total ) -      partial = total; - -    MatchTeam( ent, MOVER_2TO1, level.time - ( total - partial ) ); - -    if( ent->sound2to1 ) -      G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound2to1 ); -  } -  else if( ent->moverState == ROTATOR_POS1 ) -  { -    // start moving 50 msec later, becase if this was player -    // triggered, level.time hasn't been advanced yet -    MatchTeam( ent, ROTATOR_1TO2, level.time + 50 ); - -    // starting sound -    if( ent->sound1to2 ) -      G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 ); - -    // looping sound -    ent->s.loopSound = ent->soundLoop; - -    // open areaportal -    if( ent->teammaster == ent || !ent->teammaster ) -      trap_AdjustAreaPortalState( ent, qtrue ); -  } -  else if( ent->moverState == ROTATOR_POS2 ) -  { -    // if all the way up, just delay before coming down -    ent->nextthink = level.time + ent->wait; -  } -  else if( ent->moverState == ROTATOR_2TO1 ) -  { -    // only partway down before reversing -    total = ent->s.apos.trDuration; -    partial = level.time - ent->s.apos.trTime; - -    if( partial > total ) -      partial = total; - -    MatchTeam( ent, ROTATOR_1TO2, level.time - ( total - partial ) ); - -    if( ent->sound1to2 ) -      G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 ); -  } -  else if( ent->moverState == ROTATOR_1TO2 ) -  { -    // only partway up before reversing -    total = ent->s.apos.trDuration; -    partial = level.time - ent->s.apos.trTime; - -    if( partial > total ) -      partial = total; - -    MatchTeam( ent, ROTATOR_2TO1, level.time - ( total - partial ) ); - -    if( ent->sound2to1 ) -      G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound2to1 ); -  } -  else if( ent->moverState == MODEL_POS1 ) -  { -    //toggle door state -    ent->s.legsAnim = qtrue; - -    ent->think = Think_OpenModelDoor; -    ent->nextthink = level.time + ent->speed; - -    // starting sound -    if( ent->sound1to2 ) -      G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 ); - -    // looping sound -    ent->s.loopSound = ent->soundLoop; - -    // open areaportal -    if( ent->teammaster == ent || !ent->teammaster ) -      trap_AdjustAreaPortalState( ent, qtrue ); - -    ent->moverState = MODEL_1TO2; -  } -  else if( ent->moverState == MODEL_POS2 ) -  { -    // if all the way up, just delay before coming down -    ent->nextthink = level.time + ent->wait; -  } -} - - - -/* -================ -InitMover - -"pos1", "pos2", and "speed" should be set before calling, -so the movement delta can be calculated -================ -*/ -void InitMover( gentity_t *ent ) -{ -  vec3_t    move; -  float     distance; -  float     light; -  vec3_t    color; -  qboolean  lightSet, colorSet; -  char      *sound; - -  // if the "model2" key is set, use a seperate model -  // for drawing, but clip against the brushes -  if( ent->model2 ) -    ent->s.modelindex2 = G_ModelIndex( ent->model2 ); - -  // if the "loopsound" key is set, use a constant looping sound when moving -  if( G_SpawnString( "noise", "100", &sound ) ) -    ent->s.loopSound = G_SoundIndex( sound ); - -  // if the "color" or "light" keys are set, setup constantLight -  lightSet = G_SpawnFloat( "light", "100", &light ); -  colorSet = G_SpawnVector( "color", "1 1 1", color ); - -  if( lightSet || colorSet ) -  { -    int   r, g, b, i; - -    r = color[ 0 ] * 255; -    if( r > 255 ) -      r = 255; - -    g = color[ 1 ] * 255; -    if( g > 255 ) -      g = 255; - -    b = color[ 2 ] * 255; -    if( b > 255 ) -      b = 255; - -    i = light / 4; -    if( i > 255 ) -      i = 255; - -    ent->s.constantLight = r | ( g << 8 ) | ( b << 16 ) | ( i << 24 ); -  } - - -  ent->use = Use_BinaryMover; -  ent->reached = Reached_BinaryMover; - -  ent->moverState = MOVER_POS1; -  ent->r.svFlags = SVF_USE_CURRENT_ORIGIN; -  ent->s.eType = ET_MOVER; -  VectorCopy( ent->pos1, ent->r.currentOrigin ); -  trap_LinkEntity( ent ); - -  ent->s.pos.trType = TR_STATIONARY; -  VectorCopy( ent->pos1, ent->s.pos.trBase ); - -  // calculate time to reach second position from speed -  VectorSubtract( ent->pos2, ent->pos1, move ); -  distance = VectorLength( move ); -  if( !ent->speed ) -    ent->speed = 100; - -  VectorScale( move, ent->speed, ent->s.pos.trDelta ); -  ent->s.pos.trDuration = distance * 1000 / ent->speed; - -  if( ent->s.pos.trDuration <= 0 ) -    ent->s.pos.trDuration = 1; -} - - -/* -================ -InitRotator - -"pos1", "pos2", and "speed" should be set before calling, -so the movement delta can be calculated -================ -*/ -void InitRotator( gentity_t *ent ) -{ -  vec3_t    move; -  float     angle; -  float     light; -  vec3_t    color; -  qboolean  lightSet, colorSet; -  char      *sound; - -  // if the "model2" key is set, use a seperate model -  // for drawing, but clip against the brushes -  if( ent->model2 ) -    ent->s.modelindex2 = G_ModelIndex( ent->model2 ); - -  // if the "loopsound" key is set, use a constant looping sound when moving -  if( G_SpawnString( "noise", "100", &sound ) ) -    ent->s.loopSound = G_SoundIndex( sound ); - -  // if the "color" or "light" keys are set, setup constantLight -  lightSet = G_SpawnFloat( "light", "100", &light ); -  colorSet = G_SpawnVector( "color", "1 1 1", color ); - -  if( lightSet || colorSet ) -  { -    int   r, g, b, i; - -    r = color[ 0 ] * 255; - -    if( r > 255 ) -      r = 255; - -    g = color[ 1 ] * 255; - -    if( g > 255 ) -      g = 255; - -    b = color[ 2 ] * 255; - -    if( b > 255 ) -      b = 255; - -    i = light / 4; - -    if( i > 255 ) -      i = 255; - -    ent->s.constantLight = r | ( g << 8 ) | ( b << 16 ) | ( i << 24 ); -  } - - -  ent->use = Use_BinaryMover; -  ent->reached = Reached_BinaryMover; - -  ent->moverState = ROTATOR_POS1; -  ent->r.svFlags = SVF_USE_CURRENT_ORIGIN; -  ent->s.eType = ET_MOVER; -  VectorCopy( ent->pos1, ent->r.currentAngles ); -  trap_LinkEntity( ent ); - -  ent->s.apos.trType = TR_STATIONARY; -  VectorCopy( ent->pos1, ent->s.apos.trBase ); - -  // calculate time to reach second position from speed -  VectorSubtract( ent->pos2, ent->pos1, move ); -  angle = VectorLength( move ); - -  if( !ent->speed ) -    ent->speed = 120; - -  VectorScale( move, ent->speed, ent->s.apos.trDelta ); -  ent->s.apos.trDuration = angle * 1000 / ent->speed; - -  if( ent->s.apos.trDuration <= 0 ) -    ent->s.apos.trDuration = 1; -} - - -/* -=============================================================================== - -DOOR - -A use can be triggered either by a touch function, by being shot, or by being -targeted by another entity. - -=============================================================================== -*/ - -/* -================ -Blocked_Door -================ -*/ -void Blocked_Door( gentity_t *ent, gentity_t *other ) -{ -  // remove anything other than a client or buildable -  if( !other->client && other->s.eType != ET_BUILDABLE ) -  { -    G_FreeEntity( other ); -    return; -  } - -  if( ent->damage ) -    G_Damage( other, ent, ent, NULL, NULL, ent->damage, 0, MOD_CRUSH ); - -  if( ent->spawnflags & 4 ) -    return;   // crushers don't reverse - -  // reverse direction -  Use_BinaryMover( ent, ent, other ); -} - -/* -================ -Touch_DoorTriggerSpectator -================ -*/ -static void Touch_DoorTriggerSpectator( gentity_t *ent, gentity_t *other, trace_t *trace ) -{ -  int     i, axis; -  vec3_t  origin, dir, angles; - -  axis = ent->count; -  VectorClear( dir ); - -  if( fabs( other->s.origin[ axis ] - ent->r.absmax[ axis ] ) < -      fabs( other->s.origin[ axis ] - ent->r.absmin[ axis ] ) ) -  { -    origin[ axis ] = ent->r.absmin[ axis ] - 20; -    dir[ axis ] = -1; -  } -  else -  { -    origin[ axis ] = ent->r.absmax[ axis ] + 20; -    dir[ axis ] = 1; -  } - -  for( i = 0; i < 3; i++ ) -  { -    if( i == axis ) -      continue; - -    origin[ i ] = ( ent->r.absmin[ i ] + ent->r.absmax[ i ] ) * 0.5; -  } - -  vectoangles( dir, angles ); -  TeleportPlayer( other, origin, angles ); -} - - -/* -================ -manualDoorTriggerSpectator - -This effectively creates a temporary door auto trigger so manually -triggers doors can be skipped by spectators -================ -*/ -static void manualDoorTriggerSpectator( gentity_t *door, gentity_t *player ) -{ -  gentity_t *other; -  gentity_t triggerHull; -  int       best, i; -  vec3_t    mins, maxs; - -  //don't skip a door that is already open -  if( door->moverState == MOVER_1TO2 || -      door->moverState == MOVER_POS2 || -      door->moverState == ROTATOR_1TO2 || -      door->moverState == ROTATOR_POS2 || -      door->moverState == MODEL_1TO2 || -      door->moverState == MODEL_POS2 ) -    return; - -  // find the bounds of everything on the team -  VectorCopy( door->r.absmin, mins ); -  VectorCopy( door->r.absmax, maxs ); - -  for( other = door->teamchain; other; other = other->teamchain ) -  { -    AddPointToBounds( other->r.absmin, mins, maxs ); -    AddPointToBounds( other->r.absmax, mins, maxs ); -  } - -  // find the thinnest axis, which will be the one we expand -  best = 0; -  for( i = 1; i < 3; i++ ) -  { -    if( maxs[ i ] - mins[ i ] < maxs[ best ] - mins[ best ] ) -      best = i; -  } - -  maxs[ best ] += 60; -  mins[ best ] -= 60; - -  VectorCopy( mins, triggerHull.r.absmin ); -  VectorCopy( maxs, triggerHull.r.absmax ); -  triggerHull.count = best; - -  Touch_DoorTriggerSpectator( &triggerHull, player, NULL ); -} - -/* -================ -manualTriggerSpectator - -Trip to skip the closest door targetted by trigger -================ -*/ -void manualTriggerSpectator( gentity_t *trigger, gentity_t *player ) -{ -  gentity_t *t = NULL; -  gentity_t *targets[ MAX_GENTITIES ]; -  int       i = 0, j; -  float     minDistance = (float)INFINITE; - -  //restrict this hack to trigger_multiple only for now -  if( strcmp( trigger->classname, "trigger_multiple" ) ) -    return; - -  if( !trigger->target ) -    return; - -  //create a list of door entities this trigger targets -  while( ( t = G_Find( t, FOFS( targetname ), trigger->target ) ) != NULL ) -  { -    if( !strcmp( t->classname, "func_door" ) ) -      targets[ i++ ] = t; -    else if( t == trigger ) -      G_Printf( "WARNING: Entity used itself.\n" ); - -    if( !trigger->inuse ) -    { -      G_Printf( "triggerity was removed while using targets\n" ); -      return; -    } -  } - -  //if more than 0 targets -  if( i > 0 ) -  { -    gentity_t *closest = NULL; - -    //pick the closest door -    for( j = 0; j < i; j++ ) -    { -      float d = Distance( player->r.currentOrigin, targets[ j ]->r.currentOrigin ); - -      if( d < minDistance ) -      { -        minDistance = d; -        closest = targets[ j ]; -      } -    } - -    //try and skip the door -    manualDoorTriggerSpectator( closest, player ); -  } -} - - -/* -================ -Touch_DoorTrigger -================ -*/ -void Touch_DoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace ) -{ -  //buildables don't trigger movers -  if( other->s.eType == ET_BUILDABLE ) -    return; - -  if( other->client && other->client->sess.sessionTeam == TEAM_SPECTATOR ) -  { -    // if the door is not open and not opening -    if( ent->parent->moverState != MOVER_1TO2 && -        ent->parent->moverState != MOVER_POS2 && -        ent->parent->moverState != ROTATOR_1TO2 && -        ent->parent->moverState != ROTATOR_POS2 ) -      Touch_DoorTriggerSpectator( ent, other, trace ); -  } -  else if( ent->parent->moverState != MOVER_1TO2 && -           ent->parent->moverState != ROTATOR_1TO2 && -           ent->parent->moverState != ROTATOR_2TO1 ) -  { -    Use_BinaryMover( ent->parent, ent, other ); -  } -} - - -/* -====================== -Think_SpawnNewDoorTrigger - -All of the parts of a door have been spawned, so create -a trigger that encloses all of them -====================== -*/ -void Think_SpawnNewDoorTrigger( gentity_t *ent ) -{ -  gentity_t *other; -  vec3_t    mins, maxs; -  int       i, best; - -  //TA: disable shootable doors -  // set all of the slaves as shootable -  //for( other = ent; other; other = other->teamchain ) -  //  other->takedamage = qtrue; - -  // find the bounds of everything on the team -  VectorCopy( ent->r.absmin, mins ); -  VectorCopy( ent->r.absmax, maxs ); - -  for( other = ent->teamchain; other; other=other->teamchain ) -  { -    AddPointToBounds( other->r.absmin, mins, maxs ); -    AddPointToBounds( other->r.absmax, mins, maxs ); -  } - -  // find the thinnest axis, which will be the one we expand -  best = 0; -  for( i = 1; i < 3; i++ ) -  { -    if( maxs[ i ] - mins[ i ] < maxs[ best ] - mins[ best ] ) -      best = i; -  } - -  maxs[ best ] += 60; -  mins[ best ] -= 60; - -  // create a trigger with this size -  other = G_Spawn( ); -  other->classname = "door_trigger"; -  VectorCopy( mins, other->r.mins ); -  VectorCopy( maxs, other->r.maxs ); -  other->parent = ent; -  other->r.contents = CONTENTS_TRIGGER; -  other->touch = Touch_DoorTrigger; -  // remember the thinnest axis -  other->count = best; -  trap_LinkEntity( other ); - -  if( ent->moverState < MODEL_POS1 ) -    MatchTeam( ent, ent->moverState, level.time ); -} - -void Think_MatchTeam( gentity_t *ent ) -{ -  MatchTeam( ent, ent->moverState, level.time ); -} - - -/*QUAKED func_door (0 .5 .8) ? START_OPEN x CRUSHER -TOGGLE    wait in both the start and end states for a trigger event. -START_OPEN  the door to moves to its destination when spawned, and operate in reverse.  It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors). -NOMONSTER monsters will not trigger this door - -"model2"  .md3 model to also draw -"angle"   determines the opening direction -"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door. -"speed"   movement speed (100 default) -"wait"    wait before returning (3 default, -1 = never return) -"lip"   lip remaining at end of move (8 default) -"dmg"   damage to inflict when blocked (2 default) -"color"   constantLight color -"light"   constantLight radius -"health"  if set, the door must be shot open -*/ -void SP_func_door( gentity_t *ent ) -{ -  vec3_t  abs_movedir; -  float   distance; -  vec3_t  size; -  float   lip; -  char    *s; - -  G_SpawnString( "sound2to1", "sound/movers/doors/dr1_strt.wav", &s ); -  ent->sound2to1 = G_SoundIndex( s ); -  G_SpawnString( "sound1to2", "sound/movers/doors/dr1_strt.wav", &s ); -  ent->sound1to2 = G_SoundIndex( s ); - -  G_SpawnString( "soundPos2", "sound/movers/doors/dr1_end.wav", &s ); -  ent->soundPos2 = G_SoundIndex( s ); -  G_SpawnString( "soundPos1", "sound/movers/doors/dr1_end.wav", &s ); -  ent->soundPos1 = G_SoundIndex( s ); - -  ent->blocked = Blocked_Door; - -  // default speed of 400 -  if( !ent->speed ) -    ent->speed = 400; - -  // default wait of 2 seconds -  if( !ent->wait ) -    ent->wait = 2; - -  ent->wait *= 1000; - -  // default lip of 8 units -  G_SpawnFloat( "lip", "8", &lip ); - -  // default damage of 2 points -  G_SpawnInt( "dmg", "2", &ent->damage ); - -  // first position at start -  VectorCopy( ent->s.origin, ent->pos1 ); - -  // calculate second position -  trap_SetBrushModel( ent, ent->model ); -  G_SetMovedir( ent->s.angles, ent->movedir ); -  abs_movedir[ 0 ] = fabs( ent->movedir[ 0 ] ); -  abs_movedir[ 1 ] = fabs( ent->movedir[ 1 ] ); -  abs_movedir[ 2 ] = fabs( ent->movedir[ 2 ] ); -  VectorSubtract( ent->r.maxs, ent->r.mins, size ); -  distance = DotProduct( abs_movedir, size ) - lip; -  VectorMA( ent->pos1, distance, ent->movedir, ent->pos2 ); - -  // if "start_open", reverse position 1 and 2 -  if( ent->spawnflags & 1 ) -  { -    vec3_t  temp; - -    VectorCopy( ent->pos2, temp ); -    VectorCopy( ent->s.origin, ent->pos2 ); -    VectorCopy( temp, ent->pos1 ); -  } - -  InitMover( ent ); - -  ent->nextthink = level.time + FRAMETIME; - -  if( !( ent->flags & FL_TEAMSLAVE ) ) -  { -    int health; - -    G_SpawnInt( "health", "0", &health ); -    if( health ) -      ent->takedamage = qtrue; - -    if( ent->targetname || health ) -    { -      // non touch/shoot doors -      ent->think = Think_MatchTeam; -    } -    else -      ent->think = Think_SpawnNewDoorTrigger; -  } -} - -/*QUAKED func_door_rotating (0 .5 .8) START_OPEN CRUSHER REVERSE TOGGLE X_AXIS Y_AXIS - * This is the rotating door... just as the name suggests it's a door that rotates - * START_OPEN the door to moves to its destination when spawned, and operate in reverse. - * REVERSE    if you want the door to open in the other direction, use this switch. - * TOGGLE   wait in both the start and end states for a trigger event. - * X_AXIS   open on the X-axis instead of the Z-axis - * Y_AXIS   open on the Y-axis instead of the Z-axis - * - *   You need to have an origin brush as part of this entity.  The center of that brush will be - *   the point around which it is rotated. It will rotate around the Z axis by default.  You can - *   check either the X_AXIS or Y_AXIS box to change that. - * - *   "model2" .md3 model to also draw - *   "distance" how many degrees the door will open - *   "speed"    how fast the door will open (degrees/second) - *   "color"    constantLight color - *   "light"    constantLight radius - *   */ - -void SP_func_door_rotating( gentity_t *ent ) -{ -  char    *s; - -  G_SpawnString( "sound2to1", "sound/movers/doors/dr1_strt.wav", &s ); -  ent->sound2to1 = G_SoundIndex( s ); -  G_SpawnString( "sound1to2", "sound/movers/doors/dr1_strt.wav", &s ); -  ent->sound1to2 = G_SoundIndex( s ); - -  G_SpawnString( "soundPos2", "sound/movers/doors/dr1_end.wav", &s ); -  ent->soundPos2 = G_SoundIndex( s ); -  G_SpawnString( "soundPos1", "sound/movers/doors/dr1_end.wav", &s ); -  ent->soundPos1 = G_SoundIndex( s ); - -  ent->blocked = Blocked_Door; - -  //default speed of 120 -  if( !ent->speed ) -    ent->speed = 120; - -  // if speed is negative, positize it and add reverse flag -  if( ent->speed < 0 ) -  { -    ent->speed *= -1; -    ent->spawnflags |= 8; -  } - -  // default of 2 seconds -  if( !ent->wait ) -    ent->wait = 2; - -  ent->wait *= 1000; - -  // set the axis of rotation -  VectorClear( ent->movedir ); -  VectorClear( ent->s.angles ); - -  if( ent->spawnflags & 32 ) -    ent->movedir[ 2 ] = 1.0; -  else if( ent->spawnflags & 64 ) -    ent->movedir[ 0 ] = 1.0; -  else -    ent->movedir[ 1 ] = 1.0; - -  // reverse direction if necessary -  if( ent->spawnflags & 8 ) -    VectorNegate ( ent->movedir, ent->movedir ); - -  // default distance of 90 degrees. This is something the mapper should not -  // leave out, so we'll tell him if he does. -  if( !ent->rotatorAngle ) -  { -    G_Printf( "%s at %s with no rotatorAngle set.\n", -              ent->classname, vtos( ent->s.origin ) ); - -    ent->rotatorAngle = 90.0; -  } - -  VectorCopy( ent->s.angles, ent->pos1 ); -  trap_SetBrushModel( ent, ent->model ); -  VectorMA( ent->pos1, ent->rotatorAngle, ent->movedir, ent->pos2 ); - -  // if "start_open", reverse position 1 and 2 -  if( ent->spawnflags & 1 ) -  { -    vec3_t  temp; - -    VectorCopy( ent->pos2, temp ); -    VectorCopy( ent->s.angles, ent->pos2 ); -    VectorCopy( temp, ent->pos1 ); -    VectorNegate( ent->movedir, ent->movedir ); -  } - -  // set origin -  VectorCopy( ent->s.origin, ent->s.pos.trBase ); -  VectorCopy( ent->s.pos.trBase, ent->r.currentOrigin ); - -  InitRotator( ent ); - -  ent->nextthink = level.time + FRAMETIME; - -  if( !( ent->flags & FL_TEAMSLAVE ) ) -  { -    int health; - -    G_SpawnInt( "health", "0", &health ); - -    if( health ) -      ent->takedamage = qtrue; - -    if( ent->targetname || health ) -    { -      // non touch/shoot doors -      ent->think = Think_MatchTeam; -    } -    else -      ent->think = Think_SpawnNewDoorTrigger; -  } -} - -/*QUAKED func_door_model (0 .5 .8) ? START_OPEN -TOGGLE    wait in both the start and end states for a trigger event. -START_OPEN  the door to moves to its destination when spawned, and operate in reverse.  It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors). -NOMONSTER monsters will not trigger this door - -"model2"  .md3 model to also draw -"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door. -"speed"   movement speed (100 default) -"wait"    wait before returning (3 default, -1 = never return) -"color"   constantLight color -"light"   constantLight radius -"health"  if set, the door must be shot open -*/ -void SP_func_door_model( gentity_t *ent ) -{ -  char      *s; -  float     light; -  vec3_t    color; -  qboolean  lightSet, colorSet; -  char      *sound; -  gentity_t *clipBrush; - -  G_SpawnString( "sound2to1", "sound/movers/doors/dr1_strt.wav", &s ); -  ent->sound2to1 = G_SoundIndex( s ); -  G_SpawnString( "sound1to2", "sound/movers/doors/dr1_strt.wav", &s ); -  ent->sound1to2 = G_SoundIndex( s ); - -  G_SpawnString( "soundPos2", "sound/movers/doors/dr1_end.wav", &s ); -  ent->soundPos2 = G_SoundIndex( s ); -  G_SpawnString( "soundPos1", "sound/movers/doors/dr1_end.wav", &s ); -  ent->soundPos1 = G_SoundIndex( s ); - -  //default speed of 100ms -  if( !ent->speed ) -    ent->speed = 200; - -  //default wait of 2 seconds -  if( ent->wait <= 0 ) -    ent->wait = 2; - -  ent->wait *= 1000; - -  //brush model -  clipBrush = ent->clipBrush = G_Spawn( ); -  clipBrush->model = ent->model; -  trap_SetBrushModel( clipBrush, clipBrush->model ); -  clipBrush->s.eType = ET_INVISIBLE; -  trap_LinkEntity( clipBrush ); - -  //copy the bounds back from the clipBrush so the -  //triggers can be made -  VectorCopy( clipBrush->r.absmin, ent->r.absmin ); -  VectorCopy( clipBrush->r.absmax, ent->r.absmax ); -  VectorCopy( clipBrush->r.mins, ent->r.mins ); -  VectorCopy( clipBrush->r.maxs, ent->r.maxs ); - -  G_SpawnVector( "modelOrigin", "0 0 0", ent->s.origin ); - -  G_SpawnVector( "scale", "1 1 1", ent->s.origin2 ); - -  // if the "model2" key is set, use a seperate model -  // for drawing, but clip against the brushes -  if( !ent->model2 ) -    G_Printf( S_COLOR_YELLOW "WARNING: func_door_model %d spawned with no model2 key\n", ent->s.number ); -  else -    ent->s.modelindex = G_ModelIndex( ent->model2 ); - -  // if the "loopsound" key is set, use a constant looping sound when moving -  if( G_SpawnString( "noise", "100", &sound ) ) -    ent->s.loopSound = G_SoundIndex( sound ); - -  // if the "color" or "light" keys are set, setup constantLight -  lightSet = G_SpawnFloat( "light", "100", &light ); -  colorSet = G_SpawnVector( "color", "1 1 1", color ); - -  if( lightSet || colorSet ) -  { -    int   r, g, b, i; - -    r = color[ 0 ] * 255; -    if( r > 255 ) -      r = 255; - -    g = color[ 1 ] * 255; -    if( g > 255 ) -      g = 255; - -    b = color[ 2 ] * 255; -    if( b > 255 ) -      b = 255; - -    i = light / 4; -    if( i > 255 ) -      i = 255; - -    ent->s.constantLight = r | ( g << 8 ) | ( b << 16 ) | ( i << 24 ); -  } - -  ent->use = Use_BinaryMover; - -  ent->moverState = MODEL_POS1; -  ent->s.eType = ET_MODELDOOR; -  VectorCopy( ent->s.origin, ent->s.pos.trBase ); -  ent->s.pos.trType = TR_STATIONARY; -  ent->s.pos.trTime = 0; -  ent->s.pos.trDuration = 0; -  VectorClear( ent->s.pos.trDelta ); -  VectorCopy( ent->s.angles, ent->s.apos.trBase ); -  ent->s.apos.trType = TR_STATIONARY; -  ent->s.apos.trTime = 0; -  ent->s.apos.trDuration = 0; -  VectorClear( ent->s.apos.trDelta ); - -  ent->s.powerups  = (int)ent->animation[ 0 ];                  //first frame -  ent->s.weapon    = abs( (int)ent->animation[ 1 ] );           //number of frames - -  //must be at least one frame -- mapper has forgotten animation key -  if( ent->s.weapon == 0 ) -    ent->s.weapon = 1; - -  ent->s.torsoAnim = ent->s.weapon * ( 1000.0f / ent->speed );  //framerate - -  trap_LinkEntity( ent ); - -  if( !( ent->flags & FL_TEAMSLAVE ) ) -  { -    int health; - -    G_SpawnInt( "health", "0", &health ); -    if( health ) -      ent->takedamage = qtrue; - -    if( !( ent->targetname || health ) ) -    { -      ent->nextthink = level.time + FRAMETIME; -      ent->think = Think_SpawnNewDoorTrigger; -    } -  } -} - -/* -=============================================================================== - -PLAT - -=============================================================================== -*/ - -/* -============== -Touch_Plat - -Don't allow decent if a living player is on it -=============== -*/ -void Touch_Plat( gentity_t *ent, gentity_t *other, trace_t *trace ) -{ -  if( !other->client || other->client->ps.stats[ STAT_HEALTH ] <= 0 ) -    return; - -  // delay return-to-pos1 by one second -  if( ent->moverState == MOVER_POS2 ) -    ent->nextthink = level.time + 1000; -} - -/* -============== -Touch_PlatCenterTrigger - -If the plat is at the bottom position, start it going up -=============== -*/ -void Touch_PlatCenterTrigger( gentity_t *ent, gentity_t *other, trace_t *trace ) -{ -  if( !other->client ) -    return; - -  if( ent->parent->moverState == MOVER_POS1 ) -    Use_BinaryMover( ent->parent, ent, other ); -} - - -/* -================ -SpawnPlatTrigger - -Spawn a trigger in the middle of the plat's low position -Elevator cars require that the trigger extend through the entire low position, -not just sit on top of it. -================ -*/ -void SpawnPlatTrigger( gentity_t *ent ) -{ -  gentity_t *trigger; -  vec3_t    tmin, tmax; - -  // the middle trigger will be a thin trigger just -  // above the starting position -  trigger = G_Spawn( ); -  trigger->classname = "plat_trigger"; -  trigger->touch = Touch_PlatCenterTrigger; -  trigger->r.contents = CONTENTS_TRIGGER; -  trigger->parent = ent; - -  tmin[ 0 ] = ent->pos1[ 0 ] + ent->r.mins[ 0 ] + 33; -  tmin[ 1 ] = ent->pos1[ 1 ] + ent->r.mins[ 1 ] + 33; -  tmin[ 2 ] = ent->pos1[ 2 ] + ent->r.mins[ 2 ]; - -  tmax[ 0 ] = ent->pos1[ 0 ] + ent->r.maxs[ 0 ] - 33; -  tmax[ 1 ] = ent->pos1[ 1 ] + ent->r.maxs[ 1 ] - 33; -  tmax[ 2 ] = ent->pos1[ 2 ] + ent->r.maxs[ 2 ] + 8; - -  if( tmax[ 0 ] <= tmin[ 0 ] ) -  { -    tmin[ 0 ] = ent->pos1[ 0 ] + ( ent->r.mins[ 0 ] + ent->r.maxs[ 0 ] ) * 0.5; -    tmax[ 0 ] = tmin[ 0 ] + 1; -  } - -  if( tmax[ 1 ] <= tmin[ 1 ] ) -  { -    tmin[ 1 ] = ent->pos1[ 1 ] + ( ent->r.mins[ 1 ] + ent->r.maxs[ 1 ] ) * 0.5; -    tmax[ 1 ] = tmin[ 1 ] + 1; -  } - -  VectorCopy( tmin, trigger->r.mins ); -  VectorCopy( tmax, trigger->r.maxs ); - -  trap_LinkEntity( trigger ); -} - - -/*QUAKED func_plat (0 .5 .8) ? -Plats are always drawn in the extended position so they will light correctly. - -"lip"   default 8, protrusion above rest position -"height"  total height of movement, defaults to model height -"speed"   overrides default 200. -"dmg"   overrides default 2 -"model2"  .md3 model to also draw -"color"   constantLight color -"light"   constantLight radius -*/ -void SP_func_plat( gentity_t *ent ) -{ -  float lip, height; -  char  *s; - -  G_SpawnString( "sound2to1", "sound/movers/plats/pt1_strt.wav", &s ); -  ent->sound2to1 = G_SoundIndex( s ); -  G_SpawnString( "sound1to2", "sound/movers/plats/pt1_strt.wav", &s ); -  ent->sound1to2 = G_SoundIndex( s ); - -  G_SpawnString( "soundPos2", "sound/movers/plats/pt1_end.wav", &s ); -  ent->soundPos2 = G_SoundIndex( s ); -  G_SpawnString( "soundPos1", "sound/movers/plats/pt1_end.wav", &s ); -  ent->soundPos1 = G_SoundIndex( s ); - -  VectorClear( ent->s.angles ); - -  G_SpawnFloat( "speed", "200", &ent->speed ); -  G_SpawnInt( "dmg", "2", &ent->damage ); -  G_SpawnFloat( "wait", "1", &ent->wait ); -  G_SpawnFloat( "lip", "8", &lip ); - -  ent->wait = 1000; - -  // create second position -  trap_SetBrushModel( ent, ent->model ); - -  if( !G_SpawnFloat( "height", "0", &height ) ) -    height = ( ent->r.maxs[ 2 ] - ent->r.mins[ 2 ] ) - lip; - -  // pos1 is the rest (bottom) position, pos2 is the top -  VectorCopy( ent->s.origin, ent->pos2 ); -  VectorCopy( ent->pos2, ent->pos1 ); -  ent->pos1[ 2 ] -= height; - -  InitMover( ent ); - -  // touch function keeps the plat from returning while -  // a live player is standing on it -  ent->touch = Touch_Plat; - -  ent->blocked = Blocked_Door; - -  ent->parent = ent;  // so it can be treated as a door - -  // spawn the trigger if one hasn't been custom made -  if( !ent->targetname ) -    SpawnPlatTrigger( ent ); -} - - -/* -=============================================================================== - -BUTTON - -=============================================================================== -*/ - -/* -============== -Touch_Button - -=============== -*/ -void Touch_Button( gentity_t *ent, gentity_t *other, trace_t *trace ) -{ -  if( !other->client ) -    return; - -  if( ent->moverState == MOVER_POS1 ) -    Use_BinaryMover( ent, other, other ); -} - - -/*QUAKED func_button (0 .5 .8) ? -When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again. - -"model2"  .md3 model to also draw -"angle"   determines the opening direction -"target"  all entities with a matching targetname will be used -"speed"   override the default 40 speed -"wait"    override the default 1 second wait (-1 = never return) -"lip"   override the default 4 pixel lip remaining at end of move -"health"  if set, the button must be killed instead of touched -"color"   constantLight color -"light"   constantLight radius -*/ -void SP_func_button( gentity_t *ent ) -{ -  vec3_t  abs_movedir; -  float   distance; -  vec3_t  size; -  float   lip; -  char    *s; - -  G_SpawnString( "sound1to2", "sound/movers/switches/butn2.wav", &s ); -  ent->sound1to2 = G_SoundIndex( s ); - -  if( !ent->speed ) -    ent->speed = 40; - -  if( !ent->wait ) -    ent->wait = 1; - -  ent->wait *= 1000; - -  // first position -  VectorCopy( ent->s.origin, ent->pos1 ); - -  // calculate second position -  trap_SetBrushModel( ent, ent->model ); - -  G_SpawnFloat( "lip", "4", &lip ); - -  G_SetMovedir( ent->s.angles, ent->movedir ); -  abs_movedir[ 0 ] = fabs( ent->movedir[ 0 ] ); -  abs_movedir[ 1 ] = fabs( ent->movedir[ 1 ] ); -  abs_movedir[ 2 ] = fabs( ent->movedir[ 2 ] ); -  VectorSubtract( ent->r.maxs, ent->r.mins, size ); -  distance = abs_movedir[ 0 ] * size[ 0 ] + abs_movedir[ 1 ] * size[ 1 ] + abs_movedir[ 2 ] * size[ 2 ] - lip; -  VectorMA( ent->pos1, distance, ent->movedir, ent->pos2 ); - -  if( ent->health ) -  { -    // shootable button -    ent->takedamage = qtrue; -  } -  else -  { -    // touchable button -    ent->touch = Touch_Button; -  } - -  InitMover( ent ); -} - - - -/* -=============================================================================== - -TRAIN - -=============================================================================== -*/ - - -#define TRAIN_START_OFF   1 -#define TRAIN_BLOCK_STOPS 2 - -/* -=============== -Think_BeginMoving - -The wait time at a corner has completed, so start moving again -=============== -*/ -void Think_BeginMoving( gentity_t *ent ) -{ -  ent->s.pos.trTime = level.time; -  ent->s.pos.trType = TR_LINEAR_STOP; -} - -/* -=============== -Reached_Train -=============== -*/ -void Reached_Train( gentity_t *ent ) -{ -  gentity_t *next; -  float     speed; -  vec3_t    move; -  float     length; - -  // copy the apropriate values -  next = ent->nextTrain; -  if( !next || !next->nextTrain ) -    return;   // just stop - -  // fire all other targets -  G_UseTargets( next, NULL ); - -  // set the new trajectory -  ent->nextTrain = next->nextTrain; -  VectorCopy( next->s.origin, ent->pos1 ); -  VectorCopy( next->nextTrain->s.origin, ent->pos2 ); - -  // if the path_corner has a speed, use that -  if( next->speed ) -  { -    speed = next->speed; -  } -  else -  { -    // otherwise use the train's speed -    speed = ent->speed; -  } - -  if( speed < 1 ) -    speed = 1; - -  ent->lastSpeed = speed; - -  // calculate duration -  VectorSubtract( ent->pos2, ent->pos1, move ); -  length = VectorLength( move ); - -  ent->s.pos.trDuration = length * 1000 / speed; - -  // looping sound -  ent->s.loopSound = next->soundLoop; - -  // start it going -  SetMoverState( ent, MOVER_1TO2, level.time ); - -  if( ent->spawnflags & TRAIN_START_OFF ) -  { -    ent->s.pos.trType = TR_STATIONARY; -    return; -  } - -  // if there is a "wait" value on the target, don't start moving yet -  if( next->wait ) -  { -    ent->nextthink = level.time + next->wait * 1000; -    ent->think = Think_BeginMoving; -    ent->s.pos.trType = TR_STATIONARY; -  } -} - -/* -================ -Start_Train -================ -*/ -void Start_Train( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  vec3_t  move; - -  //recalculate duration as the mover is highly -  //unlikely to be right on a path_corner -  VectorSubtract( ent->pos2, ent->pos1, move ); -  ent->s.pos.trDuration = VectorLength( move ) * 1000 / ent->lastSpeed; -  SetMoverState( ent, MOVER_1TO2, level.time ); - -  ent->spawnflags &= ~TRAIN_START_OFF; -} - -/* -================ -Stop_Train -================ -*/ -void Stop_Train( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  vec3_t  origin; - -  //get current origin -  BG_EvaluateTrajectory( &ent->s.pos, level.time, origin ); -  VectorCopy( origin, ent->pos1 ); -  SetMoverState( ent, MOVER_POS1, level.time ); - -  ent->spawnflags |= TRAIN_START_OFF; -} - -/* -================ -Use_Train -================ -*/ -void Use_Train( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  if( ent->spawnflags & TRAIN_START_OFF ) -  { -    //train is currently not moving so start it -    Start_Train( ent, other, activator ); -  } -  else -  { -    //train is moving so stop it -    Stop_Train( ent, other, activator ); -  } -} - -/* -=============== -Think_SetupTrainTargets - -Link all the corners together -=============== -*/ -void Think_SetupTrainTargets( gentity_t *ent ) -{ -  gentity_t *path, *next, *start; - -  ent->nextTrain = G_Find( NULL, FOFS( targetname ), ent->target ); - -  if( !ent->nextTrain ) -  { -    G_Printf( "func_train at %s with an unfound target\n", -      vtos( ent->r.absmin ) ); -    return; -  } - -  start = NULL; -  for( path = ent->nextTrain; path != start; path = next ) -  { -    if( !start ) -      start = path; - -    if( !path->target ) -    { -      G_Printf( "Train corner at %s without a target\n", -        vtos( path->s.origin ) ); -      return; -    } - -    // find a path_corner among the targets -    // there may also be other targets that get fired when the corner -    // is reached -    next = NULL; -    do -    { -      next = G_Find( next, FOFS( targetname ), path->target ); - -      if( !next ) -      { -        G_Printf( "Train corner at %s without a target path_corner\n", -          vtos( path->s.origin ) ); -        return; -      } -    } while( strcmp( next->classname, "path_corner" ) ); - -    path->nextTrain = next; -  } - -  // start the train moving from the first corner -  Reached_Train( ent ); -} - - - -/*QUAKED path_corner (.5 .3 0) (-8 -8 -8) (8 8 8) -Train path corners. -Target: next path corner and other targets to fire -"speed" speed to move to the next corner -"wait" seconds to wait before behining move to next corner -*/ -void SP_path_corner( gentity_t *self ) -{ -  if( !self->targetname ) -  { -    G_Printf( "path_corner with no targetname at %s\n", vtos( self->s.origin ) ); -    G_FreeEntity( self ); -    return; -  } -  // path corners don't need to be linked in -} - -/* -================ -Blocked_Train -================ -*/ -void Blocked_Train( gentity_t *self, gentity_t *other ) -{ -  if( self->spawnflags & TRAIN_BLOCK_STOPS ) -    Stop_Train( self, other, other ); -  else -  { -    if( !other->client ) -    { -      //whatever is blocking the train isn't a client - -      //KILL!!1!!! -      G_Damage( other, self, self, NULL, NULL, 10000, 0, MOD_CRUSH ); - -      //buildables need to be handled differently since even when -      //dealth fatal amounts of damage they won't instantly become non-solid -      if( other->s.eType == ET_BUILDABLE && other->spawned ) -      { -        vec3_t    dir; -        gentity_t *tent; - -        if( other->biteam == BIT_ALIENS ) -        { -          VectorCopy( other->s.origin2, dir ); -          tent = G_TempEntity( other->s.origin, EV_ALIEN_BUILDABLE_EXPLOSION ); -          tent->s.eventParm = DirToByte( dir ); -        } -        else if( other->biteam == BIT_HUMANS ) -        { -          VectorSet( dir, 0.0f, 0.0f, 1.0f ); -          tent = G_TempEntity( other->s.origin, EV_HUMAN_BUILDABLE_EXPLOSION ); -          tent->s.eventParm = DirToByte( dir ); -        } -      } - -      //if it's still around free it -      if( other ) -        G_FreeEntity( other ); - -      return; -    } - -    G_Damage( other, self, self, NULL, NULL, 10000, 0, MOD_CRUSH ); -  } -} - - -/*QUAKED func_train (0 .5 .8) ? START_ON TOGGLE BLOCK_STOPS -A train is a mover that moves between path_corner target points. -Trains MUST HAVE AN ORIGIN BRUSH. -The train spawns at the first target it is pointing at. -"model2"  .md3 model to also draw -"speed"   default 100 -"dmg"   default 2 -"noise"   looping sound to play when the train is in motion -"target"  next path corner -"color"   constantLight color -"light"   constantLight radius -*/ -void SP_func_train( gentity_t *self ) -{ -  VectorClear( self->s.angles ); - -  if( self->spawnflags & TRAIN_BLOCK_STOPS ) -    self->damage = 0; -  else if( !self->damage ) -    self->damage = 2; - -  if( !self->speed ) -    self->speed = 100; - -  if( !self->target ) -  { -    G_Printf( "func_train without a target at %s\n", vtos( self->r.absmin ) ); -    G_FreeEntity( self ); -    return; -  } - -  trap_SetBrushModel( self, self->model ); -  InitMover( self ); - -  self->reached = Reached_Train; -  self->use = Use_Train; -  self->blocked = Blocked_Train; - -  // start trains on the second frame, to make sure their targets have had -  // a chance to spawn -  self->nextthink = level.time + FRAMETIME; -  self->think = Think_SetupTrainTargets; -} - -/* -=============================================================================== - -STATIC - -=============================================================================== -*/ - - -/*QUAKED func_static (0 .5 .8) ? -A bmodel that just sits there, doing nothing.  Can be used for conditional walls and models. -"model2"  .md3 model to also draw -"color"   constantLight color -"light"   constantLight radius -*/ -void SP_func_static( gentity_t *ent ) -{ -  trap_SetBrushModel( ent, ent->model ); -  InitMover( ent ); -  VectorCopy( ent->s.origin, ent->s.pos.trBase ); -  VectorCopy( ent->s.origin, ent->r.currentOrigin ); -} - - -/* -=============================================================================== - -ROTATING - -=============================================================================== -*/ - - -/*QUAKED func_rotating (0 .5 .8) ? START_ON - X_AXIS Y_AXIS -You need to have an origin brush as part of this entity.  The center of that brush will be -the point around which it is rotated. It will rotate around the Z axis by default.  You can -check either the X_AXIS or Y_AXIS box to change that. - -"model2"  .md3 model to also draw -"speed"   determines how fast it moves; default value is 100. -"dmg"   damage to inflict when blocked (2 default) -"color"   constantLight color -"light"   constantLight radius -*/ -void SP_func_rotating( gentity_t *ent ) -{ -  if( !ent->speed ) -    ent->speed = 100; - -  // set the axis of rotation -  ent->s.apos.trType = TR_LINEAR; - -  if( ent->spawnflags & 4 ) -    ent->s.apos.trDelta[ 2 ] = ent->speed; -  else if( ent->spawnflags & 8 ) -    ent->s.apos.trDelta[ 0 ] = ent->speed; -  else -    ent->s.apos.trDelta[ 1 ] = ent->speed; - -  if( !ent->damage ) -    ent->damage = 2; - -  trap_SetBrushModel( ent, ent->model ); -  InitMover( ent ); - -  VectorCopy( ent->s.origin, ent->s.pos.trBase ); -  VectorCopy( ent->s.pos.trBase, ent->r.currentOrigin ); -  VectorCopy( ent->s.apos.trBase, ent->r.currentAngles ); - -  trap_LinkEntity( ent ); -} - - -/* -=============================================================================== - -BOBBING - -=============================================================================== -*/ - - -/*QUAKED func_bobbing (0 .5 .8) ? X_AXIS Y_AXIS -Normally bobs on the Z axis -"model2"  .md3 model to also draw -"height"  amplitude of bob (32 default) -"speed"   seconds to complete a bob cycle (4 default) -"phase"   the 0.0 to 1.0 offset in the cycle to start at -"dmg"   damage to inflict when blocked (2 default) -"color"   constantLight color -"light"   constantLight radius -*/ -void SP_func_bobbing( gentity_t *ent ) -{ -  float   height; -  float   phase; - -  G_SpawnFloat( "speed", "4", &ent->speed ); -  G_SpawnFloat( "height", "32", &height ); -  G_SpawnInt( "dmg", "2", &ent->damage ); -  G_SpawnFloat( "phase", "0", &phase ); - -  trap_SetBrushModel( ent, ent->model ); -  InitMover( ent ); - -  VectorCopy( ent->s.origin, ent->s.pos.trBase ); -  VectorCopy( ent->s.origin, ent->r.currentOrigin ); - -  ent->s.pos.trDuration = ent->speed * 1000; -  ent->s.pos.trTime = ent->s.pos.trDuration * phase; -  ent->s.pos.trType = TR_SINE; - -  // set the axis of bobbing -  if( ent->spawnflags & 1 ) -    ent->s.pos.trDelta[ 0 ] = height; -  else if( ent->spawnflags & 2 ) -    ent->s.pos.trDelta[ 1 ] = height; -  else -    ent->s.pos.trDelta[ 2 ] = height; -} - -/* -=============================================================================== - -PENDULUM - -=============================================================================== -*/ - - -/*QUAKED func_pendulum (0 .5 .8) ? -You need to have an origin brush as part of this entity. -Pendulums always swing north / south on unrotated models.  Add an angles field to the model to allow rotation in other directions. -Pendulum frequency is a physical constant based on the length of the beam and gravity. -"model2"  .md3 model to also draw -"speed"   the number of degrees each way the pendulum swings, (30 default) -"phase"   the 0.0 to 1.0 offset in the cycle to start at -"dmg"   damage to inflict when blocked (2 default) -"color"   constantLight color -"light"   constantLight radius -*/ -void SP_func_pendulum( gentity_t *ent ) -{ -  float freq; -  float length; -  float phase; -  float speed; - -  G_SpawnFloat( "speed", "30", &speed ); -  G_SpawnInt( "dmg", "2", &ent->damage ); -  G_SpawnFloat( "phase", "0", &phase ); - -  trap_SetBrushModel( ent, ent->model ); - -  // find pendulum length -  length = fabs( ent->r.mins[ 2 ] ); - -  if( length < 8 ) -    length = 8; - -  freq = 1 / ( M_PI * 2 ) * sqrt( g_gravity.value / ( 3 * length ) ); - -  ent->s.pos.trDuration = ( 1000 / freq ); - -  InitMover( ent ); - -  VectorCopy( ent->s.origin, ent->s.pos.trBase ); -  VectorCopy( ent->s.origin, ent->r.currentOrigin ); - -  VectorCopy( ent->s.angles, ent->s.apos.trBase ); - -  ent->s.apos.trDuration = 1000 / freq; -  ent->s.apos.trTime = ent->s.apos.trDuration * phase; -  ent->s.apos.trType = TR_SINE; -  ent->s.apos.trDelta[ 2 ] = speed; -} diff --git a/mod/src/game/g_physics.c b/mod/src/game/g_physics.c deleted file mode 100644 index c6c03f69..00000000 --- a/mod/src/game/g_physics.c +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -/* -================ -G_Bounce - -================ -*/ -static void G_Bounce( gentity_t *ent, trace_t *trace ) -{ -  vec3_t    velocity; -  float     dot; -  int       hitTime; -  float     minNormal; -  qboolean  invert = qfalse; - -  // reflect the velocity on the trace plane -  hitTime = level.previousTime + ( level.time - level.previousTime ) * trace->fraction; -  BG_EvaluateTrajectoryDelta( &ent->s.pos, hitTime, velocity ); -  dot = DotProduct( velocity, trace->plane.normal ); -  VectorMA( velocity, -2*dot, trace->plane.normal, ent->s.pos.trDelta ); - -  if( ent->s.eType == ET_BUILDABLE ) -  { -    minNormal = BG_FindMinNormalForBuildable( ent->s.modelindex ); -    invert = BG_FindInvertNormalForBuildable( ent->s.modelindex ); -  } -  else -    minNormal = 0.707f; - -  // cut the velocity to keep from bouncing forever -  if( ( trace->plane.normal[ 2 ] >= minNormal || -      ( invert && trace->plane.normal[ 2 ] <= -minNormal ) ) && -      trace->entityNum == ENTITYNUM_WORLD ) -    VectorScale( ent->s.pos.trDelta, ent->physicsBounce, ent->s.pos.trDelta ); -  else -    VectorScale( ent->s.pos.trDelta, 0.3f, ent->s.pos.trDelta ); - -  if( VectorLength( ent->s.pos.trDelta ) < 10 ) -  { -    VectorMA( trace->endpos, 0.5, trace->plane.normal, trace->endpos ); // make sure it is off ground -    SnapVector( trace->endpos ); -    G_SetOrigin( ent, trace->endpos ); -    ent->s.groundEntityNum = trace->entityNum; -    VectorCopy( trace->plane.normal, ent->s.origin2 ); -    VectorSet( ent->s.pos.trDelta, 0.0f, 0.0f, 0.0f ); -    return; -  } - -  VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase ); -  VectorAdd( ent->r.currentOrigin, trace->plane.normal, ent->r.currentOrigin); -  ent->s.pos.trTime = level.time; -} - -#define PHYSICS_TIME 200 - -/* -================ -G_Physics - -================ -*/ -void G_Physics( gentity_t *ent, int msec ) -{ -  vec3_t    origin; -  trace_t   tr; -  int     contents; -  int     mask; - -  // if groundentity has been set to -1, it may have been pushed off an edge -  if( ent->s.groundEntityNum == -1 ) -  { -    if( ent->s.eType == ET_BUILDABLE ) -    { -      if( ent->s.pos.trType != BG_FindTrajectoryForBuildable( ent->s.modelindex ) ) -      { -        ent->s.pos.trType = BG_FindTrajectoryForBuildable( ent->s.modelindex ); -        ent->s.pos.trTime = level.time; -      } -    } -    else if( ent->s.pos.trType != TR_GRAVITY ) -    { -      ent->s.pos.trType = TR_GRAVITY; -      ent->s.pos.trTime = level.time; -    } -  } - -  // trace a line from the previous position to the current position -  if( ent->clipmask ) -    mask = ent->clipmask; -  else -    mask = MASK_PLAYERSOLID & ~CONTENTS_BODY;//MASK_SOLID; - -  if( ent->s.pos.trType == TR_STATIONARY ) -  { -    // check think function -    G_RunThink( ent ); - -    //check floor infrequently -    if( ent->nextPhysicsTime < level.time ) -    { -      VectorCopy( ent->r.currentOrigin, origin ); - -      VectorMA( origin, -2.0f, ent->s.origin2, origin ); - -      trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, ent->s.number, mask ); - -      if( tr.fraction == 1.0f ) -        ent->s.groundEntityNum = -1; - -      ent->nextPhysicsTime = level.time + PHYSICS_TIME; -    } - -    return; -  } - -  // get current position -  BG_EvaluateTrajectory( &ent->s.pos, level.time, origin ); - -  trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, ent->s.number, mask ); - -  VectorCopy( tr.endpos, ent->r.currentOrigin ); - -  if( tr.startsolid ) -    tr.fraction = 0; - -  trap_LinkEntity( ent ); // FIXME: avoid this for stationary? - -  // check think function -  G_RunThink( ent ); - -  if( tr.fraction == 1.0f ) -    return; - -  // if it is in a nodrop volume, remove it -  contents = trap_PointContents( ent->r.currentOrigin, -1 ); -  if( contents & CONTENTS_NODROP ) -  { -    G_FreeEntity( ent ); -    return; -  } - -  G_Bounce( ent, &tr ); -} - diff --git a/mod/src/game/g_ptr.c b/mod/src/game/g_ptr.c deleted file mode 100644 index f597a196..00000000 --- a/mod/src/game/g_ptr.c +++ /dev/null @@ -1,167 +0,0 @@ -// g_ptr.c -- post timeout restoration handling - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -static connectionRecord_t connections[ MAX_CLIENTS ]; - -/* -=============== -G_CheckForUniquePTRC - -Callback to detect ptrc clashes -=============== -*/ -static qboolean G_CheckForUniquePTRC( int code ) -{ -  int i; - -  if( code == 0 ) -    return qfalse; - -  for( i = 0; i < MAX_CLIENTS; i++ ) -  { -    if( connections[ i ].ptrCode == code ) -      return qfalse; -  } - -  return qtrue; -} - -/* -=============== -G_UpdatePTRConnection - -Update the data in a connection record -=============== -*/ -void G_UpdatePTRConnection( gclient_t *client ) -{ -  if( client && client->pers.connection ) -  { -    client->pers.connection->clientTeam = client->ps.stats[ STAT_PTEAM ]; -    client->pers.connection->clientCredit = client->ps.persistant[ PERS_CREDIT ]; -  } -} - -/* -=============== -G_GenerateNewConnection - -Generates a new connection -=============== -*/ -connectionRecord_t *G_GenerateNewConnection( gclient_t *client ) -{ -  int     code = 0; -  int     i; - -  // this should be really random -  srand( trap_Milliseconds( ) ); - -  // there is a very very small possibility that this -  // will loop infinitely -  do -  { -    code = rand( ); -  } while( !G_CheckForUniquePTRC( code ) ); - -  for( i = 0; i < MAX_CLIENTS; i++ ) -  { -    //found an unused slot -    if( !connections[ i ].ptrCode ) -    { -      connections[ i ].ptrCode = code; -      connections[ i ].clientNum = client->ps.clientNum; -      client->pers.connection = &connections[ i ]; -      G_UpdatePTRConnection( client ); - -      return &connections[ i ]; -    } -  } - -  return NULL; -} - -/* -=============== -G_VerifyPTRC - -Check a PTR code for validity -=============== -*/ -qboolean G_VerifyPTRC( int code ) -{ -  int i; - -  if( code == 0 ) -    return qfalse; - -  for( i = 0; i < MAX_CLIENTS; i++ ) -  { -    if( connections[ i ].ptrCode == code ) -      return qtrue; -  } - -  return qfalse; -} - -/* -=============== -G_FindConnectionForCode - -Finds a connection for a given code -=============== -*/ -connectionRecord_t *G_FindConnectionForCode( int code ) -{ -  int i; - -  if( code == 0 ) -    return NULL; - -  for( i = 0; i < MAX_CLIENTS; i++ ) -  { -    if( connections[ i ].ptrCode == code ) -      return &connections[ i ]; -  } - -  return NULL; -} - -/* -=============== -G_DeletePTRConnection - -Finds a connection and deletes it -=============== -*/ -void G_DeletePTRConnection( connectionRecord_t *connection ) -{ -  if( connection ) -    memset( connection, 0, sizeof( connectionRecord_t ) ); -} - -/* -=============== -G_ResetPTRConnections - -Invalidate any existing codes -=============== -*/ -void G_ResetPTRConnections( void ) -{ -  memset( connections, 0, sizeof( connectionRecord_t ) * MAX_CLIENTS ); -} diff --git a/mod/src/game/g_public.h b/mod/src/game/g_public.h deleted file mode 100644 index e5652b79..00000000 --- a/mod/src/game/g_public.h +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -// g_public.h -- game module information visible to server - -#define GAME_API_VERSION  8 - -// entity->svFlags -// the server does not know how to interpret most of the values -// in entityStates (level eType), so the game must explicitly flag -// special server behaviors -#define SVF_NOCLIENT            0x00000001  // don't send entity to clients, even if it has effects - -// TTimo -// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=551 -#define SVF_CLIENTMASK 0x00000002 - -#define SVF_BOT                 0x00000008 -#define SVF_BROADCAST           0x00000020  // send to all connected clients -#define SVF_PORTAL              0x00000040  // merge a second pvs at origin2 into snapshots -#define SVF_USE_CURRENT_ORIGIN  0x00000080  // entity->r.currentOrigin instead of entity->s.origin -                      // for link position (missiles and movers) -#define SVF_SINGLECLIENT    0x00000100  // only send to a single client (entityShared_t->singleClient) -#define SVF_NOSERVERINFO    0x00000200  // don't send CS_SERVERINFO updates to this client -                      // so that it can be updated for ping tools without -                      // lagging clients -#define SVF_CAPSULE        0x00000400  // use capsule for collision detection instead of bbox -#define SVF_NOTSINGLECLIENT    0x00000800  // send entity to everyone but one client -                      // (entityShared_t->singleClient) - -//=============================================================== - - -typedef struct { -  entityState_t s;        // communicated by server to clients - -  qboolean  linked;       // qfalse if not in any good cluster -  int     linkcount; - -  int     svFlags;      // SVF_NOCLIENT, SVF_BROADCAST, etc -  int     singleClient;   // only send to this client when SVF_SINGLECLIENT is set - -  qboolean  bmodel;       // if false, assume an explicit mins / maxs bounding box -                  // only set by trap_SetBrushModel -  vec3_t    mins, maxs; -  int     contents;     // CONTENTS_TRIGGER, CONTENTS_SOLID, CONTENTS_BODY, etc -                  // a non-solid entity should set to 0 - -  vec3_t    absmin, absmax;   // derived from mins/maxs and origin + rotation - -  // currentOrigin will be used for all collision detection and world linking. -  // it will not necessarily be the same as the trajectory evaluation for the current -  // time, because each entity must be moved one at a time after time is advanced -  // to avoid simultanious collision issues -  vec3_t    currentOrigin; -  vec3_t    currentAngles; - -  // when a trace call is made and passEntityNum != ENTITYNUM_NONE, -  // an ent will be excluded from testing if: -  // ent->s.number == passEntityNum (don't interact with self) -  // ent->s.ownerNum = passEntityNum  (don't interact with your own missiles) -  // entity[ent->s.ownerNum].ownerNum = passEntityNum (don't interact with other missiles from owner) -  int     ownerNum; -} entityShared_t; - - - -// the server looks at a sharedEntity, which is the start of the game's gentity_t structure -typedef struct { -  entityState_t s;        // communicated by server to clients -  entityShared_t  r;        // shared by both the server system and game -} sharedEntity_t; - - - -//=============================================================== - -// -// system traps provided by the main engine -// -typedef enum { -  //============== general Quake services ================== - -  G_PRINT,    // ( const char *string ); -  // print message on the local console - -  G_ERROR,    // ( const char *string ); -  // abort the game - -  G_MILLISECONDS, // ( void ); -  // get current time for profiling reasons -  // this should NOT be used for any game related tasks, -  // because it is not journaled - -  // console variable interaction -  G_CVAR_REGISTER,  // ( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags ); -  G_CVAR_UPDATE,  // ( vmCvar_t *vmCvar ); -  G_CVAR_SET,   // ( const char *var_name, const char *value ); -  G_CVAR_VARIABLE_INTEGER_VALUE,  // ( const char *var_name ); - -  G_CVAR_VARIABLE_STRING_BUFFER,  // ( const char *var_name, char *buffer, int bufsize ); - -  G_ARGC,     // ( void ); -  // ClientCommand and ServerCommand parameter access - -  G_ARGV,     // ( int n, char *buffer, int bufferLength ); - -  G_FS_FOPEN_FILE,  // ( const char *qpath, fileHandle_t *file, fsMode_t mode ); -  G_FS_READ,    // ( void *buffer, int len, fileHandle_t f ); -  G_FS_WRITE,   // ( const void *buffer, int len, fileHandle_t f ); -  G_FS_FCLOSE_FILE,   // ( fileHandle_t f ); - -  G_SEND_CONSOLE_COMMAND, // ( const char *text ); -  // add commands to the console as if they were typed in -  // for map changing, etc - - -  //=========== server specific functionality ============= - -  G_LOCATE_GAME_DATA,   // ( gentity_t *gEnts, int numGEntities, int sizeofGEntity_t, -  //              playerState_t *clients, int sizeofGameClient ); -  // the game needs to let the server system know where and how big the gentities -  // are, so it can look at them directly without going through an interface - -  G_DROP_CLIENT,    // ( int clientNum, const char *reason ); -  // kick a client off the server with a message - -  G_SEND_SERVER_COMMAND,  // ( int clientNum, const char *fmt, ... ); -  // reliably sends a command string to be interpreted by the given -  // client.  If clientNum is -1, it will be sent to all clients - -  G_SET_CONFIGSTRING, // ( int num, const char *string ); -  // config strings hold all the index strings, and various other information -  // that is reliably communicated to all clients -  // All of the current configstrings are sent to clients when -  // they connect, and changes are sent to all connected clients. -  // All confgstrings are cleared at each level start. - -  G_GET_CONFIGSTRING, // ( int num, char *buffer, int bufferSize ); - -  G_GET_USERINFO,   // ( int num, char *buffer, int bufferSize ); -  // userinfo strings are maintained by the server system, so they -  // are persistant across level loads, while all other game visible -  // data is completely reset - -  G_SET_USERINFO,   // ( int num, const char *buffer ); - -  G_GET_SERVERINFO, // ( char *buffer, int bufferSize ); -  // the serverinfo info string has all the cvars visible to server browsers - -  G_SET_BRUSH_MODEL,  // ( gentity_t *ent, const char *name ); -  // sets mins and maxs based on the brushmodel name - -  G_TRACE,  // ( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask ); -  // collision detection against all linked entities - -  G_POINT_CONTENTS, // ( const vec3_t point, int passEntityNum ); -  // point contents against all linked entities - -  G_IN_PVS,     // ( const vec3_t p1, const vec3_t p2 ); - -  G_IN_PVS_IGNORE_PORTALS,  // ( const vec3_t p1, const vec3_t p2 ); - -  G_ADJUST_AREA_PORTAL_STATE, // ( gentity_t *ent, qboolean open ); - -  G_AREAS_CONNECTED,  // ( int area1, int area2 ); - -  G_LINKENTITY,   // ( gentity_t *ent ); -  // an entity will never be sent to a client or used for collision -  // if it is not passed to linkentity.  If the size, position, or -  // solidity changes, it must be relinked. - -  G_UNLINKENTITY,   // ( gentity_t *ent ); -  // call before removing an interactive entity - -  G_ENTITIES_IN_BOX,  // ( const vec3_t mins, const vec3_t maxs, gentity_t **list, int maxcount ); -  // EntitiesInBox will return brush models based on their bounding box, -  // so exact determination must still be done with EntityContact - -  G_ENTITY_CONTACT, // ( const vec3_t mins, const vec3_t maxs, const gentity_t *ent ); -  // perform an exact check against inline brush models of non-square shape - -  // access for bots to get and free a server client (FIXME?) -  G_BOT_ALLOCATE_CLIENT,  // ( void ); - -  G_BOT_FREE_CLIENT,  // ( int clientNum ); - -  G_GET_USERCMD,  // ( int clientNum, usercmd_t *cmd ) - -  G_GET_ENTITY_TOKEN, // qboolean ( char *buffer, int bufferSize ) -  // Retrieves the next string token from the entity spawn text, returning -  // false when all tokens have been parsed. -  // This should only be done at GAME_INIT time. - -  G_FS_GETFILELIST, -  G_DEBUG_POLYGON_CREATE, -  G_DEBUG_POLYGON_DELETE, -  G_REAL_TIME, -  G_SNAPVECTOR, - -  G_TRACECAPSULE, // ( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask ); -  G_ENTITY_CONTACTCAPSULE,  // ( const vec3_t mins, const vec3_t maxs, const gentity_t *ent ); - -  // 1.32 -  G_FS_SEEK, - -  BOTLIB_SETUP = 200,       // ( void ); -  BOTLIB_SHUTDOWN,        // ( void ); -  BOTLIB_LIBVAR_SET, -  BOTLIB_LIBVAR_GET, -  BOTLIB_PC_ADD_GLOBAL_DEFINE, -  BOTLIB_START_FRAME, -  BOTLIB_LOAD_MAP, -  BOTLIB_UPDATENTITY, -  BOTLIB_TEST, - -  BOTLIB_GET_SNAPSHOT_ENTITY,   // ( int client, int ent ); -  BOTLIB_GET_CONSOLE_MESSAGE,   // ( int client, char *message, int size ); -  BOTLIB_USER_COMMAND,      // ( int client, usercmd_t *ucmd ); - -  BOTLIB_AAS_ENABLE_ROUTING_AREA = 300, -  BOTLIB_AAS_BBOX_AREAS, -  BOTLIB_AAS_AREA_INFO, -  BOTLIB_AAS_ENTITY_INFO, - -  BOTLIB_AAS_INITIALIZED, -  BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX, -  BOTLIB_AAS_TIME, - -  BOTLIB_AAS_POINT_AREA_NUM, -  BOTLIB_AAS_TRACE_AREAS, - -  BOTLIB_AAS_POINT_CONTENTS, -  BOTLIB_AAS_NEXT_BSP_ENTITY, -  BOTLIB_AAS_VALUE_FOR_BSP_EPAIR_KEY, -  BOTLIB_AAS_VECTOR_FOR_BSP_EPAIR_KEY, -  BOTLIB_AAS_FLOAT_FOR_BSP_EPAIR_KEY, -  BOTLIB_AAS_INT_FOR_BSP_EPAIR_KEY, - -  BOTLIB_AAS_AREA_REACHABILITY, - -  BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA, - -  BOTLIB_AAS_SWIMMING, -  BOTLIB_AAS_PREDICT_CLIENT_MOVEMENT, - - - -  BOTLIB_EA_SAY = 400, -  BOTLIB_EA_SAY_TEAM, -  BOTLIB_EA_COMMAND, - -  BOTLIB_EA_ACTION, -  BOTLIB_EA_GESTURE, -  BOTLIB_EA_TALK, -  BOTLIB_EA_ATTACK, -  BOTLIB_EA_USE, -  BOTLIB_EA_RESPAWN, -  BOTLIB_EA_CROUCH, -  BOTLIB_EA_MOVE_UP, -  BOTLIB_EA_MOVE_DOWN, -  BOTLIB_EA_MOVE_FORWARD, -  BOTLIB_EA_MOVE_BACK, -  BOTLIB_EA_MOVE_LEFT, -  BOTLIB_EA_MOVE_RIGHT, - -  BOTLIB_EA_SELECT_WEAPON, -  BOTLIB_EA_JUMP, -  BOTLIB_EA_DELAYED_JUMP, -  BOTLIB_EA_MOVE, -  BOTLIB_EA_VIEW, - -  BOTLIB_EA_END_REGULAR, -  BOTLIB_EA_GET_INPUT, -  BOTLIB_EA_RESET_INPUT, - - - -  BOTLIB_AI_LOAD_CHARACTER = 500, -  BOTLIB_AI_FREE_CHARACTER, -  BOTLIB_AI_CHARACTERISTIC_FLOAT, -  BOTLIB_AI_CHARACTERISTIC_BFLOAT, -  BOTLIB_AI_CHARACTERISTIC_INTEGER, -  BOTLIB_AI_CHARACTERISTIC_BINTEGER, -  BOTLIB_AI_CHARACTERISTIC_STRING, - -  BOTLIB_AI_ALLOC_CHAT_STATE, -  BOTLIB_AI_FREE_CHAT_STATE, -  BOTLIB_AI_QUEUE_CONSOLE_MESSAGE, -  BOTLIB_AI_REMOVE_CONSOLE_MESSAGE, -  BOTLIB_AI_NEXT_CONSOLE_MESSAGE, -  BOTLIB_AI_NUM_CONSOLE_MESSAGE, -  BOTLIB_AI_INITIAL_CHAT, -  BOTLIB_AI_REPLY_CHAT, -  BOTLIB_AI_CHAT_LENGTH, -  BOTLIB_AI_ENTER_CHAT, -  BOTLIB_AI_STRING_CONTAINS, -  BOTLIB_AI_FIND_MATCH, -  BOTLIB_AI_MATCH_VARIABLE, -  BOTLIB_AI_UNIFY_WHITE_SPACES, -  BOTLIB_AI_REPLACE_SYNONYMS, -  BOTLIB_AI_LOAD_CHAT_FILE, -  BOTLIB_AI_SET_CHAT_GENDER, -  BOTLIB_AI_SET_CHAT_NAME, - -  BOTLIB_AI_RESET_GOAL_STATE, -  BOTLIB_AI_RESET_AVOID_GOALS, -  BOTLIB_AI_PUSH_GOAL, -  BOTLIB_AI_POP_GOAL, -  BOTLIB_AI_EMPTY_GOAL_STACK, -  BOTLIB_AI_DUMP_AVOID_GOALS, -  BOTLIB_AI_DUMP_GOAL_STACK, -  BOTLIB_AI_GOAL_NAME, -  BOTLIB_AI_GET_TOP_GOAL, -  BOTLIB_AI_GET_SECOND_GOAL, -  BOTLIB_AI_CHOOSE_LTG_ITEM, -  BOTLIB_AI_CHOOSE_NBG_ITEM, -  BOTLIB_AI_TOUCHING_GOAL, -  BOTLIB_AI_ITEM_GOAL_IN_VIS_BUT_NOT_VISIBLE, -  BOTLIB_AI_GET_LEVEL_ITEM_GOAL, -  BOTLIB_AI_AVOID_GOAL_TIME, -  BOTLIB_AI_INIT_LEVEL_ITEMS, -  BOTLIB_AI_UPDATE_ENTITY_ITEMS, -  BOTLIB_AI_LOAD_ITEM_WEIGHTS, -  BOTLIB_AI_FREE_ITEM_WEIGHTS, -  BOTLIB_AI_SAVE_GOAL_FUZZY_LOGIC, -  BOTLIB_AI_ALLOC_GOAL_STATE, -  BOTLIB_AI_FREE_GOAL_STATE, - -  BOTLIB_AI_RESET_MOVE_STATE, -  BOTLIB_AI_MOVE_TO_GOAL, -  BOTLIB_AI_MOVE_IN_DIRECTION, -  BOTLIB_AI_RESET_AVOID_REACH, -  BOTLIB_AI_RESET_LAST_AVOID_REACH, -  BOTLIB_AI_REACHABILITY_AREA, -  BOTLIB_AI_MOVEMENT_VIEW_TARGET, -  BOTLIB_AI_ALLOC_MOVE_STATE, -  BOTLIB_AI_FREE_MOVE_STATE, -  BOTLIB_AI_INIT_MOVE_STATE, - -  BOTLIB_AI_CHOOSE_BEST_FIGHT_WEAPON, -  BOTLIB_AI_GET_WEAPON_INFO, -  BOTLIB_AI_LOAD_WEAPON_WEIGHTS, -  BOTLIB_AI_ALLOC_WEAPON_STATE, -  BOTLIB_AI_FREE_WEAPON_STATE, -  BOTLIB_AI_RESET_WEAPON_STATE, - -  BOTLIB_AI_GENETIC_PARENTS_AND_CHILD_SELECTION, -  BOTLIB_AI_INTERBREED_GOAL_FUZZY_LOGIC, -  BOTLIB_AI_MUTATE_GOAL_FUZZY_LOGIC, -  BOTLIB_AI_GET_NEXT_CAMP_SPOT_GOAL, -  BOTLIB_AI_GET_MAP_LOCATION_GOAL, -  BOTLIB_AI_NUM_INITIAL_CHATS, -  BOTLIB_AI_GET_CHAT_MESSAGE, -  BOTLIB_AI_REMOVE_FROM_AVOID_GOALS, -  BOTLIB_AI_PREDICT_VISIBLE_POSITION, - -  BOTLIB_AI_SET_AVOID_GOAL_TIME, -  BOTLIB_AI_ADD_AVOID_SPOT, -  BOTLIB_AAS_ALTERNATIVE_ROUTE_GOAL, -  BOTLIB_AAS_PREDICT_ROUTE, -  BOTLIB_AAS_POINT_REACHABILITY_AREA_INDEX, - -  BOTLIB_PC_LOAD_SOURCE, -  BOTLIB_PC_FREE_SOURCE, -  BOTLIB_PC_READ_TOKEN, -  BOTLIB_PC_SOURCE_FILE_AND_LINE -} gameImport_t; - - -// -// functions exported by the game subsystem -// -typedef enum { -  GAME_INIT,  // ( int levelTime, int randomSeed, int restart ); -  // init and shutdown will be called every single level -  // The game should call G_GET_ENTITY_TOKEN to parse through all the -  // entity configuration text and spawn gentities. - -  GAME_SHUTDOWN,  // (void); - -  GAME_CLIENT_CONNECT,  // ( int clientNum, qboolean firstTime, qboolean isBot ); -  // return NULL if the client is allowed to connect, otherwise return -  // a text string with the reason for denial - -  GAME_CLIENT_BEGIN,        // ( int clientNum ); - -  GAME_CLIENT_USERINFO_CHANGED, // ( int clientNum ); - -  GAME_CLIENT_DISCONNECT,     // ( int clientNum ); - -  GAME_CLIENT_COMMAND,      // ( int clientNum ); - -  GAME_CLIENT_THINK,        // ( int clientNum ); - -  GAME_RUN_FRAME,         // ( int levelTime ); - -  GAME_CONSOLE_COMMAND,     // ( void ); -  // ConsoleCommand will be called when a command has been issued -  // that is not recognized as a builtin function. -  // The game can issue trap_argc() / trap_argv() commands to get the command -  // and parameters.  Return qfalse if the game doesn't recognize it as a command. - -  BOTAI_START_FRAME       // ( int time ); -} gameExport_t; - diff --git a/mod/src/game/g_session.c b/mod/src/game/g_session.c deleted file mode 100644 index 1dcb8883..00000000 --- a/mod/src/game/g_session.c +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - - -/* -======================================================================= - -  SESSION DATA - -Session data is the only data that stays persistant across level loads -and tournament restarts. -======================================================================= -*/ - -/* -================ -G_WriteClientSessionData - -Called on game shutdown -================ -*/ -void G_WriteClientSessionData( gclient_t *client ) -{ -  const char  *s; -  const char  *var; - -  s = va( "%i %i %i %i %i %i %i", -    client->sess.sessionTeam, -    client->sess.spectatorTime, -    client->sess.spectatorState, -    client->sess.spectatorClient, -    client->sess.wins, -    client->sess.losses, -    client->sess.teamLeader -    ); - -  var = va( "session%i", client - level.clients ); - -  trap_Cvar_Set( var, s ); -} - -/* -================ -G_ReadSessionData - -Called on a reconnect -================ -*/ -void G_ReadSessionData( gclient_t *client ) -{ -  char  s[ MAX_STRING_CHARS ]; -  const char  *var; - -  // bk001205 - format -  int teamLeader; -  int spectatorState; -  int sessionTeam; - -  var = va( "session%i", client - level.clients ); -  trap_Cvar_VariableStringBuffer( var, s, sizeof(s) ); - -  sscanf( s, "%i %i %i %i %i %i %i", -    &sessionTeam, -    &client->sess.spectatorTime, -    &spectatorState, -    &client->sess.spectatorClient, -    &client->sess.wins, -    &client->sess.losses, -    &teamLeader -    ); - -  // bk001205 - format issues -  client->sess.sessionTeam = (team_t)sessionTeam; -  client->sess.spectatorState = (spectatorState_t)spectatorState; -  client->sess.teamLeader = (qboolean)teamLeader; -} - - -/* -================ -G_InitSessionData - -Called on a first-time connect -================ -*/ -void G_InitSessionData( gclient_t *client, char *userinfo ) -{ -  clientSession_t  *sess; -  const char      *value; - -  sess = &client->sess; - -  // initial team determination -  value = Info_ValueForKey( userinfo, "team" ); -  if( value[ 0 ] == 's' ) -  { -    // a willing spectator, not a waiting-in-line -    sess->sessionTeam = TEAM_SPECTATOR; -  } -  else -  { -    if( g_maxGameClients.integer > 0 && -      level.numNonSpectatorClients >= g_maxGameClients.integer ) -      sess->sessionTeam = TEAM_SPECTATOR; -    else -      sess->sessionTeam = TEAM_FREE; -  } - -  sess->spectatorState = SPECTATOR_FREE; -  sess->spectatorTime = level.time; -  sess->spectatorClient = -1; - -  G_WriteClientSessionData( client ); -} - - -/* -================== -G_WriteSessionData - -================== -*/ -void G_WriteSessionData( void ) -{ -  int    i; - -  //TA: ? -  trap_Cvar_Set( "session", va( "%i", 0 ) ); - -  for( i = 0 ; i < level.maxclients ; i++ ) -  { -    if( level.clients[ i ].pers.connected == CON_CONNECTED ) -      G_WriteClientSessionData( &level.clients[ i ] ); -  } -} diff --git a/mod/src/game/g_spawn.c b/mod/src/game/g_spawn.c deleted file mode 100644 index c8481d9d..00000000 --- a/mod/src/game/g_spawn.c +++ /dev/null @@ -1,701 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -qboolean G_SpawnString( const char *key, const char *defaultString, char **out ) -{ -  int   i; - -  if( !level.spawning ) -  { -    *out = (char *)defaultString; -//    G_Error( "G_SpawnString() called while not spawning" ); -  } - -  for( i = 0; i < level.numSpawnVars; i++ ) -  { -    if( !Q_stricmp( key, level.spawnVars[ i ][ 0 ] ) ) -    { -      *out = level.spawnVars[ i ][ 1 ]; -      return qtrue; -    } -  } - -  *out = (char *)defaultString; -  return qfalse; -} - -qboolean  G_SpawnFloat( const char *key, const char *defaultString, float *out ) -{ -  char    *s; -  qboolean  present; - -  present = G_SpawnString( key, defaultString, &s ); -  *out = atof( s ); -  return present; -} - -qboolean G_SpawnInt( const char *key, const char *defaultString, int *out ) -{ -  char      *s; -  qboolean  present; - -  present = G_SpawnString( key, defaultString, &s ); -  *out = atoi( s ); -  return present; -} - -qboolean  G_SpawnVector( const char *key, const char *defaultString, float *out ) -{ -  char    *s; -  qboolean  present; - -  present = G_SpawnString( key, defaultString, &s ); -  sscanf( s, "%f %f %f", &out[ 0 ], &out[ 1 ], &out[ 2 ] ); -  return present; -} - -qboolean  G_SpawnVector4( const char *key, const char *defaultString, float *out ) -{ -  char    *s; -  qboolean  present; - -  present = G_SpawnString( key, defaultString, &s ); -  sscanf( s, "%f %f %f %f", &out[ 0 ], &out[ 1 ], &out[ 2 ], &out[ 3 ] ); -  return present; -} - - - -// -// fields are needed for spawning from the entity string -// -typedef enum -{ -  F_INT, -  F_FLOAT, -  F_LSTRING,      // string on disk, pointer in memory, TAG_LEVEL -  F_GSTRING,      // string on disk, pointer in memory, TAG_GAME -  F_VECTOR, -  F_VECTOR4,    //TA -  F_ANGLEHACK, -  F_ENTITY,     // index on disk, pointer in memory -  F_ITEM,       // index on disk, pointer in memory -  F_CLIENT,     // index on disk, pointer in memory -  F_IGNORE -} fieldtype_t; - -typedef struct -{ -  char  *name; -  int   ofs; -  fieldtype_t type; -  int   flags; -} field_t; - -field_t fields[ ] = -{ -  {"classname", FOFS(classname), F_LSTRING}, -  {"origin", FOFS(s.origin), F_VECTOR}, -  {"model", FOFS(model), F_LSTRING}, -  {"model2", FOFS(model2), F_LSTRING}, -  {"spawnflags", FOFS(spawnflags), F_INT}, -  {"speed", FOFS(speed), F_FLOAT}, -  {"target", FOFS(target), F_LSTRING}, -  {"targetname", FOFS(targetname), F_LSTRING}, -  {"message", FOFS(message), F_LSTRING}, -  {"team", FOFS(team), F_LSTRING}, -  {"wait", FOFS(wait), F_FLOAT}, -  {"random", FOFS(random), F_FLOAT}, -  {"count", FOFS(count), F_INT}, -  {"health", FOFS(health), F_INT}, -  {"light", 0, F_IGNORE}, -  {"dmg", FOFS(damage), F_INT}, -  {"angles", FOFS(s.angles), F_VECTOR}, -  {"angle", FOFS(s.angles), F_ANGLEHACK}, -  //TA -  {"bounce", FOFS(physicsBounce), F_FLOAT}, -  {"alpha", FOFS(pos1), F_VECTOR}, -  {"radius", FOFS(pos2), F_VECTOR}, -  {"acceleration", FOFS(acceleration), F_VECTOR}, -  {"animation", FOFS(animation), F_VECTOR4}, -  {"rotatorAngle", FOFS(rotatorAngle), F_FLOAT}, -  //TA -  {"targetShaderName", FOFS(targetShaderName), F_LSTRING}, -  {"targetShaderNewName", FOFS(targetShaderNewName), F_LSTRING}, - -  {NULL} -}; - - -typedef struct -{ -  char  *name; -  void  (*spawn)(gentity_t *ent); -} spawn_t; - -void SP_info_player_start( gentity_t *ent ); -void SP_info_player_deathmatch( gentity_t *ent ); -void SP_info_player_intermission( gentity_t *ent ); - -//TA: extra bits -void SP_info_alien_intermission( gentity_t *ent ); -void SP_info_human_intermission( gentity_t *ent ); - -void SP_info_firstplace( gentity_t *ent ); -void SP_info_secondplace( gentity_t *ent ); -void SP_info_thirdplace( gentity_t *ent ); -void SP_info_podium( gentity_t *ent ); - -void SP_func_plat( gentity_t *ent ); -void SP_func_static( gentity_t *ent ); -void SP_func_rotating( gentity_t *ent ); -void SP_func_bobbing( gentity_t *ent ); -void SP_func_pendulum( gentity_t *ent ); -void SP_func_button( gentity_t *ent ); -void SP_func_door( gentity_t *ent ); -void SP_func_door_rotating( gentity_t *ent ); //TA -void SP_func_door_model( gentity_t *ent ); //TA -void SP_func_train( gentity_t *ent ); -void SP_func_timer( gentity_t *self); - -void SP_trigger_always( gentity_t *ent ); -void SP_trigger_multiple( gentity_t *ent ); -void SP_trigger_push( gentity_t *ent ); -void SP_trigger_teleport( gentity_t *ent ); -void SP_trigger_hurt( gentity_t *ent ); -void SP_trigger_stage( gentity_t *ent ); -void SP_trigger_win( gentity_t *ent ); -void SP_trigger_buildable( gentity_t *ent ); -void SP_trigger_class( gentity_t *ent ); -void SP_trigger_equipment( gentity_t *ent ); -void SP_trigger_gravity( gentity_t *ent ); -void SP_trigger_heal( gentity_t *ent ); -void SP_trigger_ammo( gentity_t *ent ); - -void SP_target_delay( gentity_t *ent ); -void SP_target_speaker( gentity_t *ent ); -void SP_target_print( gentity_t *ent ); -void SP_target_character( gentity_t *ent ); -void SP_target_score( gentity_t *ent ); -void SP_target_teleporter( gentity_t *ent ); -void SP_target_relay( gentity_t *ent ); -void SP_target_kill( gentity_t *ent ); -void SP_target_position( gentity_t *ent ); -void SP_target_location( gentity_t *ent ); -void SP_target_push( gentity_t *ent ); -void SP_target_rumble( gentity_t *ent ); -void SP_target_alien_win( gentity_t *ent ); -void SP_target_human_win( gentity_t *ent ); - -void SP_light( gentity_t *self ); -void SP_info_null( gentity_t *self ); -void SP_info_notnull( gentity_t *self ); -void SP_info_camp( gentity_t *self ); -void SP_path_corner( gentity_t *self ); - -void SP_misc_teleporter_dest( gentity_t *self ); -void SP_misc_model( gentity_t *ent ); -void SP_misc_portal_camera( gentity_t *ent ); -void SP_misc_portal_surface( gentity_t *ent ); - -void SP_shooter_rocket( gentity_t *ent ); -void SP_shooter_plasma( gentity_t *ent ); -void SP_shooter_grenade( gentity_t *ent ); - -//TA: -void SP_misc_particle_system( gentity_t *ent ); -void SP_misc_anim_model( gentity_t *ent ); -void SP_misc_light_flare( gentity_t *ent ); - -spawn_t spawns[ ] = -{ -  // info entities don't do anything at all, but provide positional -  // information for things controlled by other processes -  { "info_player_start",        SP_info_player_start }, -  { "info_player_deathmatch",   SP_info_player_deathmatch }, -  { "info_player_intermission", SP_info_player_intermission }, - -  //TA: extra bits -  { "info_alien_intermission",  SP_info_alien_intermission }, -  { "info_human_intermission",  SP_info_human_intermission }, - -  { "info_null",                SP_info_null }, -  { "info_notnull",             SP_info_notnull },    // use target_position instead - -  { "func_plat",                SP_func_plat }, -  { "func_button",              SP_func_button }, -  { "func_door",                SP_func_door }, -  { "func_door_rotating",       SP_func_door_rotating }, //TA -  { "func_door_model",          SP_func_door_model }, //TA -  { "func_static",              SP_func_static }, -  { "func_rotating",            SP_func_rotating }, -  { "func_bobbing",             SP_func_bobbing }, -  { "func_pendulum",            SP_func_pendulum }, -  { "func_train",               SP_func_train }, -  { "func_group",               SP_info_null }, -  { "func_timer",               SP_func_timer },      // rename trigger_timer? - -  // Triggers are brush objects that cause an effect when contacted -  // by a living player, usually involving firing targets. -  // While almost everything could be done with -  // a single trigger class and different targets, triggered effects -  // could not be client side predicted (push and teleport). -  { "trigger_always",           SP_trigger_always }, -  { "trigger_multiple",         SP_trigger_multiple }, -  { "trigger_push",             SP_trigger_push }, -  { "trigger_teleport",         SP_trigger_teleport }, -  { "trigger_hurt",             SP_trigger_hurt }, -  { "trigger_stage",            SP_trigger_stage }, -  { "trigger_win",              SP_trigger_win }, -  { "trigger_buildable",        SP_trigger_buildable }, -  { "trigger_class",            SP_trigger_class }, -  { "trigger_equipment",        SP_trigger_equipment }, -  { "trigger_gravity",          SP_trigger_gravity }, -  { "trigger_heal",             SP_trigger_heal }, -  { "trigger_ammo",             SP_trigger_ammo }, - -  // targets perform no action by themselves, but must be triggered -  // by another entity -  { "target_delay",             SP_target_delay }, -  { "target_speaker",           SP_target_speaker }, -  { "target_print",             SP_target_print }, -  { "target_score",             SP_target_score }, -  { "target_teleporter",        SP_target_teleporter }, -  { "target_relay",             SP_target_relay }, -  { "target_kill",              SP_target_kill }, -  { "target_position",          SP_target_position }, -  { "target_location",          SP_target_location }, -  { "target_push",              SP_target_push }, -  { "target_rumble",            SP_target_rumble }, -  { "target_alien_win",         SP_target_alien_win }, -  { "target_human_win",         SP_target_human_win }, - -  { "light",                    SP_light }, -  { "path_corner",              SP_path_corner }, - -  { "misc_teleporter_dest",     SP_misc_teleporter_dest }, -  { "misc_model",               SP_misc_model }, -  { "misc_portal_surface",      SP_misc_portal_surface }, -  { "misc_portal_camera",       SP_misc_portal_camera }, - -  { "misc_particle_system",     SP_misc_particle_system }, -  { "misc_anim_model",          SP_misc_anim_model }, -  { "misc_light_flare",         SP_misc_light_flare }, - -  { NULL, 0 } -}; - -/* -=============== -G_CallSpawn - -Finds the spawn function for the entity and calls it, -returning qfalse if not found -=============== -*/ -qboolean G_CallSpawn( gentity_t *ent ) -{ -  spawn_t     *s; -  buildable_t buildable; - -  if( !ent->classname ) -  { -    G_Printf( "G_CallSpawn: NULL classname\n" ); -    return qfalse; -  } - -  //check buildable spawn functions -  if( ( buildable = BG_FindBuildNumForEntityName( ent->classname ) ) != BA_NONE ) -  { -    if( buildable == BA_A_SPAWN || buildable == BA_H_SPAWN ) -    { -      ent->s.angles[ YAW ] += 180.0f; -      AngleNormalize360( ent->s.angles[ YAW ] ); -    } - -    G_SpawnBuildable( ent, buildable ); -    return qtrue; -  } - -  // check normal spawn functions -  for( s = spawns; s->name; s++ ) -  { -    if( !strcmp( s->name, ent->classname ) ) -    { -      // found it -      s->spawn( ent ); -      return qtrue; -    } -  } - -  G_Printf( "%s doesn't have a spawn function\n", ent->classname ); -  return qfalse; -} - -/* -============= -G_NewString - -Builds a copy of the string, translating \n to real linefeeds -so message texts can be multi-line -============= -*/ -char *G_NewString( const char *string ) -{ -  char  *newb, *new_p; -  int   i,l; - -  l = strlen( string ) + 1; - -  newb = G_Alloc( l ); - -  new_p = newb; - -  // turn \n into a real linefeed -  for( i = 0 ; i < l ; i++ ) -  { -    if( string[ i ] == '\\' && i < l - 1 ) -    { -      i++; -      if( string[ i ] == 'n' ) -        *new_p++ = '\n'; -      else -        *new_p++ = '\\'; -    } -    else -      *new_p++ = string[ i ]; -  } - -  return newb; -} - - - - -/* -=============== -G_ParseField - -Takes a key/value pair and sets the binary values -in a gentity -=============== -*/ -void G_ParseField( const char *key, const char *value, gentity_t *ent ) -{ -  field_t *f; -  byte    *b; -  float   v; -  vec3_t  vec; -  vec4_t  vec4; - -  for( f = fields; f->name; f++ ) -  { -    if( !Q_stricmp( f->name, key ) ) -    { -      // found it -      b = (byte *)ent; - -      switch( f->type ) -      { -        case F_LSTRING: -          *(char **)( b + f->ofs ) = G_NewString( value ); -          break; - -        case F_VECTOR: -          sscanf( value, "%f %f %f", &vec[ 0 ], &vec[ 1 ], &vec[ 2 ] ); - -          ( (float *)( b + f->ofs ) )[ 0 ] = vec[ 0 ]; -          ( (float *)( b + f->ofs ) )[ 1 ] = vec[ 1 ]; -          ( (float *)( b + f->ofs ) )[ 2 ] = vec[ 2 ]; -          break; - -        case F_VECTOR4: -          sscanf( value, "%f %f %f %f", &vec4[ 0 ], &vec4[ 1 ], &vec4[ 2 ], &vec4[ 3 ] ); - -          ( (float *)( b + f->ofs ) )[ 0 ] = vec4[ 0 ]; -          ( (float *)( b + f->ofs ) )[ 1 ] = vec4[ 1 ]; -          ( (float *)( b + f->ofs ) )[ 2 ] = vec4[ 2 ]; -          ( (float *)( b + f->ofs ) )[ 3 ] = vec4[ 3 ]; -          break; - -        case F_INT: -          *(int *)( b + f->ofs ) = atoi( value ); -          break; - -        case F_FLOAT: -          *(float *)( b + f->ofs ) = atof( value ); -          break; - -        case F_ANGLEHACK: -          v = atof( value ); -          ( (float *)( b + f->ofs ) )[ 0 ] = 0; -          ( (float *)( b + f->ofs ) )[ 1 ] = v; -          ( (float *)( b + f->ofs ) )[ 2 ] = 0; -          break; - -        default: -        case F_IGNORE: -          break; -      } - -      return; -    } -  } -} - - - - -/* -=================== -G_SpawnGEntityFromSpawnVars - -Spawn an entity and fill in all of the level fields from -level.spawnVars[], then call the class specfic spawn function -=================== -*/ -void G_SpawnGEntityFromSpawnVars( void ) -{ -  int         i; -  gentity_t   *ent; - -  // get the next free entity -  ent = G_Spawn( ); - -  for( i = 0 ; i < level.numSpawnVars ; i++ ) -    G_ParseField( level.spawnVars[ i ][ 0 ], level.spawnVars[ i ][ 1 ], ent ); - -  G_SpawnInt( "notq3a", "0", &i ); - -  if( i ) -  { -    G_FreeEntity( ent ); -    return; -  } - -  // move editor origin to pos -  VectorCopy( ent->s.origin, ent->s.pos.trBase ); -  VectorCopy( ent->s.origin, ent->r.currentOrigin ); - -  // if we didn't get a classname, don't bother spawning anything -  if( !G_CallSpawn( ent ) ) -    G_FreeEntity( ent ); -} - - - -/* -==================== -G_AddSpawnVarToken -==================== -*/ -char *G_AddSpawnVarToken( const char *string ) -{ -  int   l; -  char  *dest; - -  l = strlen( string ); -  if( level.numSpawnVarChars + l + 1 > MAX_SPAWN_VARS_CHARS ) -    G_Error( "G_AddSpawnVarToken: MAX_SPAWN_CHARS" ); - -  dest = level.spawnVarChars + level.numSpawnVarChars; -  memcpy( dest, string, l + 1 ); - -  level.numSpawnVarChars += l + 1; - -  return dest; -} - -/* -==================== -G_ParseSpawnVars - -Parses a brace bounded set of key / value pairs out of the -level's entity strings into level.spawnVars[] - -This does not actually spawn an entity. -==================== -*/ -qboolean G_ParseSpawnVars( void ) -{ -  char keyname[ MAX_TOKEN_CHARS ]; -  char com_token[ MAX_TOKEN_CHARS ]; - -  level.numSpawnVars = 0; -  level.numSpawnVarChars = 0; - -  // parse the opening brace -  if( !trap_GetEntityToken( com_token, sizeof( com_token ) ) ) -  { -    // end of spawn string -    return qfalse; -  } - -  if( com_token[ 0 ] != '{' ) -    G_Error( "G_ParseSpawnVars: found %s when expecting {", com_token ); - -  // go through all the key / value pairs -  while( 1 ) -  { -    // parse key -    if( !trap_GetEntityToken( keyname, sizeof( keyname ) ) ) -      G_Error( "G_ParseSpawnVars: EOF without closing brace" ); - -    if( keyname[0] == '}' ) -      break; - -    // parse value -    if( !trap_GetEntityToken( com_token, sizeof( com_token ) ) ) -      G_Error( "G_ParseSpawnVars: EOF without closing brace" ); - -    if( com_token[0] == '}' ) -      G_Error( "G_ParseSpawnVars: closing brace without data" ); - -    if( level.numSpawnVars == MAX_SPAWN_VARS ) -      G_Error( "G_ParseSpawnVars: MAX_SPAWN_VARS" ); - -    level.spawnVars[ level.numSpawnVars ][ 0 ] = G_AddSpawnVarToken( keyname ); -    level.spawnVars[ level.numSpawnVars ][ 1 ] = G_AddSpawnVarToken( com_token ); -    level.numSpawnVars++; -  } - -  return qtrue; -} - - - -/*QUAKED worldspawn (0 0 0) ? - -Every map should have exactly one worldspawn. -"music"   music wav file -"gravity" 800 is default gravity -"message" Text to print during connection process -*/ -void SP_worldspawn( void ) -{ -  char *s; - -  G_SpawnString( "classname", "", &s ); - -  if( Q_stricmp( s, "worldspawn" ) ) -    G_Error( "SP_worldspawn: The first entity isn't 'worldspawn'" ); - -  // make some data visible to connecting client -  trap_SetConfigstring( CS_GAME_VERSION, GAME_VERSION ); - -  trap_SetConfigstring( CS_LEVEL_START_TIME, va( "%i", level.startTime ) ); - -  G_SpawnString( "music", "", &s ); -  trap_SetConfigstring( CS_MUSIC, s ); - -  G_SpawnString( "message", "", &s ); -  trap_SetConfigstring( CS_MESSAGE, s );        // map specific message - -  trap_SetConfigstring( CS_MOTD, g_motd.string );   // message of the day - -  G_SpawnString( "gravity", "800", &s ); -  trap_Cvar_Set( "g_gravity", s ); - -  G_SpawnString( "humanBuildPoints", DEFAULT_HUMAN_BUILDPOINTS, &s ); -  trap_Cvar_Set( "g_humanBuildPoints", s ); - -  G_SpawnString( "humanMaxStage", "2", &s ); -  trap_Cvar_Set( "g_humanMaxStage", s ); - -  G_SpawnString( "humanStage2Threshold", g_humanStage2Threshold.string, &s ); -  trap_Cvar_Set( "g_humanStage2Threshold", s ); - -  G_SpawnString( "humanStage3Threshold", g_humanStage3Threshold.string, &s ); -  trap_Cvar_Set( "g_humanStage3Threshold", s ); - -  G_SpawnString( "alienBuildPoints", DEFAULT_ALIEN_BUILDPOINTS, &s ); -  trap_Cvar_Set( "g_alienBuildPoints", s ); - -  G_SpawnString( "alienMaxStage", "2", &s ); -  trap_Cvar_Set( "g_alienMaxStage", s ); - -  G_SpawnString( "alienStage2Threshold", g_alienStage2Threshold.string, &s ); -  trap_Cvar_Set( "g_alienStage2Threshold", s ); - -  G_SpawnString( "alienStage3Threshold", g_alienStage3Threshold.string, &s ); -  trap_Cvar_Set( "g_alienStage3Threshold", s ); - -  G_SpawnString( "enableDust", "0", &s ); -  trap_Cvar_Set( "g_enableDust", s ); - -  G_SpawnString( "enableBreath", "0", &s ); -  trap_Cvar_Set( "g_enableBreath", s ); - -  G_SpawnString( "disabledEquipment", "", &s ); -  trap_Cvar_Set( "g_disabledEquipment", s ); - -  G_SpawnString( "disabledClasses", "", &s ); -  trap_Cvar_Set( "g_disabledClasses", s ); - -  G_SpawnString( "disabledBuildables", "", &s ); -  trap_Cvar_Set( "g_disabledBuildables", s ); - -  g_entities[ ENTITYNUM_WORLD ].s.number = ENTITYNUM_WORLD; -  g_entities[ ENTITYNUM_WORLD ].classname = "worldspawn"; - -  // see if we want a warmup time -  trap_SetConfigstring( CS_WARMUP, "" ); -  if( g_restarted.integer ) -  { -    trap_Cvar_Set( "g_restarted", "0" ); -    level.warmupTime = 0; -  } -  else if( g_doWarmup.integer ) -  { -    // Turn it on -    level.warmupTime = -1; -    trap_SetConfigstring( CS_WARMUP, va( "%i", level.warmupTime ) ); -    G_LogPrintf( "Warmup:\n" ); -  } - -} - - -/* -============== -G_SpawnEntitiesFromString - -Parses textual entity definitions out of an entstring and spawns gentities. -============== -*/ -void G_SpawnEntitiesFromString( void ) -{ -  // allow calls to G_Spawn*() -  level.spawning = qtrue; -  level.numSpawnVars = 0; - -  // the worldspawn is not an actual entity, but it still -  // has a "spawn" function to perform any global setup -  // needed by a level (setting configstrings or cvars, etc) -  if( !G_ParseSpawnVars( ) ) -    G_Error( "SpawnEntities: no entities" ); - -  SP_worldspawn( ); - -  // parse ents -  while( G_ParseSpawnVars( ) ) -    G_SpawnGEntityFromSpawnVars( ); - -  level.spawning = qfalse;      // any future calls to G_Spawn*() will be errors -} - diff --git a/mod/src/game/g_svcmds.c b/mod/src/game/g_svcmds.c deleted file mode 100644 index efe76991..00000000 --- a/mod/src/game/g_svcmds.c +++ /dev/null @@ -1,581 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -// this file holds commands that can be executed by the server console, but not remote clients - -#include "g_local.h" - - -/* -============================================================================== - -PACKET FILTERING - - -You can add or remove addresses from the filter list with: - -addip <ip> -removeip <ip> - -The ip address is specified in dot format, and you can use '*' to match any value -so you can specify an entire class C network with "addip 192.246.40.*" - -Removeip will only remove an address specified exactly the same way.  You cannot addip a subnet, then removeip a single host. - -listip -Prints the current list of filters. - -g_filterban <0 or 1> - -If 1 (the default), then ip addresses matching the current list will be prohibited from entering the game.  This is the default setting. - -If 0, then only addresses matching the list will be allowed.  This lets you easily set up a private game, or a game that only allows players from your local network. - -TTimo NOTE: for persistence, bans are stored in g_banIPs cvar MAX_CVAR_VALUE_STRING -The size of the cvar string buffer is limiting the banning to around 20 masks -this could be improved by putting some g_banIPs2 g_banIps3 etc. maybe -still, you should rely on PB for banning instead - -============================================================================== -*/ - -// extern vmCvar_t  g_banIPs; -// extern vmCvar_t  g_filterBan; - - -typedef struct ipFilter_s -{ -  unsigned  mask; -  unsigned  compare; -} ipFilter_t; - -#define MAX_IPFILTERS 1024 - -static ipFilter_t ipFilters[ MAX_IPFILTERS ]; -static int        numIPFilters; - -/* -================= -StringToFilter -================= -*/ -static qboolean StringToFilter( char *s, ipFilter_t *f ) -{ -  char  num[ 128 ]; -  int   i, j; -  byte  b[ 4 ]; -  byte  m[ 4 ]; - -  for( i = 0; i < 4; i++ ) -  { -    b[ i ] = 0; -    m[ i ] = 0; -  } - -  for( i = 0; i < 4; i++ ) -  { -    if( *s < '0' || *s > '9' ) -    { -      if( *s == '*' ) // 'match any' -      { -        //b[ i ] and m[ i ] to 0 -        s++; -        if ( !*s ) -          break; - -        s++; -        continue; -      } - -      G_Printf( "Bad filter address: %s\n", s ); -      return qfalse; -    } - -    j = 0; -    while( *s >= '0' && *s <= '9' ) -      num[ j++ ] = *s++; - -    num[ j ] = 0; -    b[ i ] = atoi( num ); - -    m[ i ] = 255; - -    if( !*s ) -      break; - -    s++; -  } - -  f->mask = *(unsigned *)m; -  f->compare = *(unsigned *)b; - -  return qtrue; -} - -/* -================= -UpdateIPBans -================= -*/ -static void UpdateIPBans( void ) -{ -  byte  b[ 4 ]; -  byte  m[ 4 ]; -  int    i, j; -  char  iplist_final[ MAX_CVAR_VALUE_STRING ]; -  char  ip[ 64 ]; - -  *iplist_final = 0; - -  for( i = 0 ; i < numIPFilters ; i++ ) -  { -    if( ipFilters[ i ].compare == 0xffffffff ) -      continue; - -    *(unsigned *)b = ipFilters[ i ].compare; -    *(unsigned *)m = ipFilters[ i ].mask; -    *ip = 0; - -    for( j = 0 ; j < 4 ; j++ ) -    { -      if( m[ j ] != 255 ) -        Q_strcat( ip, sizeof( ip ), "*" ); -      else -        Q_strcat( ip, sizeof( ip ), va( "%i", b[ j ] ) ); - -      Q_strcat( ip, sizeof( ip ), ( j < 3 ) ? "." : " " ); -    } - -    if( strlen( iplist_final ) + strlen( ip ) < MAX_CVAR_VALUE_STRING ) -      Q_strcat( iplist_final, sizeof( iplist_final ), ip ); -    else -    { -      Com_Printf( "g_banIPs overflowed at MAX_CVAR_VALUE_STRING\n" ); -      break; -    } -  } - -  trap_Cvar_Set( "g_banIPs", iplist_final ); -} - -/* -================= -G_FilterPacket -================= -*/ -qboolean G_FilterPacket( char *from ) -{ -  int       i; -  unsigned  in; -  byte      m[ 4 ]; -  char      *p; - -  i = 0; -  p = from; -  while( *p && i < 4 ) -  { -    m[ i ] = 0; -    while( *p >= '0' && *p <= '9' ) -    { -      m[ i ] = m[ i ] * 10 + ( *p - '0' ); -      p++; -    } - -    if( !*p || *p == ':' ) -      break; - -    i++, p++; -  } - -  in = *(unsigned *)m; - -  for( i = 0; i < numIPFilters; i++ ) -    if( ( in & ipFilters[ i ].mask ) == ipFilters[ i ].compare ) -      return g_filterBan.integer != 0; - -  return g_filterBan.integer == 0; -} - -/* -================= -AddIP -================= -*/ -static void AddIP( char *str ) -{ -  int   i; - -  for( i = 0 ; i < numIPFilters ; i++ ) -    if( ipFilters[ i ].compare == 0xffffffff ) -      break;    // free spot - -  if( i == numIPFilters ) -  { -    if( numIPFilters == MAX_IPFILTERS ) -    { -      G_Printf( "IP filter list is full\n" ); -      return; -    } - -    numIPFilters++; -  } - -  if( !StringToFilter( str, &ipFilters[ i ] ) ) -    ipFilters[ i ].compare = 0xffffffffu; - -  UpdateIPBans( ); -} - -/* -================= -G_ProcessIPBans -================= -*/ -void G_ProcessIPBans( void ) -{ -  char *s, *t; -  char str[ MAX_CVAR_VALUE_STRING ]; - -  Q_strncpyz( str, g_banIPs.string, sizeof( str ) ); - -  for( t = s = g_banIPs.string; *t; /* */ ) -  { -    s = strchr( s, ' ' ); - -    if( !s ) -      break; - -    while( *s == ' ' ) -      *s++ = 0; - -    if( *t ) -      AddIP( t ); - -    t = s; -  } -} - - -/* -================= -Svcmd_AddIP_f -================= -*/ -void Svcmd_AddIP_f( void ) -{ -  char str[ MAX_TOKEN_CHARS ]; - -  if( trap_Argc( ) < 2 ) -  { -    G_Printf( "Usage:  addip <ip-mask>\n" ); -    return; -  } - -  trap_Argv( 1, str, sizeof( str ) ); - -  AddIP( str ); -} - -/* -================= -Svcmd_RemoveIP_f -================= -*/ -void Svcmd_RemoveIP_f( void ) -{ -  ipFilter_t  f; -  int         i; -  char        str[ MAX_TOKEN_CHARS ]; - -  if( trap_Argc( ) < 2 ) -  { -    G_Printf( "Usage:  sv removeip <ip-mask>\n" ); -    return; -  } - -  trap_Argv( 1, str, sizeof( str ) ); - -  if( !StringToFilter( str, &f ) ) -    return; - -  for( i = 0; i < numIPFilters; i++ ) -  { -    if( ipFilters[ i ].mask == f.mask && -        ipFilters[ i ].compare == f.compare) -    { -      ipFilters[ i ].compare = 0xffffffffu; -      G_Printf ( "Removed.\n" ); - -      UpdateIPBans( ); -      return; -    } -  } - -  G_Printf ( "Didn't find %s.\n", str ); -} - -/* -=================== -Svcmd_EntityList_f -=================== -*/ -void  Svcmd_EntityList_f( void ) -{ -  int       e; -  gentity_t *check; - -  check = g_entities + 1; - -  for( e = 1; e < level.num_entities; e++, check++ ) -  { -    if( !check->inuse ) -      continue; - -    G_Printf( "%3i:", e ); - -    switch( check->s.eType ) -    { -      case ET_GENERAL: -        G_Printf( "ET_GENERAL          " ); -        break; -      case ET_PLAYER: -        G_Printf( "ET_PLAYER           " ); -        break; -      case ET_ITEM: -        G_Printf( "ET_ITEM             " ); -        break; -      case ET_BUILDABLE: -        G_Printf( "ET_BUILDABLE        " ); -        break; -      case ET_MISSILE: -        G_Printf( "ET_MISSILE          " ); -        break; -      case ET_MOVER: -        G_Printf( "ET_MOVER            " ); -        break; -      case ET_BEAM: -        G_Printf( "ET_BEAM             " ); -        break; -      case ET_PORTAL: -        G_Printf( "ET_PORTAL           " ); -        break; -      case ET_SPEAKER: -        G_Printf( "ET_SPEAKER          " ); -        break; -      case ET_PUSH_TRIGGER: -        G_Printf( "ET_PUSH_TRIGGER     " ); -        break; -      case ET_TELEPORT_TRIGGER: -        G_Printf( "ET_TELEPORT_TRIGGER " ); -        break; -      case ET_INVISIBLE: -        G_Printf( "ET_INVISIBLE        " ); -        break; -      case ET_GRAPPLE: -        G_Printf( "ET_GRAPPLE          " ); -        break; -      default: -        G_Printf( "%3i                 ", check->s.eType ); -        break; -    } - -    if( check->classname ) -      G_Printf( "%s", check->classname ); - -    G_Printf( "\n" ); -  } -} - -gclient_t *ClientForString( const char *s ) -{ -  gclient_t *cl; -  int       i; -  int       idnum; - -  // numeric values are just slot numbers -  if( s[ 0 ] >= '0' && s[ 0 ] <= '9' ) -  { -    idnum = atoi( s ); - -    if( idnum < 0 || idnum >= level.maxclients ) -    { -      Com_Printf( "Bad client slot: %i\n", idnum ); -      return NULL; -    } - -    cl = &level.clients[ idnum ]; - -    if( cl->pers.connected == CON_DISCONNECTED ) -    { -      G_Printf( "Client %i is not connected\n", idnum ); -      return NULL; -    } - -    return cl; -  } - -  // check for a name match -  for( i = 0; i < level.maxclients; i++ ) -  { -    cl = &level.clients[ i ]; -    if( cl->pers.connected == CON_DISCONNECTED ) -      continue; - -    if( !Q_stricmp( cl->pers.netname, s ) ) -      return cl; -  } - -  G_Printf( "User %s is not on the server\n", s ); - -  return NULL; -} - -/* -=================== -Svcmd_ForceTeam_f - -forceteam <player> <team> -=================== -*/ -void  Svcmd_ForceTeam_f( void ) -{ -  gclient_t *cl; -  char      str[ MAX_TOKEN_CHARS ]; - -  // find the player -  trap_Argv( 1, str, sizeof( str ) ); -  cl = ClientForString( str ); - -  if( !cl ) -    return; - -  // set the team -  trap_Argv( 2, str, sizeof( str ) ); -  /*SetTeam( &g_entities[cl - level.clients], str );*/ -  //FIXME: tremulise this -} - -char  *ConcatArgs( int start ); - -/* -================= -ConsoleCommand - -================= -*/ -qboolean  ConsoleCommand( void ) -{ -  char cmd[ MAX_TOKEN_CHARS ]; - -  trap_Argv( 0, cmd, sizeof( cmd ) ); - -  if( Q_stricmp( cmd, "entitylist" ) == 0 ) -  { -    Svcmd_EntityList_f( ); -    return qtrue; -  } - -  if( Q_stricmp( cmd, "forceteam" ) == 0 ) -  { -    Svcmd_ForceTeam_f( ); -    return qtrue; -  } - -  if( Q_stricmp( cmd, "game_memory" ) == 0 ) -  { -    Svcmd_GameMem_f( ); -    return qtrue; -  } - -  if( Q_stricmp( cmd, "addip" ) == 0 ) -  { -    Svcmd_AddIP_f( ); -    return qtrue; -  } - -  if( Q_stricmp( cmd, "removeip" ) == 0 ) -  { -    Svcmd_RemoveIP_f( ); -    return qtrue; -  } - -  if( Q_stricmp( cmd, "listip" ) == 0 ) -  { -    trap_SendConsoleCommand( EXEC_NOW, "g_banIPs\n" ); -    return qtrue; -  } - -  if( Q_stricmp( cmd, "mapRotation" ) == 0 ) -  { -    char *rotationName = ConcatArgs( 1 ); - -    if( !G_StartMapRotation( rotationName, qfalse ) ) -      G_Printf( "Can't find map rotation %s\n", rotationName ); - -    return qtrue; -  } - -  if( Q_stricmp( cmd, "stopMapRotation" ) == 0 ) -  { -    G_StopMapRotation( ); - -    return qtrue; -  } - -  if( Q_stricmp( cmd, "alienWin" ) == 0 ) -  { -    int       i; -    gentity_t *e; - -    for( i = 1, e = g_entities + i; i < level.num_entities; i++, e++ ) -    { -      if( e->s.modelindex == BA_H_SPAWN ) -        G_Damage( e, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE ); -    } - -    return qtrue; -  } - -  if( Q_stricmp( cmd, "humanWin" ) == 0 ) -  { -    int       i; -    gentity_t *e; - -    for( i = 1, e = g_entities + i; i < level.num_entities; i++, e++ ) -    { -      if( e->s.modelindex == BA_A_SPAWN ) -        G_Damage( e, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE ); -    } - -    return qtrue; -  } - -  if( g_dedicated.integer ) -  { -    if( Q_stricmp( cmd, "say" ) == 0 ) -    { -      G_SendCommandFromServer( -1, va( "print \"server: %s\n\"", ConcatArgs( 1 ) ) ); -      return qtrue; -    } - -    // everything else will also be printed as a say command -    G_SendCommandFromServer( -1, va( "print \"server: %s\n\"", ConcatArgs( 0 ) ) ); -    return qtrue; -  } - -  return qfalse; -} - diff --git a/mod/src/game/g_syscalls.asm b/mod/src/game/g_syscalls.asm deleted file mode 100644 index 8035c349..00000000 --- a/mod/src/game/g_syscalls.asm +++ /dev/null @@ -1,61 +0,0 @@ -code - -equ	trap_Printf				              -1 -equ	trap_Error                      -2 -equ	trap_Milliseconds               -3 -equ	trap_Cvar_Register              -4 -equ	trap_Cvar_Update                -5 -equ	trap_Cvar_Set                   -6 -equ	trap_Cvar_VariableIntegerValue	-7 -equ	trap_Cvar_VariableStringBuffer	-8 -equ	trap_Argc                       -9 -equ	trap_Argv                       -10 -equ	trap_FS_FOpenFile               -11 -equ	trap_FS_Read                    -12 -equ	trap_FS_Write                   -13 -equ	trap_FS_FCloseFile              -14 -equ	trap_SendConsoleCommand         -15 -equ	trap_LocateGameData             -16 -equ	trap_DropClient                 -17 -equ	trap_SendServerCommand          -18 -equ	trap_SetConfigstring            -19 -equ	trap_GetConfigstring            -20 -equ	trap_GetUserinfo                -21 -equ	trap_SetUserinfo                -22 -equ	trap_GetServerinfo              -23 -equ	trap_SetBrushModel              -24 -equ	trap_Trace                      -25 -equ	trap_PointContents              -26 -equ trap_InPVS                      -27 -equ	trap_InPVSIgnorePortals         -28 -equ	trap_AdjustAreaPortalState      -29 -equ	trap_AreasConnected             -30 -equ	trap_LinkEntity                 -31 -equ	trap_UnlinkEntity               -32 -equ	trap_EntitiesInBox              -33 -equ	trap_EntityContact              -34 -equ	trap_BotAllocateClient          -35 -equ	trap_BotFreeClient              -36 -equ	trap_GetUsercmd                 -37 -equ	trap_GetEntityToken             -38 -equ	trap_FS_GetFileList             -39 -equ trap_DebugPolygonCreate         -40 -equ trap_DebugPolygonDelete         -41 -equ trap_RealTime                   -42 -equ trap_SnapVector                 -43 -equ trap_TraceCapsule               -44 -equ trap_EntityContactCapsule       -45 -equ trap_FS_Seek                    -46 - - -equ	memset                          -101 -equ	memcpy                          -102 -equ	strncpy                         -103 -equ	sin                             -104 -equ	cos                             -105 -equ	atan2                           -106 -equ	sqrt                            -107 -equ floor                           -111 -equ	ceil                            -112 -equ	testPrintInt                    -113 -equ	testPrintFloat                  -114 diff --git a/mod/src/game/g_syscalls.c b/mod/src/game/g_syscalls.c deleted file mode 100644 index 4f8a8ca7..00000000 --- a/mod/src/game/g_syscalls.c +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -// this file is only included when building a dll -// g_syscalls.asm is included instead when building a qvm - -static long (QDECL *syscall)( long arg, ... ) = (long (QDECL *)( long, ...))-1; - - -void dllEntry( long (QDECL *syscallptr)( long arg,... ) ) -{ -  syscall = syscallptr; -} - -int PASSFLOAT( float x ) -{ -  float floatTemp; -  floatTemp = x; -  return *(int *)&floatTemp; -} - -void  trap_Printf( const char *fmt ) -{ -  syscall( G_PRINT, fmt ); -} - -void  trap_Error( const char *fmt ) -{ -  syscall( G_ERROR, fmt ); -} - -int   trap_Milliseconds( void ) -{ -  return syscall( G_MILLISECONDS ); -} -int   trap_Argc( void ) -{ -  return syscall( G_ARGC ); -} - -void  trap_Argv( int n, char *buffer, int bufferLength ) -{ -  syscall( G_ARGV, n, buffer, bufferLength ); -} - -int   trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode ) -{ -  return syscall( G_FS_FOPEN_FILE, qpath, f, mode ); -} - -void  trap_FS_Read( void *buffer, int len, fileHandle_t f ) -{ -  syscall( G_FS_READ, buffer, len, f ); -} - -void  trap_FS_Write( const void *buffer, int len, fileHandle_t f ) -{ -  syscall( G_FS_WRITE, buffer, len, f ); -} - -void  trap_FS_FCloseFile( fileHandle_t f ) -{ -  syscall( G_FS_FCLOSE_FILE, f ); -} - -int trap_FS_GetFileList(  const char *path, const char *extension, char *listbuf, int bufsize ) -{ -  return syscall( G_FS_GETFILELIST, path, extension, listbuf, bufsize ); -} - -void  trap_SendConsoleCommand( int exec_when, const char *text ) -{ -  syscall( G_SEND_CONSOLE_COMMAND, exec_when, text ); -} - -void  trap_Cvar_Register( vmCvar_t *cvar, const char *var_name, const char *value, int flags ) -{ -  syscall( G_CVAR_REGISTER, cvar, var_name, value, flags ); -} - -void  trap_Cvar_Update( vmCvar_t *cvar ) -{ -  syscall( G_CVAR_UPDATE, cvar ); -} - -void trap_Cvar_Set( const char *var_name, const char *value ) -{ -  syscall( G_CVAR_SET, var_name, value ); -} - -int trap_Cvar_VariableIntegerValue( const char *var_name ) -{ -  return syscall( G_CVAR_VARIABLE_INTEGER_VALUE, var_name ); -} - -void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ) -{ -  syscall( G_CVAR_VARIABLE_STRING_BUFFER, var_name, buffer, bufsize ); -} - - -void trap_LocateGameData( gentity_t *gEnts, int numGEntities, int sizeofGEntity_t, -                          playerState_t *clients, int sizeofGClient ) -{ -  syscall( G_LOCATE_GAME_DATA, gEnts, numGEntities, sizeofGEntity_t, clients, sizeofGClient ); -} - -void trap_DropClient( int clientNum, const char *reason ) -{ -  syscall( G_DROP_CLIENT, clientNum, reason ); -} - -void trap_SendServerCommand( int clientNum, const char *text ) -{ -  syscall( G_SEND_SERVER_COMMAND, clientNum, text ); -} - -void trap_SetConfigstring( int num, const char *string ) -{ -  syscall( G_SET_CONFIGSTRING, num, string ); -} - -void trap_GetConfigstring( int num, char *buffer, int bufferSize ) -{ -  syscall( G_GET_CONFIGSTRING, num, buffer, bufferSize ); -} - -void trap_GetUserinfo( int num, char *buffer, int bufferSize ) -{ -  syscall( G_GET_USERINFO, num, buffer, bufferSize ); -} - -void trap_SetUserinfo( int num, const char *buffer ) -{ -  syscall( G_SET_USERINFO, num, buffer ); -} - -void trap_GetServerinfo( char *buffer, int bufferSize ) -{ -  syscall( G_GET_SERVERINFO, buffer, bufferSize ); -} - -void trap_SetBrushModel( gentity_t *ent, const char *name ) -{ -  syscall( G_SET_BRUSH_MODEL, ent, name ); -} - -void trap_Trace( trace_t *results, const vec3_t start, const vec3_t mins, -                 const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask ) -{ -  syscall( G_TRACE, results, start, mins, maxs, end, passEntityNum, contentmask ); -} - -void trap_TraceCapsule( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask ) -{ -  syscall( G_TRACECAPSULE, results, start, mins, maxs, end, passEntityNum, contentmask ); -} - -int trap_PointContents( const vec3_t point, int passEntityNum ) -{ -  return syscall( G_POINT_CONTENTS, point, passEntityNum ); -} - - -qboolean trap_InPVS( const vec3_t p1, const vec3_t p2 ) -{ -  return syscall( G_IN_PVS, p1, p2 ); -} - -qboolean trap_InPVSIgnorePortals( const vec3_t p1, const vec3_t p2 ) -{ -  return syscall( G_IN_PVS_IGNORE_PORTALS, p1, p2 ); -} - -void trap_AdjustAreaPortalState( gentity_t *ent, qboolean open ) -{ -  syscall( G_ADJUST_AREA_PORTAL_STATE, ent, open ); -} - -qboolean trap_AreasConnected( int area1, int area2 ) -{ -  return syscall( G_AREAS_CONNECTED, area1, area2 ); -} - -void trap_LinkEntity( gentity_t *ent ) -{ -  syscall( G_LINKENTITY, ent ); -} - -void trap_UnlinkEntity( gentity_t *ent ) -{ -  syscall( G_UNLINKENTITY, ent ); -} - - -int trap_EntitiesInBox( const vec3_t mins, const vec3_t maxs, int *list, int maxcount ) -{ -  return syscall( G_ENTITIES_IN_BOX, mins, maxs, list, maxcount ); -} - -qboolean trap_EntityContact( const vec3_t mins, const vec3_t maxs, const gentity_t *ent ) -{ -  return syscall( G_ENTITY_CONTACT, mins, maxs, ent ); -} - -qboolean trap_EntityContactCapsule( const vec3_t mins, const vec3_t maxs, const gentity_t *ent ) -{ -  return syscall( G_ENTITY_CONTACTCAPSULE, mins, maxs, ent ); -} -int trap_BotAllocateClient( void ) -{ -  return syscall( G_BOT_ALLOCATE_CLIENT ); -} - -void trap_BotFreeClient( int clientNum ) -{ -  syscall( G_BOT_FREE_CLIENT, clientNum ); -} - -void trap_GetUsercmd( int clientNum, usercmd_t *cmd ) -{ -  syscall( G_GET_USERCMD, clientNum, cmd ); -} - -qboolean trap_GetEntityToken( char *buffer, int bufferSize ) -{ -  return syscall( G_GET_ENTITY_TOKEN, buffer, bufferSize ); -} - -int trap_DebugPolygonCreate(int color, int numPoints, vec3_t *points) -{ -  return syscall( G_DEBUG_POLYGON_CREATE, color, numPoints, points ); -} - -void trap_DebugPolygonDelete(int id) -{ -  syscall( G_DEBUG_POLYGON_DELETE, id ); -} - -int trap_RealTime( qtime_t *qtime ) -{ -  return syscall( G_REAL_TIME, qtime ); -} - -void trap_SnapVector( float *v ) -{ -  syscall( G_SNAPVECTOR, v ); -  return; -} diff --git a/mod/src/game/g_target.c b/mod/src/game/g_target.c deleted file mode 100644 index c704d72f..00000000 --- a/mod/src/game/g_target.c +++ /dev/null @@ -1,432 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -//========================================================== - -/*QUAKED target_delay (1 0 0) (-8 -8 -8) (8 8 8) -"wait" seconds to pause before firing targets. -"random" delay variance, total delay = delay +/- random seconds -*/ -void Think_Target_Delay( gentity_t *ent ) -{ -  G_UseTargets( ent, ent->activator ); -} - -void Use_Target_Delay( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  ent->nextthink = level.time + ( ent->wait + ent->random * crandom( ) ) * 1000; -  ent->think = Think_Target_Delay; -  ent->activator = activator; -} - -void SP_target_delay( gentity_t *ent ) -{ -  // check delay for backwards compatability -  if( !G_SpawnFloat( "delay", "0", &ent->wait ) ) -    G_SpawnFloat( "wait", "1", &ent->wait ); - -  if( !ent->wait ) -    ent->wait = 1; - -  ent->use = Use_Target_Delay; -} - - -//========================================================== - -/*QUAKED target_score (1 0 0) (-8 -8 -8) (8 8 8) -"count" number of points to add, default 1 - -The activator is given this many points. -*/ -void Use_Target_Score( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  AddScore( activator, ent->count ); -} - -void SP_target_score( gentity_t *ent ) -{ -  if( !ent->count ) -    ent->count = 1; - -  ent->use = Use_Target_Score; -} - - -//========================================================== - -/*QUAKED target_print (1 0 0) (-8 -8 -8) (8 8 8) humanteam alienteam private -"message" text to print -If "private", only the activator gets the message.  If no checks, all clients get the message. -*/ -void Use_Target_Print( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  if( activator->client && ( ent->spawnflags & 4 ) ) -  { -    G_SendCommandFromServer( activator-g_entities, va( "cp \"%s\"", ent->message ) ); -    return; -  } - -  if( ent->spawnflags & 3 ) -  { -    if( ent->spawnflags & 1 ) -      G_TeamCommand( PTE_HUMANS, va( "cp \"%s\"", ent->message ) ); -    if( ent->spawnflags & 2 ) -      G_TeamCommand( PTE_ALIENS, va( "cp \"%s\"", ent->message ) ); - -    return; -  } - -  G_SendCommandFromServer( -1, va("cp \"%s\"", ent->message ) ); -} - -void SP_target_print( gentity_t *ent ) -{ -  ent->use = Use_Target_Print; -} - - -//========================================================== - - -/*QUAKED target_speaker (1 0 0) (-8 -8 -8) (8 8 8) looped-on looped-off global activator -"noise"   wav file to play - -A global sound will play full volume throughout the level. -Activator sounds will play on the player that activated the target. -Global and activator sounds can't be combined with looping. -Normal sounds play each time the target is used. -Looped sounds will be toggled by use functions. -Multiple identical looping sounds will just increase volume without any speed cost. -"wait" : Seconds between auto triggerings, 0 = don't auto trigger -"random"  wait variance, default is 0 -*/ -void Use_Target_Speaker( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  if( ent->spawnflags & 3 ) -  {  // looping sound toggles -    if( ent->s.loopSound ) -      ent->s.loopSound = 0; // turn it off -    else -      ent->s.loopSound = ent->noise_index;  // start it -  } -  else -  { -    // normal sound -    if( ent->spawnflags & 8 ) -      G_AddEvent( activator, EV_GENERAL_SOUND, ent->noise_index ); -    else if( ent->spawnflags & 4 ) -      G_AddEvent( ent, EV_GLOBAL_SOUND, ent->noise_index ); -    else -      G_AddEvent( ent, EV_GENERAL_SOUND, ent->noise_index ); -  } -} - -void SP_target_speaker( gentity_t *ent ) -{ -  char  buffer[ MAX_QPATH ]; -  char  *s; - -  G_SpawnFloat( "wait", "0", &ent->wait ); -  G_SpawnFloat( "random", "0", &ent->random ); - -  if( !G_SpawnString( "noise", "NOSOUND", &s ) ) -    G_Error( "target_speaker without a noise key at %s", vtos( ent->s.origin ) ); - -  // force all client reletive sounds to be "activator" speakers that -  // play on the entity that activates it -  if( s[ 0 ] == '*' ) -    ent->spawnflags |= 8; - -  if( !strstr( s, ".wav" ) ) -    Com_sprintf( buffer, sizeof( buffer ), "%s.wav", s ); -  else -    Q_strncpyz( buffer, s, sizeof( buffer ) ); - -  ent->noise_index = G_SoundIndex( buffer ); - -  // a repeating speaker can be done completely client side -  ent->s.eType = ET_SPEAKER; -  ent->s.eventParm = ent->noise_index; -  ent->s.frame = ent->wait * 10; -  ent->s.clientNum = ent->random * 10; - - -  // check for prestarted looping sound -  if( ent->spawnflags & 1 ) -    ent->s.loopSound = ent->noise_index; - -  ent->use = Use_Target_Speaker; - -  if( ent->spawnflags & 4 ) -    ent->r.svFlags |= SVF_BROADCAST; - -  VectorCopy( ent->s.origin, ent->s.pos.trBase ); - -  // must link the entity so we get areas and clusters so -  // the server can determine who to send updates to -  trap_LinkEntity( ent ); -} - -//========================================================== - -void target_teleporter_use( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  gentity_t *dest; - -  if( !activator->client ) -    return; - -  dest =  G_PickTarget( self->target ); - -  if( !dest ) -  { -    G_Printf( "Couldn't find teleporter destination\n" ); -    return; -  } - -  TeleportPlayer( activator, dest->s.origin, dest->s.angles ); -} - -/*QUAKED target_teleporter (1 0 0) (-8 -8 -8) (8 8 8) -The activator will be teleported away. -*/ -void SP_target_teleporter( gentity_t *self ) -{ -  if( !self->targetname ) -    G_Printf( "untargeted %s at %s\n", self->classname, vtos( self->s.origin ) ); - -  self->use = target_teleporter_use; -} - -//========================================================== - - -/*QUAKED target_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) RED_ONLY BLUE_ONLY RANDOM -This doesn't perform any actions except fire its targets. -The activator can be forced to be from a certain team. -if RANDOM is checked, only one of the targets will be fired, not all of them -*/ -void target_relay_use( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  if( ( self->spawnflags & 1 ) && activator->client && -      activator->client->ps.stats[ STAT_PTEAM ] != PTE_HUMANS ) -    return; - -  if( ( self->spawnflags & 2 ) && activator->client && -      activator->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS ) -    return; - -  if( self->spawnflags & 4 ) -  { -    gentity_t *ent; - -    ent = G_PickTarget( self->target ); -    if( ent && ent->use ) -      ent->use( ent, self, activator ); - -    return; -  } - -  G_UseTargets( self, activator ); -} - -void SP_target_relay( gentity_t *self ) -{ -  self->use = target_relay_use; -} - - -//========================================================== - -/*QUAKED target_kill (.5 .5 .5) (-8 -8 -8) (8 8 8) -Kills the activator. -*/ -void target_kill_use( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  G_Damage( activator, NULL, NULL, NULL, NULL, 100000, DAMAGE_NO_PROTECTION, MOD_TELEFRAG ); -} - -void SP_target_kill( gentity_t *self ) -{ -  self->use = target_kill_use; -} - -/*QUAKED target_position (0 0.5 0) (-4 -4 -4) (4 4 4) -Used as a positional target for in-game calculation, like jumppad targets. -*/ -void SP_target_position( gentity_t *self ) -{ -  G_SetOrigin( self, self->s.origin ); -} - -static void target_location_linkup( gentity_t *ent ) -{ -  int i; -  int n; - -  if( level.locationLinked ) -    return; - -  level.locationLinked = qtrue; - -  level.locationHead = NULL; - -  trap_SetConfigstring( CS_LOCATIONS, "unknown" ); - -  for( i = 0, ent = g_entities, n = 1; i < level.num_entities; i++, ent++) -  { -    if( ent->classname && !Q_stricmp( ent->classname, "target_location" ) ) -    { -      // lets overload some variables! -      ent->health = n; // use for location marking -      trap_SetConfigstring( CS_LOCATIONS + n, ent->message ); -      n++; -      ent->nextTrain = level.locationHead; -      level.locationHead = ent; -    } -  } -  // All linked together now -} - -/*QUAKED target_location (0 0.5 0) (-8 -8 -8) (8 8 8) -Set "message" to the name of this location. -Set "count" to 0-7 for color. -0:white 1:red 2:green 3:yellow 4:blue 5:cyan 6:magenta 7:white - -Closest target_location in sight used for the location, if none -in site, closest in distance -*/ -void SP_target_location( gentity_t *self ) -{ -  self->think = target_location_linkup; -  self->nextthink = level.time + 200;  // Let them all spawn first - -  G_SetOrigin( self, self->s.origin ); -} - - -/* -=============== -target_rumble_think -=============== -*/ -void target_rumble_think( gentity_t *self ) -{ -  int        i; -  gentity_t  *ent; - -  if( self->last_move_time < level.time ) -    self->last_move_time = level.time + 0.5; - -  for( i = 0, ent = g_entities + i; i < level.num_entities; i++, ent++ ) -  { -    if( !ent->inuse ) -      continue; - -    if( !ent->client ) -      continue; - -    if( ent->client->ps.groundEntityNum == ENTITYNUM_NONE ) -      continue; - -    ent->client->ps.groundEntityNum = ENTITYNUM_NONE; -    ent->client->ps.velocity[ 0 ] += crandom( ) * 150; -    ent->client->ps.velocity[ 1 ] += crandom( ) * 150; -    ent->client->ps.velocity[ 2 ] = self->speed; -  } - -  if( level.time < self->timestamp ) -    self->nextthink = level.time + FRAMETIME; -} - -/* -=============== -target_rumble_use -=============== -*/ -void target_rumble_use( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  self->timestamp = level.time + ( self->count * FRAMETIME ); -  self->nextthink = level.time + FRAMETIME; -  self->activator = activator; -  self->last_move_time = 0; -} - -/* -=============== -SP_target_rumble -=============== -*/ -void SP_target_rumble( gentity_t *self ) -{ -  if( !self->targetname ) -  { -    G_Printf( S_COLOR_YELLOW "WARNING: untargeted %s at %s\n", self->classname, -                                                               vtos( self->s.origin ) ); -  } - -  if( !self->count ) -    self->count = 10; - -  if( !self->speed ) -    self->speed = 100; - -  self->think = target_rumble_think; -  self->use = target_rumble_use; -} - -/* -=============== -target_alien_win_use -=============== -*/ -void target_alien_win_use( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  level.uncondAlienWin = qtrue; -} - -/* -=============== -SP_target_alien_win -=============== -*/ -void SP_target_alien_win( gentity_t *self ) -{ -  self->use = target_alien_win_use; -} - -/* -=============== -target_human_win_use -=============== -*/ -void target_human_win_use( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  level.uncondHumanWin = qtrue; -} - -/* -=============== -SP_target_human_win -=============== -*/ -void SP_target_human_win( gentity_t *self ) -{ -  self->use = target_human_win_use; -} diff --git a/mod/src/game/g_team.c b/mod/src/game/g_team.c deleted file mode 100644 index ffe28c39..00000000 --- a/mod/src/game/g_team.c +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -// NULL for everyone -void QDECL PrintMsg( gentity_t *ent, const char *fmt, ... ) -{ -  char    msg[ 1024 ]; -  va_list argptr; -  char    *p; - -  va_start( argptr,fmt ); - -  if( vsprintf( msg, fmt, argptr ) > sizeof( msg ) ) -    G_Error ( "PrintMsg overrun" ); - -  va_end( argptr ); - -  // double quotes are bad -  while( ( p = strchr( msg, '"' ) ) != NULL ) -    *p = '\''; - -  G_SendCommandFromServer( ( ( ent == NULL ) ? -1 : ent-g_entities ), va( "print \"%s\"", msg ) ); -} - - -/* -============== -OnSameTeam -============== -*/ -qboolean OnSameTeam( gentity_t *ent1, gentity_t *ent2 ) -{ -  if( !ent1->client || !ent2->client ) -    return qfalse; - -  if( ent1->client->pers.teamSelection == ent2->client->pers.teamSelection ) -    return qtrue; - -  return qfalse; -} - -/* -=========== -Team_GetLocation - -Report a location for the player. Uses placed nearby target_location entities -============ -*/ -gentity_t *Team_GetLocation( gentity_t *ent ) -{ -  gentity_t   *eloc, *best; -  float       bestlen, len; -  vec3_t      origin; - -  best = NULL; -  bestlen = 3.0f * 8192.0f * 8192.0f; - -  VectorCopy( ent->r.currentOrigin, origin ); - -  for( eloc = level.locationHead; eloc; eloc = eloc->nextTrain ) -  { -    len = ( origin[ 0 ] - eloc->r.currentOrigin[ 0 ] ) * ( origin[ 0 ] - eloc->r.currentOrigin[ 0 ] ) -        + ( origin[ 1 ] - eloc->r.currentOrigin[ 1 ] ) * ( origin[ 1 ] - eloc->r.currentOrigin[ 1 ] ) -        + ( origin[ 2 ] - eloc->r.currentOrigin[ 2 ] ) * ( origin[ 2 ] - eloc->r.currentOrigin[ 2 ] ); - -    if( len > bestlen ) -      continue; - -    if( !trap_InPVS( origin, eloc->r.currentOrigin ) ) -      continue; - -    bestlen = len; -    best = eloc; -  } - -  return best; -} - - -/* -=========== -Team_GetLocationMsg - -Report a location message for the player. Uses placed nearby target_location entities -============ -*/ -qboolean Team_GetLocationMsg( gentity_t *ent, char *loc, int loclen ) -{ -  gentity_t *best; - -  best = Team_GetLocation( ent ); - -  if( !best ) -    return qfalse; - -  if( best->count ) -  { -    if( best->count < 0 ) -      best->count = 0; - -    if( best->count > 7 ) -      best->count = 7; - -    Com_sprintf( loc, loclen, "%c%c%s" S_COLOR_WHITE, Q_COLOR_ESCAPE, best->count + '0', best->message ); -  } -  else -    Com_sprintf( loc, loclen, "%s", best->message ); - -  return qtrue; -} - - -/*---------------------------------------------------------------------------*/ - -static int QDECL SortClients( const void *a, const void *b ) -{ -  return *(int *)a - *(int *)b; -} - - -/* -================== -TeamplayLocationsMessage - -Format: -  clientNum location health armor weapon powerups - -================== -*/ -void TeamplayInfoMessage( gentity_t *ent ) -{ -  char      entry[ 1024 ]; -  char      string[ 8192 ]; -  int       stringlength; -  int       i, j; -  gentity_t *player; -  int       cnt; -  int       h, a = 0; -  int       clients[ TEAM_MAXOVERLAY ]; - -  if( ! ent->client->pers.teamInfo ) -    return; - -  // figure out what client should be on the display -  // we are limited to 8, but we want to use the top eight players -  // but in client order (so they don't keep changing position on the overlay) -  for( i = 0, cnt = 0; i < g_maxclients.integer && cnt < TEAM_MAXOVERLAY; i++ ) -  { -    player = g_entities + level.sortedClients[ i ]; - -    if( player->inuse && player->client->sess.sessionTeam == -        ent->client->sess.sessionTeam ) -      clients[ cnt++ ] = level.sortedClients[ i ]; -  } - -  // We have the top eight players, sort them by clientNum -  qsort( clients, cnt, sizeof( clients[ 0 ] ), SortClients ); - -  // send the latest information on all clients -  string[ 0 ] = 0; -  stringlength = 0; - -  for( i = 0, cnt = 0; i < g_maxclients.integer && cnt < TEAM_MAXOVERLAY; i++) -  { -    player = g_entities + i; - -    if( player->inuse && player->client->sess.sessionTeam == -        ent->client->sess.sessionTeam ) -    { -      h = player->client->ps.stats[ STAT_HEALTH ]; - -      if( h < 0 ) -        h = 0; - -      Com_sprintf( entry, sizeof( entry ), -        " %i %i %i %i %i %i", -//        level.sortedClients[i], player->client->pers.teamState.location, h, a, -        i, player->client->pers.teamState.location, h, a, -        player->client->ps.weapon, player->s.powerups ); - -      j = strlen( entry ); - -      if( stringlength + j > sizeof( string ) ) -        break; - -      strcpy( string + stringlength, entry ); -      stringlength += j; -      cnt++; -    } -  } - -  G_SendCommandFromServer( ent - g_entities, va( "tinfo %i %s", cnt, string ) ); -} - -void CheckTeamStatus( void ) -{ -  int i; -  gentity_t *loc, *ent; - -  if( level.time - level.lastTeamLocationTime > TEAM_LOCATION_UPDATE_TIME ) -  { -    level.lastTeamLocationTime = level.time; - -    for( i = 0; i < g_maxclients.integer; i++ ) -    { -      ent = g_entities + i; -      if( ent->client->pers.connected != CON_CONNECTED ) -        continue; - -      if( ent->inuse && ( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS || -                          ent->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) ) -      { - -        loc = Team_GetLocation( ent ); - -        if( loc ) -          ent->client->pers.teamState.location = loc->health; -        else -          ent->client->pers.teamState.location = 0; -      } -    } - -    for( i = 0; i < g_maxclients.integer; i++ ) -    { -      ent = g_entities + i; -      if( ent->client->pers.connected != CON_CONNECTED ) -        continue; - -      if( ent->inuse && ( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS || -                          ent->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) ) -        TeamplayInfoMessage( ent ); -    } -  } -} diff --git a/mod/src/game/g_trigger.c b/mod/src/game/g_trigger.c deleted file mode 100644 index d92e44b4..00000000 --- a/mod/src/game/g_trigger.c +++ /dev/null @@ -1,1037 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - - -void InitTrigger( gentity_t *self ) -{ -  if( !VectorCompare( self->s.angles, vec3_origin ) ) -    G_SetMovedir( self->s.angles, self->movedir ); - -  trap_SetBrushModel( self, self->model ); -  self->r.contents = CONTENTS_TRIGGER;    // replaces the -1 from trap_SetBrushModel -  self->r.svFlags = SVF_NOCLIENT; -} - - -// the wait time has passed, so set back up for another activation -void multi_wait( gentity_t *ent ) -{ -  ent->nextthink = 0; -} - - -// the trigger was just activated -// ent->activator should be set to the activator so it can be held through a delay -// so wait for the delay time before firing -void multi_trigger( gentity_t *ent, gentity_t *activator ) -{ -  ent->activator = activator; -  if( ent->nextthink ) -    return;   // can't retrigger until the wait is over - -  if( activator->client ) -  { -    if( ( ent->spawnflags & 1 ) && -        activator->client->ps.stats[ STAT_PTEAM ] != PTE_HUMANS ) -      return; - -    if( ( ent->spawnflags & 2 ) && -        activator->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS ) -      return; -  } - -  G_UseTargets( ent, ent->activator ); - -  if( ent->wait > 0 ) -  { -    ent->think = multi_wait; -    ent->nextthink = level.time + ( ent->wait + ent->random * crandom( ) ) * 1000; -  } -  else -  { -    // we can't just remove (self) here, because this is a touch function -    // called while looping through area links... -    ent->touch = 0; -    ent->nextthink = level.time + FRAMETIME; -    ent->think = G_FreeEntity; -  } -} - -void Use_Multi( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  multi_trigger( ent, activator ); -} - -void Touch_Multi( gentity_t *self, gentity_t *other, trace_t *trace ) -{ -  if( !other->client && other->s.eType != ET_BUILDABLE ) -    return; - -  multi_trigger( self, other ); -} - -/*QUAKED trigger_multiple (.5 .5 .5) ? -"wait" : Seconds between triggerings, 0.5 default, -1 = one time only. -"random"  wait variance, default is 0 -Variable sized repeatable trigger.  Must be targeted at one or more entities. -so, the basic time between firing is a random time between -(wait - random) and (wait + random) -*/ -void SP_trigger_multiple( gentity_t *ent ) -{ -  G_SpawnFloat( "wait", "0.5", &ent->wait ); -  G_SpawnFloat( "random", "0", &ent->random ); - -  if( ent->random >= ent->wait && ent->wait >= 0 ) -  { -    ent->random = ent->wait - FRAMETIME; -    G_Printf( "trigger_multiple has random >= wait\n" ); -  } - -  ent->touch = Touch_Multi; -  ent->use = Use_Multi; - -  InitTrigger( ent ); -  trap_LinkEntity( ent ); -} - - - -/* -============================================================================== - -trigger_always - -============================================================================== -*/ - -void trigger_always_think( gentity_t *ent ) -{ -  G_UseTargets( ent, ent ); -  G_FreeEntity( ent ); -} - -/*QUAKED trigger_always (.5 .5 .5) (-8 -8 -8) (8 8 8) -This trigger will always fire.  It is activated by the world. -*/ -void SP_trigger_always( gentity_t *ent ) -{ -  // we must have some delay to make sure our use targets are present -  ent->nextthink = level.time + 300; -  ent->think = trigger_always_think; -} - - -/* -============================================================================== - -trigger_push - -============================================================================== -*/ - -void trigger_push_touch( gentity_t *self, gentity_t *other, trace_t *trace ) -{ -  if( !other->client ) -    return; -} - - -/* -================= -AimAtTarget - -Calculate origin2 so the target apogee will be hit -================= -*/ -void AimAtTarget( gentity_t *self ) -{ -  gentity_t *ent; -  vec3_t    origin; -  float     height, gravity, time, forward; -  float     dist; - -  VectorAdd( self->r.absmin, self->r.absmax, origin ); -  VectorScale( origin, 0.5, origin ); - -  ent = G_PickTarget( self->target ); - -  if( !ent ) -  { -    G_FreeEntity( self ); -    return; -  } - -  height = ent->s.origin[ 2 ] - origin[ 2 ]; -  gravity = g_gravity.value; -  time = sqrt( height / ( 0.5 * gravity ) ); - -  if( !time ) -  { -    G_FreeEntity( self ); -    return; -  } - -  // set s.origin2 to the push velocity -  VectorSubtract( ent->s.origin, origin, self->s.origin2 ); -  self->s.origin2[ 2 ] = 0; -  dist = VectorNormalize( self->s.origin2 ); - -  forward = dist / time; -  VectorScale( self->s.origin2, forward, self->s.origin2 ); - -  self->s.origin2[ 2 ] = time * gravity; -} - - -/*QUAKED trigger_push (.5 .5 .5) ? -Must point at a target_position, which will be the apex of the leap. -This will be client side predicted, unlike target_push -*/ -void SP_trigger_push( gentity_t *self ) -{ -  InitTrigger( self ); - -  // unlike other triggers, we need to send this one to the client -  self->r.svFlags &= ~SVF_NOCLIENT; - -  // make sure the client precaches this sound -  G_SoundIndex( "sound/world/jumppad.wav" ); - -  self->s.eType = ET_PUSH_TRIGGER; -  self->touch = trigger_push_touch; -  self->think = AimAtTarget; -  self->nextthink = level.time + FRAMETIME; -  trap_LinkEntity( self ); -} - - -void Use_target_push( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  if( !activator->client ) -    return; - -  if( activator->client->ps.pm_type != PM_NORMAL ) -    return; - -  VectorCopy( self->s.origin2, activator->client->ps.velocity ); - -  // play fly sound every 1.5 seconds -  if( activator->fly_sound_debounce_time < level.time ) -  { -    activator->fly_sound_debounce_time = level.time + 1500; -    G_Sound( activator, CHAN_AUTO, self->noise_index ); -  } -} - -/*QUAKED target_push (.5 .5 .5) (-8 -8 -8) (8 8 8) bouncepad -Pushes the activator in the direction.of angle, or towards a target apex. -"speed"   defaults to 1000 -if "bouncepad", play bounce noise instead of windfly -*/ -void SP_target_push( gentity_t *self ) -{ -  if( !self->speed ) -    self->speed = 1000; - -  G_SetMovedir( self->s.angles, self->s.origin2 ); -  VectorScale( self->s.origin2, self->speed, self->s.origin2 ); - -  if( self->spawnflags & 1 ) -    self->noise_index = G_SoundIndex( "sound/world/jumppad.wav" ); -  else -    self->noise_index = G_SoundIndex( "sound/misc/windfly.wav" ); - -  if( self->target ) -  { -    VectorCopy( self->s.origin, self->r.absmin ); -    VectorCopy( self->s.origin, self->r.absmax ); -    self->think = AimAtTarget; -    self->nextthink = level.time + FRAMETIME; -  } - -  self->use = Use_target_push; -} - -/* -============================================================================== - -trigger_teleport - -============================================================================== -*/ - -void trigger_teleporter_touch( gentity_t *self, gentity_t *other, trace_t *trace ) -{ -  gentity_t *dest; - -  if( !other->client ) -    return; - -  if( other->client->ps.pm_type == PM_DEAD ) -    return; - -  // Spectators only? -  if( ( self->spawnflags & 1 ) && -      other->client->sess.sessionTeam != TEAM_SPECTATOR ) -    return; - - -  dest = G_PickTarget( self->target ); - -  if( !dest ) -  { -    G_Printf( "Couldn't find teleporter destination\n" ); -    return; -  } - -  TeleportPlayer( other, dest->s.origin, dest->s.angles ); -} - - -/*QUAKED trigger_teleport (.5 .5 .5) ? SPECTATOR -Allows client side prediction of teleportation events. -Must point at a target_position, which will be the teleport destination. - -If spectator is set, only spectators can use this teleport -Spectator teleporters are not normally placed in the editor, but are created -automatically near doors to allow spectators to move through them -*/ -void SP_trigger_teleport( gentity_t *self ) -{ -  InitTrigger( self ); - -  // unlike other triggers, we need to send this one to the client -  // unless is a spectator trigger -  if( self->spawnflags & 1 ) -    self->r.svFlags |= SVF_NOCLIENT; -  else -    self->r.svFlags &= ~SVF_NOCLIENT; - -  // make sure the client precaches this sound -  G_SoundIndex( "sound/world/jumppad.wav" ); - -  self->s.eType = ET_TELEPORT_TRIGGER; -  self->touch = trigger_teleporter_touch; - -  trap_LinkEntity( self ); -} - - -/* -============================================================================== - -trigger_hurt - -============================================================================== -*/ - -/*QUAKED trigger_hurt (.5 .5 .5) ? START_OFF - SILENT NO_PROTECTION SLOW -Any entity that touches this will be hurt. -It does dmg points of damage each server frame -Targeting the trigger will toggle its on / off state. - -SILENT      supresses playing the sound -SLOW      changes the damage rate to once per second -NO_PROTECTION *nothing* stops the damage - -"dmg"     default 5 (whole numbers only) - -*/ -void hurt_use( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  if( self->r.linked ) -    trap_UnlinkEntity( self ); -  else -    trap_LinkEntity( self ); -} - -void hurt_touch( gentity_t *self, gentity_t *other, trace_t *trace ) -{ -  int   dflags; - -  if( !other->takedamage ) -    return; - -  if( self->timestamp > level.time ) -    return; - -  if( self->spawnflags & 16 ) -    self->timestamp = level.time + 1000; -  else -    self->timestamp = level.time + FRAMETIME; - -  // play sound -  if( !( self->spawnflags & 4 ) ) -    G_Sound( other, CHAN_AUTO, self->noise_index ); - -  if( self->spawnflags & 8 ) -    dflags = DAMAGE_NO_PROTECTION; -  else -    dflags = 0; - -  G_Damage( other, self, self, NULL, NULL, self->damage, dflags, MOD_TRIGGER_HURT ); -} - -void SP_trigger_hurt( gentity_t *self ) -{ -  InitTrigger( self ); - -  self->noise_index = G_SoundIndex( "sound/world/electro.wav" ); -  self->touch = hurt_touch; - -  if( !self->damage ) -    self->damage = 5; - -  self->r.contents = CONTENTS_TRIGGER; - -  if( self->spawnflags & 2 ) -    self->use = hurt_use; - -  // link in to the world if starting active -  if( !( self->spawnflags & 1 ) ) -    trap_LinkEntity( self ); -} - - -/* -============================================================================== - -timer - -============================================================================== -*/ - - -/*QUAKED func_timer (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) START_ON -This should be renamed trigger_timer... -Repeatedly fires its targets. -Can be turned on or off by using. - -"wait"      base time between triggering all targets, default is 1 -"random"    wait variance, default is 0 -so, the basic time between firing is a random time between -(wait - random) and (wait + random) - -*/ -void func_timer_think( gentity_t *self ) -{ -  G_UseTargets( self, self->activator ); -  // set time before next firing -  self->nextthink = level.time + 1000 * ( self->wait + crandom( ) * self->random ); -} - -void func_timer_use( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  self->activator = activator; - -  // if on, turn it off -  if( self->nextthink ) -  { -    self->nextthink = 0; -    return; -  } - -  // turn it on -  func_timer_think( self ); -} - -void SP_func_timer( gentity_t *self ) -{ -  G_SpawnFloat( "random", "1", &self->random ); -  G_SpawnFloat( "wait", "1", &self->wait ); - -  self->use = func_timer_use; -  self->think = func_timer_think; - -  if( self->random >= self->wait ) -  { -    self->random = self->wait - FRAMETIME; -    G_Printf( "func_timer at %s has random >= wait\n", vtos( self->s.origin ) ); -  } - -  if( self->spawnflags & 1 ) -  { -    self->nextthink = level.time + FRAMETIME; -    self->activator = self; -  } - -  self->r.svFlags = SVF_NOCLIENT; -} - - -/* -=============== -G_Checktrigger_stages - -Called when stages change -=============== -*/ -void G_Checktrigger_stages( pTeam_t team, stage_t stage ) -{ -  int i; -  gentity_t *ent; - -  for( i = 1, ent = g_entities + i ; i < level.num_entities ; i++, ent++ ) -  { -    if( !ent->inuse ) -      continue; - -    if( !Q_stricmp( ent->classname, "trigger_stage" ) ) -    { -      if( team == ent->stageTeam && stage == ent->stageStage ) -        ent->use( ent, ent, ent ); -    } -  } -} - - -/* -=============== -trigger_stage_use -=============== -*/ -void trigger_stage_use( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  G_UseTargets( self, self ); -} - -void SP_trigger_stage( gentity_t *self ) -{ -  G_SpawnInt( "team", "0", (int *)&self->stageTeam ); -  G_SpawnInt( "stage", "0", (int *)&self->stageStage ); - -  self->use = trigger_stage_use; - -  self->r.svFlags = SVF_NOCLIENT; -} - - -/* -=============== -trigger_win -=============== -*/ -void trigger_win( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  G_UseTargets( self, self ); -} - -void SP_trigger_win( gentity_t *self ) -{ -  G_SpawnInt( "team", "0", (int *)&self->stageTeam ); - -  self->use = trigger_win; - -  self->r.svFlags = SVF_NOCLIENT; -} - - -/* -=============== -trigger_buildable_trigger -=============== -*/ -void trigger_buildable_trigger( gentity_t *self, gentity_t *activator ) -{ -  int i = 0; - -  self->activator = activator; -  if( self->nextthink ) -    return;   // can't retrigger until the wait is over - -  //if there is no buildable list every buildable triggers -  if( self->bTriggers[ i ] == BA_NONE ) -    G_UseTargets( self, activator ); -  else -  { -    //otherwise check against the list -    for( i = 0; self->bTriggers[ i ] != BA_NONE; i++ ) -    { -      if( activator->s.modelindex == self->bTriggers[ i ] ) -      { -        G_UseTargets( self, activator ); -        return; -      } -    } -  } - -  if( self->wait > 0 ) -  { -    self->think = multi_wait; -    self->nextthink = level.time + ( self->wait + self->random * crandom( ) ) * 1000; -  } -  else -  { -    // we can't just remove (self) here, because this is a touch function -    // called while looping through area links... -    self->touch = 0; -    self->nextthink = level.time + FRAMETIME; -    self->think = G_FreeEntity; -  } -} - -/* -=============== -trigger_buildable_touch -=============== -*/ -void trigger_buildable_touch( gentity_t *ent, gentity_t *other, trace_t *trace ) -{ -  //only triggered by buildables -  if( other->s.eType != ET_BUILDABLE ) -    return; - -  trigger_buildable_trigger( ent, other ); -} - -/* -=============== -trigger_buildable_use -=============== -*/ -void trigger_buildable_use( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  trigger_buildable_trigger( ent, activator ); -} - -/* -=============== -SP_trigger_buildable -=============== -*/ -void SP_trigger_buildable( gentity_t *self ) -{ -  char *buffer; - -  G_SpawnFloat( "wait", "0.5", &self->wait ); -  G_SpawnFloat( "random", "0", &self->random ); - -  if( self->random >= self->wait && self->wait >= 0 ) -  { -    self->random = self->wait - FRAMETIME; -    G_Printf( S_COLOR_YELLOW "WARNING: trigger_buildable has random >= wait\n" ); -  } - -  G_SpawnString( "buildables", "", &buffer ); - -  BG_ParseCSVBuildableList( buffer, self->bTriggers, BA_NUM_BUILDABLES ); - -  self->touch = trigger_buildable_touch; -  self->use = trigger_buildable_use; - -  InitTrigger( self ); -  trap_LinkEntity( self ); -} - - -/* -=============== -trigger_class_trigger -=============== -*/ -void trigger_class_trigger( gentity_t *self, gentity_t *activator ) -{ -  int i = 0; - -  //sanity check -  if( !activator->client ) -    return; - -  if( activator->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS ) -    return; - -  self->activator = activator; -  if( self->nextthink ) -    return;   // can't retrigger until the wait is over - -  //if there is no class list every class triggers (stupid case) -  if( self->cTriggers[ i ] == PCL_NONE ) -    G_UseTargets( self, activator ); -  else -  { -    //otherwise check against the list -    for( i = 0; self->cTriggers[ i ] != PCL_NONE; i++ ) -    { -      if( activator->client->ps.stats[ STAT_PCLASS ] == self->cTriggers[ i ] ) -      { -        G_UseTargets( self, activator ); -        return; -      } -    } -  } - -  if( self->wait > 0 ) -  { -    self->think = multi_wait; -    self->nextthink = level.time + ( self->wait + self->random * crandom( ) ) * 1000; -  } -  else -  { -    // we can't just remove (self) here, because this is a touch function -    // called while looping through area links... -    self->touch = 0; -    self->nextthink = level.time + FRAMETIME; -    self->think = G_FreeEntity; -  } -} - -/* -=============== -trigger_class_touch -=============== -*/ -void trigger_class_touch( gentity_t *ent, gentity_t *other, trace_t *trace ) -{ -  //only triggered by clients -  if( !other->client ) -    return; - -  trigger_class_trigger( ent, other ); -} - -/* -=============== -trigger_class_use -=============== -*/ -void trigger_class_use( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  trigger_class_trigger( ent, activator ); -} - -/* -=============== -SP_trigger_class -=============== -*/ -void SP_trigger_class( gentity_t *self ) -{ -  char *buffer; - -  G_SpawnFloat( "wait", "0.5", &self->wait ); -  G_SpawnFloat( "random", "0", &self->random ); - -  if( self->random >= self->wait && self->wait >= 0 ) -  { -    self->random = self->wait - FRAMETIME; -    G_Printf( S_COLOR_YELLOW "WARNING: trigger_class has random >= wait\n" ); -  } - -  G_SpawnString( "classes", "", &buffer ); - -  BG_ParseCSVClassList( buffer, self->cTriggers, PCL_NUM_CLASSES ); - -  self->touch = trigger_class_touch; -  self->use = trigger_class_use; - -  InitTrigger( self ); -  trap_LinkEntity( self ); -} - - -/* -=============== -trigger_equipment_trigger -=============== -*/ -void trigger_equipment_trigger( gentity_t *self, gentity_t *activator ) -{ -  int i = 0; - -  //sanity check -  if( !activator->client ) -    return; - -  if( activator->client->ps.stats[ STAT_PTEAM ] != PTE_HUMANS ) -    return; - -  self->activator = activator; -  if( self->nextthink ) -    return;   // can't retrigger until the wait is over - -  //if there is no equipment list all equipment triggers (stupid case) -  if( self->wTriggers[ i ] == WP_NONE && self->wTriggers[ i ] == UP_NONE ) -    G_UseTargets( self, activator ); -  else -  { -    //otherwise check against the lists -    for( i = 0; self->wTriggers[ i ] != WP_NONE; i++ ) -    { -      if( BG_InventoryContainsWeapon( self->wTriggers[ i ], activator->client->ps.stats ) ) -      { -        G_UseTargets( self, activator ); -        return; -      } -    } - -    for( i = 0; self->uTriggers[ i ] != UP_NONE; i++ ) -    { -      if( BG_InventoryContainsUpgrade( self->uTriggers[ i ], activator->client->ps.stats ) ) -      { -        G_UseTargets( self, activator ); -        return; -      } -    } -  } - -  if( self->wait > 0 ) -  { -    self->think = multi_wait; -    self->nextthink = level.time + ( self->wait + self->random * crandom( ) ) * 1000; -  } -  else -  { -    // we can't just remove (self) here, because this is a touch function -    // called while looping through area links... -    self->touch = 0; -    self->nextthink = level.time + FRAMETIME; -    self->think = G_FreeEntity; -  } -} - -/* -=============== -trigger_equipment_touch -=============== -*/ -void trigger_equipment_touch( gentity_t *ent, gentity_t *other, trace_t *trace ) -{ -  //only triggered by clients -  if( !other->client ) -    return; - -  trigger_equipment_trigger( ent, other ); -} - -/* -=============== -trigger_equipment_use -=============== -*/ -void trigger_equipment_use( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  trigger_equipment_trigger( ent, activator ); -} - -/* -=============== -SP_trigger_equipment -=============== -*/ -void SP_trigger_equipment( gentity_t *self ) -{ -  char *buffer; - -  G_SpawnFloat( "wait", "0.5", &self->wait ); -  G_SpawnFloat( "random", "0", &self->random ); - -  if( self->random >= self->wait && self->wait >= 0 ) -  { -    self->random = self->wait - FRAMETIME; -    G_Printf( S_COLOR_YELLOW "WARNING: trigger_equipment has random >= wait\n" ); -  } - -  G_SpawnString( "equipment", "", &buffer ); - -  BG_ParseCSVEquipmentList( buffer, self->wTriggers, WP_NUM_WEAPONS, -      self->uTriggers, UP_NUM_UPGRADES ); - -  self->touch = trigger_equipment_touch; -  self->use = trigger_equipment_use; - -  InitTrigger( self ); -  trap_LinkEntity( self ); -} - - -/* -=============== -trigger_gravity_touch -=============== -*/ -void trigger_gravity_touch( gentity_t *ent, gentity_t *other, trace_t *trace ) -{ -  //only triggered by clients -  if( !other->client ) -    return; - -  other->client->ps.gravity = ent->triggerGravity; -} - -/* -=============== -trigger_gravity_use -=============== -*/ -void trigger_gravity_use( gentity_t *ent, gentity_t *other, gentity_t *activator ) -{ -  if( ent->r.linked ) -    trap_UnlinkEntity( ent ); -  else -    trap_LinkEntity( ent ); -} - - -/* -=============== -SP_trigger_gravity -=============== -*/ -void SP_trigger_gravity( gentity_t *self ) -{ -  G_SpawnInt( "gravity", "800", &self->triggerGravity ); - -  self->touch = trigger_gravity_touch; -  self->use = trigger_gravity_use; - -  InitTrigger( self ); -  trap_LinkEntity( self ); -} - - -/* -=============== -trigger_heal_use -=============== -*/ -void trigger_heal_use( gentity_t *self, gentity_t *other, gentity_t *activator ) -{ -  if( self->r.linked ) -    trap_UnlinkEntity( self ); -  else -    trap_LinkEntity( self ); -} - -/* -=============== -trigger_heal_touch -=============== -*/ -void trigger_heal_touch( gentity_t *self, gentity_t *other, trace_t *trace ) -{ -  int max; - -  if( !other->client ) -    return; - -  if( self->timestamp > level.time ) -    return; - -  if( self->spawnflags & 2 ) -    self->timestamp = level.time + 1000; -  else -    self->timestamp = level.time + FRAMETIME; - -  max = other->client->ps.stats[ STAT_MAX_HEALTH ]; - -  other->health += self->damage; - -  if( other->health > max ) -    other->health = max; - -  other->client->ps.stats[ STAT_HEALTH ] = other->health; -} - -/* -=============== -SP_trigger_heal -=============== -*/ -void SP_trigger_heal( gentity_t *self ) -{ -  G_SpawnInt( "heal", "5", &self->damage ); - -  self->touch = trigger_heal_touch; -  self->use = trigger_heal_use; - -  InitTrigger( self ); - -  // link in to the world if starting active -  if( !( self->spawnflags & 1 ) ) -    trap_LinkEntity( self ); -} - - -/* -=============== -trigger_ammo_touch -=============== -*/ -void trigger_ammo_touch( gentity_t *self, gentity_t *other, trace_t *trace ) -{ -  int ammo, clips, maxClips, maxAmmo; - -  if( !other->client ) -    return; - -  if( other->client->ps.stats[ STAT_PTEAM ] != PTE_HUMANS ) -    return; - -  if( self->timestamp > level.time ) -    return; - -  if( other->client->ps.weaponstate != WEAPON_READY ) -    return; - -  if( BG_FindUsesEnergyForWeapon( other->client->ps.weapon ) && self->spawnflags & 2 ) -    return; - -  if( !BG_FindUsesEnergyForWeapon( other->client->ps.weapon ) && self->spawnflags & 4 ) -    return; - -  if( self->spawnflags & 1 ) -    self->timestamp = level.time + 1000; -  else -    self->timestamp = level.time + FRAMETIME; - -  BG_FindAmmoForWeapon( other->client->ps.weapon, &maxAmmo, &maxClips ); -  BG_UnpackAmmoArray( other->client->ps.weapon, other->client->ps.ammo, other->client->ps.powerups, -                      &ammo, &clips ); - -  if( ( ammo + self->damage ) > maxAmmo ) -  { -    if( clips < maxClips ) -    { -      clips++; -      ammo = 1; -    } -    else -      ammo = maxAmmo; -  } -  else -    ammo += self->damage; - -  BG_PackAmmoArray( other->client->ps.weapon, other->client->ps.ammo, other->client->ps.powerups, -                    ammo, clips ); -} - -/* -=============== -SP_trigger_ammo -=============== -*/ -void SP_trigger_ammo( gentity_t *self ) -{ -  G_SpawnInt( "ammo", "1", &self->damage ); - -  self->touch = trigger_ammo_touch; - -  InitTrigger( self ); -  trap_LinkEntity( self ); -} diff --git a/mod/src/game/g_utils.c b/mod/src/game/g_utils.c deleted file mode 100644 index 9b163a92..00000000 --- a/mod/src/game/g_utils.c +++ /dev/null @@ -1,1071 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// g_utils.c -- misc utility functions for game module - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -typedef struct -{ -  char oldShader[ MAX_QPATH ]; -  char newShader[ MAX_QPATH ]; -  float timeOffset; -} shaderRemap_t; - -#define MAX_SHADER_REMAPS 128 - -int remapCount = 0; -shaderRemap_t remappedShaders[ MAX_SHADER_REMAPS ]; - -void AddRemap( const char *oldShader, const char *newShader, float timeOffset ) -{ -  int i; - -  for( i = 0; i < remapCount; i++ ) -  { -    if( Q_stricmp( oldShader, remappedShaders[ i ].oldShader ) == 0 ) -    { -      // found it, just update this one -      strcpy( remappedShaders[ i ].newShader,newShader ); -      remappedShaders[ i ].timeOffset = timeOffset; -      return; -    } -  } - -  if( remapCount < MAX_SHADER_REMAPS ) -  { -    strcpy( remappedShaders[ remapCount ].newShader,newShader ); -    strcpy( remappedShaders[ remapCount ].oldShader,oldShader ); -    remappedShaders[ remapCount ].timeOffset = timeOffset; -    remapCount++; -  } -} - -const char *BuildShaderStateConfig( void ) -{ -  static char buff[ MAX_STRING_CHARS * 4 ]; -  char        out[ ( MAX_QPATH * 2 ) + 5 ]; -  int         i; - -  memset( buff, 0, MAX_STRING_CHARS ); - -  for( i = 0; i < remapCount; i++ ) -  { -    Com_sprintf( out, ( MAX_QPATH * 2 ) + 5, "%s=%s:%5.2f@", remappedShaders[ i ].oldShader, -                 remappedShaders[ i ].newShader, remappedShaders[ i ].timeOffset ); -    Q_strcat( buff, sizeof( buff ), out ); -  } -  return buff; -} - - -/* -========================================================================= - -model / sound configstring indexes - -========================================================================= -*/ - -/* -================ -G_FindConfigstringIndex - -================ -*/ -int G_FindConfigstringIndex( char *name, int start, int max, qboolean create ) -{ -  int   i; -  char  s[ MAX_STRING_CHARS ]; - -  if( !name || !name[ 0 ] ) -    return 0; - -  for( i = 1; i < max; i++ ) -  { -    trap_GetConfigstring( start + i, s, sizeof( s ) ); -    if( !s[ 0 ] ) -      break; - -    if( !strcmp( s, name ) ) -      return i; -  } - -  if( !create ) -    return 0; - -  if( i == max ) -    G_Error( "G_FindConfigstringIndex: overflow" ); - -  trap_SetConfigstring( start + i, name ); - -  return i; -} - -//TA: added ParticleSystemIndex -int G_ParticleSystemIndex( char *name ) -{ -  return G_FindConfigstringIndex( name, CS_PARTICLE_SYSTEMS, MAX_GAME_PARTICLE_SYSTEMS, qtrue ); -} - -//TA: added ShaderIndex -int G_ShaderIndex( char *name ) -{ -  return G_FindConfigstringIndex( name, CS_SHADERS, MAX_SHADERS, qtrue ); -} - -int G_ModelIndex( char *name ) -{ -  return G_FindConfigstringIndex( name, CS_MODELS, MAX_MODELS, qtrue ); -} - -int G_SoundIndex( char *name ) -{ -  return G_FindConfigstringIndex( name, CS_SOUNDS, MAX_SOUNDS, qtrue ); -} - -//===================================================================== - - -/* -================ -G_TeamCommand - -Broadcasts a command to only a specific team -================ -*/ -void G_TeamCommand( pTeam_t team, char *cmd ) -{ -  int   i; - -  for( i = 0 ; i < level.maxclients ; i++ ) -  { -    if( level.clients[ i ].pers.connected == CON_CONNECTED ) -    { -      if( level.clients[ i ].ps.stats[ STAT_PTEAM ] == team ) -        G_SendCommandFromServer( i, va( "%s", cmd ) ); -    } -  } -} - - -/* -============= -G_Find - -Searches all active entities for the next one that holds -the matching string at fieldofs (use the FOFS() macro) in the structure. - -Searches beginning at the entity after from, or the beginning if NULL -NULL will be returned if the end of the list is reached. - -============= -*/ -gentity_t *G_Find( gentity_t *from, int fieldofs, const char *match ) -{ -  char  *s; - -  if( !from ) -    from = g_entities; -  else -    from++; - -  for( ; from < &g_entities[ level.num_entities ]; from++ ) -  { -    if( !from->inuse ) -      continue; -    s = *(char **)( (byte *)from + fieldofs ); - -    if( !s ) -      continue; - -    if( !Q_stricmp( s, match ) ) -      return from; -  } - -  return NULL; -} - - -/* -============= -G_PickTarget - -Selects a random entity from among the targets -============= -*/ -#define MAXCHOICES  32 - -gentity_t *G_PickTarget( char *targetname ) -{ -  gentity_t *ent = NULL; -  int       num_choices = 0; -  gentity_t *choice[ MAXCHOICES ]; - -  if( !targetname ) -  { -    G_Printf("G_PickTarget called with NULL targetname\n"); -    return NULL; -  } - -  while( 1 ) -  { -    ent = G_Find( ent, FOFS( targetname ), targetname ); - -    if( !ent ) -      break; - -    choice[ num_choices++ ] = ent; - -    if( num_choices == MAXCHOICES ) -      break; -  } - -  if( !num_choices ) -  { -    G_Printf( "G_PickTarget: target %s not found\n", targetname ); -    return NULL; -  } - -  return choice[ rand( ) % num_choices ]; -} - - -/* -============================== -G_UseTargets - -"activator" should be set to the entity that initiated the firing. - -Search for (string)targetname in all entities that -match (string)self.target and call their .use function - -============================== -*/ -void G_UseTargets( gentity_t *ent, gentity_t *activator ) -{ -  gentity_t   *t; - -  if( !ent ) -    return; - -  if( ent->targetShaderName && ent->targetShaderNewName ) -  { -    float f = level.time * 0.001; -    AddRemap( ent->targetShaderName, ent->targetShaderNewName, f ); -    trap_SetConfigstring( CS_SHADERSTATE, BuildShaderStateConfig( ) ); -  } - -  if( !ent->target ) -    return; - -  t = NULL; -  while( ( t = G_Find( t, FOFS( targetname ), ent->target ) ) != NULL ) -  { -    if( t == ent ) -      G_Printf( "WARNING: Entity used itself.\n" ); -    else -    { -      if( t->use ) -        t->use( t, ent, activator ); -    } - -    if( !ent->inuse ) -    { -      G_Printf( "entity was removed while using targets\n" ); -      return; -    } -  } -} - - -/* -============= -TempVector - -This is just a convenience function -for making temporary vectors for function calls -============= -*/ -float *tv( float x, float y, float z ) -{ -  static  int     index; -  static  vec3_t  vecs[ 8 ]; -  float           *v; - -  // use an array so that multiple tempvectors won't collide -  // for a while -  v = vecs[ index ]; -  index = ( index + 1 ) & 7; - -  v[ 0 ] = x; -  v[ 1 ] = y; -  v[ 2 ] = z; - -  return v; -} - - -/* -============= -VectorToString - -This is just a convenience function -for printing vectors -============= -*/ -char *vtos( const vec3_t v ) -{ -  static  int   index; -  static  char  str[ 8 ][ 32 ]; -  char          *s; - -  // use an array so that multiple vtos won't collide -  s = str[ index ]; -  index = ( index + 1 ) & 7; - -  Com_sprintf( s, 32, "(%i %i %i)", (int)v[ 0 ], (int)v[ 1 ], (int)v[ 2 ] ); - -  return s; -} - - -/* -=============== -G_SetMovedir - -The editor only specifies a single value for angles (yaw), -but we have special constants to generate an up or down direction. -Angles will be cleared, because it is being used to represent a direction -instead of an orientation. -=============== -*/ -void G_SetMovedir( vec3_t angles, vec3_t movedir ) -{ -  static vec3_t VEC_UP        = { 0, -1, 0 }; -  static vec3_t MOVEDIR_UP    = { 0, 0, 1 }; -  static vec3_t VEC_DOWN      = { 0, -2, 0 }; -  static vec3_t MOVEDIR_DOWN  = { 0, 0, -1 }; - -  if( VectorCompare( angles, VEC_UP ) ) -    VectorCopy( MOVEDIR_UP, movedir ); -  else if( VectorCompare( angles, VEC_DOWN ) ) -    VectorCopy( MOVEDIR_DOWN, movedir ); -  else -    AngleVectors( angles, movedir, NULL, NULL ); - -  VectorClear( angles ); -} - - -float vectoyaw( const vec3_t vec ) -{ -  float yaw; - -  if( vec[ YAW ] == 0 && vec[ PITCH ] == 0 ) -  { -    yaw = 0; -  } -  else -  { -    if( vec[ PITCH ] ) -      yaw = ( atan2( vec[ YAW ], vec[ PITCH ] ) * 180 / M_PI ); -    else if( vec[ YAW ] > 0 ) -      yaw = 90; -    else -      yaw = 270; - -    if( yaw < 0 ) -      yaw += 360; -  } - -  return yaw; -} - - -void G_InitGentity( gentity_t *e ) -{ -  e->inuse = qtrue; -  e->classname = "noclass"; -  e->s.number = e - g_entities; -  e->r.ownerNum = ENTITYNUM_NONE; -} - -/* -================= -G_Spawn - -Either finds a free entity, or allocates a new one. - -  The slots from 0 to MAX_CLIENTS-1 are always reserved for clients, and will -never be used by anything else. - -Try to avoid reusing an entity that was recently freed, because it -can cause the client to think the entity morphed into something else -instead of being removed and recreated, which can cause interpolated -angles and bad trails. -================= -*/ -gentity_t *G_Spawn( void ) -{ -  int       i, force; -  gentity_t *e; - -  e = NULL; // shut up warning -  i = 0;    // shut up warning - -  for( force = 0; force < 2; force++ ) -  { -    // if we go through all entities and can't find one to free, -    // override the normal minimum times before use -    e = &g_entities[ MAX_CLIENTS ]; - -    for( i = MAX_CLIENTS; i < level.num_entities; i++, e++ ) -    { -      if( e->inuse ) -        continue; - -      // the first couple seconds of server time can involve a lot of -      // freeing and allocating, so relax the replacement policy -      if( !force && e->freetime > level.startTime + 2000 && level.time - e->freetime < 1000 ) -        continue; - -      // reuse this slot -      G_InitGentity( e ); -      return e; -    } - -    if( i != MAX_GENTITIES ) -      break; -  } - -  if( i == ENTITYNUM_MAX_NORMAL ) -  { -    for( i = 0; i < MAX_GENTITIES; i++ ) -      G_Printf( "%4i: %s\n", i, g_entities[ i ].classname ); - -    G_Error( "G_Spawn: no free entities" ); -  } - -  // open up a new slot -  level.num_entities++; - -  // let the server system know that there are more entities -  trap_LocateGameData( level.gentities, level.num_entities, sizeof( gentity_t ), -    &level.clients[ 0 ].ps, sizeof( level.clients[ 0 ] ) ); - -  G_InitGentity( e ); -  return e; -} - - -/* -================= -G_EntitiesFree -================= -*/ -qboolean G_EntitiesFree( void ) -{ -  int     i; -  gentity_t *e; - -  e = &g_entities[ MAX_CLIENTS ]; - -  for( i = MAX_CLIENTS; i < level.num_entities; i++, e++ ) -  { -    if( e->inuse ) -      continue; - -    // slot available -    return qtrue; -  } - -  return qfalse; -} - - -/* -================= -G_FreeEntity - -Marks the entity as free -================= -*/ -void G_FreeEntity( gentity_t *ent ) -{ -  trap_UnlinkEntity( ent );   // unlink from world - -  if( ent->neverFree ) -    return; - -  memset( ent, 0, sizeof( *ent ) ); -  ent->classname = "freent"; -  ent->freetime = level.time; -  ent->inuse = qfalse; -} - -/* -================= -G_TempEntity - -Spawns an event entity that will be auto-removed -The origin will be snapped to save net bandwidth, so care -must be taken if the origin is right on a surface (snap towards start vector first) -================= -*/ -gentity_t *G_TempEntity( vec3_t origin, int event ) -{ -  gentity_t *e; -  vec3_t    snapped; - -  e = G_Spawn( ); -  e->s.eType = ET_EVENTS + event; - -  e->classname = "tempEntity"; -  e->eventTime = level.time; -  e->freeAfterEvent = qtrue; - -  VectorCopy( origin, snapped ); -  SnapVector( snapped );    // save network bandwidth -  G_SetOrigin( e, snapped ); - -  // find cluster for PVS -  trap_LinkEntity( e ); - -  return e; -} - - - -/* -============================================================================== - -Kill box - -============================================================================== -*/ - -/* -================= -G_KillBox - -Kills all entities that would touch the proposed new positioning -of ent.  Ent should be unlinked before calling this! -================= -*/ -void G_KillBox( gentity_t *ent ) -{ -  int       i, num; -  int       touch[ MAX_GENTITIES ]; -  gentity_t *hit; -  vec3_t    mins, maxs; - -  VectorAdd( ent->client->ps.origin, ent->r.mins, mins ); -  VectorAdd( ent->client->ps.origin, ent->r.maxs, maxs ); -  num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES ); - -  for( i = 0; i < num; i++ ) -  { -    hit = &g_entities[ touch[ i ] ]; - -    if( !hit->client ) -      continue; - -    //TA: impossible to telefrag self -    if( ent == hit ) -      continue; - -    // nail it -    G_Damage( hit, ent, ent, NULL, NULL, -      100000, DAMAGE_NO_PROTECTION, MOD_TELEFRAG ); -  } - -} - -//============================================================================== - -/* -=============== -G_AddPredictableEvent - -Use for non-pmove events that would also be predicted on the -client side: jumppads and item pickups -Adds an event+parm and twiddles the event counter -=============== -*/ -void G_AddPredictableEvent( gentity_t *ent, int event, int eventParm ) -{ -  if( !ent->client ) -    return; - -  BG_AddPredictableEventToPlayerstate( event, eventParm, &ent->client->ps ); -} - - -/* -=============== -G_AddEvent - -Adds an event+parm and twiddles the event counter -=============== -*/ -void G_AddEvent( gentity_t *ent, int event, int eventParm ) -{ -  int bits; - -  if( !event ) -  { -    G_Printf( "G_AddEvent: zero event added for entity %i\n", ent->s.number ); -    return; -  } - -  // clients need to add the event in playerState_t instead of entityState_t -  if( ent->client ) -  { -    bits = ent->client->ps.externalEvent & EV_EVENT_BITS; -    bits = ( bits + EV_EVENT_BIT1 ) & EV_EVENT_BITS; -    ent->client->ps.externalEvent = event | bits; -    ent->client->ps.externalEventParm = eventParm; -    ent->client->ps.externalEventTime = level.time; -  } -  else -  { -    bits = ent->s.event & EV_EVENT_BITS; -    bits = ( bits + EV_EVENT_BIT1 ) & EV_EVENT_BITS; -    ent->s.event = event | bits; -    ent->s.eventParm = eventParm; -  } - -  ent->eventTime = level.time; -} - - -/* -=============== -G_BroadcastEvent - -Sends an event to every client -=============== -*/ -void G_BroadcastEvent( int event, int eventParm ) -{ -  gentity_t *ent; - -  ent = G_TempEntity( vec3_origin, event ); -  ent->s.eventParm = eventParm; -  ent->r.svFlags = SVF_BROADCAST; // send to everyone -} - - -/* -============= -G_Sound -============= -*/ -void G_Sound( gentity_t *ent, int channel, int soundIndex ) -{ -  gentity_t *te; - -  te = G_TempEntity( ent->r.currentOrigin, EV_GENERAL_SOUND ); -  te->s.eventParm = soundIndex; -} - - -/* -============= -G_ClientIsLagging -============= -*/ -qboolean G_ClientIsLagging( gclient_t *client ) -{ -  if( client ) -  { -    if( client->ps.ping >= 999 ) -      return qtrue; -    else -      return qfalse; -  } - -  return qfalse; //is a non-existant client lagging? woooo zen -} - - -static commandQueue_t queuedCommands[ MAX_CLIENTS ]; - -/* -=============== -G_PopCommandQueue - -Return the front of a command queue -Must use immediately or copy to a buffer -=============== -*/ -static const char *G_PopCommandQueue( commandQueue_t *cq ) -{ -  if( cq->front ) -  { -    commandQueueElement_t *cqe = cq->front; - -    cq->front = cqe->next; - -    // last element in the queue -    if( cq->front == NULL ) -      cq->back = NULL; - -    cq->nextCommandTime = level.time + g_minCommandPeriod.integer; -    cqe->used = qfalse; - -    return cqe->command; -  } -  else -    return NULL; -} - -/* -=============== -G_PushCommandQueue - -Put a command on a command queue -=============== -*/ -static void G_PushCommandQueue( commandQueue_t *cq, const char *cmd ) -{ -  int i; - -  for( i = 0; i < MAX_QUEUE_COMMANDS; i++ ) -  { -    commandQueueElement_t *cqe = &cq->pool[ i ]; - -    if( !cqe->used ) -    { -      cqe->used = qtrue; -      cqe->next = NULL; -      Q_strncpyz( cqe->command, cmd, MAX_TOKEN_CHARS ); - -      if( cq->back ) -      { -        cq->back->next = cqe; -        cq->back = cqe; -      } -      else -      { -        cq->front = cqe; -        cq->back = cqe; -      } - -      return; -    } -  } - -  //drop the command -} - -/* -=============== -G_PrintCommandQueue -=============== -*/ -#if 0 //quiet compiler -static void G_PrintCommandQueue( commandQueue_t *cq ) -{ -  commandQueueElement_t *cqe; - -  if( cq->front ) -  { -    cqe = cq->front; - -    do -    { -      G_Printf( "->\"%s\"", cqe->command ); -    } while( ( cqe = cqe->next ) ); - -    G_Printf( "\n" ); -  } -} -#endif - -/* -=============== -G_ReadyToDequeue -=============== -*/ -static qboolean G_ReadyToDequeue( commandQueue_t *cq ) -{ -  if( !cq ) -    return qfalse; - -  return cq->front && cq->nextCommandTime <= level.time; -} - -/* -=============== -G_ProcessCommandQueues - -Check for any outstanding commands to be sent -=============== -*/ -void G_ProcessCommandQueues( void ) -{ -  int i; - -  for( i = 0; i < MAX_CLIENTS; i++ ) -  { -    gclient_t       *cl = &level.clients[ i ]; -    commandQueue_t  *cq = &queuedCommands[ i ]; - -    if( !G_ClientIsLagging( cl ) && G_ReadyToDequeue( cq ) ) -    { -      const char *command = G_PopCommandQueue( cq ); - -      if( command ) -        trap_SendServerCommand( i, command ); -    } -  } -} - -/* -=============== -G_InitCommandQueue -=============== -*/ -void G_InitCommandQueue( int clientNum ) -{ -  int             i; -  commandQueue_t  *cq = &queuedCommands[ clientNum ]; - -  if( clientNum >= 0 && clientNum < MAX_CLIENTS ) -  { -    cq->front = cq->back = NULL; -    cq->nextCommandTime = 0; - -    for( i = 0; i < MAX_QUEUE_COMMANDS; i++ ) -    { -      commandQueueElement_t *cqe = &cq->pool[ i ]; - -      cqe->used = qfalse; -    } -  } -} - -/* -=============== -G_SendCommandFromServer - -Sends a command to a client -=============== -*/ -void G_SendCommandFromServer( int clientNum, const char *cmd ) -{ -  commandQueue_t  *cq = &queuedCommands[ clientNum ]; - -  if( clientNum < 0 ) -    cq = NULL; - -  if( strlen( cmd ) > 1022 ) -  { -    G_LogPrintf( "G_SendCommandFromServer( %d, ... ) length exceeds 1022.\n", clientNum ); -    G_LogPrintf( "cmd [%s]\n", cmd ); -    return; -  } - -  if( cq ) -  { -    gclient_t *cl = &level.clients[ clientNum ]; - -    if( cq->nextCommandTime > level.time || G_ClientIsLagging( cl ) ) -    { -      //can't send yet, so queue the command up -      G_PushCommandQueue( cq, cmd ); -    } -    else -    { -      cq->nextCommandTime = level.time + g_minCommandPeriod.integer; -      trap_SendServerCommand( clientNum, cmd ); -    } -  } -  else //no queue exists for this client -    trap_SendServerCommand( clientNum, cmd ); -} - -//============================================================================== - - -/* -================ -G_SetOrigin - -Sets the pos trajectory for a fixed position -================ -*/ -void G_SetOrigin( gentity_t *ent, vec3_t origin ) -{ -  VectorCopy( origin, ent->s.pos.trBase ); -  ent->s.pos.trType = TR_STATIONARY; -  ent->s.pos.trTime = 0; -  ent->s.pos.trDuration = 0; -  VectorClear( ent->s.pos.trDelta ); - -  VectorCopy( origin, ent->r.currentOrigin ); -  VectorCopy( origin, ent->s.origin ); //TA: if shit breaks - blame this line -} - -//TA: from quakestyle.telefragged.com -// (NOBODY): Code helper function -// -gentity_t *G_FindRadius( gentity_t *from, vec3_t org, float rad ) -{ -  vec3_t  eorg; -  int j; - -  if( !from ) -    from = g_entities; -  else -    from++; - -  for( ; from < &g_entities[ level.num_entities ]; from++ ) -  { -    if( !from->inuse ) -      continue; - -    for( j = 0; j < 3; j++ ) -      eorg[ j ] = org[ j ] - ( from->r.currentOrigin[ j ] + ( from->r.mins[ j ] + from->r.maxs[ j ] ) * 0.5 ); - -    if( VectorLength( eorg ) > rad ) -      continue; - -    return from; -  } - -  return NULL; -} - -/* -=============== -G_Visible - -Test for a LOS between two entities -=============== -*/ -qboolean G_Visible( gentity_t *ent1, gentity_t *ent2 ) -{ -  trace_t trace; - -  trap_Trace( &trace, ent1->s.pos.trBase, NULL, NULL, ent2->s.pos.trBase, ent1->s.number, MASK_SHOT ); - -  if( trace.contents & CONTENTS_SOLID ) -    return qfalse; - -  return qtrue; -} - -/* -=============== -G_ClosestEnt - -Test a list of entities for the closest to a particular point -=============== -*/ -gentity_t *G_ClosestEnt( vec3_t origin, gentity_t **entities, int numEntities ) -{ -  int       i; -  float     nd, d = 1000000.0f; -  gentity_t *closestEnt = NULL; - -  for( i = 0; i < numEntities; i++ ) -  { -    gentity_t *ent = entities[ i ]; - -    if( ( nd = Distance( origin, ent->s.origin ) ) < d ) -    { -      d = nd; -      closestEnt = ent; -    } -  } - -  return closestEnt; -} - -/* -=============== -G_TriggerMenu - -Trigger a menu on some client -=============== -*/ -void G_TriggerMenu( int clientNum, dynMenu_t menu ) -{ -  char buffer[ 32 ]; - -  Com_sprintf( buffer, 32, "servermenu %d", menu ); -  G_SendCommandFromServer( clientNum, buffer ); -} - - -/* -=============== -G_CloseMenus - -Close all open menus on some client -=============== -*/ -void G_CloseMenus( int clientNum ) -{ -  char buffer[ 32 ]; - -  Com_sprintf( buffer, 32, "serverclosemenus" ); -  G_SendCommandFromServer( clientNum, buffer ); -} - - -/* -================ -DebugLine - -  debug polygons only work when running a local game -  with r_debugSurface set to 2 -================ -*/ -int DebugLine( vec3_t start, vec3_t end, int color ) -{ -  vec3_t  points[ 4 ], dir, cross, up = { 0, 0, 1 }; -  float   dot; - -  VectorCopy( start, points[ 0 ] ); -  VectorCopy( start, points[ 1 ] ); -  //points[1][2] -= 2; -  VectorCopy( end, points[ 2 ] ); -  //points[2][2] -= 2; -  VectorCopy( end, points[ 3 ] ); - - -  VectorSubtract( end, start, dir ); -  VectorNormalize( dir ); -  dot = DotProduct( dir, up ); - -  if( dot > 0.99 || dot < -0.99 ) -    VectorSet( cross, 1, 0, 0 ); -  else -    CrossProduct( dir, up, cross ); - -  VectorNormalize( cross ); - -  VectorMA(points[ 0 ], 2, cross, points[ 0 ] ); -  VectorMA(points[ 1 ], -2, cross, points[ 1 ] ); -  VectorMA(points[ 2 ], -2, cross, points[ 2 ] ); -  VectorMA(points[ 3 ], 2, cross, points[ 3 ] ); - -  return trap_DebugPolygonCreate( color, 4, points ); -} - diff --git a/mod/src/game/g_weapon.c b/mod/src/game/g_weapon.c deleted file mode 100644 index a18a8c39..00000000 --- a/mod/src/game/g_weapon.c +++ /dev/null @@ -1,1553 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// g_weapon.c -// perform the server side effects of a weapon firing - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "g_local.h" - -static  vec3_t  forward, right, up; -static  vec3_t  muzzle; - -/* -================ -G_ForceWeaponChange -================ -*/ -void G_ForceWeaponChange( gentity_t *ent, weapon_t weapon ) -{ -  int i; - -  if( ent ) -  { -    ent->client->ps.pm_flags |= PMF_WEAPON_SWITCH; - -    if( weapon == WP_NONE ) -    { -      //switch to the first non blaster weapon -      for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) -      { -        if( i == WP_BLASTER ) -          continue; - -        if( BG_InventoryContainsWeapon( i, ent->client->ps.stats ) ) -        { -          ent->client->ps.persistant[ PERS_NEWWEAPON ] = i; -          break; -        } -      } - -      //only got the blaster to switch to -      if( i == WP_NUM_WEAPONS ) -        ent->client->ps.persistant[ PERS_NEWWEAPON ] = WP_BLASTER; -    } -    else -      ent->client->ps.persistant[ PERS_NEWWEAPON ] = weapon; -  } -} - -/* -================= -G_GiveClientMaxAmmo -================= -*/ -void G_GiveClientMaxAmmo( gentity_t *ent, qboolean buyingEnergyAmmo ) -{ -  int       i; -  int       maxAmmo, maxClips; -  qboolean  weaponType, restoredAmmo = qfalse; - -  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) -  { -    if( buyingEnergyAmmo ) -      weaponType = BG_FindUsesEnergyForWeapon( i ); -    else -      weaponType = !BG_FindUsesEnergyForWeapon( i ); - -    if( BG_InventoryContainsWeapon( i, ent->client->ps.stats ) && -        weaponType && !BG_FindInfinteAmmoForWeapon( i ) && -        !BG_WeaponIsFull( i, ent->client->ps.stats, -          ent->client->ps.ammo, ent->client->ps.powerups ) ) -    { -      BG_FindAmmoForWeapon( i, &maxAmmo, &maxClips ); - -      if( buyingEnergyAmmo ) -      { -        G_AddEvent( ent, EV_RPTUSE_SOUND, 0 ); - -        if( BG_InventoryContainsUpgrade( UP_BATTPACK, ent->client->ps.stats ) ) -          maxAmmo = (int)( (float)maxAmmo * BATTPACK_MODIFIER ); -      } - -      BG_PackAmmoArray( i, ent->client->ps.ammo, ent->client->ps.powerups, -                        maxAmmo, maxClips ); - -      restoredAmmo = qtrue; -    } -  } - -  if( restoredAmmo ) -    G_ForceWeaponChange( ent, ent->client->ps.weapon ); -} - -/* -================ -G_BounceProjectile -================ -*/ -void G_BounceProjectile( vec3_t start, vec3_t impact, vec3_t dir, vec3_t endout ) -{ -  vec3_t v, newv; -  float dot; - -  VectorSubtract( impact, start, v ); -  dot = DotProduct( v, dir ); -  VectorMA( v, -2 * dot, dir, newv ); - -  VectorNormalize(newv); -  VectorMA(impact, 8192, newv, endout); -} - -/* -====================== -SnapVectorTowards - -Round a vector to integers for more efficient network -transmission, but make sure that it rounds towards a given point -rather than blindly truncating.  This prevents it from truncating -into a wall. -====================== -*/ -void SnapVectorTowards( vec3_t v, vec3_t to ) -{ -  int   i; - -  for( i = 0 ; i < 3 ; i++ ) -  { -    if( to[ i ] <= v[ i ] ) -      v[ i ] = (int)v[ i ]; -    else -      v[ i ] = (int)v[ i ] + 1; -  } -} - -/* -=============== -meleeAttack -=============== -*/ -void meleeAttack( gentity_t *ent, float range, float width, int damage, meansOfDeath_t mod ) -{ -  trace_t   tr; -  vec3_t    end; -  gentity_t *tent; -  gentity_t *traceEnt; -  vec3_t    mins, maxs; - -  VectorSet( mins, -width, -width, -width ); -  VectorSet( maxs, width, width, width ); - -  // set aiming directions -  AngleVectors( ent->client->ps.viewangles, forward, right, up ); - -  CalcMuzzlePoint( ent, forward, right, up, muzzle ); - -  VectorMA( muzzle, range, forward, end ); - -  trap_Trace( &tr, muzzle, mins, maxs, end, ent->s.number, MASK_SHOT ); -  if( tr.surfaceFlags & SURF_NOIMPACT ) -    return; - -  traceEnt = &g_entities[ tr.entityNum ]; - -  // send blood impact -  if( traceEnt->takedamage && traceEnt->client ) -  { -    tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT ); -    tent->s.otherEntityNum = traceEnt->s.number; -    tent->s.eventParm = DirToByte( tr.plane.normal ); -    tent->s.weapon = ent->s.weapon; -    tent->s.generic1 = ent->s.generic1; //weaponMode -  } - -  if( traceEnt->takedamage ) -    G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, mod ); -} - -/* -====================================================================== - -MACHINEGUN - -====================================================================== -*/ - -void bulletFire( gentity_t *ent, float spread, int damage, int mod ) -{ -  trace_t   tr; -  vec3_t    end; -  float   r; -  float   u; -  gentity_t *tent; -  gentity_t *traceEnt; - -  r = random( ) * M_PI * 2.0f; -  u = sin( r ) * crandom( ) * spread * 16; -  r = cos( r ) * crandom( ) * spread * 16; -  VectorMA( muzzle, 8192 * 16, forward, end ); -  VectorMA( end, r, right, end ); -  VectorMA( end, u, up, end ); - -  trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); -  if( tr.surfaceFlags & SURF_NOIMPACT ) -    return; - -  traceEnt = &g_entities[ tr.entityNum ]; - -  // snap the endpos to integers, but nudged towards the line -  SnapVectorTowards( tr.endpos, muzzle ); - -  // send bullet impact -  if( traceEnt->takedamage && traceEnt->client ) -  { -    tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_FLESH ); -    tent->s.eventParm = traceEnt->s.number; -  } -  else -  { -    tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_WALL ); -    tent->s.eventParm = DirToByte( tr.plane.normal ); -  } -  tent->s.otherEntityNum = ent->s.number; - -  if( traceEnt->takedamage ) -  { -    G_Damage( traceEnt, ent, ent, forward, tr.endpos, -      damage, 0, mod ); -  } -} - -/* -====================================================================== - -SHOTGUN - -====================================================================== -*/ - -// this should match CG_ShotgunPattern -void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent ) -{ -  int        i; -  float      r, u; -  vec3_t    end; -  vec3_t    forward, right, up; -  trace_t    tr; -  gentity_t  *traceEnt; - -  // derive the right and up vectors from the forward vector, because -  // the client won't have any other information -  VectorNormalize2( origin2, forward ); -  PerpendicularVector( right, forward ); -  CrossProduct( forward, right, up ); - -  // generate the "random" spread pattern -  for( i = 0; i < SHOTGUN_PELLETS; i++ ) -  { -    r = Q_crandom( &seed ) * SHOTGUN_SPREAD * 16; -    u = Q_crandom( &seed ) * SHOTGUN_SPREAD * 16; -    VectorMA( origin, 8192 * 16, forward, end ); -    VectorMA( end, r, right, end ); -    VectorMA( end, u, up, end ); - -    trap_Trace( &tr, origin, NULL, NULL, end, ent->s.number, MASK_SHOT ); -    traceEnt = &g_entities[ tr.entityNum ]; - -    // send bullet impact -    if( !( tr.surfaceFlags & SURF_NOIMPACT ) ) -    { -      if( traceEnt->takedamage ) -        G_Damage( traceEnt, ent, ent, forward, tr.endpos,  SHOTGUN_DMG, 0, MOD_SHOTGUN ); -    } -  } -} - - -void shotgunFire( gentity_t *ent ) -{ -  gentity_t    *tent; - -  // send shotgun blast -  tent = G_TempEntity( muzzle, EV_SHOTGUN ); -  VectorScale( forward, 4096, tent->s.origin2 ); -  SnapVector( tent->s.origin2 ); -  tent->s.eventParm = rand() & 255;    // seed for spread pattern -  tent->s.otherEntityNum = ent->s.number; - -  ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent ); -} - -/* -====================================================================== - -MASS DRIVER - -====================================================================== -*/ - -void massDriverFire( gentity_t *ent ) -{ -  trace_t   tr; -  vec3_t    end; -  gentity_t *tent; -  gentity_t *traceEnt; - -  VectorMA( muzzle, 8192 * 16, forward, end ); - -  trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); -  if( tr.surfaceFlags & SURF_NOIMPACT ) -    return; - -  traceEnt = &g_entities[ tr.entityNum ]; - -  // snap the endpos to integers, but nudged towards the line -  SnapVectorTowards( tr.endpos, muzzle ); - -  // send impact -  if( traceEnt->takedamage && traceEnt->client ) -  { -    tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT ); -    tent->s.otherEntityNum = traceEnt->s.number; -    tent->s.eventParm = DirToByte( tr.plane.normal ); -    tent->s.weapon = ent->s.weapon; -    tent->s.generic1 = ent->s.generic1; //weaponMode -  } -  else -  { -    tent = G_TempEntity( tr.endpos, EV_MISSILE_MISS ); -    tent->s.eventParm = DirToByte( tr.plane.normal ); -    tent->s.weapon = ent->s.weapon; -    tent->s.generic1 = ent->s.generic1; //weaponMode -  } - -  if( traceEnt->takedamage ) -  { -    G_Damage( traceEnt, ent, ent, forward, tr.endpos, -      MDRIVER_DMG, 0, MOD_MDRIVER ); -  } -} - -/* -====================================================================== - -LOCKBLOB - -====================================================================== -*/ - -void lockBlobLauncherFire( gentity_t *ent ) -{ -  gentity_t *m; - -  m = fire_lockblob( ent, muzzle, forward ); - -//  VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta );  // "real" physics -} - -/* -====================================================================== - -HIVE - -====================================================================== -*/ - -void hiveFire( gentity_t *ent ) -{ -  gentity_t *m; - -  m = fire_hive( ent, muzzle, forward ); - -//  VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta );  // "real" physics -} - -/* -====================================================================== - -BLASTER PISTOL - -====================================================================== -*/ - -void blasterFire( gentity_t *ent ) -{ -  gentity_t *m; - -  m = fire_blaster( ent, muzzle, forward ); - -//  VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta );  // "real" physics -} - -/* -====================================================================== - -PULSE RIFLE - -====================================================================== -*/ - -void pulseRifleFire( gentity_t *ent ) -{ -  gentity_t *m; - -  m = fire_pulseRifle( ent, muzzle, forward ); - -//  VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta );  // "real" physics -} - -/* -====================================================================== - -FLAME THROWER - -====================================================================== -*/ - -void flamerFire( gentity_t *ent ) -{ -  gentity_t *m; - -  m = fire_flamer( ent, muzzle, forward ); -} - -/* -====================================================================== - -GRENADE - -====================================================================== -*/ - -void throwGrenade( gentity_t *ent ) -{ -  gentity_t *m; - -  m = launch_grenade( ent, muzzle, forward ); -} - -/* -====================================================================== - -LAS GUN - -====================================================================== -*/ - -/* -=============== -lasGunFire -=============== -*/ -void lasGunFire( gentity_t *ent ) -{ -  trace_t   tr; -  vec3_t    end; -  gentity_t *tent; -  gentity_t *traceEnt; - -  VectorMA( muzzle, 8192 * 16, forward, end ); - -  trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); -  if( tr.surfaceFlags & SURF_NOIMPACT ) -    return; - -  traceEnt = &g_entities[ tr.entityNum ]; - -  // snap the endpos to integers, but nudged towards the line -  SnapVectorTowards( tr.endpos, muzzle ); - -  // send impact -  if( traceEnt->takedamage && traceEnt->client ) -  { -    tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT ); -    tent->s.otherEntityNum = traceEnt->s.number; -    tent->s.eventParm = DirToByte( tr.plane.normal ); -    tent->s.weapon = ent->s.weapon; -    tent->s.generic1 = ent->s.generic1; //weaponMode -  } -  else -  { -    tent = G_TempEntity( tr.endpos, EV_MISSILE_MISS ); -    tent->s.eventParm = DirToByte( tr.plane.normal ); -    tent->s.weapon = ent->s.weapon; -    tent->s.generic1 = ent->s.generic1; //weaponMode -  } - -  if( traceEnt->takedamage ) -    G_Damage( traceEnt, ent, ent, forward, tr.endpos, LASGUN_DAMAGE, 0, MOD_LASGUN ); -} - -/* -====================================================================== - -PAIN SAW - -====================================================================== -*/ - -void painSawFire( gentity_t *ent ) -{ -  trace_t   tr; -  vec3_t    end; -  gentity_t *tent; -  gentity_t *traceEnt; - -  // set aiming directions -  AngleVectors( ent->client->ps.viewangles, forward, right, up ); - -  CalcMuzzlePoint( ent, forward, right, up, muzzle ); - -  VectorMA( muzzle, PAINSAW_RANGE, forward, end ); - -  trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); -  if( tr.surfaceFlags & SURF_NOIMPACT ) -    return; - -  traceEnt = &g_entities[ tr.entityNum ]; - -  // send blood impact -  if( traceEnt->takedamage ) -  { -    vec3_t  temp; - -    //hack to get the particle system to line up with the weapon -    VectorCopy( tr.endpos, temp ); -    temp[ 2 ] -= 10.0f; - -    if( traceEnt->client ) -    { -      tent = G_TempEntity( temp, EV_MISSILE_HIT ); -      tent->s.otherEntityNum = traceEnt->s.number; -    } -    else -      tent = G_TempEntity( temp, EV_MISSILE_MISS ); - -    tent->s.eventParm = DirToByte( tr.plane.normal ); -    tent->s.weapon = ent->s.weapon; -    tent->s.generic1 = ent->s.generic1; //weaponMode -  } - -  if( traceEnt->takedamage ) -    G_Damage( traceEnt, ent, ent, forward, tr.endpos, PAINSAW_DAMAGE, DAMAGE_NO_KNOCKBACK, MOD_PAINSAW ); -} - -/* -====================================================================== - -LUCIFER CANNON - -====================================================================== -*/ - -/* -=============== -LCChargeFire -=============== -*/ -void LCChargeFire( gentity_t *ent, qboolean secondary ) -{ -  gentity_t *m; - -  if( secondary ) -    m = fire_luciferCannon( ent, muzzle, forward, LCANNON_SECONDARY_DAMAGE, LCANNON_SECONDARY_RADIUS ); -  else -    m = fire_luciferCannon( ent, muzzle, forward, ent->client->ps.stats[ STAT_MISC ], LCANNON_RADIUS ); - -  ent->client->ps.stats[ STAT_MISC ] = 0; -} - -/* -====================================================================== - -TESLA GENERATOR - -====================================================================== -*/ - - -void teslaFire( gentity_t *ent ) -{ -  trace_t   tr; -  vec3_t    end; -  gentity_t *traceEnt, *tent; - -  VectorMA( muzzle, TESLAGEN_RANGE, forward, end ); - -  trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); - -  if( tr.entityNum == ENTITYNUM_NONE ) -    return; - -  traceEnt = &g_entities[ tr.entityNum ]; - -  if( !traceEnt->client ) -    return; - -  if( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS ) -    return; - -  //so the client side knows -  ent->s.eFlags |= EF_FIRING; - -  if( traceEnt->takedamage ) -  { -    G_Damage( traceEnt, ent, ent, forward, tr.endpos, -      TESLAGEN_DMG, 0, MOD_TESLAGEN ); -  } - -  // snap the endpos to integers to save net bandwidth, but nudged towards the line -  SnapVectorTowards( tr.endpos, muzzle ); - -  // send railgun beam effect -  tent = G_TempEntity( tr.endpos, EV_TESLATRAIL ); - -  VectorCopy( muzzle, tent->s.origin2 ); - -  tent->s.generic1 = ent->s.number; //src -  tent->s.clientNum = traceEnt->s.number; //dest - -  // move origin a bit to come closer to the drawn gun muzzle -  VectorMA( tent->s.origin2, 28, up, tent->s.origin2 ); -} - - -/* -====================================================================== - -BUILD GUN - -====================================================================== -*/ - -/* -=============== -cancelBuildFire -=============== -*/ -void cancelBuildFire( gentity_t *ent ) -{ -  vec3_t      forward, end; -  trace_t     tr; -  gentity_t   *traceEnt; -  int         bHealth; - -  if( ent->client->ps.stats[ STAT_BUILDABLE ] != BA_NONE ) -  { -    ent->client->ps.stats[ STAT_BUILDABLE ] = BA_NONE; -    return; -  } - -  //repair buildable -  if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -  { -    AngleVectors( ent->client->ps.viewangles, forward, NULL, NULL ); -    VectorMA( ent->client->ps.origin, 100, forward, end ); - -    trap_Trace( &tr, ent->client->ps.origin, NULL, NULL, end, ent->s.number, MASK_PLAYERSOLID ); -    traceEnt = &g_entities[ tr.entityNum ]; - -    if( tr.fraction < 1.0 && -        ( traceEnt->s.eType == ET_BUILDABLE ) && -        ( traceEnt->biteam == ent->client->ps.stats[ STAT_PTEAM ] ) && -        ( ( ent->client->ps.weapon >= WP_HBUILD2 ) && -          ( ent->client->ps.weapon <= WP_HBUILD ) ) && -        traceEnt->spawned && traceEnt->health > 0 ) -    { -      if( ent->client->ps.stats[ STAT_MISC ] > 0 ) -      { -        G_AddEvent( ent, EV_BUILD_DELAY, ent->client->ps.clientNum ); -        return; -      } - -      bHealth = BG_FindHealthForBuildable( traceEnt->s.modelindex ); - -      traceEnt->health += HBUILD_HEALRATE; - -      if( traceEnt->health > bHealth ) -        traceEnt->health = bHealth; - -      if( traceEnt->health == bHealth ) -        G_AddEvent( ent, EV_BUILD_REPAIRED, 0 ); -      else -        G_AddEvent( ent, EV_BUILD_REPAIR, 0 ); -    } -  } -  else if( ent->client->ps.weapon == WP_ABUILD2 ) -    meleeAttack( ent, ABUILDER_CLAW_RANGE, ABUILDER_CLAW_WIDTH, -                 ABUILDER_CLAW_DMG, MOD_ABUILDER_CLAW ); //melee attack for alien builder -} - -/* -=============== -buildFire -=============== -*/ -void buildFire( gentity_t *ent, dynMenu_t menu ) -{ -  if( ( ent->client->ps.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) > BA_NONE ) -  { -    if( ent->client->ps.stats[ STAT_MISC ] > 0 ) -    { -      G_AddEvent( ent, EV_BUILD_DELAY, ent->client->ps.clientNum ); -      return; -    } - -    if( G_ValidateBuild( ent, ent->client->ps.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) ) -    { -      if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS && !G_isOvermind( ) ) -      { -        ent->client->ps.stats[ STAT_MISC ] += -          BG_FindBuildDelayForWeapon( ent->s.weapon ) * 2; -      } -      else if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS && !G_isPower( muzzle ) && -          ( ent->client->ps.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) != BA_H_REPEATER ) //hack -      { -        ent->client->ps.stats[ STAT_MISC ] += -          BG_FindBuildDelayForWeapon( ent->s.weapon ) * 2; -      } -      else -        ent->client->ps.stats[ STAT_MISC ] += -          BG_FindBuildDelayForWeapon( ent->s.weapon ); - -      ent->client->ps.stats[ STAT_BUILDABLE ] = BA_NONE; - -      // don't want it bigger than 32k -      if( ent->client->ps.stats[ STAT_MISC ] > 30000 ) -        ent->client->ps.stats[ STAT_MISC ] = 30000; -    } -    return; -  } - -  G_TriggerMenu( ent->client->ps.clientNum, menu ); -} - -void slowBlobFire( gentity_t *ent ) -{ -  gentity_t *m; - -  m = fire_slowBlob( ent, muzzle, forward ); - -//  VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta );  // "real" physics -} - - -/* -====================================================================== - -LEVEL0 - -====================================================================== -*/ - -/* -=============== -CheckVenomAttack -=============== -*/ -qboolean CheckVenomAttack( gentity_t *ent ) -{ -  trace_t   tr; -  vec3_t    end; -  gentity_t *tent; -  gentity_t *traceEnt; -  vec3_t    mins, maxs; -  int       damage = LEVEL0_BITE_DMG; - -  VectorSet( mins, -LEVEL0_BITE_WIDTH, -LEVEL0_BITE_WIDTH, -LEVEL0_BITE_WIDTH ); -  VectorSet( maxs, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH ); - -  // set aiming directions -  AngleVectors( ent->client->ps.viewangles, forward, right, up ); - -  CalcMuzzlePoint( ent, forward, right, up, muzzle ); - -  VectorMA( muzzle, LEVEL0_BITE_RANGE, forward, end ); - -  trap_Trace( &tr, muzzle, mins, maxs, end, ent->s.number, MASK_SHOT ); - -  if( tr.surfaceFlags & SURF_NOIMPACT ) -    return qfalse; - -  traceEnt = &g_entities[ tr.entityNum ]; - -  if( !traceEnt->takedamage ) -    return qfalse; - -  if( !traceEnt->client && !traceEnt->s.eType == ET_BUILDABLE ) -    return qfalse; - -  //allow bites to work against defensive buildables only -  if( traceEnt->s.eType == ET_BUILDABLE ) -  { -    if( traceEnt->s.modelindex != BA_H_MGTURRET && -        traceEnt->s.modelindex != BA_H_TESLAGEN ) -      return qfalse; - -    //hackery -    damage *= 0.5f; -  } - -  if( traceEnt->client ) -  { -    if( traceEnt->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -      return qfalse; -    if( traceEnt->client->ps.stats[ STAT_HEALTH ] <= 0 ) -      return qfalse; -  } - -  // send blood impact -  if( traceEnt->takedamage && traceEnt->client ) -  { -    tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT ); -    tent->s.otherEntityNum = traceEnt->s.number; -    tent->s.eventParm = DirToByte( tr.plane.normal ); -    tent->s.weapon = ent->s.weapon; -    tent->s.generic1 = ent->s.generic1; //weaponMode -  } - -  G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, MOD_LEVEL0_BITE ); - -  return qtrue; -} - -/* -====================================================================== - -LEVEL1 - -====================================================================== -*/ - -/* -=============== -CheckGrabAttack -=============== -*/ -void CheckGrabAttack( gentity_t *ent ) -{ -  trace_t   tr; -  vec3_t    end, dir; -  gentity_t *traceEnt; - -  // set aiming directions -  AngleVectors( ent->client->ps.viewangles, forward, right, up ); - -  CalcMuzzlePoint( ent, forward, right, up, muzzle ); - -  VectorMA( muzzle, LEVEL1_GRAB_RANGE, forward, end ); - -  trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); -  if( tr.surfaceFlags & SURF_NOIMPACT ) -    return; - -  traceEnt = &g_entities[ tr.entityNum ]; - -  if( !traceEnt->takedamage ) -    return; - -  if( traceEnt->client ) -  { -    if( traceEnt->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) -      return; - -    if( traceEnt->client->ps.stats[ STAT_HEALTH ] <= 0 ) -      return; - -    if( !( traceEnt->client->ps.stats[ STAT_STATE ] & SS_GRABBED ) ) -    { -      AngleVectors( traceEnt->client->ps.viewangles, dir, NULL, NULL ); -      traceEnt->client->ps.stats[ STAT_VIEWLOCK ] = DirToByte( dir ); - -      //event for client side grab effect -      G_AddPredictableEvent( ent, EV_LEV1_GRAB, 0 ); -    } - -    traceEnt->client->ps.stats[ STAT_STATE ] |= SS_GRABBED; - -    if( ent->client->ps.weapon == WP_ALEVEL1 ) -      traceEnt->client->grabExpiryTime = level.time + LEVEL1_GRAB_TIME; -    else if( ent->client->ps.weapon == WP_ALEVEL1_UPG ) -      traceEnt->client->grabExpiryTime = level.time + LEVEL1_GRAB_U_TIME; -  } -  else if( traceEnt->s.eType == ET_BUILDABLE && -      traceEnt->s.modelindex == BA_H_MGTURRET ) -  { -    if( !traceEnt->lev1Grabbed ) -      G_AddPredictableEvent( ent, EV_LEV1_GRAB, 0 ); - -    traceEnt->lev1Grabbed = qtrue; -    traceEnt->lev1GrabTime = level.time; -  } -} - -/* -=============== -poisonCloud -=============== -*/ -void poisonCloud( gentity_t *ent ) -{ -  int       entityList[ MAX_GENTITIES ]; -  vec3_t    range = { LEVEL1_PCLOUD_RANGE, LEVEL1_PCLOUD_RANGE, LEVEL1_PCLOUD_RANGE }; -  vec3_t    mins, maxs; -  int       i, num; -  gentity_t *humanPlayer; -  trace_t   tr; - -  VectorAdd( ent->client->ps.origin, range, maxs ); -  VectorSubtract( ent->client->ps.origin, range, mins ); - -  num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -  for( i = 0; i < num; i++ ) -  { -    humanPlayer = &g_entities[ entityList[ i ] ]; - -    if( humanPlayer->client && humanPlayer->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) -    { -      if( BG_InventoryContainsUpgrade( UP_LIGHTARMOUR, humanPlayer->client->ps.stats ) ) -        continue; - -      if( BG_InventoryContainsUpgrade( UP_BATTLESUIT, humanPlayer->client->ps.stats ) ) -        continue; - -      trap_Trace( &tr, muzzle, NULL, NULL, humanPlayer->s.origin, humanPlayer->s.number, MASK_SHOT ); - -      //can't see target from here -      if( tr.entityNum == ENTITYNUM_WORLD ) -        continue; - -      if( !( humanPlayer->client->ps.stats[ STAT_STATE ] & SS_POISONCLOUDED ) ) -      { -        humanPlayer->client->ps.stats[ STAT_STATE ] |= SS_POISONCLOUDED; -        humanPlayer->client->lastPoisonCloudedTime = level.time; -        humanPlayer->client->lastPoisonCloudedClient = ent; -        G_SendCommandFromServer( humanPlayer->client->ps.clientNum, "poisoncloud" ); -      } -    } -  } -} - - -/* -====================================================================== - -LEVEL2 - -====================================================================== -*/ - -#define MAX_ZAPS  64 - -static zap_t  zaps[ MAX_CLIENTS ]; - -/* -=============== -G_FindNewZapTarget -=============== -*/ -static gentity_t *G_FindNewZapTarget( gentity_t *ent ) -{ -  int       entityList[ MAX_GENTITIES ]; -  vec3_t    range = { LEVEL2_AREAZAP_RANGE, LEVEL2_AREAZAP_RANGE, LEVEL2_AREAZAP_RANGE }; -  vec3_t    mins, maxs; -  int       i, j, k, num; -  gentity_t *enemy; -  trace_t   tr; - -  VectorScale( range, 1.0f / M_ROOT3, range ); -  VectorAdd( ent->s.origin, range, maxs ); -  VectorSubtract( ent->s.origin, range, mins ); - -  num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); - -  for( i = 0; i < num; i++ ) -  { -    enemy = &g_entities[ entityList[ i ] ]; - -    if( ( ( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) || -        ( enemy->s.eType == ET_BUILDABLE && -          BG_FindTeamForBuildable( enemy->s.modelindex ) == BIT_HUMANS ) ) && enemy->health > 0 ) -    { -      qboolean foundOldTarget = qfalse; - -      trap_Trace( &tr, muzzle, NULL, NULL, enemy->s.origin, ent->s.number, MASK_SHOT ); - -      //can't see target from here -      if( tr.entityNum == ENTITYNUM_WORLD ) -        continue; - -      for( j = 0; j < MAX_ZAPS; j++ ) -      { -        zap_t *zap = &zaps[ j ]; - -        for( k = 0; k < zap->numTargets; k++ ) -        { -          if( zap->targets[ k ] == enemy ) -          { -            foundOldTarget = qtrue; -            break; -          } -        } - -        if( foundOldTarget ) -          break; -      } - -      // enemy is already targetted -      if( foundOldTarget ) -        continue; - -      return enemy; -    } -  } - -  return NULL; -} - -/* -=============== -G_UpdateZapEffect -=============== -*/ -static void G_UpdateZapEffect( zap_t *zap ) -{ -  int       j; -  gentity_t *effect = zap->effectChannel; - -  effect->s.eType = ET_LEV2_ZAP_CHAIN; -  effect->classname = "lev2zapchain"; -  G_SetOrigin( effect, zap->creator->s.origin ); -  effect->s.powerups = zap->creator->s.number; - -  effect->s.time = effect->s.time2 = effect->s.constantLight = -1; - -  for( j = 0; j < zap->numTargets; j++ ) -  { -    int number = zap->targets[ j ]->s.number; - -    switch( j ) -    { -      case 0: effect->s.time = number;          break; -      case 1: effect->s.time2 = number;         break; -      case 2: effect->s.constantLight = number; break; -      default:                                  break; -    } -  } - -  trap_LinkEntity( effect ); -} - -/* -=============== -G_CreateNewZap -=============== -*/ -static void G_CreateNewZap( gentity_t *creator, gentity_t *target ) -{ -  int       i, j; -  zap_t     *zap; - -  for( i = 0; i < MAX_ZAPS; i++ ) -  { -    zap = &zaps[ i ]; - -    if( !zap->used ) -    { -      zap->used = qtrue; - -      zap->timeToLive = LEVEL2_AREAZAP_TIME; - -      zap->creator = creator; - -      zap->targets[ 0 ] = target; -      zap->numTargets = 1; - -      for( j = 1; j < MAX_ZAP_TARGETS && zap->targets[ j - 1 ]; j++ ) -      { -        zap->targets[ j ] = G_FindNewZapTarget( zap->targets[ j - 1 ] ); - -        if( zap->targets[ j ] ) -          zap->numTargets++; -      } - -      zap->effectChannel = G_Spawn( ); -      G_UpdateZapEffect( zap ); - -      return; -    } -  } -} - - -/* -=============== -G_UpdateZaps -=============== -*/ -void G_UpdateZaps( int msec ) -{ -  int   i, j; -  zap_t *zap; -  int   damage; - -  for( i = 0; i < MAX_ZAPS; i++ ) -  { -    zap = &zaps[ i ]; - -    if( zap->used ) -    { -      //check each target is valid -      for( j = 0; j < zap->numTargets; j++ ) -      { -        gentity_t *source; -        gentity_t *target = zap->targets[ j ]; - -        if( j == 0 ) -          source = zap->creator; -        else -          source = zap->targets[ j - 1 ]; - -        if( target->health <= 0 || !target->inuse || //early out -            Distance( source->s.origin, target->s.origin ) > LEVEL2_AREAZAP_RANGE ) -        { -          target = zap->targets[ j ] = G_FindNewZapTarget( source ); - -          //couldn't find a target, so forget about the rest of the chain -          if( !target ) -            zap->numTargets = j; -        } -      } - -      if( zap->numTargets ) -      { -        for( j = 0; j < zap->numTargets; j++ ) -        { -          gentity_t *source; -          gentity_t *target = zap->targets[ j ]; -          float     r = 1.0f / zap->numTargets; -          float     damageFraction = 2 * r - 2 * j * r * r - r * r; -          vec3_t    forward; - -          if( j == 0 ) -            source = zap->creator; -          else -            source = zap->targets[ j - 1 ]; - -          damage = ceil( ( (float)msec / LEVEL2_AREAZAP_TIME ) * -              LEVEL2_AREAZAP_DMG * damageFraction ); - -          VectorSubtract( target->s.origin, source->s.origin, forward ); -          VectorNormalize( forward ); - -          //do the damage -          if( damage ) -            G_Damage( target, source, zap->creator, forward, target->s.origin, -                    damage, DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE, MOD_LEVEL2_ZAP ); -        } -      } - -      G_UpdateZapEffect( zap ); - -      zap->timeToLive -= msec; - -      if( zap->timeToLive <= 0 || zap->numTargets == 0 || zap->creator->health <= 0 ) -      { -        zap->used = qfalse; -        G_FreeEntity( zap->effectChannel ); -      } -    } -  } -} - -/* -=============== -areaZapFire -=============== -*/ -void areaZapFire( gentity_t *ent ) -{ -  trace_t   tr; -  vec3_t    end; -  gentity_t *traceEnt; -  vec3_t    mins, maxs; - -  VectorSet( mins, -LEVEL2_AREAZAP_WIDTH, -LEVEL2_AREAZAP_WIDTH, -LEVEL2_AREAZAP_WIDTH ); -  VectorSet( maxs, LEVEL2_AREAZAP_WIDTH, LEVEL2_AREAZAP_WIDTH, LEVEL2_AREAZAP_WIDTH ); - -  // set aiming directions -  AngleVectors( ent->client->ps.viewangles, forward, right, up ); - -  CalcMuzzlePoint( ent, forward, right, up, muzzle ); - -  VectorMA( muzzle, LEVEL2_AREAZAP_RANGE, forward, end ); - -  trap_Trace( &tr, muzzle, mins, maxs, end, ent->s.number, MASK_SHOT ); - -  if( tr.surfaceFlags & SURF_NOIMPACT ) -    return; - -  traceEnt = &g_entities[ tr.entityNum ]; - -  if( ( ( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) || -      ( traceEnt->s.eType == ET_BUILDABLE && -        BG_FindTeamForBuildable( traceEnt->s.modelindex ) == BIT_HUMANS ) ) && traceEnt->health > 0 ) -  { -    G_CreateNewZap( ent, traceEnt ); -  } -} - - -/* -====================================================================== - -LEVEL3 - -====================================================================== -*/ - -/* -=============== -CheckPounceAttack -=============== -*/ -qboolean CheckPounceAttack( gentity_t *ent ) -{ -  trace_t   tr; -  vec3_t    end; -  gentity_t *tent; -  gentity_t *traceEnt; -  int       damage; -  vec3_t    mins, maxs; - -  VectorSet( mins, -LEVEL3_POUNCE_WIDTH, -LEVEL3_POUNCE_WIDTH, -LEVEL3_POUNCE_WIDTH ); -  VectorSet( maxs, LEVEL3_POUNCE_WIDTH, LEVEL3_POUNCE_WIDTH, LEVEL3_POUNCE_WIDTH ); - -  if( !ent->client->allowedToPounce ) -    return qfalse; - -  if( ent->client->ps.groundEntityNum != ENTITYNUM_NONE ) -  { -    ent->client->allowedToPounce = qfalse; -    return qfalse; -  } - -  if( ent->client->ps.weaponTime ) -    return qfalse; - -  // set aiming directions -  AngleVectors( ent->client->ps.viewangles, forward, right, up ); - -  CalcMuzzlePoint( ent, forward, right, up, muzzle ); - -  VectorMA( muzzle, LEVEL3_POUNCE_RANGE, forward, end ); - -  trap_Trace( &tr, ent->s.origin, mins, maxs, end, ent->s.number, MASK_SHOT ); - -  //miss -  if( tr.fraction >= 1.0 ) -    return qfalse; - -  if( tr.surfaceFlags & SURF_NOIMPACT ) -    return qfalse; - -  traceEnt = &g_entities[ tr.entityNum ]; - -  // send blood impact -  if( traceEnt->takedamage && traceEnt->client ) -  { -    tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT ); -    tent->s.otherEntityNum = traceEnt->s.number; -    tent->s.eventParm = DirToByte( tr.plane.normal ); -    tent->s.weapon = ent->s.weapon; -    tent->s.generic1 = ent->s.generic1; //weaponMode -  } - -  if( !traceEnt->takedamage ) -    return qfalse; - -  damage = (int)( ( (float)ent->client->pouncePayload / (float)LEVEL3_POUNCE_SPEED ) * LEVEL3_POUNCE_DMG ); - -  G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, -      DAMAGE_NO_KNOCKBACK|DAMAGE_NO_LOCDAMAGE, MOD_LEVEL3_POUNCE ); - -  ent->client->ps.weaponTime += LEVEL3_POUNCE_TIME; -  ent->client->allowedToPounce = qfalse; - -  return qtrue; -} - -void bounceBallFire( gentity_t *ent ) -{ -  gentity_t *m; - -  m = fire_bounceBall( ent, muzzle, forward ); - -//  VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta );  // "real" physics -} - - -/* -====================================================================== - -LEVEL4 - -====================================================================== -*/ - -/* -=============== -ChargeAttack -=============== -*/ -void ChargeAttack( gentity_t *ent, gentity_t *victim ) -{ -  gentity_t *tent; -  int       damage; -  vec3_t    forward, normal; - -  if( level.time < victim->chargeRepeat ) -    return; - -  victim->chargeRepeat = level.time + LEVEL4_CHARGE_REPEAT; - -  VectorSubtract( victim->s.origin, ent->s.origin, forward ); -  VectorNormalize( forward ); -  VectorNegate( forward, normal ); - -  if( victim->client ) -  { -    tent = G_TempEntity( victim->s.origin, EV_MISSILE_HIT ); -    tent->s.otherEntityNum = victim->s.number; -    tent->s.eventParm = DirToByte( normal ); -    tent->s.weapon = ent->s.weapon; -    tent->s.generic1 = ent->s.generic1; //weaponMode -  } - -  if( !victim->takedamage ) -    return; - -  damage = (int)( ( (float)ent->client->ps.stats[ STAT_MISC ] / (float)LEVEL4_CHARGE_TIME ) * LEVEL4_CHARGE_DMG ); - -  G_Damage( victim, ent, ent, forward, victim->s.origin, damage, 0, MOD_LEVEL4_CHARGE ); -} - -//====================================================================== - -/* -=============== -CalcMuzzlePoint - -set muzzle location relative to pivoting eye -=============== -*/ -void CalcMuzzlePoint( gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint ) -{ -  VectorCopy( ent->s.pos.trBase, muzzlePoint ); -  muzzlePoint[ 2 ] += ent->client->ps.viewheight; -  VectorMA( muzzlePoint, 1, forward, muzzlePoint ); -  VectorMA( muzzlePoint, 1, right, muzzlePoint ); -  // snap to integer coordinates for more efficient network bandwidth usage -  SnapVector( muzzlePoint ); -} - -/* -=============== -FireWeapon3 -=============== -*/ -void FireWeapon3( gentity_t *ent ) -{ -  if( ent->client ) -  { -    // set aiming directions -    AngleVectors( ent->client->ps.viewangles, forward, right, up ); -    CalcMuzzlePoint( ent, forward, right, up, muzzle ); -  } -  else -  { -    AngleVectors( ent->s.angles2, forward, right, up ); -    VectorCopy( ent->s.pos.trBase, muzzle ); -  } - -  // fire the specific weapon -  switch( ent->s.weapon ) -  { -    case WP_ALEVEL3_UPG: -      bounceBallFire( ent ); -      break; - -    case WP_ABUILD2: -      slowBlobFire( ent ); -      break; - -    default: -      break; -  } -} - -/* -=============== -FireWeapon2 -=============== -*/ -void FireWeapon2( gentity_t *ent ) -{ -  if( ent->client ) -  { -    // set aiming directions -    AngleVectors( ent->client->ps.viewangles, forward, right, up ); -    CalcMuzzlePoint( ent, forward, right, up, muzzle ); -  } -  else -  { -    AngleVectors( ent->s.angles2, forward, right, up ); -    VectorCopy( ent->s.pos.trBase, muzzle ); -  } - -  // fire the specific weapon -  switch( ent->s.weapon ) -  { -    case WP_ALEVEL1_UPG: -      poisonCloud( ent ); -      break; -    case WP_ALEVEL2_UPG: -      areaZapFire( ent ); -      break; - -    case WP_LUCIFER_CANNON: -      LCChargeFire( ent, qtrue ); -      break; - -    case WP_ABUILD: -    case WP_ABUILD2: -    case WP_HBUILD: -    case WP_HBUILD2: -      cancelBuildFire( ent ); -      break; -    default: -      break; -  } -} - -/* -=============== -FireWeapon -=============== -*/ -void FireWeapon( gentity_t *ent ) -{ -  if( ent->client ) -  { -    // set aiming directions -    AngleVectors( ent->client->ps.viewangles, forward, right, up ); -    CalcMuzzlePoint( ent, forward, right, up, muzzle ); -  } -  else -  { -    AngleVectors( ent->turretAim, forward, right, up ); -    VectorCopy( ent->s.pos.trBase, muzzle ); -  } - -  // fire the specific weapon -  switch( ent->s.weapon ) -  { -    case WP_ALEVEL1: -    case WP_ALEVEL1_UPG: -      meleeAttack( ent, LEVEL1_CLAW_RANGE, LEVEL1_CLAW_WIDTH, LEVEL1_CLAW_DMG, MOD_LEVEL1_CLAW ); -      break; -    case WP_ALEVEL3: -    case WP_ALEVEL3_UPG: -      meleeAttack( ent, LEVEL3_CLAW_RANGE, LEVEL3_CLAW_WIDTH, LEVEL3_CLAW_DMG, MOD_LEVEL3_CLAW ); -      break; -    case WP_ALEVEL2: -      meleeAttack( ent, LEVEL2_CLAW_RANGE, LEVEL2_CLAW_WIDTH, LEVEL2_CLAW_DMG, MOD_LEVEL2_CLAW ); -      break; -    case WP_ALEVEL2_UPG: -      meleeAttack( ent, LEVEL2_CLAW_RANGE, LEVEL2_CLAW_WIDTH, LEVEL2_CLAW_DMG, MOD_LEVEL2_CLAW ); -      break; -    case WP_ALEVEL4: -      meleeAttack( ent, LEVEL4_CLAW_RANGE, LEVEL4_CLAW_WIDTH, LEVEL4_CLAW_DMG, MOD_LEVEL4_CLAW ); -      break; - -    case WP_BLASTER: -      blasterFire( ent ); -      break; -    case WP_MACHINEGUN: -      bulletFire( ent, RIFLE_SPREAD, RIFLE_DMG, MOD_MACHINEGUN ); -      break; -    case WP_SHOTGUN: -      shotgunFire( ent ); -      break; -    case WP_CHAINGUN: -      bulletFire( ent, CHAINGUN_SPREAD, CHAINGUN_DMG, MOD_CHAINGUN ); -      break; -    case WP_FLAMER: -      flamerFire( ent ); -      break; -    case WP_PULSE_RIFLE: -      pulseRifleFire( ent ); -      break; -    case WP_MASS_DRIVER: -      massDriverFire( ent ); -      break; -    case WP_LUCIFER_CANNON: -      LCChargeFire( ent, qfalse ); -      break; -    case WP_LAS_GUN: -      lasGunFire( ent ); -      break; -    case WP_PAIN_SAW: -      painSawFire( ent ); -      break; -    case WP_GRENADE: -      throwGrenade( ent ); -      break; - -    case WP_LOCKBLOB_LAUNCHER: -      lockBlobLauncherFire( ent ); -      break; -    case WP_HIVE: -      hiveFire( ent ); -      break; -    case WP_TESLAGEN: -      teslaFire( ent ); -      break; -    case WP_MGTURRET: -      bulletFire( ent, MGTURRET_SPREAD, MGTURRET_DMG, MOD_MGTURRET ); -      break; - -    case WP_ABUILD: -    case WP_ABUILD2: -      buildFire( ent, MN_A_BUILD ); -      break; -    case WP_HBUILD: -    case WP_HBUILD2: -      buildFire( ent, MN_H_BUILD ); -      break; -    default: -      break; -  } -} - diff --git a/mod/src/game/q_math.c b/mod/src/game/q_math.c deleted file mode 100644 index 4171ebfc..00000000 --- a/mod/src/game/q_math.c +++ /dev/null @@ -1,1482 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// q_math.c -- stateless support routines that are included in each code module - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "q_shared.h" - - -vec3_t  vec3_origin = {0,0,0}; -vec3_t  axisDefault[3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; - - -vec4_t    colorBlack  = {0, 0, 0, 1}; -vec4_t    colorRed  = {1, 0, 0, 1}; -vec4_t    colorGreen  = {0, 1, 0, 1}; -vec4_t    colorBlue = {0, 0, 1, 1}; -vec4_t    colorYellow = {1, 1, 0, 1}; -vec4_t    colorMagenta= {1, 0, 1, 1}; -vec4_t    colorCyan = {0, 1, 1, 1}; -vec4_t    colorWhite  = {1, 1, 1, 1}; -vec4_t    colorLtGrey = {0.75, 0.75, 0.75, 1}; -vec4_t    colorMdGrey = {0.5, 0.5, 0.5, 1}; -vec4_t    colorDkGrey = {0.25, 0.25, 0.25, 1}; - -vec4_t  g_color_table[8] = -  { -  {0.0, 0.0, 0.0, 1.0}, -  {1.0, 0.0, 0.0, 1.0}, -  {0.0, 1.0, 0.0, 1.0}, -  {1.0, 1.0, 0.0, 1.0}, -  {0.0, 0.0, 1.0, 1.0}, -  {0.0, 1.0, 1.0, 1.0}, -  {1.0, 0.0, 1.0, 1.0}, -  {1.0, 1.0, 1.0, 1.0}, -  }; - - -vec3_t  bytedirs[NUMVERTEXNORMALS] = -{ -{-0.525731f, 0.000000f, 0.850651f}, {-0.442863f, 0.238856f, 0.864188f}, -{-0.295242f, 0.000000f, 0.955423f}, {-0.309017f, 0.500000f, 0.809017f}, -{-0.162460f, 0.262866f, 0.951056f}, {0.000000f, 0.000000f, 1.000000f}, -{0.000000f, 0.850651f, 0.525731f}, {-0.147621f, 0.716567f, 0.681718f}, -{0.147621f, 0.716567f, 0.681718f}, {0.000000f, 0.525731f, 0.850651f}, -{0.309017f, 0.500000f, 0.809017f}, {0.525731f, 0.000000f, 0.850651f}, -{0.295242f, 0.000000f, 0.955423f}, {0.442863f, 0.238856f, 0.864188f}, -{0.162460f, 0.262866f, 0.951056f}, {-0.681718f, 0.147621f, 0.716567f}, -{-0.809017f, 0.309017f, 0.500000f},{-0.587785f, 0.425325f, 0.688191f}, -{-0.850651f, 0.525731f, 0.000000f},{-0.864188f, 0.442863f, 0.238856f}, -{-0.716567f, 0.681718f, 0.147621f},{-0.688191f, 0.587785f, 0.425325f}, -{-0.500000f, 0.809017f, 0.309017f}, {-0.238856f, 0.864188f, 0.442863f}, -{-0.425325f, 0.688191f, 0.587785f}, {-0.716567f, 0.681718f, -0.147621f}, -{-0.500000f, 0.809017f, -0.309017f}, {-0.525731f, 0.850651f, 0.000000f}, -{0.000000f, 0.850651f, -0.525731f}, {-0.238856f, 0.864188f, -0.442863f}, -{0.000000f, 0.955423f, -0.295242f}, {-0.262866f, 0.951056f, -0.162460f}, -{0.000000f, 1.000000f, 0.000000f}, {0.000000f, 0.955423f, 0.295242f}, -{-0.262866f, 0.951056f, 0.162460f}, {0.238856f, 0.864188f, 0.442863f}, -{0.262866f, 0.951056f, 0.162460f}, {0.500000f, 0.809017f, 0.309017f}, -{0.238856f, 0.864188f, -0.442863f},{0.262866f, 0.951056f, -0.162460f}, -{0.500000f, 0.809017f, -0.309017f},{0.850651f, 0.525731f, 0.000000f}, -{0.716567f, 0.681718f, 0.147621f}, {0.716567f, 0.681718f, -0.147621f}, -{0.525731f, 0.850651f, 0.000000f}, {0.425325f, 0.688191f, 0.587785f}, -{0.864188f, 0.442863f, 0.238856f}, {0.688191f, 0.587785f, 0.425325f}, -{0.809017f, 0.309017f, 0.500000f}, {0.681718f, 0.147621f, 0.716567f}, -{0.587785f, 0.425325f, 0.688191f}, {0.955423f, 0.295242f, 0.000000f}, -{1.000000f, 0.000000f, 0.000000f}, {0.951056f, 0.162460f, 0.262866f}, -{0.850651f, -0.525731f, 0.000000f},{0.955423f, -0.295242f, 0.000000f}, -{0.864188f, -0.442863f, 0.238856f}, {0.951056f, -0.162460f, 0.262866f}, -{0.809017f, -0.309017f, 0.500000f}, {0.681718f, -0.147621f, 0.716567f}, -{0.850651f, 0.000000f, 0.525731f}, {0.864188f, 0.442863f, -0.238856f}, -{0.809017f, 0.309017f, -0.500000f}, {0.951056f, 0.162460f, -0.262866f}, -{0.525731f, 0.000000f, -0.850651f}, {0.681718f, 0.147621f, -0.716567f}, -{0.681718f, -0.147621f, -0.716567f},{0.850651f, 0.000000f, -0.525731f}, -{0.809017f, -0.309017f, -0.500000f}, {0.864188f, -0.442863f, -0.238856f}, -{0.951056f, -0.162460f, -0.262866f}, {0.147621f, 0.716567f, -0.681718f}, -{0.309017f, 0.500000f, -0.809017f}, {0.425325f, 0.688191f, -0.587785f}, -{0.442863f, 0.238856f, -0.864188f}, {0.587785f, 0.425325f, -0.688191f}, -{0.688191f, 0.587785f, -0.425325f}, {-0.147621f, 0.716567f, -0.681718f}, -{-0.309017f, 0.500000f, -0.809017f}, {0.000000f, 0.525731f, -0.850651f}, -{-0.525731f, 0.000000f, -0.850651f}, {-0.442863f, 0.238856f, -0.864188f}, -{-0.295242f, 0.000000f, -0.955423f}, {-0.162460f, 0.262866f, -0.951056f}, -{0.000000f, 0.000000f, -1.000000f}, {0.295242f, 0.000000f, -0.955423f}, -{0.162460f, 0.262866f, -0.951056f}, {-0.442863f, -0.238856f, -0.864188f}, -{-0.309017f, -0.500000f, -0.809017f}, {-0.162460f, -0.262866f, -0.951056f}, -{0.000000f, -0.850651f, -0.525731f}, {-0.147621f, -0.716567f, -0.681718f}, -{0.147621f, -0.716567f, -0.681718f}, {0.000000f, -0.525731f, -0.850651f}, -{0.309017f, -0.500000f, -0.809017f}, {0.442863f, -0.238856f, -0.864188f}, -{0.162460f, -0.262866f, -0.951056f}, {0.238856f, -0.864188f, -0.442863f}, -{0.500000f, -0.809017f, -0.309017f}, {0.425325f, -0.688191f, -0.587785f}, -{0.716567f, -0.681718f, -0.147621f}, {0.688191f, -0.587785f, -0.425325f}, -{0.587785f, -0.425325f, -0.688191f}, {0.000000f, -0.955423f, -0.295242f}, -{0.000000f, -1.000000f, 0.000000f}, {0.262866f, -0.951056f, -0.162460f}, -{0.000000f, -0.850651f, 0.525731f}, {0.000000f, -0.955423f, 0.295242f}, -{0.238856f, -0.864188f, 0.442863f}, {0.262866f, -0.951056f, 0.162460f}, -{0.500000f, -0.809017f, 0.309017f}, {0.716567f, -0.681718f, 0.147621f}, -{0.525731f, -0.850651f, 0.000000f}, {-0.238856f, -0.864188f, -0.442863f}, -{-0.500000f, -0.809017f, -0.309017f}, {-0.262866f, -0.951056f, -0.162460f}, -{-0.850651f, -0.525731f, 0.000000f}, {-0.716567f, -0.681718f, -0.147621f}, -{-0.716567f, -0.681718f, 0.147621f}, {-0.525731f, -0.850651f, 0.000000f}, -{-0.500000f, -0.809017f, 0.309017f}, {-0.238856f, -0.864188f, 0.442863f}, -{-0.262866f, -0.951056f, 0.162460f}, {-0.864188f, -0.442863f, 0.238856f}, -{-0.809017f, -0.309017f, 0.500000f}, {-0.688191f, -0.587785f, 0.425325f}, -{-0.681718f, -0.147621f, 0.716567f}, {-0.442863f, -0.238856f, 0.864188f}, -{-0.587785f, -0.425325f, 0.688191f}, {-0.309017f, -0.500000f, 0.809017f}, -{-0.147621f, -0.716567f, 0.681718f}, {-0.425325f, -0.688191f, 0.587785f}, -{-0.162460f, -0.262866f, 0.951056f}, {0.442863f, -0.238856f, 0.864188f}, -{0.162460f, -0.262866f, 0.951056f}, {0.309017f, -0.500000f, 0.809017f}, -{0.147621f, -0.716567f, 0.681718f}, {0.000000f, -0.525731f, 0.850651f}, -{0.425325f, -0.688191f, 0.587785f}, {0.587785f, -0.425325f, 0.688191f}, -{0.688191f, -0.587785f, 0.425325f}, {-0.955423f, 0.295242f, 0.000000f}, -{-0.951056f, 0.162460f, 0.262866f}, {-1.000000f, 0.000000f, 0.000000f}, -{-0.850651f, 0.000000f, 0.525731f}, {-0.955423f, -0.295242f, 0.000000f}, -{-0.951056f, -0.162460f, 0.262866f}, {-0.864188f, 0.442863f, -0.238856f}, -{-0.951056f, 0.162460f, -0.262866f}, {-0.809017f, 0.309017f, -0.500000f}, -{-0.864188f, -0.442863f, -0.238856f}, {-0.951056f, -0.162460f, -0.262866f}, -{-0.809017f, -0.309017f, -0.500000f}, {-0.681718f, 0.147621f, -0.716567f}, -{-0.681718f, -0.147621f, -0.716567f}, {-0.850651f, 0.000000f, -0.525731f}, -{-0.688191f, 0.587785f, -0.425325f}, {-0.587785f, 0.425325f, -0.688191f}, -{-0.425325f, 0.688191f, -0.587785f}, {-0.425325f, -0.688191f, -0.587785f}, -{-0.587785f, -0.425325f, -0.688191f}, {-0.688191f, -0.587785f, -0.425325f} -}; - -//============================================================== - -int   Q_rand( int *seed ) { -  *seed = (69069 * *seed + 1); -  return *seed; -} - -float Q_random( int *seed ) { -  return ( Q_rand( seed ) & 0xffff ) / (float)0x10000; -} - -float Q_crandom( int *seed ) { -  return 2.0 * ( Q_random( seed ) - 0.5 ); -} - -#ifdef __LCC__ - -int VectorCompare( const vec3_t v1, const vec3_t v2 ) { -  if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) { -    return 0; -  } -  return 1; -} - -vec_t VectorLength( const vec3_t v ) -{ -  return (vec_t)sqrt( v[ 0 ] * v[ 0 ] + v[ 1 ] * v[ 1 ] + v[ 2 ] * v[ 2 ] ); -} - -vec_t VectorLengthSquared( const vec3_t v ) { -  return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); -} - -vec_t Distance( const vec3_t p1, const vec3_t p2 ) { -  vec3_t  v; - -  VectorSubtract (p2, p1, v); -  return VectorLength( v ); -} - -vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 ) { -  vec3_t  v; - -  VectorSubtract (p2, p1, v); -  return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; -} - -// fast vector normalize routine that does not check to make sure -// that length != 0, nor does it return length, uses rsqrt approximation -void VectorNormalizeFast( vec3_t v ) -{ -  float ilength; - -  ilength = Q_rsqrt( DotProduct( v, v ) ); - -  v[0] *= ilength; -  v[1] *= ilength; -  v[2] *= ilength; -} - -void VectorInverse( vec3_t v ){ -  v[0] = -v[0]; -  v[1] = -v[1]; -  v[2] = -v[2]; -} - -void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ) { -  cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; -  cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; -  cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; -} -#endif - -//======================================================= - -signed char ClampChar( int i ) { -  if ( i < -128 ) { -    return -128; -  } -  if ( i > 127 ) { -    return 127; -  } -  return i; -} - -signed short ClampShort( int i ) { -  if ( i < -32768 ) { -    return -32768; -  } -  if ( i > 0x7fff ) { -    return 0x7fff; -  } -  return i; -} - - -// this isn't a real cheap function to call! -int DirToByte( vec3_t dir ) -{ -  int   i, best; -  float d, bestd; - -  if( !dir ) -    return 0; - -  bestd = 0; -  best = 0; - -  for( i = 0; i < NUMVERTEXNORMALS; i++ ) -  { -    d = DotProduct( dir, bytedirs[ i ] ); - -    if( d > bestd ) -    { -      bestd = d; -      best = i; -    } -  } - -  return best; -} - -void ByteToDir( int b, vec3_t dir ) -{ -  if( b < 0 || b >= NUMVERTEXNORMALS ) -  { -    VectorCopy( vec3_origin, dir ); -    return; -  } - -  VectorCopy( bytedirs[ b ], dir); -} - - -unsigned ColorBytes3 (float r, float g, float b) { -  unsigned  i; - -  ( (byte *)&i )[0] = r * 255; -  ( (byte *)&i )[1] = g * 255; -  ( (byte *)&i )[2] = b * 255; - -  return i; -} - -unsigned ColorBytes4 (float r, float g, float b, float a) { -  unsigned  i; - -  ( (byte *)&i )[0] = r * 255; -  ( (byte *)&i )[1] = g * 255; -  ( (byte *)&i )[2] = b * 255; -  ( (byte *)&i )[3] = a * 255; - -  return i; -} - -float NormalizeColor( const vec3_t in, vec3_t out ) { -  float max; - -  max = in[0]; -  if ( in[1] > max ) { -    max = in[1]; -  } -  if ( in[2] > max ) { -    max = in[2]; -  } - -  if ( !max ) { -    VectorClear( out ); -  } else { -    out[0] = in[0] / max; -    out[1] = in[1] / max; -    out[2] = in[2] / max; -  } -  return max; -} - - -/* -===================== -PlaneFromPoints - -Returns false if the triangle is degenrate. -The normal will point out of the clock for clockwise ordered points -===================== -*/ -qboolean PlaneFromPoints( vec4_t plane, const vec3_t a, const vec3_t b, const vec3_t c ) { -  vec3_t  d1, d2; - -  VectorSubtract( b, a, d1 ); -  VectorSubtract( c, a, d2 ); -  CrossProduct( d2, d1, plane ); -  if ( VectorNormalize( plane ) == 0 ) { -    return qfalse; -  } - -  plane[3] = DotProduct( a, plane ); -  return qtrue; -} - - -/// These optimised and much cleaner implementations of the Vector Rotation -/// functions were provided by Riv (riviera@planetquake.com) -/// ...Cheers Riv... -/* -=============== -RotatePointAroundVector - -This is not implemented very well... -=============== -*/ -void RotatePointAroundVector(vec3_t dst, const vec3_t dir, const vec3_t point, float degrees) -{ -  float sin_a; -  float cos_a; -  float cos_ia; -  float i_i_ia; -  float j_j_ia; -  float k_k_ia; -  float i_j_ia; -  float i_k_ia; -  float j_k_ia; -  float a_sin; -  float b_sin; -  float c_sin; -  float rot[3][3]; - -  cos_ia = DEG2RAD(degrees); -  sin_a = sin(cos_ia); -  cos_a = cos(cos_ia); -  cos_ia = 1.0F - cos_a; - -  i_i_ia = dir[0] * dir[0] * cos_ia; -  j_j_ia = dir[1] * dir[1] * cos_ia; -  k_k_ia = dir[2] * dir[2] * cos_ia; -  i_j_ia = dir[0] * dir[1] * cos_ia; -  i_k_ia = dir[0] * dir[2] * cos_ia; -  j_k_ia = dir[1] * dir[2] * cos_ia; - -  a_sin = dir[0] * sin_a; -  b_sin = dir[1] * sin_a; -  c_sin = dir[2] * sin_a; - -  rot[0][0] = i_i_ia + cos_a; -  rot[0][1] = i_j_ia - c_sin; -  rot[0][2] = i_k_ia + b_sin; -  rot[1][0] = i_j_ia + c_sin; -  rot[1][1] = j_j_ia + cos_a; -  rot[1][2] = j_k_ia - a_sin; -  rot[2][0] = i_k_ia - b_sin; -  rot[2][1] = j_k_ia + a_sin; -  rot[2][2] = k_k_ia + cos_a; - -  dst[0] = point[0] * rot[0][0] + point[1] * rot[0][1] + point[2] * rot[0][2]; -  dst[1] = point[0] * rot[1][0] + point[1] * rot[1][1] + point[2] * rot[1][2]; -  dst[2] = point[0] * rot[2][0] + point[1] * rot[2][1] + point[2] * rot[2][2]; -} - - -/* -=============== -RotateAroundDirection -=============== -*/ -void RotateAroundDirection( vec3_t axis[ 3 ], vec_t angle ) -{ -  vec_t scale; - -  angle = DEG2RAD( angle ); - -  // create an arbitrary axis[1] -  PerpendicularVector( axis[ 1 ], axis[ 0 ] ); - -  // cross to get axis[2] -  CrossProduct( axis[ 0 ], axis[ 1 ], axis[ 2 ] ); - -  // rotate -  scale = cos( angle ); -  VectorScale( axis[ 1 ], scale, axis[ 1 ] ); - -  scale = sin( angle ); -  VectorMA( axis[ 1 ], scale, axis[ 2 ], axis[ 1 ] ); - -  // recalculate axis[2] -  CrossProduct( axis[ 0 ], axis[ 1 ], axis[ 2 ] ); -} - - -void vectoangles( const vec3_t value1, vec3_t angles ) -{ -  float forward; -  float yaw, pitch; - -  if( value1[ 1 ] == 0 && value1[ 0 ] == 0 ) -  { -    yaw = 0; -    if( value1[ 2 ] > 0 ) -      pitch = 90; -    else -      pitch = 270; -  } -  else -  { -    if( value1[ 0 ] ) -      yaw = ( atan2 ( value1[ 1 ], value1[ 0 ] ) * 180 / M_PI ); -    else if( value1[ 1 ] > 0 ) -      yaw = 90; -    else -      yaw = 270; - -    if( yaw < 0 ) -      yaw += 360; - -    forward = sqrt( value1[ 0 ] * value1[ 0 ] + value1[ 1 ] * value1[ 1 ] ); -    pitch = ( atan2( value1[ 2 ], forward ) * 180 / M_PI ); -    if( pitch < 0 ) -      pitch += 360; -  } - -  angles[ PITCH ] = -pitch; -  angles[ YAW ] = yaw; -  angles[ ROLL ] = 0; -} - - -/* -================= -AxisToAngles -TA: takes an axis (forward + right + up) -    and returns angles -- including a roll -================= -*/ -void AxisToAngles( vec3_t axis[3], vec3_t angles ) { -  float length1; -  float yaw, pitch, roll = 0.0f; - -  if ( axis[0][1] == 0 && axis[0][0] == 0 ) { -    yaw = 0; -    if ( axis[0][2] > 0 ) { -      pitch = 90; -    } -    else { -      pitch = 270; -    } -  } -  else { -    if ( axis[0][0] ) { -      yaw = ( atan2 ( axis[0][1], axis[0][0] ) * 180 / M_PI ); -    } -    else if ( axis[0][1] > 0 ) { -      yaw = 90; -    } -    else { -      yaw = 270; -    } -    if ( yaw < 0 ) { -      yaw += 360; -    } - -    length1 = sqrt ( axis[0][0]*axis[0][0] + axis[0][1]*axis[0][1] ); -    pitch = ( atan2(axis[0][2], length1) * 180 / M_PI ); -    if ( pitch < 0 ) { -      pitch += 360; -    } - -    roll = ( atan2( axis[1][2], axis[2][2] ) * 180 / M_PI ); -    if ( roll < 0 ) { -      roll += 360; -    } -  } - -  angles[PITCH] = -pitch; -  angles[YAW] = yaw; -  angles[ROLL] = roll; -} - -/* -================= -AnglesToAxis -================= -*/ -void AnglesToAxis( const vec3_t angles, vec3_t axis[3] ) { -  vec3_t  right; - -  // angle vectors returns "right" instead of "y axis" -  AngleVectors( angles, axis[0], right, axis[2] ); -  VectorSubtract( vec3_origin, right, axis[1] ); -} - -void AxisClear( vec3_t axis[ 3 ] ) -{ -  axis[ 0 ][ 0 ] = 1; -  axis[ 0 ][ 1 ] = 0; -  axis[ 0 ][ 2 ] = 0; -  axis[ 1 ][ 0 ] = 0; -  axis[ 1 ][ 1 ] = 1; -  axis[ 1 ][ 2 ] = 0; -  axis[ 2 ][ 0 ] = 0; -  axis[ 2 ][ 1 ] = 0; -  axis[ 2 ][ 2 ] = 1; -} - -void AxisCopy( vec3_t in[3], vec3_t out[3] ) { -  VectorCopy( in[0], out[0] ); -  VectorCopy( in[1], out[1] ); -  VectorCopy( in[2], out[2] ); -} - -void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ) -{ -  float d; -  vec3_t n; -  float inv_denom; - -  inv_denom = 1.0F / DotProduct( normal, normal ); - -#ifndef Q3_VM -  assert( Q_fabs(inv_denom) != 0.0f ); // bk010122 - zero vectors get here -#endif -  inv_denom = 1.0f / inv_denom; - -  d = DotProduct( normal, p ) * inv_denom; - -  n[0] = normal[0] * inv_denom; -  n[1] = normal[1] * inv_denom; -  n[2] = normal[2] * inv_denom; - -  dst[0] = p[0] - d * n[0]; -  dst[1] = p[1] - d * n[1]; -  dst[2] = p[2] - d * n[2]; -} - -/* -================ -MakeNormalVectors - -Given a normalized forward vector, create two -other perpendicular vectors -================ -*/ -void MakeNormalVectors( const vec3_t forward, vec3_t right, vec3_t up) { -  float   d; - -  // this rotate and negate guarantees a vector -  // not colinear with the original -  right[1] = -forward[0]; -  right[2] = forward[1]; -  right[0] = forward[2]; - -  d = DotProduct (right, forward); -  VectorMA (right, -d, forward, right); -  VectorNormalize (right); -  CrossProduct (right, forward, up); -} - - -void VectorRotate( vec3_t in, vec3_t matrix[3], vec3_t out ) -{ -  out[0] = DotProduct( in, matrix[0] ); -  out[1] = DotProduct( in, matrix[1] ); -  out[2] = DotProduct( in, matrix[2] ); -} - -//============================================================================ - -#if !idppc -/* -** float q_rsqrt( float number ) -*/ -float Q_rsqrt( float number ) -{ -  long i; -  float x2, y; -  const float threehalfs = 1.5F; - -  x2 = number * 0.5F; -  y  = number; -  i  = * ( long * ) &y;           // evil floating point bit level hacking -  i  = 0x5f3759df - ( i >> 1 );               // what the fuck? -  y  = * ( float * ) &i; -  y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration -//  y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed - -#ifndef Q3_VM -#ifdef __linux__ -  assert( !isnan(y) ); // bk010122 - FPE? -#endif -#endif - -  return y; -} -#endif - -float Q_fabs( float f ) { -  int tmp = * ( int * ) &f; -  tmp &= 0x7FFFFFFF; -  return * ( float * ) &tmp; -} - -//============================================================ - -/* -=============== -LerpAngle - -=============== -*/ -float LerpAngle (float from, float to, float frac) { -  float a; - -  if ( to - from > 180 ) { -    to -= 360; -  } -  if ( to - from < -180 ) { -    to += 360; -  } -  a = from + frac * (to - from); - -  return a; -} - - -/* -================= -AngleSubtract - -Always returns a value from -180 to 180 -================= -*/ -float AngleSubtract( float a1, float a2 ) { -  float a; - -  a = a1 - a2; -  while ( a > 180 ) { -    a -= 360; -  } -  while ( a < -180 ) { -    a += 360; -  } -  return a; -} - - -void AnglesSubtract( vec3_t v1, vec3_t v2, vec3_t v3 ) { -  v3[0] = AngleSubtract( v1[0], v2[0] ); -  v3[1] = AngleSubtract( v1[1], v2[1] ); -  v3[2] = AngleSubtract( v1[2], v2[2] ); -} - - -float AngleMod( float a ) -{ -  a = ( 360.0 / 65536 ) * ( (int)( a * ( 65536 / 360.0 ) ) & 65535 ); -  return a; -} - - -/* -================= -AngleNormalize360 - -returns angle normalized to the range [0 <= angle < 360] -================= -*/ -float AngleNormalize360 ( float angle ) { -  return (360.0 / 65536) * ((int)(angle * (65536 / 360.0)) & 65535); -} - - -/* -================= -AngleNormalize180 - -returns angle normalized to the range [-180 < angle <= 180] -================= -*/ -float AngleNormalize180 ( float angle ) { -  angle = AngleNormalize360( angle ); -  if ( angle > 180.0 ) { -    angle -= 360.0; -  } -  return angle; -} - - -/* -================= -AngleDelta - -returns the normalized delta from angle1 to angle2 -================= -*/ -float AngleDelta ( float angle1, float angle2 ) { -  return AngleNormalize180( angle1 - angle2 ); -} - - -//============================================================ - - -/* -================= -SetPlaneSignbits -================= -*/ -void SetPlaneSignbits (cplane_t *out) { -  int bits, j; - -  // for fast box on planeside test -  bits = 0; -  for (j=0 ; j<3 ; j++) { -    if (out->normal[j] < 0) { -      bits |= 1<<j; -    } -  } -  out->signbits = bits; -} - - -/* -================== -BoxOnPlaneSide - -Returns 1, 2, or 1 + 2 - -// this is the slow, general version -int BoxOnPlaneSide2 (vec3_t emins, vec3_t emaxs, struct cplane_s *p) -{ -  int   i; -  float dist1, dist2; -  int   sides; -  vec3_t  corners[2]; - -  for (i=0 ; i<3 ; i++) -  { -    if (p->normal[i] < 0) -    { -      corners[0][i] = emins[i]; -      corners[1][i] = emaxs[i]; -    } -    else -    { -      corners[1][i] = emins[i]; -      corners[0][i] = emaxs[i]; -    } -  } -  dist1 = DotProduct (p->normal, corners[0]) - p->dist; -  dist2 = DotProduct (p->normal, corners[1]) - p->dist; -  sides = 0; -  if (dist1 >= 0) -    sides = 1; -  if (dist2 < 0) -    sides |= 2; - -  return sides; -} - -================== -*/ -#if !( (defined __linux__ || __FreeBSD__) && (defined __i386__) && (!defined C_ONLY)) // rb010123 -#if defined __LCC__ || defined C_ONLY || !id386 || defined __VECTORC - -int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p) -{ -  float dist1, dist2; -  int   sides; - -// fast axial cases -  if (p->type < 3) -  { -    if (p->dist <= emins[p->type]) -      return 1; -    if (p->dist >= emaxs[p->type]) -      return 2; -    return 3; -  } - -// general case -  switch (p->signbits) -  { -  case 0: -    dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; -    dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; -    break; -  case 1: -    dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; -    dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; -    break; -  case 2: -    dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; -    dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; -    break; -  case 3: -    dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; -    dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; -    break; -  case 4: -    dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; -    dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; -    break; -  case 5: -    dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; -    dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; -    break; -  case 6: -    dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; -    dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; -    break; -  case 7: -    dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; -    dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; -    break; -  default: -    dist1 = dist2 = 0;    // shut up compiler -    break; -  } - -  sides = 0; -  if (dist1 >= p->dist) -    sides = 1; -  if (dist2 < p->dist) -    sides |= 2; - -  return sides; -} -#else -#pragma warning( disable: 4035 ) - -__declspec( naked ) int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p) -{ -  static int bops_initialized; -  static int Ljmptab[8]; - -  __asm { - -    push ebx - -    cmp bops_initialized, 1 -    je  initialized -    mov bops_initialized, 1 - -    mov Ljmptab[0*4], offset Lcase0 -    mov Ljmptab[1*4], offset Lcase1 -    mov Ljmptab[2*4], offset Lcase2 -    mov Ljmptab[3*4], offset Lcase3 -    mov Ljmptab[4*4], offset Lcase4 -    mov Ljmptab[5*4], offset Lcase5 -    mov Ljmptab[6*4], offset Lcase6 -    mov Ljmptab[7*4], offset Lcase7 - -initialized: - -    mov edx,dword ptr[4+12+esp] -    mov ecx,dword ptr[4+4+esp] -    xor eax,eax -    mov ebx,dword ptr[4+8+esp] -    mov al,byte ptr[17+edx] -    cmp al,8 -    jge Lerror -    fld dword ptr[0+edx] -    fld st(0) -    jmp dword ptr[Ljmptab+eax*4] -Lcase0: -    fmul dword ptr[ebx] -    fld dword ptr[0+4+edx] -    fxch st(2) -    fmul dword ptr[ecx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[4+ebx] -    fld dword ptr[0+8+edx] -    fxch st(2) -    fmul dword ptr[4+ecx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[8+ebx] -    fxch st(5) -    faddp st(3),st(0) -    fmul dword ptr[8+ecx] -    fxch st(1) -    faddp st(3),st(0) -    fxch st(3) -    faddp st(2),st(0) -    jmp LSetSides -Lcase1: -    fmul dword ptr[ecx] -    fld dword ptr[0+4+edx] -    fxch st(2) -    fmul dword ptr[ebx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[4+ebx] -    fld dword ptr[0+8+edx] -    fxch st(2) -    fmul dword ptr[4+ecx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[8+ebx] -    fxch st(5) -    faddp st(3),st(0) -    fmul dword ptr[8+ecx] -    fxch st(1) -    faddp st(3),st(0) -    fxch st(3) -    faddp st(2),st(0) -    jmp LSetSides -Lcase2: -    fmul dword ptr[ebx] -    fld dword ptr[0+4+edx] -    fxch st(2) -    fmul dword ptr[ecx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[4+ecx] -    fld dword ptr[0+8+edx] -    fxch st(2) -    fmul dword ptr[4+ebx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[8+ebx] -    fxch st(5) -    faddp st(3),st(0) -    fmul dword ptr[8+ecx] -    fxch st(1) -    faddp st(3),st(0) -    fxch st(3) -    faddp st(2),st(0) -    jmp LSetSides -Lcase3: -    fmul dword ptr[ecx] -    fld dword ptr[0+4+edx] -    fxch st(2) -    fmul dword ptr[ebx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[4+ecx] -    fld dword ptr[0+8+edx] -    fxch st(2) -    fmul dword ptr[4+ebx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[8+ebx] -    fxch st(5) -    faddp st(3),st(0) -    fmul dword ptr[8+ecx] -    fxch st(1) -    faddp st(3),st(0) -    fxch st(3) -    faddp st(2),st(0) -    jmp LSetSides -Lcase4: -    fmul dword ptr[ebx] -    fld dword ptr[0+4+edx] -    fxch st(2) -    fmul dword ptr[ecx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[4+ebx] -    fld dword ptr[0+8+edx] -    fxch st(2) -    fmul dword ptr[4+ecx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[8+ecx] -    fxch st(5) -    faddp st(3),st(0) -    fmul dword ptr[8+ebx] -    fxch st(1) -    faddp st(3),st(0) -    fxch st(3) -    faddp st(2),st(0) -    jmp LSetSides -Lcase5: -    fmul dword ptr[ecx] -    fld dword ptr[0+4+edx] -    fxch st(2) -    fmul dword ptr[ebx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[4+ebx] -    fld dword ptr[0+8+edx] -    fxch st(2) -    fmul dword ptr[4+ecx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[8+ecx] -    fxch st(5) -    faddp st(3),st(0) -    fmul dword ptr[8+ebx] -    fxch st(1) -    faddp st(3),st(0) -    fxch st(3) -    faddp st(2),st(0) -    jmp LSetSides -Lcase6: -    fmul dword ptr[ebx] -    fld dword ptr[0+4+edx] -    fxch st(2) -    fmul dword ptr[ecx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[4+ecx] -    fld dword ptr[0+8+edx] -    fxch st(2) -    fmul dword ptr[4+ebx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[8+ecx] -    fxch st(5) -    faddp st(3),st(0) -    fmul dword ptr[8+ebx] -    fxch st(1) -    faddp st(3),st(0) -    fxch st(3) -    faddp st(2),st(0) -    jmp LSetSides -Lcase7: -    fmul dword ptr[ecx] -    fld dword ptr[0+4+edx] -    fxch st(2) -    fmul dword ptr[ebx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[4+ecx] -    fld dword ptr[0+8+edx] -    fxch st(2) -    fmul dword ptr[4+ebx] -    fxch st(2) -    fld st(0) -    fmul dword ptr[8+ecx] -    fxch st(5) -    faddp st(3),st(0) -    fmul dword ptr[8+ebx] -    fxch st(1) -    faddp st(3),st(0) -    fxch st(3) -    faddp st(2),st(0) -LSetSides: -    faddp st(2),st(0) -    fcomp dword ptr[12+edx] -    xor ecx,ecx -    fnstsw ax -    fcomp dword ptr[12+edx] -    and ah,1 -    xor ah,1 -    add cl,ah -    fnstsw ax -    and ah,1 -    add ah,ah -    add cl,ah -    pop ebx -    mov eax,ecx -    ret -Lerror: -    int 3 -  } -} -#pragma warning( default: 4035 ) - -#endif -#endif - -/* -================= -RadiusFromBounds -================= -*/ -float RadiusFromBounds( const vec3_t mins, const vec3_t maxs ) { -  int   i; -  vec3_t  corner; -  float a, b; - -  for (i=0 ; i<3 ; i++) { -    a = fabs( mins[i] ); -    b = fabs( maxs[i] ); -    corner[i] = a > b ? a : b; -  } - -  return VectorLength (corner); -} - - -void ClearBounds( vec3_t mins, vec3_t maxs ) { -  mins[0] = mins[1] = mins[2] = 99999; -  maxs[0] = maxs[1] = maxs[2] = -99999; -} - -void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs ) { -  if ( v[0] < mins[0] ) { -    mins[0] = v[0]; -  } -  if ( v[0] > maxs[0]) { -    maxs[0] = v[0]; -  } - -  if ( v[1] < mins[1] ) { -    mins[1] = v[1]; -  } -  if ( v[1] > maxs[1]) { -    maxs[1] = v[1]; -  } - -  if ( v[2] < mins[2] ) { -    mins[2] = v[2]; -  } -  if ( v[2] > maxs[2]) { -    maxs[2] = v[2]; -  } -} - - -vec_t VectorNormalize( vec3_t v ) { -  float length, ilength; - -  length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; -  length = sqrt (length); - -  if ( length ) { -    ilength = 1/length; -    v[0] *= ilength; -    v[1] *= ilength; -    v[2] *= ilength; -  } - -  return length; -} - -vec_t VectorNormalize2( const vec3_t v, vec3_t out) { -  float length, ilength; - -  length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; -  length = sqrt (length); - -  if (length) -  { -    ilength = 1/length; -    out[0] = v[0]*ilength; -    out[1] = v[1]*ilength; -    out[2] = v[2]*ilength; -  } else { -    VectorClear( out ); -  } - -  return length; - -} - -void _VectorMA( const vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc) { -  vecc[0] = veca[0] + scale*vecb[0]; -  vecc[1] = veca[1] + scale*vecb[1]; -  vecc[2] = veca[2] + scale*vecb[2]; -} - - -vec_t _DotProduct( const vec3_t v1, const vec3_t v2 ) { -  return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; -} - -void _VectorSubtract( const vec3_t veca, const vec3_t vecb, vec3_t out ) { -  out[0] = veca[0]-vecb[0]; -  out[1] = veca[1]-vecb[1]; -  out[2] = veca[2]-vecb[2]; -} - -void _VectorAdd( const vec3_t veca, const vec3_t vecb, vec3_t out ) { -  out[0] = veca[0]+vecb[0]; -  out[1] = veca[1]+vecb[1]; -  out[2] = veca[2]+vecb[2]; -} - -void _VectorCopy( const vec3_t in, vec3_t out ) { -  out[0] = in[0]; -  out[1] = in[1]; -  out[2] = in[2]; -} - -void _VectorScale( const vec3_t in, vec_t scale, vec3_t out ) { -  out[0] = in[0]*scale; -  out[1] = in[1]*scale; -  out[2] = in[2]*scale; -} - -void Vector4Scale( const vec4_t in, vec_t scale, vec4_t out ) { -  out[0] = in[0]*scale; -  out[1] = in[1]*scale; -  out[2] = in[2]*scale; -  out[3] = in[3]*scale; -} - - -int Q_log2( int val ) { -  int answer; - -  answer = 0; -  while ( ( val>>=1 ) != 0 ) { -    answer++; -  } -  return answer; -} - - - -/* -================= -PlaneTypeForNormal -================= -*/ -/* -int PlaneTypeForNormal (vec3_t normal) { -  if ( normal[0] == 1.0 ) -    return PLANE_X; -  if ( normal[1] == 1.0 ) -    return PLANE_Y; -  if ( normal[2] == 1.0 ) -    return PLANE_Z; - -  return PLANE_NON_AXIAL; -} -*/ - - -/* -================ -MatrixMultiply -================ -*/ -void MatrixMultiply( float in1[ 3 ][ 3 ], float in2[ 3 ][ 3 ], float out[ 3 ][ 3 ] ) -{ -  out[ 0 ][ 0 ] = in1[ 0 ][ 0 ] * in2[ 0 ][ 0 ] + in1[ 0 ][ 1 ] * in2[ 1 ][ 0 ] + -                  in1[ 0 ][ 2 ] * in2[ 2 ][ 0 ]; -  out[ 0 ][ 1 ] = in1[ 0 ][ 0 ] * in2[ 0 ][ 1 ] + in1[ 0 ][ 1 ] * in2[ 1 ][ 1 ] + -                  in1[ 0 ][ 2 ] * in2[ 2 ][ 1 ]; -  out[ 0 ][ 2 ] = in1[ 0 ][ 0 ] * in2[ 0 ][ 2 ] + in1[ 0 ][ 1 ] * in2[ 1 ][ 2 ] + -                  in1[ 0 ][ 2 ] * in2[ 2 ][ 2 ]; -  out[ 1 ][ 0 ] = in1[ 1 ][ 0 ] * in2[ 0 ][ 0 ] + in1[ 1 ][ 1 ] * in2[ 1 ][ 0 ] + -                  in1[ 1 ][ 2 ] * in2[ 2 ][ 0 ]; -  out[ 1 ][ 1 ] = in1[ 1 ][ 0 ] * in2[ 0 ][ 1 ] + in1[ 1 ][ 1 ] * in2[ 1 ][ 1 ] + -                  in1[ 1 ][ 2 ] * in2[ 2 ][ 1 ]; -  out[ 1 ][ 2 ] = in1[ 1 ][ 0 ] * in2[ 0 ][ 2 ] + in1[ 1 ][ 1 ] * in2[ 1 ][ 2 ] + -                  in1[ 1 ][ 2 ] * in2[ 2 ][ 2 ]; -  out[ 2 ][ 0 ] = in1[ 2 ][ 0 ] * in2[ 0 ][ 0 ] + in1[ 2 ][ 1 ] * in2[ 1 ][ 0 ] + -                  in1[ 2 ][ 2 ] * in2[ 2 ][ 0 ]; -  out[ 2 ][ 1 ] = in1[ 2 ][ 0 ] * in2[ 0 ][ 1 ] + in1[ 2 ][ 1 ] * in2[ 1 ][ 1 ] + -                  in1[ 2 ][ 2 ] * in2[ 2 ][ 1 ]; -  out[ 2 ][ 2 ] = in1[ 2 ][ 0 ] * in2[ 0 ][ 2 ] + in1[ 2 ][ 1 ] * in2[ 1 ][ 2 ] + -                  in1[ 2 ][ 2 ] * in2[ 2 ][ 2 ]; -} - -/* -================ -VectorMatrixMultiply -================ -*/ -void VectorMatrixMultiply( const vec3_t p, vec3_t m[ 3 ], vec3_t out ) -{ -  out[ 0 ] = m[ 0 ][ 0 ] * p[ 0 ] + m[ 1 ][ 0 ] * p[ 1 ] + m[ 2 ][ 0 ] * p[ 2 ]; -  out[ 1 ] = m[ 0 ][ 1 ] * p[ 0 ] + m[ 1 ][ 1 ] * p[ 1 ] + m[ 2 ][ 1 ] * p[ 2 ]; -  out[ 2 ] = m[ 0 ][ 2 ] * p[ 0 ] + m[ 1 ][ 2 ] * p[ 1 ] + m[ 2 ][ 2 ] * p[ 2 ]; -} - -void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) -{ -  float         angle; -  static float  sr, sp, sy, cr, cp, cy; -  // static to help MS compiler fp bugs - -  angle = angles[ YAW ] * ( M_PI * 2 / 360 ); -  sy = sin( angle ); -  cy = cos( angle ); -  angle = angles[ PITCH ] * ( M_PI * 2 / 360 ); -  sp = sin( angle ); -  cp = cos( angle ); -  angle = angles[ ROLL ] * ( M_PI * 2 / 360 ); -  sr = sin( angle ); -  cr = cos( angle ); - -  if( forward ) -  { -    forward[ 0 ] = cp * cy; -    forward[ 1 ] = cp * sy; -    forward[ 2 ] = -sp; -  } - -  if( right ) -  { -    right[ 0 ] = ( -1 * sr * sp * cy + -1 * cr * -sy ); -    right[ 1 ] = ( -1 * sr * sp * sy + -1 * cr * cy ); -    right[ 2 ] = -1 * sr * cp; -  } - -  if( up ) -  { -    up[ 0 ] = ( cr * sp * cy + -sr * -sy ); -    up[ 1 ] = ( cr * sp * sy + -sr * cy ); -    up[ 2 ] = cr * cp; -  } -} - -/* -** assumes "src" is normalized -*/ -void PerpendicularVector( vec3_t dst, const vec3_t src ) -{ -  int pos; -  int i; -  float minelem = 1.0F; -  vec3_t tempvec; - -  /* -  ** find the smallest magnitude axially aligned vector -  */ -  for ( pos = 0, i = 0; i < 3; i++ ) -  { -    if ( fabs( src[i] ) < minelem ) -    { -      pos = i; -      minelem = fabs( src[i] ); -    } -  } -  tempvec[0] = tempvec[1] = tempvec[2] = 0.0F; -  tempvec[pos] = 1.0F; - -  /* -  ** project the point onto the plane defined by src -  */ -  ProjectPointOnPlane( dst, tempvec, src ); - -  /* -  ** normalize the result -  */ -  VectorNormalize( dst ); -} - -/* -================= -pointToLineDistance - -Distance from a point to some line -================= -*/ -float pointToLineDistance( const vec3_t p0, const vec3_t p1, const vec3_t p2 ) -{ -  vec3_t  v, w, y; -  float   c1, c2; - -  VectorSubtract( p2, p1, v ); -  VectorSubtract( p1, p0, w ); - -  CrossProduct( w, v, y ); -  c1 = VectorLength( y ); -  c2 = VectorLength( v ); - -  if( c2 == 0.0f ) -    return 0.0f; -  else -    return c1 / c2; -} - -/* -================= -GetPerpendicularViewVector - -Used to find an "up" vector for drawing a sprite so that it always faces the view as best as possible -================= -*/ -void GetPerpendicularViewVector( const vec3_t point, const vec3_t p1, const vec3_t p2, vec3_t up ) -{ -  vec3_t  v1, v2; - -  VectorSubtract( point, p1, v1 ); -  VectorNormalize( v1 ); - -  VectorSubtract( point, p2, v2 ); -  VectorNormalize( v2 ); - -  CrossProduct( v1, v2, up ); -  VectorNormalize( up ); -} - -/* -================ -ProjectPointOntoVector -================ -*/ -void ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vProj ) -{ -  vec3_t pVec, vec; - -  VectorSubtract( point, vStart, pVec ); -  VectorSubtract( vEnd, vStart, vec ); -  VectorNormalize( vec ); -  // project onto the directional vector for this segment -  VectorMA( vStart, DotProduct( pVec, vec ), vec, vProj ); -} - -/* -================ -VectorMaxComponent - -Return the biggest component of some vector -================ -*/ -float VectorMaxComponent( vec3_t v ) -{ -  float biggest = v[ 0 ]; - -  if( v[ 1 ] > biggest ) -    biggest = v[ 1 ]; - -  if( v[ 2 ] > biggest ) -    biggest = v[ 2 ]; - -  return biggest; -} - -/* -================ -VectorMinComponent - -Return the smallest component of some vector -================ -*/ -float VectorMinComponent( vec3_t v ) -{ -  float smallest = v[ 0 ]; - -  if( v[ 1 ] < smallest ) -    smallest = v[ 1 ]; - -  if( v[ 2 ] < smallest ) -    smallest = v[ 2 ]; - -  return smallest; -} - -#ifdef Q3_VM -/* -=============== -round -=============== -*/ -float round( float v ) -{ -  if( v >= 0.5f ) -    return ceil( v ); -  else -    return floor( v ); -} -#endif diff --git a/mod/src/game/q_shared.c b/mod/src/game/q_shared.c deleted file mode 100644 index 6133c89a..00000000 --- a/mod/src/game/q_shared.c +++ /dev/null @@ -1,1286 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// q_shared.c -- stateless support routines that are included in each code dll - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "q_shared.h" - -float Com_Clamp( float min, float max, float value ) { -  if ( value < min ) { -    return min; -  } -  if ( value > max ) { -    return max; -  } -  return value; -} - - -/* -============ -COM_SkipPath -============ -*/ -char *COM_SkipPath (char *pathname) -{ -  char  *last; - -  last = pathname; -  while (*pathname) -  { -    if (*pathname=='/') -      last = pathname+1; -    pathname++; -  } -  return last; -} - -/* -============ -COM_StripExtension -============ -*/ -void COM_StripExtension( const char *in, char *out ) { -  while ( *in && *in != '.' ) { -    *out++ = *in++; -  } -  *out = 0; -} - - -/* -================== -COM_DefaultExtension -================== -*/ -void COM_DefaultExtension (char *path, int maxSize, const char *extension ) { -  char  oldPath[MAX_QPATH]; -  char    *src; - -// -// if path doesn't have a .EXT, append extension -// (extension should include the .) -// -  src = path + strlen(path) - 1; - -  while (*src != '/' && src != path) { -    if ( *src == '.' ) { -      return;                 // it has an extension -    } -    src--; -  } - -  Q_strncpyz( oldPath, path, sizeof( oldPath ) ); -  Com_sprintf( path, maxSize, "%s%s", oldPath, extension ); -} - -/* -============================================================================ - -          BYTE ORDER FUNCTIONS - -============================================================================ -*/ - -// can't just use function pointers, or dll linkage can -// mess up when qcommon is included in multiple places -/*static short  (*_BigShort) (short l); -static short  (*_LittleShort) (short l); -static int    (*_BigLong) (int l); -static int    (*_LittleLong) (int l); -static qint64 (*_BigLong64) (qint64 l); -static qint64 (*_LittleLong64) (qint64 l); -static float  (*_BigFloat) (const float *l); -static float  (*_LittleFloat) (const float *l); - -short BigShort(short l){return _BigShort(l);} -short LittleShort(short l) {return _LittleShort(l);} -int   BigLong (int l) {return _BigLong(l);} -int   LittleLong (int l) {return _LittleLong(l);} -qint64  BigLong64 (qint64 l) {return _BigLong64(l);} -qint64  LittleLong64 (qint64 l) {return _LittleLong64(l);} -float BigFloat (const float *l) {return _BigFloat(l);} -float LittleFloat (const float *l) {return _LittleFloat(l);}*/ - -short   ShortSwap (short l) -{ -  byte    b1,b2; - -  b1 = l&255; -  b2 = (l>>8)&255; - -  return (b1<<8) + b2; -} - -short ShortNoSwap (short l) -{ -  return l; -} - -int    LongSwap (int l) -{ -  byte    b1,b2,b3,b4; - -  b1 = l&255; -  b2 = (l>>8)&255; -  b3 = (l>>16)&255; -  b4 = (l>>24)&255; - -  return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; -} - -int LongNoSwap (int l) -{ -  return l; -} - -qint64 Long64Swap (qint64 ll) -{ -  qint64  result; - -  result.b0 = ll.b7; -  result.b1 = ll.b6; -  result.b2 = ll.b5; -  result.b3 = ll.b4; -  result.b4 = ll.b3; -  result.b5 = ll.b2; -  result.b6 = ll.b1; -  result.b7 = ll.b0; - -  return result; -} - -qint64 Long64NoSwap (qint64 ll) -{ -  return ll; -} - -typedef union { -  float f; -  unsigned int i; -} _FloatByteUnion; - -float FloatSwap (const float *f) { -  const _FloatByteUnion *in; -  _FloatByteUnion out; - -  in = (_FloatByteUnion *)f; -  out.i = LongSwap(in->i); - -  return out.f; -} - -float FloatNoSwap (const float *f) -{ -  return *f; -} - -/* -================ -Swap_Init -================ -*/ -void Swap_Init (void) -{ -/*  byte  swaptest[2] = {1,0}; - -// set the byte swapping variables in a portable manner -  if ( *(short *)swaptest == 1) -  { -    _BigShort = ShortSwap; -    _LittleShort = ShortNoSwap; -    _BigLong = LongSwap; -    _LittleLong = LongNoSwap; -    _BigLong64 = Long64Swap; -    _LittleLong64 = Long64NoSwap; -    _BigFloat = FloatSwap; -    _LittleFloat = FloatNoSwap; -  } -  else -  { -    _BigShort = ShortNoSwap; -    _LittleShort = ShortSwap; -    _BigLong = LongNoSwap; -    _LittleLong = LongSwap; -    _BigLong64 = Long64NoSwap; -    _LittleLong64 = Long64Swap; -    _BigFloat = FloatNoSwap; -    _LittleFloat = FloatSwap; -  } -*/ -} - - -/* -============================================================================ - -PARSING - -============================================================================ -*/ - -static  char  com_token[MAX_TOKEN_CHARS]; -static  char  com_parsename[MAX_TOKEN_CHARS]; -static  int   com_lines; - -void COM_BeginParseSession( const char *name ) -{ -  com_lines = 0; -  Com_sprintf(com_parsename, sizeof(com_parsename), "%s", name); -} - -int COM_GetCurrentParseLine( void ) -{ -  return com_lines; -} - -char *COM_Parse( char **data_p ) -{ -  return COM_ParseExt( data_p, qtrue ); -} - - -void COM_ParseError( char *format, ... ) -{ -  va_list argptr; -  static char string[4096]; - -  va_start (argptr, format); -  vsprintf (string, format, argptr); -  va_end (argptr); - -  Com_Printf("ERROR: %s, line %d: %s\n", com_parsename, com_lines, string); -} - -void COM_ParseWarning( char *format, ... ) -{ -  va_list argptr; -  static char string[4096]; - -  va_start (argptr, format); -  vsprintf (string, format, argptr); -  va_end (argptr); - -  Com_Printf("WARNING: %s, line %d: %s\n", com_parsename, com_lines, string); -} - - -/* -============== -COM_Parse - -Parse a token out of a string -Will never return NULL, just empty strings - -If "allowLineBreaks" is qtrue then an empty -string will be returned if the next token is -a newline. -============== -*/ -static char *SkipWhitespace( char *data, qboolean *hasNewLines ) { -  int c; - -  while( (c = *data) <= ' ') { -    if( !c ) { -      return NULL; -    } -    if( c == '\n' ) { -      com_lines++; -      *hasNewLines = qtrue; -    } -    data++; -  } - -  return data; -} - - -int COM_Compress( char *data_p ) -{ -  char      *in, *out; -  int       c; -  qboolean  newline = qfalse, whitespace = qfalse; - -  in = out = data_p; -  if( in ) -  { -    while( ( c = *in ) != 0 ) -    { -      // skip double slash comments -      if( c == '/' && in[ 1 ] == '/' ) -      { -        while( *in && *in != '\n' ) -          in++; -      // skip /* */ comments -      } -      else if( c == '/' && in[ 1 ] == '*' ) -      { -        while( *in && ( *in != '*' || in[ 1 ] != '/' ) ) -          in++; - -        if( *in ) -          in += 2; -      // record when we hit a newline -      } -      else if( c == '\n' || c == '\r' ) -      { -        newline = qtrue; -        in++; -      // record when we hit whitespace -      } -      else if( c == ' ' || c == '\t') -      { -        whitespace = qtrue; -        in++; -      // an actual token -      } -      else -      { -        // if we have a pending newline, emit it (and it counts as whitespace) -        if( newline ) -        { -          *out++ = '\n'; -          newline = qfalse; -          whitespace = qfalse; -        } - -        if( whitespace ) -        { -          *out++ = ' '; -          whitespace = qfalse; -        } - -        // copy quoted strings unmolested -        if( c == '"' ) -        { -          *out++ = c; -          in++; - -          while( 1 ) -          { -            c = *in; - -            if( c && c != '"' ) -            { -              *out++ = c; -              in++; -            } -            else -              break; -          } - -          if( c == '"' ) -          { -            *out++ = c; -            in++; -          } -        } -        else -        { -          *out = c; -          out++; -          in++; -        } -      } -    } -  } - -  *out = 0; -  return out - data_p; -} - -char *COM_ParseExt( char **data_p, qboolean allowLineBreaks ) -{ -  int c = 0, len; -  qboolean hasNewLines = qfalse; -  char *data; - -  data = *data_p; -  len = 0; -  com_token[0] = 0; - -  // make sure incoming data is valid -  if ( !data ) -  { -    *data_p = NULL; -    return com_token; -  } - -  while ( 1 ) -  { -    // skip whitespace -    data = SkipWhitespace( data, &hasNewLines ); -    if ( !data ) -    { -      *data_p = NULL; -      return com_token; -    } -    if ( hasNewLines && !allowLineBreaks ) -    { -      *data_p = data; -      return com_token; -    } - -    c = *data; - -    // skip double slash comments -    if ( c == '/' && data[1] == '/' ) -    { -      data += 2; -      while (*data && *data != '\n') { -        data++; -      } -    } -    // skip /* */ comments -    else if ( c=='/' && data[1] == '*' ) -    { -      data += 2; -      while ( *data && ( *data != '*' || data[1] != '/' ) ) -      { -        data++; -      } -      if ( *data ) -      { -        data += 2; -      } -    } -    else -    { -      break; -    } -  } - -  // handle quoted strings -  if (c == '\"') -  { -    data++; -    while (1) -    { -      c = *data++; -      if (c=='\"' || !c) -      { -        com_token[len] = 0; -        *data_p = ( char * ) data; -        return com_token; -      } -      if (len < MAX_TOKEN_CHARS) -      { -        com_token[len] = c; -        len++; -      } -    } -  } - -  // parse a regular word -  do -  { -    if (len < MAX_TOKEN_CHARS) -    { -      com_token[len] = c; -      len++; -    } -    data++; -    c = *data; -    if ( c == '\n' ) -      com_lines++; -  } while (c>32); - -  if (len == MAX_TOKEN_CHARS) -  { -//    Com_Printf ("Token exceeded %i chars, discarded.\n", MAX_TOKEN_CHARS); -    len = 0; -  } -  com_token[len] = 0; - -  *data_p = ( char * ) data; -  return com_token; -} - - -#if 0 -// no longer used -/* -=============== -COM_ParseInfos -=============== -*/ -int COM_ParseInfos( char *buf, int max, char infos[][MAX_INFO_STRING] ) { -  char  *token; -  int   count; -  char  key[MAX_TOKEN_CHARS]; - -  count = 0; - -  while ( 1 ) { -    token = COM_Parse( &buf ); -    if ( !token[0] ) { -      break; -    } -    if ( strcmp( token, "{" ) ) { -      Com_Printf( "Missing { in info file\n" ); -      break; -    } - -    if ( count == max ) { -      Com_Printf( "Max infos exceeded\n" ); -      break; -    } - -    infos[count][0] = 0; -    while ( 1 ) { -      token = COM_ParseExt( &buf, qtrue ); -      if ( !token[0] ) { -        Com_Printf( "Unexpected end of info file\n" ); -        break; -      } -      if ( !strcmp( token, "}" ) ) { -        break; -      } -      Q_strncpyz( key, token, sizeof( key ) ); - -      token = COM_ParseExt( &buf, qfalse ); -      if ( !token[0] ) { -        strcpy( token, "<NULL>" ); -      } -      Info_SetValueForKey( infos[count], key, token ); -    } -    count++; -  } - -  return count; -} -#endif - - -/* -================== -COM_MatchToken -================== -*/ -void COM_MatchToken( char **buf_p, char *match ) { -  char  *token; - -  token = COM_Parse( buf_p ); -  if ( strcmp( token, match ) ) { -    Com_Error( ERR_DROP, "MatchToken: %s != %s", token, match ); -  } -} - - -/* -================= -SkipBracedSection - -The next token should be an open brace. -Skips until a matching close brace is found. -Internal brace depths are properly skipped. -================= -*/ -void SkipBracedSection (char **program) { -  char      *token; -  int       depth; - -  depth = 0; -  do { -    token = COM_ParseExt( program, qtrue ); -    if( token[1] == 0 ) { -      if( token[0] == '{' ) { -        depth++; -      } -      else if( token[0] == '}' ) { -        depth--; -      } -    } -  } while( depth && *program ); -} - -/* -================= -SkipRestOfLine -================= -*/ -void SkipRestOfLine ( char **data ) { -  char  *p; -  int   c; - -  p = *data; -  while ( (c = *p++) != 0 ) { -    if ( c == '\n' ) { -      com_lines++; -      break; -    } -  } - -  *data = p; -} - - -void Parse1DMatrix (char **buf_p, int x, float *m) { -  char  *token; -  int   i; - -  COM_MatchToken( buf_p, "(" ); - -  for (i = 0 ; i < x ; i++) { -    token = COM_Parse(buf_p); -    m[i] = atof(token); -  } - -  COM_MatchToken( buf_p, ")" ); -} - -void Parse2DMatrix (char **buf_p, int y, int x, float *m) { -  int   i; - -  COM_MatchToken( buf_p, "(" ); - -  for (i = 0 ; i < y ; i++) { -    Parse1DMatrix (buf_p, x, m + i * x); -  } - -  COM_MatchToken( buf_p, ")" ); -} - -void Parse3DMatrix (char **buf_p, int z, int y, int x, float *m) { -  int   i; - -  COM_MatchToken( buf_p, "(" ); - -  for (i = 0 ; i < z ; i++) { -    Parse2DMatrix (buf_p, y, x, m + i * x*y); -  } - -  COM_MatchToken( buf_p, ")" ); -} - - -/* -============================================================================ - -          LIBRARY REPLACEMENT FUNCTIONS - -============================================================================ -*/ - -int Q_isprint( int c ) -{ -  if ( c >= 0x20 && c <= 0x7E ) -    return ( 1 ); -  return ( 0 ); -} - -int Q_islower( int c ) -{ -  if (c >= 'a' && c <= 'z') -    return ( 1 ); -  return ( 0 ); -} - -int Q_isupper( int c ) -{ -  if (c >= 'A' && c <= 'Z') -    return ( 1 ); -  return ( 0 ); -} - -int Q_isalpha( int c ) -{ -  if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) -    return ( 1 ); -  return ( 0 ); -} - -char* Q_strrchr( const char* string, int c ) -{ -  char cc = c; -  char *s; -  char *sp=(char *)0; - -  s = (char*)string; - -  while (*s) -  { -    if (*s == cc) -      sp = s; -    s++; -  } -  if (cc == 0) -    sp = s; - -  return sp; -} - -/* -============= -Q_strncpyz - -Safe strncpy that ensures a trailing zero -============= -*/ -void Q_strncpyz( char *dest, const char *src, int destsize ) -{ -  // bk001129 - also NULL dest -  if( !dest ) -    Com_Error( ERR_FATAL, "Q_strncpyz: NULL dest" ); - -  if( !src ) -    Com_Error( ERR_FATAL, "Q_strncpyz: NULL src" ); - -  if( destsize < 1 ) -    Com_Error( ERR_FATAL, "Q_strncpyz: destsize < 1" ); - -  strncpy( dest, src, destsize - 1 ); -  dest[ destsize - 1 ] = 0; -} - -int Q_stricmpn( const char *s1, const char *s2, int n ) -{ -  int   c1, c2; - -  // bk001129 - moved in 1.17 fix not in id codebase -  if( s1 == NULL ) -  { -    if( s2 == NULL ) -      return 0; -    else -      return -1; -  } -  else if( s2==NULL ) -    return 1; - -  do -  { -    c1 = *s1++; -    c2 = *s2++; - -    if( !n-- ) -      return 0;   // strings are equal until end point - -    if( c1 != c2 ) -    { -      if( c1 >= 'a' && c1 <= 'z' ) -        c1 -= ( 'a' - 'A' ); - -      if( c2 >= 'a' && c2 <= 'z' ) -        c2 -= ( 'a' - 'A' ); - -      if( c1 != c2 ) -        return c1 < c2 ? -1 : 1; -    } -  } while( c1 ); - -  return 0;   // strings are equal -} - -int Q_strncmp (const char *s1, const char *s2, int n) { -  int   c1, c2; - -  do { -    c1 = *s1++; -    c2 = *s2++; - -    if (!n--) { -      return 0;   // strings are equal until end point -    } - -    if (c1 != c2) { -      return c1 < c2 ? -1 : 1; -    } -  } while (c1); - -  return 0;   // strings are equal -} - -int Q_stricmp( const char *s1, const char *s2 ) -{ -  return ( s1 && s2 ) ? Q_stricmpn( s1, s2, 99999 ) : -1; -} - - -char *Q_strlwr( char *s1 ) { -    char  *s; - -    s = s1; -  while ( *s ) { -    *s = tolower(*s); -    s++; -  } -    return s1; -} - -char *Q_strupr( char *s1 ) { -    char  *s; - -    s = s1; -  while ( *s ) { -    *s = toupper(*s); -    s++; -  } -    return s1; -} - - -// never goes past bounds or leaves without a terminating 0 -void Q_strcat( char *dest, int size, const char *src ) -{ -  int   l1; - -  l1 = strlen( dest ); -  if( l1 >= size ) -    Com_Error( ERR_FATAL, "Q_strcat: already overflowed" ); - -  Q_strncpyz( dest + l1, src, size - l1 ); -} - - -int Q_PrintStrlen( const char *string ) { -  int     len; -  const char  *p; - -  if( !string ) { -    return 0; -  } - -  len = 0; -  p = string; -  while( *p ) { -    if( Q_IsColorString( p ) ) { -      p += 2; -      continue; -    } -    p++; -    len++; -  } - -  return len; -} - - -char *Q_CleanStr( char *string ) { -  char* d; -  char* s; -  int   c; - -  s = string; -  d = string; -  while ((c = *s) != 0 ) { -    if ( Q_IsColorString( s ) ) { -      s++; -    } -    else if ( c >= 0x20 && c <= 0x7E ) { -      *d++ = c; -    } -    s++; -  } -  *d = '\0'; - -  return string; -} - - -void QDECL Com_sprintf( char *dest, int size, const char *fmt, ...) -{ -  int     len; -  va_list argptr; -  char    bigbuffer[ 32000 ]; // big, but small enough to fit in PPC stack - -  va_start( argptr, fmt ); -  len = vsprintf( bigbuffer, fmt, argptr ); -  va_end( argptr ); - -  if( len >= sizeof( bigbuffer ) ) -    Com_Error( ERR_FATAL, "Com_sprintf: overflowed bigbuffer" ); - -  if( len >= size ) -    Com_Printf( "Com_sprintf: overflow of %i in %i\n", len, size ); - -#ifdef  _DEBUG -  __asm { -    int 3; -  } -#endif -  Q_strncpyz( dest, bigbuffer, size ); -} - - -/* -============ -va - -does a varargs printf into a temp buffer, so I don't need to have -varargs versions of all text functions. -FIXME: make this buffer size safe someday -============ -*/ -char  * QDECL va( char *format, ... ) { -  va_list   argptr; -  static char   string[2][32000]; // in case va is called by nested functions -  static int    index = 0; -  char  *buf; - -  buf = string[index & 1]; -  index++; - -  va_start (argptr, format); -  vsprintf (buf, format,argptr); -  va_end (argptr); - -  return buf; -} - - -/* -===================================================================== - -  INFO STRINGS - -===================================================================== -*/ - -/* -=============== -Info_ValueForKey - -Searches the string for the given -key and returns the associated value, or an empty string. -FIXME: overflow check? -=============== -*/ -char *Info_ValueForKey( const char *s, const char *key ) -{ -  char        pkey[ BIG_INFO_KEY ]; -  static char value[ 2 ][ BIG_INFO_VALUE ];  // use two buffers so compares -                      // work without stomping on each other -  static int  valueindex = 0; -  char        *o; - -  if( !s || !key ) -    return ""; - -  if( strlen( s ) >= BIG_INFO_STRING ) -    Com_Error( ERR_DROP, "Info_ValueForKey: oversize infostring" ); - -  valueindex ^= 1; - -  if( *s == '\\' ) -    s++; - -  while( 1 ) -  { -    o = pkey; -    while( *s != '\\' ) -    { -      if( !*s ) -        return ""; - -      *o++ = *s++; -    } - -    *o = 0; -    s++; - -    o = value[ valueindex ]; - -    while( *s != '\\' && *s ) -      *o++ = *s++; - -    *o = 0; - -    if( !Q_stricmp( key, pkey ) ) -      return value[ valueindex ]; - -    if( !*s ) -      break; - -    s++; -  } - -  return ""; -} - - -/* -=================== -Info_NextPair - -Used to itterate through all the key/value pairs in an info string -=================== -*/ -void Info_NextPair( const char **head, char *key, char *value ) { -  char  *o; -  const char  *s; - -  s = *head; - -  if ( *s == '\\' ) { -    s++; -  } -  key[0] = 0; -  value[0] = 0; - -  o = key; -  while ( *s != '\\' ) { -    if ( !*s ) { -      *o = 0; -      *head = s; -      return; -    } -    *o++ = *s++; -  } -  *o = 0; -  s++; - -  o = value; -  while ( *s != '\\' && *s ) { -    *o++ = *s++; -  } -  *o = 0; - -  *head = s; -} - - -/* -=================== -Info_RemoveKey -=================== -*/ -void Info_RemoveKey( char *s, const char *key ) { -  char  *start; -  char  pkey[MAX_INFO_KEY]; -  char  value[MAX_INFO_VALUE]; -  char  *o; - -  if ( strlen( s ) >= MAX_INFO_STRING ) { -    Com_Error( ERR_DROP, "Info_RemoveKey: oversize infostring" ); -  } - -  if (strchr (key, '\\')) { -    return; -  } - -  while (1) -  { -    start = s; -    if (*s == '\\') -      s++; -    o = pkey; -    while (*s != '\\') -    { -      if (!*s) -        return; -      *o++ = *s++; -    } -    *o = 0; -    s++; - -    o = value; -    while (*s != '\\' && *s) -    { -      if (!*s) -        return; -      *o++ = *s++; -    } -    *o = 0; - -    if (!strcmp (key, pkey) ) -    { -      strcpy (start, s);  // remove this part -      return; -    } - -    if (!*s) -      return; -  } - -} - - -/* -=================== -Info_RemoveKey_Big -=================== -*/ -void Info_RemoveKey_Big( char *s, const char *key ) { -  char  *start; -  char  pkey[BIG_INFO_KEY]; -  char  value[BIG_INFO_VALUE]; -  char  *o; - -  if ( strlen( s ) >= BIG_INFO_STRING ) { -    Com_Error( ERR_DROP, "Info_RemoveKey_Big: oversize infostring" ); -  } - -  if (strchr (key, '\\')) { -    return; -  } - -  while (1) -  { -    start = s; -    if (*s == '\\') -      s++; -    o = pkey; -    while (*s != '\\') -    { -      if (!*s) -        return; -      *o++ = *s++; -    } -    *o = 0; -    s++; - -    o = value; -    while (*s != '\\' && *s) -    { -      if (!*s) -        return; -      *o++ = *s++; -    } -    *o = 0; - -    if (!strcmp (key, pkey) ) -    { -      strcpy (start, s);  // remove this part -      return; -    } - -    if (!*s) -      return; -  } - -} - - -/* -================== -Info_Validate - -Some characters are illegal in info strings because they -can mess up the server's parsing -================== -*/ -qboolean Info_Validate( const char *s ) -{ -  if( strchr( s, '\"' ) ) -    return qfalse; - -  if( strchr( s, ';' ) ) -    return qfalse; - -  return qtrue; -} - -/* -================== -Info_SetValueForKey - -Changes or adds a key/value pair -================== -*/ -void Info_SetValueForKey( char *s, const char *key, const char *value ) { -  char  newi[MAX_INFO_STRING]; - -  if ( strlen( s ) >= MAX_INFO_STRING ) { -    Com_Error( ERR_DROP, "Info_SetValueForKey: oversize infostring" ); -  } - -  if (strchr (key, '\\') || strchr (value, '\\')) -  { -    Com_Printf ("Can't use keys or values with a \\\n"); -    return; -  } - -  if (strchr (key, ';') || strchr (value, ';')) -  { -    Com_Printf ("Can't use keys or values with a semicolon\n"); -    return; -  } - -  if (strchr (key, '\"') || strchr (value, '\"')) -  { -    Com_Printf ("Can't use keys or values with a \"\n"); -    return; -  } - -  Info_RemoveKey (s, key); -  if (!value || !strlen(value)) -    return; - -  Com_sprintf (newi, sizeof(newi), "\\%s\\%s", key, value); - -  if (strlen(newi) + strlen(s) > MAX_INFO_STRING) -  { -    Com_Printf ("Info string length exceeded\n"); -    return; -  } - -  strcat (newi, s); -  strcpy (s, newi); -} - -//==================================================================== - - -/* -================== -Info_SetValueForKey_Big - -Changes or adds a key/value pair -================== -*/ -void Info_SetValueForKey_Big( char *s, const char *key, const char *value ) { -  char  newi[BIG_INFO_STRING]; - -  if ( strlen( s ) >= BIG_INFO_STRING ) { -    Com_Error( ERR_DROP, "Info_SetValueForKey: oversize infostring" ); -  } - -  if (strchr (key, '\\') || strchr (value, '\\')) -  { -    Com_Printf ("Can't use keys or values with a \\\n"); -    return; -  } - -  if (strchr (key, ';') || strchr (value, ';')) -  { -    Com_Printf ("Can't use keys or values with a semicolon\n"); -    return; -  } - -  if (strchr (key, '\"') || strchr (value, '\"')) -  { -    Com_Printf ("Can't use keys or values with a \"\n"); -    return; -  } - -  Info_RemoveKey_Big (s, key); -  if (!value || !strlen(value)) -    return; - -  Com_sprintf (newi, sizeof(newi), "\\%s\\%s", key, value); - -  if (strlen(newi) + strlen(s) > BIG_INFO_STRING) -  { -    Com_Printf ("BIG Info string length exceeded\n"); -    return; -  } - -  strcat (s, newi); -} - - - -//==================================================================== diff --git a/mod/src/game/q_shared.h b/mod/src/game/q_shared.h deleted file mode 100644 index b59f1a5e..00000000 --- a/mod/src/game/q_shared.h +++ /dev/null @@ -1,1422 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#ifndef __Q_SHARED_H -#define __Q_SHARED_H - -// q_shared.h -- included first by ALL program modules. -// A user mod should never modify this file - -#define Q3_VERSION    "Q3 1.32" - - -#define MAX_TEAMNAME 32 - -#ifdef _WIN32 - -#pragma warning(disable : 4018)     // signed/unsigned mismatch -#pragma warning(disable : 4032) -#pragma warning(disable : 4051) -#pragma warning(disable : 4057)   // slightly different base types -#pragma warning(disable : 4100)   // unreferenced formal parameter -#pragma warning(disable : 4115) -#pragma warning(disable : 4125)   // decimal digit terminates octal escape sequence -#pragma warning(disable : 4127)   // conditional expression is constant -#pragma warning(disable : 4136) -#pragma warning(disable : 4152)   // nonstandard extension, function/data pointer conversion in expression -//#pragma warning(disable : 4201) -//#pragma warning(disable : 4214) -#pragma warning(disable : 4244) -#pragma warning(disable : 4142)   // benign redefinition -//#pragma warning(disable : 4305)   // truncation from const double to float -//#pragma warning(disable : 4310)   // cast truncates constant value -//#pragma warning(disable:  4505)   // unreferenced local function has been removed -#pragma warning(disable : 4514) -#pragma warning(disable : 4702)   // unreachable code -#pragma warning(disable : 4711)   // selected for automatic inline expansion -#pragma warning(disable : 4220)   // varargs matches remaining parameters -#endif - -/********************************************************************** -  VM Considerations - -  The VM can not use the standard system headers because we aren't really -  using the compiler they were meant for.  We use bg_lib.h which contains -  prototypes for the functions we define for our own use in bg_lib.c. - -  When writing mods, please add needed headers HERE, do not start including -  stuff like <stdio.h> in the various .c files that make up each of the VMs -  since you will be including system headers files can will have issues. - -  Remember, if you use a C library function that is not defined in bg_lib.c, -  you will have to add your own version for support in the VM. - - **********************************************************************/ - -#ifdef Q3_VM - -#include "bg_lib.h" - -#else - -#include <assert.h> -#include <math.h> -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <stdlib.h> -#include <time.h> -#include <ctype.h> -#include <limits.h> - -#endif - -#ifdef _WIN32 - -//#pragma intrinsic( memset, memcpy ) - -#endif - - -// this is the define for determining if we have an asm version of a C function -#if (defined _M_IX86 || defined __i386__) && !defined __sun__  && !defined __LCC__ -#define id386 1 -#else -#define id386 0 -#endif - -#if (defined(powerc) || defined(powerpc) || defined(ppc) || defined(__ppc) || defined(__ppc__)) && !defined(C_ONLY) -#define idppc 1 -#else -#define idppc 0 -#endif - -// for windows fastcall option - -#define QDECL - -short   ShortSwap (short l); -int   LongSwap (int l); -float FloatSwap (const float *f); - -//======================= WIN32 DEFINES ================================= - -#ifdef WIN32 - -#define MAC_STATIC - -#undef QDECL -#define QDECL __cdecl - -// buildstring will be incorporated into the version string -#ifdef NDEBUG -#ifdef _M_IX86 -#define CPUSTRING "win-x86" -#elif defined _M_ALPHA -#define CPUSTRING "win-AXP" -#endif -#else -#ifdef _M_IX86 -#define CPUSTRING "win-x86-debug" -#elif defined _M_ALPHA -#define CPUSTRING "win-AXP-debug" -#endif -#endif - -#define ID_INLINE __inline - -static ID_INLINE short BigShort( short l) { return ShortSwap(l); } -#define LittleShort -static ID_INLINE int BigLong(int l) { LongSwap(l); } -#define LittleLong -static ID_INLINE float BigFloat(const float *l) { FloatSwap(l); } -#define LittleFloat - -#define PATH_SEP '\\' - -#endif - -//======================= MAC OS X DEFINES ===================== - -#if defined(MACOS_X) - -#define MAC_STATIC -#define __cdecl -#define __declspec(x) -#define stricmp strcasecmp -#define ID_INLINE inline - -#ifdef __ppc__ -#define CPUSTRING "MacOSX-ppc" -#elif defined __i386__ -#define CPUSTRING "MacOSX-i386" -#else -#define CPUSTRING "MacOSX-other" -#endif - -#define PATH_SEP  '/' - -#define __rlwimi(out, in, shift, maskBegin, maskEnd) asm("rlwimi %0,%1,%2,%3,%4" : "=r" (out) : "r" (in), "i" (shift), "i" (maskBegin), "i" (maskEnd)) -#define __dcbt(addr, offset) asm("dcbt %0,%1" : : "b" (addr), "r" (offset)) - -static inline unsigned int __lwbrx(register void *addr, register int offset) { -    register unsigned int word; - -    asm("lwbrx %0,%2,%1" : "=r" (word) : "r" (addr), "b" (offset)); -    return word; -} - -static inline unsigned short __lhbrx(register void *addr, register int offset) { -    register unsigned short halfword; - -    asm("lhbrx %0,%2,%1" : "=r" (halfword) : "r" (addr), "b" (offset)); -    return halfword; -} - -static inline float __fctiw(register float f) { -    register float fi; - -    asm("fctiw %0,%1" : "=f" (fi) : "f" (f)); - -    return fi; -} - -#define BigShort -static inline short LittleShort(short l) { return ShortSwap(l); } -#define BigLong -static inline int LittleLong (int l) { return LongSwap(l); } -#define BigFloat -static inline float LittleFloat (const float l) { return FloatSwap(&l); } - -#endif - -//======================= MAC DEFINES ================================= - -#ifdef __MACOS__ - -#include <MacTypes.h> -#define MAC_STATIC -#define ID_INLINE inline - -#define CPUSTRING "MacOS-PPC" - -#define PATH_SEP ':' - -void Sys_PumpEvents( void ); - -#define BigShort -static inline short LittleShort(short l) { return ShortSwap(l); } -#define BigLong -static inline int LittleLong (int l) { return LongSwap(l); } -#define BigFloat -static inline float LittleFloat (const float l) { return FloatSwap(&l); } - -#endif - -//======================= LINUX DEFINES ================================= - -// the mac compiler can't handle >32k of locals, so we -// just waste space and make big arrays static... -#ifdef __linux__ - -// bk001205 - from Makefile -#define stricmp strcasecmp - -#define MAC_STATIC // bk: FIXME -#define ID_INLINE inline - -#ifdef __i386__ -#define CPUSTRING "linux-i386" -#elif defined __axp__ -#define CPUSTRING "linux-alpha" -#else -#define CPUSTRING "linux-other" -#endif - -#define PATH_SEP '/' - -#if !idppc -inline static short BigShort( short l) { return ShortSwap(l); } -#define LittleShort -inline static int BigLong(int l) { return LongSwap(l); } -#define LittleLong -inline static float BigFloat(const float *l) { return FloatSwap(l); } -#define LittleFloat -#else -#define BigShort -inline static short LittleShort(short l) { return ShortSwap(l); } -#define BigLong -inline static int LittleLong (int l) { return LongSwap(l); } -#define BigFloat -inline static float LittleFloat (const float *l) { return FloatSwap(l); } -#endif - -#endif - -//======================= FreeBSD DEFINES ===================== -#ifdef __FreeBSD__ // rb010123 - -#define stricmp strcasecmp - -#define MAC_STATIC -#define ID_INLINE inline - -#ifdef __i386__ -#define CPUSTRING       "freebsd-i386" -#elif defined __axp__ -#define CPUSTRING       "freebsd-alpha" -#else -#define CPUSTRING       "freebsd-other" -#endif - -#define PATH_SEP '/' - -// bk010116 - omitted Q3STATIC (see Linux above), broken target - -#if !idppc -static short BigShort( short l) { return ShortSwap(l); } -#define LittleShort -static int BigLong(int l) { LongSwap(l); } -#define LittleLong -static float BigFloat(const float *l) { FloatSwap(l); } -#define LittleFloat -#else -#define BigShort -static short LittleShort(short l) { return ShortSwap(l); } -#define BigLong -static int LittleLong (int l) { return LongSwap(l); } -#define BigFloat -static float LittleFloat (const float *l) { return FloatSwap(l); } -#endif - -#endif - -//============================================================= - -typedef unsigned char     byte; - -typedef enum {qfalse, qtrue}  qboolean; - -typedef int   qhandle_t; -typedef int   sfxHandle_t; -typedef int   fileHandle_t; -typedef int   clipHandle_t; - - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define MAX_QINT      0x7fffffff -#define MIN_QINT      (-MAX_QINT-1) - - -// angle indexes -#define PITCH       0   // up / down -#define YAW         1   // left / right -#define ROLL        2   // fall over - -// the game guarantees that no string from the network will ever -// exceed MAX_STRING_CHARS -#define MAX_STRING_CHARS  1024  // max length of a string passed to Cmd_TokenizeString -#define MAX_STRING_TOKENS 1024  // max tokens resulting from Cmd_TokenizeString -#define MAX_TOKEN_CHARS   1024  // max length of an individual token - -#define MAX_INFO_STRING   1024 -#define MAX_INFO_KEY    1024 -#define MAX_INFO_VALUE    1024 - -#define BIG_INFO_STRING   8192  // used for system info key only -#define BIG_INFO_KEY      8192 -#define BIG_INFO_VALUE    8192 - - -#define MAX_QPATH     64    // max length of a quake game pathname -#ifdef PATH_MAX -#define MAX_OSPATH      PATH_MAX -#else -#define MAX_OSPATH      256   // max length of a filesystem pathname -#endif - -#define MAX_NAME_LENGTH   32    // max length of a client name - -#define MAX_SAY_TEXT  150 - -// paramters for command buffer stuffing -typedef enum { -  EXEC_NOW,     // don't return until completed, a VM should NEVER use this, -            // because some commands might cause the VM to be unloaded... -  EXEC_INSERT,    // insert at current position, but don't run yet -  EXEC_APPEND     // add to end of the command buffer (normal case) -} cbufExec_t; - - -// -// these aren't needed by any of the VMs.  put in another header? -// -#define MAX_MAP_AREA_BYTES    32    // bit vector of area visibility - - -// print levels from renderer (FIXME: set up for game / cgame?) -typedef enum { -  PRINT_ALL, -  PRINT_DEVELOPER,    // only print when "developer 1" -  PRINT_WARNING, -  PRINT_ERROR -} printParm_t; - - -#ifdef ERR_FATAL -#undef ERR_FATAL      // this is be defined in malloc.h -#endif - -// parameters to the main Error routine -typedef enum { -  ERR_FATAL,          // exit the entire game with a popup window -  ERR_DROP,         // print to console and disconnect from game -  ERR_SERVERDISCONNECT,   // don't kill server -  ERR_DISCONNECT,       // client disconnected from the server -  ERR_NEED_CD         // pop up the need-cd dialog -} errorParm_t; - - -// font rendering values used by ui and cgame - -#define PROP_GAP_WIDTH      3 -#define PROP_SPACE_WIDTH    8 -#define PROP_HEIGHT       27 -#define PROP_SMALL_SIZE_SCALE 0.75 - -#define BLINK_DIVISOR     200 -#define PULSE_DIVISOR     75 - -#define UI_LEFT     0x00000000  // default -#define UI_CENTER   0x00000001 -#define UI_RIGHT    0x00000002 -#define UI_FORMATMASK 0x00000007 -#define UI_SMALLFONT  0x00000010 -#define UI_BIGFONT    0x00000020  // default -#define UI_GIANTFONT  0x00000040 -#define UI_DROPSHADOW 0x00000800 -#define UI_BLINK    0x00001000 -#define UI_INVERSE    0x00002000 -#define UI_PULSE    0x00004000 - -#if defined(_DEBUG) && !defined(BSPC) -  #define HUNK_DEBUG -#endif - -typedef enum { -  h_high, -  h_low, -  h_dontcare -} ha_pref; - -#ifdef HUNK_DEBUG -#define Hunk_Alloc( size, preference )        Hunk_AllocDebug(size, preference, #size, __FILE__, __LINE__) -void *Hunk_AllocDebug( int size, ha_pref preference, char *label, char *file, int line ); -#else -void *Hunk_Alloc( int size, ha_pref preference ); -#endif - -#ifdef __linux__ -// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=371 -// custom Snd_Memset implementation for glibc memset bug workaround -void Snd_Memset (void* dest, const int val, const size_t count); -#else -#define Snd_Memset Com_Memset -#endif - -#if !( defined __VECTORC ) -void Com_Memset (void* dest, const int val, const size_t count); -void Com_Memcpy (void* dest, const void* src, const size_t count); -#else -#define Com_Memset memset -#define Com_Memcpy memcpy -#endif - -#define CIN_system  1 -#define CIN_loop  2 -#define CIN_hold  4 -#define CIN_silent  8 -#define CIN_shader  16 - -/* -============================================================== - -MATHLIB - -============================================================== -*/ - - -typedef float vec_t; -typedef vec_t vec2_t[2]; -typedef vec_t vec3_t[3]; -typedef vec_t vec4_t[4]; -typedef vec_t vec5_t[5]; - -typedef int fixed4_t; -typedef int fixed8_t; -typedef int fixed16_t; - -#ifndef M_PI -#define M_PI    3.14159265358979323846f // matches value in gcc v2 math.h -#endif - -#ifndef M_SQRT2 -#define M_SQRT2 1.414213562f -#endif - -#define NUMVERTEXNORMALS  162 -extern  vec3_t  bytedirs[NUMVERTEXNORMALS]; - -// all drawing is done to a 640*480 virtual screen size -// and will be automatically scaled to the real resolution -#define SCREEN_WIDTH    640 -#define SCREEN_HEIGHT   480 - -#define TINYCHAR_WIDTH    (SMALLCHAR_WIDTH) -#define TINYCHAR_HEIGHT   (SMALLCHAR_HEIGHT/2) - -#define SMALLCHAR_WIDTH   8 -#define SMALLCHAR_HEIGHT  16 - -#define BIGCHAR_WIDTH   16 -#define BIGCHAR_HEIGHT    16 - -#define GIANTCHAR_WIDTH   32 -#define GIANTCHAR_HEIGHT  48 - -extern  vec4_t    colorBlack; -extern  vec4_t    colorRed; -extern  vec4_t    colorGreen; -extern  vec4_t    colorBlue; -extern  vec4_t    colorYellow; -extern  vec4_t    colorMagenta; -extern  vec4_t    colorCyan; -extern  vec4_t    colorWhite; -extern  vec4_t    colorLtGrey; -extern  vec4_t    colorMdGrey; -extern  vec4_t    colorDkGrey; - -#define Q_COLOR_ESCAPE  '^' -#define Q_IsColorString(p)  ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE ) - -#define COLOR_BLACK   '0' -#define COLOR_RED   '1' -#define COLOR_GREEN   '2' -#define COLOR_YELLOW  '3' -#define COLOR_BLUE    '4' -#define COLOR_CYAN    '5' -#define COLOR_MAGENTA '6' -#define COLOR_WHITE   '7' -#define ColorIndex(c) ( ( (c) - '0' ) & 7 ) - -#define S_COLOR_BLACK "^0" -#define S_COLOR_RED   "^1" -#define S_COLOR_GREEN "^2" -#define S_COLOR_YELLOW  "^3" -#define S_COLOR_BLUE  "^4" -#define S_COLOR_CYAN  "^5" -#define S_COLOR_MAGENTA "^6" -#define S_COLOR_WHITE "^7" - -extern vec4_t g_color_table[8]; - -#define MAKERGB( v, r, g, b ) v[0]=r;v[1]=g;v[2]=b -#define MAKERGBA( v, r, g, b, a ) v[0]=r;v[1]=g;v[2]=b;v[3]=a - -#define DEG2RAD( a ) ( ( (a) * M_PI ) / 180.0F ) -#define RAD2DEG( a ) ( ( (a) * 180.0f ) / M_PI ) - -struct cplane_s; - -extern  vec3_t  vec3_origin; -extern  vec3_t  axisDefault[3]; - -#define nanmask (255<<23) - -#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) - -#if idppc - -static inline float Q_rsqrt( float number ) { -    float x = 0.5f * number; -                float y; -#ifdef __GNUC__ -                asm("frsqrte %0,%1" : "=f" (y) : "f" (number)); -#else -    y = __frsqrte( number ); -#endif -    return y * (1.5f - (x * y * y)); -  } - -#ifdef __GNUC__ -static inline float Q_fabs(float x) { -    float abs_x; - -    asm("fabs %0,%1" : "=f" (abs_x) : "f" (x)); -    return abs_x; -} -#else -#define Q_fabs __fabsf -#endif - -#else -float Q_fabs( float f ); -float Q_rsqrt( float f );   // reciprocal square root -#endif - -#define SQRTFAST( x ) ( (x) * Q_rsqrt( x ) ) - -signed char ClampChar( int i ); -signed short ClampShort( int i ); - -// this isn't a real cheap function to call! -int DirToByte( vec3_t dir ); -void ByteToDir( int b, vec3_t dir ); - -#if 1 - -#define DotProduct(x,y)     ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) -#define VectorSubtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2]) -#define VectorAdd(a,b,c)    ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2]) -#define VectorCopy(a,b)     ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2]) -#define VectorScale(v, s, o)  ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s)) -#define VectorMA(v, s, b, o)  ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s)) - -#else - -#define DotProduct(x,y)     _DotProduct(x,y) -#define VectorSubtract(a,b,c) _VectorSubtract(a,b,c) -#define VectorAdd(a,b,c)    _VectorAdd(a,b,c) -#define VectorCopy(a,b)     _VectorCopy(a,b) -#define VectorScale(v, s, o)  _VectorScale(v,s,o) -#define VectorMA(v, s, b, o)  _VectorMA(v,s,b,o) - -#endif - -#ifdef __LCC__ -#ifdef VectorCopy -#undef VectorCopy -// this is a little hack to get more efficient copies in our interpreter -typedef struct { -  float v[3]; -} vec3struct_t; -#define VectorCopy(a,b) *(vec3struct_t *)b=*(vec3struct_t *)a -#define ID_INLINE static -#endif -#endif - -#define VectorClear(a)      ((a)[0]=(a)[1]=(a)[2]=0) -#define VectorNegate(a,b)   ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2]) -#define VectorSet(v, x, y, z) ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z)) -#define Vector4Copy(a,b)    ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) -#define Vector4Add(a,b,c)    ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2],(c)[3]=(a)[3]+(b)[3]) - -#define SnapVector(v) {v[0]=((int)(v[0]));v[1]=((int)(v[1]));v[2]=((int)(v[2]));} -// just in case you do't want to use the macros -vec_t _DotProduct( const vec3_t v1, const vec3_t v2 ); -void _VectorSubtract( const vec3_t veca, const vec3_t vecb, vec3_t out ); -void _VectorAdd( const vec3_t veca, const vec3_t vecb, vec3_t out ); -void _VectorCopy( const vec3_t in, vec3_t out ); -void _VectorScale( const vec3_t in, float scale, vec3_t out ); -void _VectorMA( const vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc ); - -unsigned ColorBytes3 (float r, float g, float b); -unsigned ColorBytes4 (float r, float g, float b, float a); - -float NormalizeColor( const vec3_t in, vec3_t out ); - -float RadiusFromBounds( const vec3_t mins, const vec3_t maxs ); -void ClearBounds( vec3_t mins, vec3_t maxs ); -void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs ); - -#ifndef __LCC__ -static ID_INLINE int VectorCompare( const vec3_t v1, const vec3_t v2 ) { -  if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) { -    return 0; -  } -  return 1; -} - -static ID_INLINE vec_t VectorLength( const vec3_t v ) { -  return (vec_t)sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); -} - -static ID_INLINE vec_t VectorLengthSquared( const vec3_t v ) { -  return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); -} - -static ID_INLINE vec_t Distance( const vec3_t p1, const vec3_t p2 ) { -  vec3_t  v; - -  VectorSubtract (p2, p1, v); -  return VectorLength( v ); -} - -static ID_INLINE vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 ) { -  vec3_t  v; - -  VectorSubtract (p2, p1, v); -  return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; -} - -// fast vector normalize routine that does not check to make sure -// that length != 0, nor does it return length, uses rsqrt approximation -static ID_INLINE void VectorNormalizeFast( vec3_t v ) -{ -  float ilength; - -  ilength = Q_rsqrt( DotProduct( v, v ) ); - -  v[0] *= ilength; -  v[1] *= ilength; -  v[2] *= ilength; -} - -static ID_INLINE void VectorInverse( vec3_t v ){ -  v[0] = -v[0]; -  v[1] = -v[1]; -  v[2] = -v[2]; -} - -static ID_INLINE void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ) { -  cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; -  cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; -  cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; -} - -#else -int VectorCompare( const vec3_t v1, const vec3_t v2 ); - -vec_t VectorLength( const vec3_t v ); - -vec_t VectorLengthSquared( const vec3_t v ); - -vec_t Distance( const vec3_t p1, const vec3_t p2 ); - -vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 ); - -void VectorNormalizeFast( vec3_t v ); - -void VectorInverse( vec3_t v ); - -void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ); - -#endif - -vec_t VectorNormalize (vec3_t v);   // returns vector length -vec_t VectorNormalize2( const vec3_t v, vec3_t out ); -void Vector4Scale( const vec4_t in, vec_t scale, vec4_t out ); -void VectorRotate( vec3_t in, vec3_t matrix[3], vec3_t out ); -int Q_log2(int val); - -float Q_acos(float c); - -int   Q_rand( int *seed ); -float Q_random( int *seed ); -float Q_crandom( int *seed ); - -#define random()  ((rand () & 0x7fff) / ((float)0x7fff)) -#define crandom() (2.0 * (random() - 0.5)) - -void vectoangles( const vec3_t value1, vec3_t angles); -void AnglesToAxis( const vec3_t angles, vec3_t axis[3] ); - -void AxisClear( vec3_t axis[3] ); -void AxisCopy( vec3_t in[3], vec3_t out[3] ); - -void SetPlaneSignbits( struct cplane_s *out ); -int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *plane); - -float AngleMod(float a); -float LerpAngle (float from, float to, float frac); -float AngleSubtract( float a1, float a2 ); -void  AnglesSubtract( vec3_t v1, vec3_t v2, vec3_t v3 ); - -float AngleNormalize360 ( float angle ); -float AngleNormalize180 ( float angle ); -float AngleDelta ( float angle1, float angle2 ); - -qboolean PlaneFromPoints( vec4_t plane, const vec3_t a, const vec3_t b, const vec3_t c ); -void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ); -void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ); -void RotateAroundDirection( vec3_t axis[3], float yaw ); -void MakeNormalVectors( const vec3_t forward, vec3_t right, vec3_t up ); -// perpendicular vector could be replaced by this - -//int PlaneTypeForNormal (vec3_t normal); - -void MatrixMultiply(float in1[3][3], float in2[3][3], float out[3][3]); -void VectorMatrixMultiply( const vec3_t p, vec3_t m[ 3 ], vec3_t out ); -void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); -void PerpendicularVector( vec3_t dst, const vec3_t src ); - - -//============================================= - -float Com_Clamp( float min, float max, float value ); - -char  *COM_SkipPath( char *pathname ); -void  COM_StripExtension( const char *in, char *out ); -void  COM_DefaultExtension( char *path, int maxSize, const char *extension ); - -void  COM_BeginParseSession( const char *name ); -int   COM_GetCurrentParseLine( void ); -char  *COM_Parse( char **data_p ); -char  *COM_ParseExt( char **data_p, qboolean allowLineBreak ); -int   COM_Compress( char *data_p ); -void  COM_ParseError( char *format, ... ); -void  COM_ParseWarning( char *format, ... ); -//int   COM_ParseInfos( char *buf, int max, char infos[][MAX_INFO_STRING] ); - -#define MAX_TOKENLENGTH   1024 - -#ifndef TT_STRING -//token types -#define TT_STRING         1     // string -#define TT_LITERAL          2     // literal -#define TT_NUMBER         3     // number -#define TT_NAME           4     // name -#define TT_PUNCTUATION        5     // punctuation -#endif - -typedef struct pc_token_s -{ -  int type; -  int subtype; -  int intvalue; -  float floatvalue; -  char string[MAX_TOKENLENGTH]; -} pc_token_t; - -// data is an in/out parm, returns a parsed out token - -void  COM_MatchToken( char**buf_p, char *match ); - -void SkipBracedSection (char **program); -void SkipRestOfLine ( char **data ); - -void Parse1DMatrix (char **buf_p, int x, float *m); -void Parse2DMatrix (char **buf_p, int y, int x, float *m); -void Parse3DMatrix (char **buf_p, int z, int y, int x, float *m); - -void  QDECL Com_sprintf (char *dest, int size, const char *fmt, ...); - - -// mode parm for FS_FOpenFile -typedef enum { -  FS_READ, -  FS_WRITE, -  FS_APPEND, -  FS_APPEND_SYNC -} fsMode_t; - -typedef enum { -  FS_SEEK_CUR, -  FS_SEEK_END, -  FS_SEEK_SET -} fsOrigin_t; - -//============================================= - -int Q_isprint( int c ); -int Q_islower( int c ); -int Q_isupper( int c ); -int Q_isalpha( int c ); - -// portable case insensitive compare -int   Q_stricmp (const char *s1, const char *s2); -int   Q_strncmp (const char *s1, const char *s2, int n); -int   Q_stricmpn (const char *s1, const char *s2, int n); -char  *Q_strlwr( char *s1 ); -char  *Q_strupr( char *s1 ); -char  *Q_strrchr( const char* string, int c ); - -// buffer size safe library replacements -void  Q_strncpyz( char *dest, const char *src, int destsize ); -void  Q_strcat( char *dest, int size, const char *src ); - -// strlen that discounts Quake color sequences -int Q_PrintStrlen( const char *string ); -// removes color sequences from string -char *Q_CleanStr( char *string ); - -//============================================= - -// 64-bit integers for global rankings interface -// implemented as a struct for qvm compatibility -typedef struct -{ -  byte  b0; -  byte  b1; -  byte  b2; -  byte  b3; -  byte  b4; -  byte  b5; -  byte  b6; -  byte  b7; -} qint64; - -//============================================= -/* -short BigShort(short l); -short LittleShort(short l); -int   BigLong (int l); -int   LittleLong (int l); -qint64  BigLong64 (qint64 l); -qint64  LittleLong64 (qint64 l); -float BigFloat (const float *l); -float LittleFloat (const float *l); - -void  Swap_Init (void); -*/ -char  * QDECL va(char *format, ...); - -//============================================= - -// -// key / value info strings -// -char *Info_ValueForKey( const char *s, const char *key ); -void Info_RemoveKey( char *s, const char *key ); -void Info_RemoveKey_big( char *s, const char *key ); -void Info_SetValueForKey( char *s, const char *key, const char *value ); -void Info_SetValueForKey_Big( char *s, const char *key, const char *value ); -qboolean Info_Validate( const char *s ); -void Info_NextPair( const char **s, char *key, char *value ); - -// this is only here so the functions in q_shared.c and bg_*.c can link -void  QDECL Com_Error( int level, const char *error, ... ); -void  QDECL Com_Printf( const char *msg, ... ); - - -/* -========================================================== - -CVARS (console variables) - -Many variables can be used for cheating purposes, so when -cheats is zero, force all unspecified variables to their -default values. -========================================================== -*/ - -#define CVAR_ARCHIVE    1 // set to cause it to be saved to vars.rc -                // used for system variables, not for player -                // specific configurations -#define CVAR_USERINFO   2 // sent to server on connect or change -#define CVAR_SERVERINFO   4 // sent in response to front end requests -#define CVAR_SYSTEMINFO   8 // these cvars will be duplicated on all clients -#define CVAR_INIT     16  // don't allow change from console at all, -                // but can be set from the command line -#define CVAR_LATCH      32  // will only change when C code next does -                // a Cvar_Get(), so it can't be changed -                // without proper initialization.  modified -                // will be set, even though the value hasn't -                // changed yet -#define CVAR_ROM      64  // display only, cannot be set by user at all -#define CVAR_USER_CREATED 128 // created by a set command -#define CVAR_TEMP     256 // can be set even when cheats are disabled, but is not archived -#define CVAR_CHEAT      512 // can not be changed if cheats are disabled -#define CVAR_NORESTART    1024  // do not clear when a cvar_restart is issued - -// nothing outside the Cvar_*() functions should modify these fields! -typedef struct cvar_s { -  char    *name; -  char    *string; -  char    *resetString;   // cvar_restart will reset to this value -  char    *latchedString;   // for CVAR_LATCH vars -  int     flags; -  qboolean  modified;     // set each time the cvar is changed -  int     modificationCount;  // incremented each time the cvar is changed -  float   value;        // atof( string ) -  int     integer;      // atoi( string ) -  struct cvar_s *next; -  struct cvar_s *hashNext; -} cvar_t; - -#define MAX_CVAR_VALUE_STRING 256 - -typedef int cvarHandle_t; - -// the modules that run in the virtual machine can't access the cvar_t directly, -// so they must ask for structured updates -typedef struct { -  cvarHandle_t  handle; -  int     modificationCount; -  float   value; -  int     integer; -  char    string[MAX_CVAR_VALUE_STRING]; -} vmCvar_t; - -/* -============================================================== - -COLLISION DETECTION - -============================================================== -*/ - -#include "surfaceflags.h"     // shared with the q3map utility - -// plane types are used to speed some tests -// 0-2 are axial planes -#define PLANE_X     0 -#define PLANE_Y     1 -#define PLANE_Z     2 -#define PLANE_NON_AXIAL 3 - - -/* -================= -PlaneTypeForNormal -================= -*/ - -#define PlaneTypeForNormal(x) (x[0] == 1.0 ? PLANE_X : (x[1] == 1.0 ? PLANE_Y : (x[2] == 1.0 ? PLANE_Z : PLANE_NON_AXIAL) ) ) - -// plane_t structure -// !!! if this is changed, it must be changed in asm code too !!! -typedef struct cplane_s { -  vec3_t  normal; -  float dist; -  byte  type;     // for fast side tests: 0,1,2 = axial, 3 = nonaxial -  byte  signbits;   // signx + (signy<<1) + (signz<<2), used as lookup during collision -  byte  pad[2]; -} cplane_t; - - -// a trace is returned when a box is swept through the world -typedef struct { -  qboolean  allsolid; // if true, plane is not valid -  qboolean  startsolid; // if true, the initial point was in a solid area -  float   fraction; // time completed, 1.0 = didn't hit anything -  vec3_t    endpos;   // final position -  cplane_t  plane;    // surface normal at impact, transformed to world space -  int     surfaceFlags; // surface hit -  int     contents; // contents on other side of surface hit -  int     entityNum;  // entity the contacted sirface is a part of -} trace_t; - -// trace->entityNum can also be 0 to (MAX_GENTITIES-1) -// or ENTITYNUM_NONE, ENTITYNUM_WORLD - - -// markfragments are returned by CM_MarkFragments() -typedef struct { -  int   firstPoint; -  int   numPoints; -} markFragment_t; - - - -typedef struct { -  vec3_t    origin; -  vec3_t    axis[3]; -} orientation_t; - -//===================================================================== - - -// in order from highest priority to lowest -// if none of the catchers are active, bound key strings will be executed -#define KEYCATCH_CONSOLE    0x0001 -#define KEYCATCH_UI         0x0002 -#define KEYCATCH_MESSAGE    0x0004 -#define KEYCATCH_CGAME      0x0008 - - -// sound channels -// channel 0 never willingly overrides -// other channels will allways override a playing sound on that channel -typedef enum { -  CHAN_AUTO, -  CHAN_LOCAL,   // menu sounds, etc -  CHAN_WEAPON, -  CHAN_VOICE, -  CHAN_ITEM, -  CHAN_BODY, -  CHAN_LOCAL_SOUND, // chat messages, etc -  CHAN_ANNOUNCER    // announcer voices, etc -} soundChannel_t; - - -/* -======================================================================== - -  ELEMENTS COMMUNICATED ACROSS THE NET - -======================================================================== -*/ - -#define ANGLE2SHORT(x)  ((int)((x)*65536/360) & 65535) -#define SHORT2ANGLE(x)  ((x)*(360.0/65536)) - -#define SNAPFLAG_RATE_DELAYED 1 -#define SNAPFLAG_NOT_ACTIVE   2 // snapshot used during connection and for zombies -#define SNAPFLAG_SERVERCOUNT  4 // toggled every map_restart so transitions can be detected - -// -// per-level limits -// -#define MAX_CLIENTS     64    // absolute limit -#define MAX_LOCATIONS   64 - -#define GENTITYNUM_BITS   10    // don't need to send any more -#define MAX_GENTITIES   (1<<GENTITYNUM_BITS) - -// entitynums are communicated with GENTITY_BITS, so any reserved -// values thatare going to be communcated over the net need to -// also be in this range -#define ENTITYNUM_NONE    (MAX_GENTITIES-1) -#define ENTITYNUM_WORLD   (MAX_GENTITIES-2) -#define ENTITYNUM_MAX_NORMAL  (MAX_GENTITIES-2) - - -#define MAX_MODELS                  256   // these are sent over the net as 8 bits -#define MAX_SOUNDS                  256   // so they cannot be blindly increased -#define MAX_SHADERS                 64    //TA: should be in bg_public.h -#define MAX_GAME_PARTICLE_SYSTEMS   64    //TA: should be in bg_public.h -#define MAX_PARTICLE_FILES          128 - - -#define MAX_CONFIGSTRINGS 1024 - -// these are the only configstrings that the system reserves, all the -// other ones are strictly for servergame to clientgame communication -#define CS_SERVERINFO   0   // an info string with all the serverinfo cvars -#define CS_SYSTEMINFO   1   // an info string for server system to client system configuration (timescale, etc) - -#define RESERVED_CONFIGSTRINGS  2 // game can't modify below this, only the system can - -#define MAX_GAMESTATE_CHARS 16000 -typedef struct { -  int     stringOffsets[MAX_CONFIGSTRINGS]; -  char    stringData[MAX_GAMESTATE_CHARS]; -  int     dataCount; -} gameState_t; - -//========================================================= - -// bit field limits -#define MAX_STATS       16 -#define MAX_PERSISTANT      16 -#define MAX_POWERUPS      16 -#define MAX_WEAPONS       16 - -#define MAX_PS_EVENTS     2 - -#define PS_PMOVEFRAMECOUNTBITS  6 - -// playerState_t is the information needed by both the client and server -// to predict player motion and actions -// nothing outside of pmove should modify these, or some degree of prediction error -// will occur - -// you can't add anything to this without modifying the code in msg.c - -// playerState_t is a full superset of entityState_t as it is used by players, -// so if a playerState_t is transmitted, the entityState_t can be fully derived -// from it. -typedef struct playerState_s { -  int     commandTime;  // cmd->serverTime of last executed command -  int     pm_type; -  int     bobCycle;   // for view bobbing and footstep generation -  int     pm_flags;   // ducked, jump_held, etc -  int     pm_time; - -  vec3_t    origin; -  vec3_t    velocity; -  int     weaponTime; -  int     gravity; -  int     speed; -  int     delta_angles[3];  // add to command angles to get view direction -                  // changed by spawns, rotating objects, and teleporters - -  int     groundEntityNum;// ENTITYNUM_NONE = in air - -  int     legsTimer;    // don't change low priority animations until this runs out -  int     legsAnim;   // mask off ANIM_TOGGLEBIT - -  int     torsoTimer;   // don't change low priority animations until this runs out -  int     torsoAnim;    // mask off ANIM_TOGGLEBIT - -  int     movementDir;  // a number 0 to 7 that represents the reletive angle -                // of movement to the view angle (axial and diagonals) -                // when at rest, the value will remain unchanged -                // used to twist the legs during strafing - -  vec3_t    grapplePoint; // location of grapple to pull towards if PMF_GRAPPLE_PULL - -  int     eFlags;     // copied to entityState_t->eFlags - -  int     eventSequence;  // pmove generated events -  int     events[MAX_PS_EVENTS]; -  int     eventParms[MAX_PS_EVENTS]; - -  int     externalEvent;  // events set on player from another source -  int     externalEventParm; -  int     externalEventTime; - -  int     clientNum;    // ranges from 0 to MAX_CLIENTS-1 -  int     weapon;     // copied to entityState_t->weapon -  int     weaponstate; - -  vec3_t    viewangles;   // for fixed views -  int     viewheight; - -  // damage feedback -  int     damageEvent;  // when it changes, latch the other parms -  int     damageYaw; -  int     damagePitch; -  int     damageCount; - -  int     stats[MAX_STATS]; -  int     persistant[MAX_PERSISTANT]; // stats that aren't cleared on death -  int     powerups[MAX_POWERUPS]; // level.time that the powerup runs out -  int     ammo[MAX_WEAPONS]; - -  int     generic1; -  int     loopSound; -  int     jumppad_ent;  // jumppad entity hit this frame - -  // not communicated over the net at all -  int     ping;     // server to game info for scoreboard -  int     pmove_framecount; // FIXME: don't transmit over the network -  int     jumppad_frame; -  int     entityEventSequence; -} playerState_t; - - -//==================================================================== - - -// -// usercmd_t->button bits, many of which are generated by the client system, -// so they aren't game/cgame only definitions -// -#define BUTTON_ATTACK   1 -#define BUTTON_TALK     2     // displays talk balloon and disables actions -#define BUTTON_USE_HOLDABLE 4 -#define BUTTON_GESTURE    8 -#define BUTTON_WALKING    16      // walking can't just be infered from MOVE_RUN -                    // because a key pressed late in the frame will -                    // only generate a small move value for that frame -                    // walking will use different animations and -                    // won't generate footsteps -#define BUTTON_ATTACK2      32  //TA: should be safe to change from BUTTON_AFFIRMATIVE -#define BUTTON_NEGATIVE   64 - -#define BUTTON_GETFLAG    128 -#define BUTTON_GUARDBASE  256 -#define BUTTON_PATROL   512 -#define BUTTON_FOLLOWME   1024 - -#define BUTTON_ANY      2048      // any key whatsoever - -#define MOVE_RUN      120     // if forwardmove or rightmove are >= MOVE_RUN, -                    // then BUTTON_WALKING should be set - -// usercmd_t is sent to the server each client frame -typedef struct usercmd_s { -  int       serverTime; -  int       angles[3]; -  int       buttons; -  byte      weapon;           // weapon -  signed char forwardmove, rightmove, upmove; -} usercmd_t; - -//=================================================================== - -// if entityState->solid == SOLID_BMODEL, modelindex is an inline model number -#define SOLID_BMODEL  0xffffff - -typedef enum { -  TR_STATIONARY, -  TR_INTERPOLATE,       // non-parametric, but interpolate between snapshots -  TR_LINEAR, -  TR_LINEAR_STOP, -  TR_SINE,          // value = base + sin( time / duration ) * delta -  TR_GRAVITY, -  TR_BUOYANCY //TA: what the hell is this doing in here anyway? -} trType_t; - -typedef struct { -  trType_t  trType; -  int   trTime; -  int   trDuration;     // if non 0, trTime + trDuration = stop time -  vec3_t  trBase; -  vec3_t  trDelta;      // velocity, etc -} trajectory_t; - -// entityState_t is the information conveyed from the server -// in an update message about entities that the client will -// need to render in some way -// Different eTypes may use the information in different ways -// The messages are delta compressed, so it doesn't really matter if -// the structure size is fairly large - -typedef struct entityState_s { -  int   number;     // entity index -  int   eType;      // entityType_t -  int   eFlags; - -  trajectory_t  pos;  // for calculating position -  trajectory_t  apos; // for calculating angles - -  int   time; -  int   time2; - -  vec3_t  origin; -  vec3_t  origin2; - -  vec3_t  angles; -  vec3_t  angles2; - -  int   otherEntityNum; // shotgun sources, etc -  int   otherEntityNum2; - -  int   groundEntityNum;  // -1 = in air - -  int   constantLight;  // r + (g<<8) + (b<<16) + (intensity<<24) -  int   loopSound;    // constantly loop this sound - -  int   modelindex; -  int   modelindex2; -  int   clientNum;    // 0 to (MAX_CLIENTS - 1), for players and corpses -  int   frame; - -  int   solid;      // for client side prediction, trap_linkentity sets this properly - -  int   event;      // impulse events -- muzzle flashes, footsteps, etc -  int   eventParm; - -  // for players -  int   powerups;   // bit flags -  int   weapon;     // determines weapon and flash model, etc -  int   legsAnim;   // mask off ANIM_TOGGLEBIT -  int   torsoAnim;    // mask off ANIM_TOGGLEBIT - -  int   generic1; -} entityState_t; - -typedef enum { -  CA_UNINITIALIZED, -  CA_DISCONNECTED,  // not talking to a server -  CA_AUTHORIZING,   // not used any more, was checking cd key -  CA_CONNECTING,    // sending request packets to the server -  CA_CHALLENGING,   // sending challenge packets to the server -  CA_CONNECTED,   // netchan_t established, getting gamestate -  CA_LOADING,     // only during cgame initialization, never during main loop -  CA_PRIMED,      // got gamestate, waiting for first frame -  CA_ACTIVE,      // game views should be displayed -  CA_CINEMATIC    // playing a cinematic or a static pic, not connected to a server -} connstate_t; - -// font support - -#define GLYPH_START 0 -#define GLYPH_END 255 -#define GLYPH_CHARSTART 32 -#define GLYPH_CHAREND 127 -#define GLYPHS_PER_FONT GLYPH_END - GLYPH_START + 1 -typedef struct { -  int height;       // number of scan lines -  int top;          // top of glyph in buffer -  int bottom;       // bottom of glyph in buffer -  int pitch;        // width for copying -  int xSkip;        // x adjustment -  int imageWidth;   // width of actual image -  int imageHeight;  // height of actual image -  float s;          // x offset in image where glyph starts -  float t;          // y offset in image where glyph starts -  float s2; -  float t2; -  qhandle_t glyph;  // handle to the shader with the glyph -  char shaderName[32]; -} glyphInfo_t; - -typedef struct { -  glyphInfo_t glyphs [GLYPHS_PER_FONT]; -  float glyphScale; -  char name[MAX_QPATH]; -} fontInfo_t; - -#define Square(x) ((x)*(x)) - -// real time -//============================================= - - -typedef struct qtime_s { -  int tm_sec;     /* seconds after the minute - [0,59] */ -  int tm_min;     /* minutes after the hour - [0,59] */ -  int tm_hour;    /* hours since midnight - [0,23] */ -  int tm_mday;    /* day of the month - [1,31] */ -  int tm_mon;     /* months since January - [0,11] */ -  int tm_year;    /* years since 1900 */ -  int tm_wday;    /* days since Sunday - [0,6] */ -  int tm_yday;    /* days since January 1 - [0,365] */ -  int tm_isdst;   /* daylight savings time flag */ -} qtime_t; - - -// server browser sources -// TTimo: AS_MPLAYER is no longer used -#define AS_LOCAL      0 -#define AS_MPLAYER    1 -#define AS_GLOBAL     2 -#define AS_FAVORITES  3 - - -// cinematic states -typedef enum { -  FMV_IDLE, -  FMV_PLAY,   // play -  FMV_EOF,    // all other conditions, i.e. stop/EOF/abort -  FMV_ID_BLT, -  FMV_ID_IDLE, -  FMV_LOOPED, -  FMV_ID_WAIT -} e_status; - -typedef enum _flag_status { -  FLAG_ATBASE = 0, -  FLAG_TAKEN,     // CTF -  FLAG_TAKEN_RED,   // One Flag CTF -  FLAG_TAKEN_BLUE,  // One Flag CTF -  FLAG_DROPPED -} flagStatus_t; - - - -#define MAX_GLOBAL_SERVERS      4096 -#define MAX_OTHER_SERVERS     128 -#define MAX_PINGREQUESTS      32 -#define MAX_SERVERSTATUSREQUESTS  16 - -#define SAY_ALL   0 -#define SAY_TEAM  1 -#define SAY_TELL  2 - -#define CDKEY_LEN 16 -#define CDCHKSUM_LEN 2 - - -#endif  // __Q_SHARED_H diff --git a/mod/src/game/surfaceflags.h b/mod/src/game/surfaceflags.h deleted file mode 100644 index d7d721b4..00000000 --- a/mod/src/game/surfaceflags.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// -// This file must be identical in the quake and utils directories - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -// contents flags are seperate bits -// a given brush can contribute multiple content bits - -// these definitions also need to be in q_shared.h! - -#define CONTENTS_SOLID          1   // an eye is never valid in a solid -#define CONTENTS_LAVA           8 -#define CONTENTS_SLIME          16 -#define CONTENTS_WATER          32 -#define CONTENTS_FOG            64 - -#define CONTENTS_NOTTEAM1       0x0080 -#define CONTENTS_NOTTEAM2       0x0100 -#define CONTENTS_NOBOTCLIP      0x0200 - -#define CONTENTS_AREAPORTAL     0x8000 - -#define CONTENTS_PLAYERCLIP     0x10000 -#define CONTENTS_MONSTERCLIP    0x20000 -//bot specific contents types -#define CONTENTS_TELEPORTER     0x40000 -#define CONTENTS_JUMPPAD        0x80000 -#define CONTENTS_CLUSTERPORTAL  0x100000 -#define CONTENTS_DONOTENTER     0x200000 -#define CONTENTS_BOTCLIP        0x400000 -#define CONTENTS_MOVER          0x800000 - -#define CONTENTS_ORIGIN         0x1000000 // removed before bsping an entity - -#define CONTENTS_BODY           0x2000000 // should never be on a brush, only in game -#define CONTENTS_CORPSE         0x4000000 -#define CONTENTS_DETAIL         0x8000000 // brushes not used for the bsp -#define CONTENTS_STRUCTURAL     0x10000000  // brushes used for the bsp -#define CONTENTS_TRANSLUCENT    0x20000000  // don't consume surface fragments inside -#define CONTENTS_TRIGGER        0x40000000 -#define CONTENTS_NODROP         0x80000000  // don't leave bodies or items (death fog, lava) - -//TA: custominfoparms below -#define CONTENTS_NOALIENBUILD   0x1000 // disallow alien building -#define CONTENTS_NOHUMANBUILD   0x2000 // disallow alien building -#define CONTENTS_NOBUILD        0x4000 // disallow alien building - -#define SURF_NODAMAGE           0x1   // never give falling damage -#define SURF_SLICK              0x2   // effects game physics -#define SURF_SKY                0x4   // lighting from environment map -#define SURF_LADDER             0x8 -#define SURF_NOIMPACT           0x10  // don't make missile explosions -#define SURF_NOMARKS            0x20  // don't leave missile marks -#define SURF_FLESH              0x40  // make flesh sounds and effects -#define SURF_NODRAW             0x80  // don't generate a drawsurface at all -#define SURF_HINT               0x100 // make a primary bsp splitter -#define SURF_SKIP               0x200 // completely ignore, allowing non-closed brushes -#define SURF_NOLIGHTMAP         0x400 // surface doesn't need a lightmap -#define SURF_POINTLIGHT         0x800 // generate lighting info at vertexes -#define SURF_METALSTEPS         0x1000  // clanking footsteps -#define SURF_NOSTEPS            0x2000  // no footstep sounds -#define SURF_NONSOLID           0x4000  // don't collide against curves with this set -#define SURF_LIGHTFILTER        0x8000  // act as a light filter during q3map -light -#define SURF_ALPHASHADOW        0x10000 // do per-pixel light shadow casting in q3map -#define SURF_NODLIGHT           0x20000 // don't dlight even if solid (solid lava, skies) -#define SURF_DUST               0x40000 // leave a dust trail when walking on this surface - -//TA: custominfoparms below -#define SURF_NOALIENBUILD       0x80000 // disallow alien building -#define SURF_NOHUMANBUILD       0x100000 // disallow alien building -#define SURF_NOBUILD            0x200000 // disallow alien building - diff --git a/mod/src/game/tremulous.h b/mod/src/game/tremulous.h deleted file mode 100644 index 93a85ba0..00000000 --- a/mod/src/game/tremulous.h +++ /dev/null @@ -1,572 +0,0 @@ -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - - -/* - * ALIEN weapons - * - * _REPEAT  - time in msec until the weapon can be used again - * _DMG     - amount of damage the weapon does - * - * ALIEN_WDMG_MODIFIER - overall damage modifier for coarse tuning - * - */ - -#define ALIEN_WDMG_MODIFIER         1.0f -#define ADM(d)                      ((int)((float)d*ALIEN_WDMG_MODIFIER)) - -#define ABUILDER_BUILD_REPEAT       500 -#define ABUILDER_CLAW_DMG           ADM(20) -#define ABUILDER_CLAW_RANGE         64.0f -#define ABUILDER_CLAW_WIDTH         4.0f -#define ABUILDER_CLAW_REPEAT        1000 -#define ABUILDER_BASE_DELAY         17000 -#define ABUILDER_ADV_DELAY          12000 -#define ABUILDER_BLOB_DMG           ADM(4) -#define ABUILDER_BLOB_REPEAT        1000 -#define ABUILDER_BLOB_SPEED         800.0f -#define ABUILDER_BLOB_SPEED_MOD     0.5f -#define ABUILDER_BLOB_TIME          5000 - -#define LEVEL0_BITE_DMG             ADM(48) -#define LEVEL0_BITE_RANGE           64.0f -#define LEVEL0_BITE_WIDTH           6.0f -#define LEVEL0_BITE_REPEAT          500 - -#define LEVEL1_CLAW_DMG             ADM(32) -#define LEVEL1_CLAW_RANGE           96.0f -#define LEVEL1_CLAW_WIDTH           10.0f -#define LEVEL1_CLAW_REPEAT          600 -#define LEVEL1_CLAW_U_REPEAT        500 -#define LEVEL1_GRAB_RANGE           64.0f -#define LEVEL1_GRAB_TIME            300 -#define LEVEL1_GRAB_U_TIME          450 -#define LEVEL1_PCLOUD_DMG           ADM(4) -#define LEVEL1_PCLOUD_RANGE         200.0f -#define LEVEL1_PCLOUD_REPEAT        2000 -#define LEVEL1_PCLOUD_TIME          10000 - -#define LEVEL2_CLAW_DMG             ADM(40) -#define LEVEL2_CLAW_RANGE           96.0f -#define LEVEL2_CLAW_WIDTH           12.0f -#define LEVEL2_CLAW_REPEAT          500 -#define LEVEL2_CLAW_U_REPEAT        400 -#define LEVEL2_AREAZAP_DMG          ADM(80) -#define LEVEL2_AREAZAP_RANGE        200.0f -#define LEVEL2_AREAZAP_WIDTH        15.0f -#define LEVEL2_AREAZAP_REPEAT       2000 -#define LEVEL2_AREAZAP_TIME         1000 -#define LEVEL2_AREAZAP_MAX_TARGETS  3 -#define LEVEL2_WALLJUMP_MAXSPEED    1000.0f - -#define LEVEL3_CLAW_DMG             ADM(80) -#define LEVEL3_CLAW_RANGE           96.0f -#define LEVEL3_CLAW_WIDTH           16.0f -#define LEVEL3_CLAW_REPEAT          700 -#define LEVEL3_CLAW_U_REPEAT        600 -#define LEVEL3_POUNCE_DMG           ADM(100) -#define LEVEL3_POUNCE_RANGE         64.0f -#define LEVEL3_POUNCE_WIDTH         16.0f -#define LEVEL3_POUNCE_SPEED         700 -#define LEVEL3_POUNCE_UPG_SPEED     800 -#define LEVEL3_POUNCE_SPEED_MOD     0.75f -#define LEVEL3_POUNCE_CHARGE_TIME   700 -#define LEVEL3_POUNCE_TIME          400 -#define LEVEL3_BOUNCEBALL_DMG       ADM(110) -#define LEVEL3_BOUNCEBALL_REPEAT    1000 -#define LEVEL3_BOUNCEBALL_SPEED     1000.0f - -#define LEVEL4_CLAW_DMG             ADM(100) -#define LEVEL4_CLAW_RANGE           128.0f -#define LEVEL4_CLAW_WIDTH           20.0f -#define LEVEL4_CLAW_REPEAT          750 -#define LEVEL4_REGEN_RANGE          200.0f -#define LEVEL4_REGEN_MOD            2.0f -#define LEVEL4_CHARGE_SPEED         2.0f -#define LEVEL4_CHARGE_TIME          3000 -#define LEVEL4_CHARGE_CHARGE_TIME   1500 -#define LEVEL4_MIN_CHARGE_TIME      750 -#define LEVEL4_CHARGE_CHARGE_RATIO  (LEVEL4_CHARGE_TIME/LEVEL4_CHARGE_CHARGE_TIME) -#define LEVEL4_CHARGE_REPEAT        1000 -#define LEVEL4_CHARGE_DMG           ADM(110) - - - -/* - * ALIEN classes - * - * _SPEED   - fraction of Q3A run speed the class can move - * _REGEN   - health per second regained - * - * ALIEN_HLTH_MODIFIER - overall health modifier for coarse tuning - * - */ - -#define ALIEN_HLTH_MODIFIER         1.0f -#define AHM(h)                      ((int)((float)h*ALIEN_HLTH_MODIFIER)) - -#define ALIEN_VALUE_MODIFIER        1.0f -#define AVM(h)                      ((int)((float)h*ALIEN_VALUE_MODIFIER)) - -#define ABUILDER_SPEED              0.8f -#define ABUILDER_VALUE              AVM(200) -#define ABUILDER_HEALTH             AHM(50) -#define ABUILDER_REGEN              2 -#define ABUILDER_COST               0 - -#define ABUILDER_UPG_SPEED          1.0f -#define ABUILDER_UPG_VALUE          AVM(250) -#define ABUILDER_UPG_HEALTH         AHM(75) -#define ABUILDER_UPG_REGEN          3 -#define ABUILDER_UPG_COST           0 - -#define LEVEL0_SPEED                1.3f -#define LEVEL0_VALUE                AVM(175) -#define LEVEL0_HEALTH               AHM(25) -#define LEVEL0_REGEN                1 -#define LEVEL0_COST                 0 - -#define LEVEL1_SPEED                1.25f -#define LEVEL1_VALUE                AVM(225) -#define LEVEL1_HEALTH               AHM(75) -#define LEVEL1_REGEN                2 -#define LEVEL1_COST                 1 - -#define LEVEL1_UPG_SPEED            1.25f -#define LEVEL1_UPG_VALUE            AVM(275) -#define LEVEL1_UPG_HEALTH           AHM(100) -#define LEVEL1_UPG_REGEN            3 -#define LEVEL1_UPG_COST             1 - -#define LEVEL2_SPEED                1.2f -#define LEVEL2_VALUE                AVM(350) -#define LEVEL2_HEALTH               AHM(150) -#define LEVEL2_REGEN                4 -#define LEVEL2_COST                 1 - -#define LEVEL2_UPG_SPEED            1.2f -#define LEVEL2_UPG_VALUE            AVM(450) -#define LEVEL2_UPG_HEALTH           AHM(175) -#define LEVEL2_UPG_REGEN            5 -#define LEVEL2_UPG_COST             1 - -#define LEVEL3_SPEED                1.1f -#define LEVEL3_VALUE                AVM(500) -#define LEVEL3_HEALTH               AHM(200) -#define LEVEL3_REGEN                6 -#define LEVEL3_COST                 1 - -#define LEVEL3_UPG_SPEED            1.1f -#define LEVEL3_UPG_VALUE            AVM(600) -#define LEVEL3_UPG_HEALTH           AHM(250) -#define LEVEL3_UPG_REGEN            7 -#define LEVEL3_UPG_COST             1 - -#define LEVEL4_SPEED                1.2f -#define LEVEL4_VALUE                AVM(800) -#define LEVEL4_HEALTH               AHM(400) -#define LEVEL4_REGEN                7 -#define LEVEL4_COST                 2 - - - -/* - * ALIEN buildables - * - * _BP            - build points required for this buildable - * _BT            - build time required for this buildable - * _REGEN         - the amount of health per second regained - * _SPLASHDAMGE   - the amount of damage caused by this buildable when melting - * _SPLASHRADIUS  - the radius around which it does this damage - * - * CREEP_BASESIZE - the maximum distance a buildable can be from an egg/overmind - * ALIEN_BHLTH_MODIFIER - overall health modifier for coarse tuning - * - */ - -#define ALIEN_BHLTH_MODIFIER        1.0f -#define ABHM(h)                     ((int)((float)h*ALIEN_BHLTH_MODIFIER)) - -#define CREEP_BASESIZE              700 -#define CREEP_TIMEOUT               1000 -#define CREEP_MODIFIER              0.5f -#define CREEP_ARMOUR_MODIFIER       0.75f -#define CREEP_SCALEDOWN_TIME        3000 - -#define ASPAWN_BP                   10 -#define ASPAWN_BT                   15000 -#define ASPAWN_HEALTH               ABHM(250) -#define ASPAWN_REGEN                8 -#define ASPAWN_SPLASHDAMAGE         50 -#define ASPAWN_SPLASHRADIUS         50 -#define ASPAWN_CREEPSIZE            120 -#define ASPAWN_VALUE                150 - -#define BARRICADE_BP                10 -#define BARRICADE_BT                20000 -#define BARRICADE_HEALTH            ABHM(200) -#define BARRICADE_REGEN             14 -#define BARRICADE_SPLASHDAMAGE      50 -#define BARRICADE_SPLASHRADIUS      50 -#define BARRICADE_CREEPSIZE         120 - -#define BOOSTER_BP                  12 -#define BOOSTER_BT                  15000 -#define BOOSTER_HEALTH              ABHM(150) -#define BOOSTER_REGEN               8 -#define BOOSTER_SPLASHDAMAGE        50 -#define BOOSTER_SPLASHRADIUS        50 -#define BOOSTER_CREEPSIZE           120 -#define BOOSTER_INTERVAL            30000 //time in msec between uses (per player) -#define BOOSTER_REGEN_MOD           2.0f - -#define ACIDTUBE_BP                 8 -#define ACIDTUBE_BT                 15000 -#define ACIDTUBE_HEALTH             ABHM(125) -#define ACIDTUBE_REGEN              10 -#define ACIDTUBE_SPLASHDAMAGE       6 -#define ACIDTUBE_SPLASHRADIUS       300 -#define ACIDTUBE_CREEPSIZE          120 -#define ACIDTUBE_RANGE              300.0f -#define ACIDTUBE_REPEAT             3000 - -#define HIVE_BP                     12 -#define HIVE_BT                     20000 -#define HIVE_HEALTH                 ABHM(125) -#define HIVE_REGEN                  10 -#define HIVE_SPLASHDAMAGE           30 -#define HIVE_SPLASHRADIUS           200 -#define HIVE_CREEPSIZE              120 -#define HIVE_RANGE                  400.0f -#define HIVE_REPEAT                 5000 -#define HIVE_DMG                    50 -#define HIVE_SPEED                  240.0f -#define HIVE_DIR_CHANGE_PERIOD      500 - -#define TRAPPER_BP                  8 -#define TRAPPER_BT                  12000 -#define TRAPPER_HEALTH              ABHM(50) -#define TRAPPER_REGEN               6 -#define TRAPPER_SPLASHDAMAGE        15 -#define TRAPPER_SPLASHRADIUS        100 -#define TRAPPER_CREEPSIZE           30 -#define TRAPPER_RANGE               400 -#define TRAPPER_REPEAT              1000 -#define LOCKBLOB_SPEED              650.0f -#define LOCKBLOB_DOT                0.85f // max angle = acos( LOCKBLOB_DOT ) - -#define OVERMIND_BP                 0 -#define OVERMIND_BT                 30000 -#define OVERMIND_HEALTH             ABHM(750) -#define OVERMIND_REGEN              6 -#define OVERMIND_SPLASHDAMAGE       15 -#define OVERMIND_SPLASHRADIUS       300 -#define OVERMIND_CREEPSIZE          120 -#define OVERMIND_ATTACK_RANGE       150.0f -#define OVERMIND_ATTACK_REPEAT      1000 -#define OVERMIND_VALUE              300 - -#define HOVEL_BP                    0 -#define HOVEL_BT                    15000 -#define HOVEL_HEALTH                ABHM(375) -#define HOVEL_REGEN                 20 -#define HOVEL_SPLASHDAMAGE          20 -#define HOVEL_SPLASHRADIUS          200 -#define HOVEL_CREEPSIZE             120 - - - -/* - * ALIEN misc - * - * ALIENSENSE_RANGE - the distance alien sense is useful for - * - */ - -#define ALIENSENSE_RANGE            1000.0f - -#define ALIEN_POISON_TIME           10000 -#define ALIEN_POISON_DMG            30 -#define ALIEN_POISON_DIVIDER        (1.0f/1.32f) //about 1.0/(time`th root of damage) - -#define ALIEN_SPAWN_REPEAT_TIME     10000 - -#define ALIEN_REGEN_DAMAGE_TIME     2000 //msec since damage that regen starts again - -/* - * HUMAN weapons - * - * _REPEAT  - time between firings - * _RELOAD  - time needed to reload - * _PRICE   - amount in credits weapon costs - * - * HUMAN_WDMG_MODIFIER - overall damage modifier for coarse tuning - * - */ - -#define HUMAN_WDMG_MODIFIER         1.0f -#define HDM(d)                      ((int)((float)d*HUMAN_WDMG_MODIFIER)) - -#define BLASTER_REPEAT              600 -#define BLASTER_SPREAD              200 -#define BLASTER_SPEED               1400 -#define BLASTER_DMG                 HDM(9) - -#define RIFLE_CLIPSIZE              30 -#define RIFLE_MAXCLIPS              6 -#define RIFLE_REPEAT                90 -#define RIFLE_RELOAD                2000 -#define RIFLE_PRICE                 0 -#define RIFLE_SPREAD                200 -#define RIFLE_DMG                   HDM(5) - -#define PAINSAW_PRICE               100 -#define PAINSAW_REPEAT              75 -#define PAINSAW_DAMAGE              HDM(15) -#define PAINSAW_RANGE               40.0f - -#define GRENADE_PRICE               200 -#define GRENADE_REPEAT              0 -#define GRENADE_DAMAGE              HDM(310) -#define GRENADE_RANGE               192.0f -#define GRENADE_SPEED               400.0f - -#define SHOTGUN_PRICE               150 -#define SHOTGUN_SHELLS              8 -#define SHOTGUN_PELLETS             8 //used to sync server and client side -#define SHOTGUN_MAXCLIPS            3 -#define SHOTGUN_REPEAT              1000 -#define SHOTGUN_RELOAD              2000 -#define SHOTGUN_SPREAD              900 -#define SHOTGUN_DMG                 HDM(7) - -#define LASGUN_PRICE                250 -#define LASGUN_AMMO                 200 -#define LASGUN_REPEAT               200 -#define LASGUN_RELOAD               2000 -#define LASGUN_DAMAGE               HDM(9) - -#define MDRIVER_PRICE               350 -#define MDRIVER_CLIPSIZE            5 -#define MDRIVER_MAXCLIPS            4 -#define MDRIVER_DMG                 HDM(38) -#define MDRIVER_REPEAT              1000 -#define MDRIVER_RELOAD              2000 - -#define CHAINGUN_PRICE              400 -#define CHAINGUN_BULLETS            300 -#define CHAINGUN_REPEAT             80 -#define CHAINGUN_SPREAD             1000 -#define CHAINGUN_DMG                HDM(6) - -#define PRIFLE_PRICE                400 -#define PRIFLE_CLIPS                50 -#define PRIFLE_MAXCLIPS             4 -#define PRIFLE_REPEAT               100 -#define PRIFLE_RELOAD               2000 -#define PRIFLE_DMG                  HDM(9) -#define PRIFLE_SPEED                1000 - -#define FLAMER_PRICE                450 -#define FLAMER_GAS                  150 -#define FLAMER_REPEAT               200 -#define FLAMER_DMG                  HDM(31) -#define FLAMER_RADIUS               50 -#define FLAMER_LIFETIME             800.0f -#define FLAMER_SPEED                200.0f -#define FLAMER_LAG                  0.65f  //the amount of player velocity that is added to the fireball - -#define LCANNON_PRICE               600 -#define LCANNON_AMMO                90 -#define LCANNON_REPEAT              500 -#define LCANNON_CHARGEREPEAT        1000 -#define LCANNON_RELOAD              2000 -#define LCANNON_DAMAGE              HDM(265) -#define LCANNON_RADIUS              150 -#define LCANNON_SECONDARY_DAMAGE    HDM(27) -#define LCANNON_SECONDARY_RADIUS    75 -#define LCANNON_SPEED               350 -#define LCANNON_CHARGE_TIME         2000 -#define LCANNON_TOTAL_CHARGE        255 - -#define HBUILD_PRICE                0 -#define HBUILD_REPEAT               1000 -#define HBUILD_DELAY                17500 -#define HBUILD_HEALRATE             18 - -#define HBUILD2_PRICE               0 -#define HBUILD2_REPEAT              1000 -#define HBUILD2_DELAY               15000 - - - -/* - * HUMAN upgrades - */ - -#define LIGHTARMOUR_PRICE           70 - -#define HELMET_PRICE                90 -#define HELMET_RANGE                1000.0f - -#define MEDKIT_PRICE                0 - -#define BATTPACK_PRICE              100 -#define BATTPACK_MODIFIER           1.5f //modifier for extra energy storage available - -#define JETPACK_PRICE               120 -#define JETPACK_FLOAT_SPEED         128.0f //up movement speed -#define JETPACK_SINK_SPEED          192.0f //down movement speed -#define JETPACK_DISABLE_TIME        1000 //time to disable the jetpack when player damaged -#define JETPACK_DISABLE_CHANCE      0.3f - -#define BSUIT_PRICE                 400 - -#define MGCLIP_PRICE                0 - -#define CGAMMO_PRICE                0 - -#define GAS_PRICE                   0 - -#define MEDKIT_POISON_IMMUNITY_TIME 30000 -#define MEDKIT_STARTUP_TIME         4000 -#define MEDKIT_STARTUP_SPEED        5 - - -/* - * HUMAN buildables - * - * _BP            - build points required for this buildable - * _BT            - build time required for this buildable - * _SPLASHDAMGE   - the amount of damage caused by this buildable when it blows up - * _SPLASHRADIUS  - the radius around which it does this damage - * - * REACTOR_BASESIZE - the maximum distance a buildable can be from an reactor - * REPEATER_BASESIZE - the maximum distance a buildable can be from a repeater - * HUMAN_BHLTH_MODIFIER - overall health modifier for coarse tuning - * - */ - -#define HUMAN_BHLTH_MODIFIER        1.0f -#define HBHM(h)                     ((int)((float)h*HUMAN_BHLTH_MODIFIER)) - -#define REACTOR_BASESIZE            1000 -#define REPEATER_BASESIZE           500 -#define HUMAN_DETONATION_DELAY      5000 - -#define HSPAWN_BP                   10 -#define HSPAWN_BT                   10000 -#define HSPAWN_HEALTH               HBHM(310) -#define HSPAWN_SPLASHDAMAGE         50 -#define HSPAWN_SPLASHRADIUS         100 -#define HSPAWN_VALUE                1 - -#define MEDISTAT_BP                 8 -#define MEDISTAT_BT                 10000 -#define MEDISTAT_HEALTH             HBHM(190) -#define MEDISTAT_SPLASHDAMAGE       50 -#define MEDISTAT_SPLASHRADIUS       100 - -#define MGTURRET_BP                 8 -#define MGTURRET_BT                 10000 -#define MGTURRET_HEALTH             HBHM(190) -#define MGTURRET_SPLASHDAMAGE       100 -#define MGTURRET_SPLASHRADIUS       100 -#define MGTURRET_ANGULARSPEED       8  //degrees/think ~= 200deg/sec -#define MGTURRET_ACCURACYTOLERANCE  MGTURRET_ANGULARSPEED / 1.5f //angular difference for turret to fire -#define MGTURRET_VERTICALCAP        30  // +/- maximum pitch -#define MGTURRET_REPEAT             100 -#define MGTURRET_RANGE              300.0f -#define MGTURRET_SPREAD             200 -#define MGTURRET_DMG                HDM(4) -#define MGTURRET_DCC_ANGULARSPEED       10 -#define MGTURRET_DCC_ACCURACYTOLERANCE  MGTURRET_DCC_ANGULARSPEED / 1.5f -#define MGTURRET_GRAB_ANGULARSPEED      3 -#define MGTURRET_GRAB_ACCURACYTOLERANCE MGTURRET_GRAB_ANGULARSPEED / 1.5f - -#define TESLAGEN_BP                 10 -#define TESLAGEN_BT                 15000 -#define TESLAGEN_HEALTH             HBHM(220) -#define TESLAGEN_SPLASHDAMAGE       50 -#define TESLAGEN_SPLASHRADIUS       100 -#define TESLAGEN_REPEAT             250 -#define TESLAGEN_RANGE              250 -#define TESLAGEN_DMG                HDM(9) - -#define DC_BP                       8 -#define DC_BT                       10000 -#define DC_HEALTH                   HBHM(190) -#define DC_SPLASHDAMAGE             50 -#define DC_SPLASHRADIUS             100 - -#define ARMOURY_BP                  10 -#define ARMOURY_BT                  10000 -#define ARMOURY_HEALTH              HBHM(280) -#define ARMOURY_SPLASHDAMAGE        50 -#define ARMOURY_SPLASHRADIUS        100 - -#define REACTOR_BP                  0 -#define REACTOR_BT                  20000 -#define REACTOR_HEALTH              HBHM(930) -#define REACTOR_SPLASHDAMAGE        200 -#define REACTOR_SPLASHRADIUS        300 -#define REACTOR_ATTACK_RANGE        100.0f -#define REACTOR_ATTACK_REPEAT       1000 -#define REACTOR_ATTACK_DAMAGE       40 -#define REACTOR_VALUE               2 - -#define REPEATER_BP                 0 -#define REPEATER_BT                 10000 -#define REPEATER_HEALTH             HBHM(250) -#define REPEATER_SPLASHDAMAGE       50 -#define REPEATER_SPLASHRADIUS       100 -#define REPEATER_INACTIVE_TIME      90000 - -/* - * HUMAN misc - */ - -#define HUMAN_SPRINT_MODIFIER       1.2f -#define HUMAN_JOG_MODIFIER          1.0f -#define HUMAN_BACK_MODIFIER         0.8f -#define HUMAN_SIDE_MODIFIER         0.9f - -#define STAMINA_STOP_RESTORE        25 -#define STAMINA_WALK_RESTORE        15 -#define STAMINA_SPRINT_TAKE         8 -#define STAMINA_LARMOUR_TAKE        4 - -#define HUMAN_SPAWN_REPEAT_TIME     10000 - -/* - * Misc - */ - -#define MIN_FALL_DISTANCE           30.0f //the fall distance at which fall damage kicks in -#define MAX_FALL_DISTANCE           120.0f //the fall distance at which maximum damage is dealt -#define AVG_FALL_DISTANCE           ((MIN_FALL_DISTANCE+MAX_FALL_DISTANCE)/2.0f) - -#define HUMAN_MAXED                 900   //a human with a strong selection of weapons/upgrades -#define HUMAN_MAX_CREDITS           2000 -#define ALIEN_MAX_KILLS             9 -#define ALIEN_MAX_SINGLE_KILLS      3 - -#define FREEKILL_PERIOD             120000 //msec -#define FREEKILL_ALIEN              1 -#define FREEKILL_HUMAN              LEVEL0_VALUE - -#define DEFAULT_ALIEN_BUILDPOINTS   "100" -#define DEFAULT_HUMAN_BUILDPOINTS   "100" - -#define DAMAGE_FRACTION_FOR_KILL    0.5f //how much damage players (versus structures) need to -                                         //do to increment the stage kill counters diff --git a/mod/src/ui/keycodes.h b/mod/src/ui/keycodes.h deleted file mode 100644 index cfa82223..00000000 --- a/mod/src/ui/keycodes.h +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#ifndef __KEYCODES_H__ -#define __KEYCODES_H__ - -// -// these are the key numbers that should be passed to KeyEvent -// - -// normal keys should be passed as lowercased ascii - -typedef enum { -  K_TAB = 9, -  K_ENTER = 13, -  K_ESCAPE = 27, -  K_SPACE = 32, - -  K_BACKSPACE = 127, - -  K_COMMAND = 128, -  K_CAPSLOCK, -  K_POWER, -  K_PAUSE, - -  K_UPARROW, -  K_DOWNARROW, -  K_LEFTARROW, -  K_RIGHTARROW, - -  K_ALT, -  K_CTRL, -  K_SHIFT, -  K_INS, -  K_DEL, -  K_PGDN, -  K_PGUP, -  K_HOME, -  K_END, - -  K_F1, -  K_F2, -  K_F3, -  K_F4, -  K_F5, -  K_F6, -  K_F7, -  K_F8, -  K_F9, -  K_F10, -  K_F11, -  K_F12, -  K_F13, -  K_F14, -  K_F15, - -  K_KP_HOME, -  K_KP_UPARROW, -  K_KP_PGUP, -  K_KP_LEFTARROW, -  K_KP_5, -  K_KP_RIGHTARROW, -  K_KP_END, -  K_KP_DOWNARROW, -  K_KP_PGDN, -  K_KP_ENTER, -  K_KP_INS, -  K_KP_DEL, -  K_KP_SLASH, -  K_KP_MINUS, -  K_KP_PLUS, -  K_KP_NUMLOCK, -  K_KP_STAR, -  K_KP_EQUALS, - -  K_MOUSE1, -  K_MOUSE2, -  K_MOUSE3, -  K_MOUSE4, -  K_MOUSE5, - -  K_MWHEELDOWN, -  K_MWHEELUP, - -  K_JOY1, -  K_JOY2, -  K_JOY3, -  K_JOY4, -  K_JOY5, -  K_JOY6, -  K_JOY7, -  K_JOY8, -  K_JOY9, -  K_JOY10, -  K_JOY11, -  K_JOY12, -  K_JOY13, -  K_JOY14, -  K_JOY15, -  K_JOY16, -  K_JOY17, -  K_JOY18, -  K_JOY19, -  K_JOY20, -  K_JOY21, -  K_JOY22, -  K_JOY23, -  K_JOY24, -  K_JOY25, -  K_JOY26, -  K_JOY27, -  K_JOY28, -  K_JOY29, -  K_JOY30, -  K_JOY31, -  K_JOY32, - -  K_AUX1, -  K_AUX2, -  K_AUX3, -  K_AUX4, -  K_AUX5, -  K_AUX6, -  K_AUX7, -  K_AUX8, -  K_AUX9, -  K_AUX10, -  K_AUX11, -  K_AUX12, -  K_AUX13, -  K_AUX14, -  K_AUX15, -  K_AUX16, - -  K_LAST_KEY    // this had better be <256! -} keyNum_t; - - -// The menu code needs to get both key and char events, but -// to avoid duplicating the paths, the char events are just -// distinguished by or'ing in K_CHAR_FLAG (ugly) -#define  K_CHAR_FLAG    1024 - -#endif diff --git a/mod/src/ui/ui_atoms.c b/mod/src/ui/ui_atoms.c deleted file mode 100644 index dc6496b7..00000000 --- a/mod/src/ui/ui_atoms.c +++ /dev/null @@ -1,517 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -/********************************************************************** -  UI_ATOMS.C - -  User interface building blocks and support functions. -**********************************************************************/ -#include "ui_local.h" - -qboolean    m_entersound;    // after a frame, so caching won't disrupt the sound - -void QDECL Com_Error( int level, const char *error, ... ) { -  va_list    argptr; -  char    text[1024]; - -  va_start (argptr, error); -  vsprintf (text, error, argptr); -  va_end (argptr); - -  trap_Error( va("%s", text) ); -} - -void QDECL Com_Printf( const char *msg, ... ) { -  va_list    argptr; -  char    text[1024]; - -  va_start (argptr, msg); -  vsprintf (text, msg, argptr); -  va_end (argptr); - -  trap_Print( va("%s", text) ); -} - -qboolean newUI = qfalse; - - -/* -================= -UI_ClampCvar -================= -*/ -float UI_ClampCvar( float min, float max, float value ) -{ -  if ( value < min ) return min; -  if ( value > max ) return max; -  return value; -} - -/* -================= -UI_StartDemoLoop -================= -*/ -void UI_StartDemoLoop( void ) { -  trap_Cmd_ExecuteText( EXEC_APPEND, "d1\n" ); -} - -char *UI_Argv( int arg ) { -  static char  buffer[MAX_STRING_CHARS]; - -  trap_Argv( arg, buffer, sizeof( buffer ) ); - -  return buffer; -} - - -char *UI_Cvar_VariableString( const char *var_name ) { -  static char  buffer[MAX_STRING_CHARS]; - -  trap_Cvar_VariableStringBuffer( var_name, buffer, sizeof( buffer ) ); - -  return buffer; -} - - - -void UI_SetBestScores(postGameInfo_t *newInfo, qboolean postGame) { -  trap_Cvar_Set("ui_scoreAccuracy",     va("%i%%", newInfo->accuracy)); -  trap_Cvar_Set("ui_scoreImpressives",  va("%i", newInfo->impressives)); -  trap_Cvar_Set("ui_scoreExcellents",   va("%i", newInfo->excellents)); -  trap_Cvar_Set("ui_scoreDefends",       va("%i", newInfo->defends)); -  trap_Cvar_Set("ui_scoreAssists",       va("%i", newInfo->assists)); -  trap_Cvar_Set("ui_scoreGauntlets",     va("%i", newInfo->gauntlets)); -  trap_Cvar_Set("ui_scoreScore",         va("%i", newInfo->score)); -  trap_Cvar_Set("ui_scorePerfect",       va("%i", newInfo->perfects)); -  trap_Cvar_Set("ui_scoreTeam",          va("%i to %i", newInfo->redScore, newInfo->blueScore)); -  trap_Cvar_Set("ui_scoreBase",          va("%i", newInfo->baseScore)); -  trap_Cvar_Set("ui_scoreTimeBonus",    va("%i", newInfo->timeBonus)); -  trap_Cvar_Set("ui_scoreSkillBonus",    va("%i", newInfo->skillBonus)); -  trap_Cvar_Set("ui_scoreShutoutBonus",  va("%i", newInfo->shutoutBonus)); -  trap_Cvar_Set("ui_scoreTime",          va("%02i:%02i", newInfo->time / 60, newInfo->time % 60)); -  trap_Cvar_Set("ui_scoreCaptures",    va("%i", newInfo->captures)); -  if (postGame) { -    trap_Cvar_Set("ui_scoreAccuracy2",     va("%i%%", newInfo->accuracy)); -    trap_Cvar_Set("ui_scoreImpressives2",  va("%i", newInfo->impressives)); -    trap_Cvar_Set("ui_scoreExcellents2",   va("%i", newInfo->excellents)); -    trap_Cvar_Set("ui_scoreDefends2",       va("%i", newInfo->defends)); -    trap_Cvar_Set("ui_scoreAssists2",       va("%i", newInfo->assists)); -    trap_Cvar_Set("ui_scoreGauntlets2",     va("%i", newInfo->gauntlets)); -    trap_Cvar_Set("ui_scoreScore2",         va("%i", newInfo->score)); -    trap_Cvar_Set("ui_scorePerfect2",       va("%i", newInfo->perfects)); -    trap_Cvar_Set("ui_scoreTeam2",          va("%i to %i", newInfo->redScore, newInfo->blueScore)); -    trap_Cvar_Set("ui_scoreBase2",          va("%i", newInfo->baseScore)); -    trap_Cvar_Set("ui_scoreTimeBonus2",    va("%i", newInfo->timeBonus)); -    trap_Cvar_Set("ui_scoreSkillBonus2",    va("%i", newInfo->skillBonus)); -    trap_Cvar_Set("ui_scoreShutoutBonus2",  va("%i", newInfo->shutoutBonus)); -    trap_Cvar_Set("ui_scoreTime2",          va("%02i:%02i", newInfo->time / 60, newInfo->time % 60)); -    trap_Cvar_Set("ui_scoreCaptures2",    va("%i", newInfo->captures)); -  } -} - -void UI_LoadBestScores(const char *map, int game) { -  char    fileName[MAX_QPATH]; -  fileHandle_t f; -  postGameInfo_t newInfo; -  memset(&newInfo, 0, sizeof(postGameInfo_t)); -  Com_sprintf(fileName, MAX_QPATH, "games/%s_%i.game", map, game); -  if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) { -    int size = 0; -    trap_FS_Read(&size, sizeof(int), f); -    if (size == sizeof(postGameInfo_t)) { -      trap_FS_Read(&newInfo, sizeof(postGameInfo_t), f); -    } -    trap_FS_FCloseFile(f); -  } -  UI_SetBestScores(&newInfo, qfalse); - -  Com_sprintf(fileName, MAX_QPATH, "demos/%s_%d.dm_%d", map, game, (int)trap_Cvar_VariableValue("protocol")); -  uiInfo.demoAvailable = qfalse; -  if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) { -    uiInfo.demoAvailable = qtrue; -    trap_FS_FCloseFile(f); -  } -} - -/* -=============== -UI_ClearScores -=============== -*/ -void UI_ClearScores( void ) { -  char  gameList[4096]; -  char *gameFile; -  int    i, len, count, size; -  fileHandle_t f; -  postGameInfo_t newInfo; - -  count = trap_FS_GetFileList( "games", "game", gameList, sizeof(gameList) ); - -  size = sizeof(postGameInfo_t); -  memset(&newInfo, 0, size); - -  if (count > 0) { -    gameFile = gameList; -    for ( i = 0; i < count; i++ ) { -      len = strlen(gameFile); -      if (trap_FS_FOpenFile(va("games/%s",gameFile), &f, FS_WRITE) >= 0) { -        trap_FS_Write(&size, sizeof(int), f); -        trap_FS_Write(&newInfo, size, f); -        trap_FS_FCloseFile(f); -      } -      gameFile += len + 1; -    } -  } - -  UI_SetBestScores(&newInfo, qfalse); - -} - - - -static void  UI_Cache_f( void ) { -  Display_CacheAll(); -} - -/* -======================= -UI_CalcPostGameStats -======================= -*/ -static void UI_CalcPostGameStats( void ) { -  char    map[MAX_QPATH]; -  char    fileName[MAX_QPATH]; -  char    info[MAX_INFO_STRING]; -  fileHandle_t f; -  int size, game, time, adjustedTime; -  postGameInfo_t oldInfo; -  postGameInfo_t newInfo; -  qboolean newHigh = qfalse; - -  trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ); -  Q_strncpyz( map, Info_ValueForKey( info, "mapname" ), sizeof(map) ); -  game = atoi(Info_ValueForKey(info, "g_gametype")); - -  // compose file name -  Com_sprintf(fileName, MAX_QPATH, "games/%s_%i.game", map, game); -  // see if we have one already -  memset(&oldInfo, 0, sizeof(postGameInfo_t)); -  if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) { -  // if so load it -    size = 0; -    trap_FS_Read(&size, sizeof(int), f); -    if (size == sizeof(postGameInfo_t)) { -      trap_FS_Read(&oldInfo, sizeof(postGameInfo_t), f); -    } -    trap_FS_FCloseFile(f); -  } - -  newInfo.accuracy = atoi(UI_Argv(3)); -  newInfo.impressives = atoi(UI_Argv(4)); -  newInfo.excellents = atoi(UI_Argv(5)); -  newInfo.defends = atoi(UI_Argv(6)); -  newInfo.assists = atoi(UI_Argv(7)); -  newInfo.gauntlets = atoi(UI_Argv(8)); -  newInfo.baseScore = atoi(UI_Argv(9)); -  newInfo.perfects = atoi(UI_Argv(10)); -  newInfo.redScore = atoi(UI_Argv(11)); -  newInfo.blueScore = atoi(UI_Argv(12)); -  time = atoi(UI_Argv(13)); -  newInfo.captures = atoi(UI_Argv(14)); - -  newInfo.time = (time - trap_Cvar_VariableValue("ui_matchStartTime")) / 1000; -  adjustedTime = uiInfo.mapList[ui_currentMap.integer].timeToBeat[game]; -  if (newInfo.time < adjustedTime) { -    newInfo.timeBonus = (adjustedTime - newInfo.time) * 10; -  } else { -    newInfo.timeBonus = 0; -  } - -  if (newInfo.redScore > newInfo.blueScore && newInfo.blueScore <= 0) { -    newInfo.shutoutBonus = 100; -  } else { -    newInfo.shutoutBonus = 0; -  } - -  newInfo.skillBonus = trap_Cvar_VariableValue("g_spSkill"); -  if (newInfo.skillBonus <= 0) { -    newInfo.skillBonus = 1; -  } -  newInfo.score = newInfo.baseScore + newInfo.shutoutBonus + newInfo.timeBonus; -  newInfo.score *= newInfo.skillBonus; - -  // see if the score is higher for this one -  newHigh = (newInfo.redScore > newInfo.blueScore && newInfo.score > oldInfo.score); - -  if  (newHigh) { -    // if so write out the new one -    uiInfo.newHighScoreTime = uiInfo.uiDC.realTime + 20000; -    if (trap_FS_FOpenFile(fileName, &f, FS_WRITE) >= 0) { -      size = sizeof(postGameInfo_t); -      trap_FS_Write(&size, sizeof(int), f); -      trap_FS_Write(&newInfo, sizeof(postGameInfo_t), f); -      trap_FS_FCloseFile(f); -    } -  } - -  if (newInfo.time < oldInfo.time) { -    uiInfo.newBestTime = uiInfo.uiDC.realTime + 20000; -  } - -  // put back all the ui overrides -  trap_Cvar_Set("capturelimit", UI_Cvar_VariableString("ui_saveCaptureLimit")); -  trap_Cvar_Set("fraglimit", UI_Cvar_VariableString("ui_saveFragLimit")); -  trap_Cvar_Set("cg_drawTimer", UI_Cvar_VariableString("ui_drawTimer")); -  trap_Cvar_Set("g_doWarmup", UI_Cvar_VariableString("ui_doWarmup")); -  trap_Cvar_Set("g_Warmup", UI_Cvar_VariableString("ui_Warmup")); -  trap_Cvar_Set("sv_pure", UI_Cvar_VariableString("ui_pure")); -  trap_Cvar_Set("g_friendlyFire", UI_Cvar_VariableString("ui_friendlyFire")); - -  UI_SetBestScores(&newInfo, qtrue); -  UI_ShowPostGame(newHigh); - - -} - - -/* -================= -UI_ConsoleCommand -================= -*/ -qboolean UI_ConsoleCommand( int realTime ) -{ -  char  *cmd; -  char  *arg1; - -  uiInfo.uiDC.frameTime = realTime - uiInfo.uiDC.realTime; -  uiInfo.uiDC.realTime = realTime; - -  cmd = UI_Argv( 0 ); - -  // ensure minimum menu data is available -  //Menu_Cache(); - -  if ( Q_stricmp (cmd, "ui_test") == 0 ) { -    UI_ShowPostGame(qtrue); -  } - -  if ( Q_stricmp (cmd, "ui_report") == 0 ) { -    UI_Report(); -    return qtrue; -  } - -  if ( Q_stricmp (cmd, "ui_load") == 0 ) { -    UI_Load(); -    return qtrue; -  } - -  if ( Q_stricmp (cmd, "remapShader") == 0 ) { -    if (trap_Argc() == 4) { -      char shader1[MAX_QPATH]; -      char shader2[MAX_QPATH]; -      Q_strncpyz(shader1, UI_Argv(1), sizeof(shader1)); -      Q_strncpyz(shader2, UI_Argv(2), sizeof(shader2)); -      trap_R_RemapShader(shader1, shader2, UI_Argv(3)); -      return qtrue; -    } -  } - -  if ( Q_stricmp (cmd, "postgame") == 0 ) { -    UI_CalcPostGameStats(); -    return qtrue; -  } - -  if ( Q_stricmp (cmd, "ui_cache") == 0 ) { -    UI_Cache_f(); -    return qtrue; -  } - -  if ( Q_stricmp (cmd, "ui_teamOrders") == 0 ) { -    //UI_TeamOrdersMenu_f(); -    return qtrue; -  } - -  if( Q_stricmp ( cmd, "menu" ) == 0 ) -  { -    arg1 = UI_Argv( 1 ); - -    if( Menu_Count( ) > 0 ) -    { -      trap_Key_SetCatcher( KEYCATCH_UI ); -      Menus_ActivateByName( arg1 ); -      return qtrue; -    } -  } - -  if( Q_stricmp ( cmd, "closemenus" ) == 0 ) -  { -    if( Menu_Count( ) > 0 ) -    { -      trap_Key_SetCatcher( trap_Key_GetCatcher( ) & ~KEYCATCH_UI ); -      trap_Key_ClearStates( ); -      trap_Cvar_Set( "cl_paused", "0" ); -      Menus_CloseAll( ); -      return qtrue; -    } -  } - -  if ( Q_stricmp (cmd, "ui_cdkey") == 0 ) { -    //UI_CDKeyMenu_f(); -    return qtrue; -  } - -  return qfalse; -} - -/* -================= -UI_Shutdown -================= -*/ -void UI_Shutdown( void ) { -} - -/* -================ -UI_AdjustFrom640 - -Adjusted for resolution and screen aspect ratio -================ -*/ -void UI_AdjustFrom640( float *x, float *y, float *w, float *h ) { -  // expect valid pointers -#if 0 -  *x = *x * uiInfo.uiDC.scale + uiInfo.uiDC.bias; -  *y *= uiInfo.uiDC.scale; -  *w *= uiInfo.uiDC.scale; -  *h *= uiInfo.uiDC.scale; -#endif - -  *x *= uiInfo.uiDC.xscale; -  *y *= uiInfo.uiDC.yscale; -  *w *= uiInfo.uiDC.xscale; -  *h *= uiInfo.uiDC.yscale; - -} - -void UI_DrawNamedPic( float x, float y, float width, float height, const char *picname ) { -  qhandle_t  hShader; - -  hShader = trap_R_RegisterShaderNoMip( picname ); -  UI_AdjustFrom640( &x, &y, &width, &height ); -  trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, hShader ); -} - -void UI_DrawHandlePic( float x, float y, float w, float h, qhandle_t hShader ) { -  float  s0; -  float  s1; -  float  t0; -  float  t1; - -  if( w < 0 ) {  // flip about vertical -    w  = -w; -    s0 = 1; -    s1 = 0; -  } -  else { -    s0 = 0; -    s1 = 1; -  } - -  if( h < 0 ) {  // flip about horizontal -    h  = -h; -    t0 = 1; -    t1 = 0; -  } -  else { -    t0 = 0; -    t1 = 1; -  } - -  UI_AdjustFrom640( &x, &y, &w, &h ); -  trap_R_DrawStretchPic( x, y, w, h, s0, t0, s1, t1, hShader ); -} - -/* -================ -UI_FillRect - -Coordinates are 640*480 virtual values -================= -*/ -void UI_FillRect( float x, float y, float width, float height, const float *color ) { -  trap_R_SetColor( color ); - -  UI_AdjustFrom640( &x, &y, &width, &height ); -  trap_R_DrawStretchPic( x, y, width, height, 0, 0, 0, 0, uiInfo.uiDC.whiteShader ); - -  trap_R_SetColor( NULL ); -} - -void UI_DrawSides(float x, float y, float w, float h) { -  UI_AdjustFrom640( &x, &y, &w, &h ); -  trap_R_DrawStretchPic( x, y, 1, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader ); -  trap_R_DrawStretchPic( x + w - 1, y, 1, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader ); -} - -void UI_DrawTopBottom(float x, float y, float w, float h) { -  UI_AdjustFrom640( &x, &y, &w, &h ); -  trap_R_DrawStretchPic( x, y, w, 1, 0, 0, 0, 0, uiInfo.uiDC.whiteShader ); -  trap_R_DrawStretchPic( x, y + h - 1, w, 1, 0, 0, 0, 0, uiInfo.uiDC.whiteShader ); -} -/* -================ -UI_DrawRect - -Coordinates are 640*480 virtual values -================= -*/ -void UI_DrawRect( float x, float y, float width, float height, const float *color ) { -  trap_R_SetColor( color ); - -  UI_DrawTopBottom(x, y, width, height); -  UI_DrawSides(x, y, width, height); - -  trap_R_SetColor( NULL ); -} - -void UI_SetColor( const float *rgba ) { -  trap_R_SetColor( rgba ); -} - -void UI_UpdateScreen( void ) { -  trap_UpdateScreen(); -} - - -void UI_DrawTextBox (int x, int y, int width, int lines) -{ -  UI_FillRect( x + BIGCHAR_WIDTH/2, y + BIGCHAR_HEIGHT/2, ( width + 1 ) * BIGCHAR_WIDTH, ( lines + 1 ) * BIGCHAR_HEIGHT, colorBlack ); -  UI_DrawRect( x + BIGCHAR_WIDTH/2, y + BIGCHAR_HEIGHT/2, ( width + 1 ) * BIGCHAR_WIDTH, ( lines + 1 ) * BIGCHAR_HEIGHT, colorWhite ); -} - -qboolean UI_CursorInRect (int x, int y, int width, int height) -{ -  if (uiInfo.uiDC.cursorx < x || -    uiInfo.uiDC.cursory < y || -    uiInfo.uiDC.cursorx > x+width || -    uiInfo.uiDC.cursory > y+height) -    return qfalse; - -  return qtrue; -} diff --git a/mod/src/ui/ui_gameinfo.c b/mod/src/ui/ui_gameinfo.c deleted file mode 100644 index 49d0cdb0..00000000 --- a/mod/src/ui/ui_gameinfo.c +++ /dev/null @@ -1,293 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -// -// gameinfo.c -// - -#include "ui_local.h" - - -// -// arena and bot info -// - - -int       ui_numBots; -static char   *ui_botInfos[MAX_BOTS]; - -static int    ui_numArenas; -static char   *ui_arenaInfos[MAX_ARENAS]; - -/* -=============== -UI_ParseInfos -=============== -*/ -int UI_ParseInfos( char *buf, int max, char *infos[] ) { -  char  *token; -  int   count; -  char  key[MAX_TOKEN_CHARS]; -  char  info[MAX_INFO_STRING]; - -  count = 0; - -  while ( 1 ) { -    token = COM_Parse( &buf ); -    if ( !token[0] ) { -      break; -    } -    if ( strcmp( token, "{" ) ) { -      Com_Printf( "Missing { in info file\n" ); -      break; -    } - -    if ( count == max ) { -      Com_Printf( "Max infos exceeded\n" ); -      break; -    } - -    info[0] = '\0'; -    while ( 1 ) { -      token = COM_ParseExt( &buf, qtrue ); -      if ( !token[0] ) { -        Com_Printf( "Unexpected end of info file\n" ); -        break; -      } -      if ( !strcmp( token, "}" ) ) { -        break; -      } -      Q_strncpyz( key, token, sizeof( key ) ); - -      token = COM_ParseExt( &buf, qfalse ); -      if ( !token[0] ) { -        strcpy( token, "<NULL>" ); -      } -      Info_SetValueForKey( info, key, token ); -    } -    //NOTE: extra space for arena number -    infos[count] = UI_Alloc(strlen(info) + strlen("\\num\\") + strlen(va("%d", MAX_ARENAS)) + 1); -    if (infos[count]) { -      strcpy(infos[count], info); -      count++; -    } -  } -  return count; -} - -/* -=============== -UI_LoadArenasFromFile -=============== -*/ -static void UI_LoadArenasFromFile( char *filename ) { -  int       len; -  fileHandle_t  f; -  char      buf[MAX_ARENAS_TEXT]; - -  len = trap_FS_FOpenFile( filename, &f, FS_READ ); -  if ( !f ) { -    trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) ); -    return; -  } -  if ( len >= MAX_ARENAS_TEXT ) { -    trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_ARENAS_TEXT ) ); -    trap_FS_FCloseFile( f ); -    return; -  } - -  trap_FS_Read( buf, len, f ); -  buf[len] = 0; -  trap_FS_FCloseFile( f ); - -  ui_numArenas += UI_ParseInfos( buf, MAX_ARENAS - ui_numArenas, &ui_arenaInfos[ui_numArenas] ); -} - -/* -=============== -UI_LoadArenas -=============== -*/ -void UI_LoadArenas( void ) { -  int     numdirs; -  char    filename[128]; -  char    dirlist[1024]; -  char*   dirptr; -  int     i, n; -  int     dirlen; -  char    *type; - -  ui_numArenas = 0; -  uiInfo.mapCount = 0; - -/*  trap_Cvar_Register( &arenasFile, "g_arenasFile", "", CVAR_INIT|CVAR_ROM ); -  if( *arenasFile.string ) { -    UI_LoadArenasFromFile(arenasFile.string); -  } -  else { -    UI_LoadArenasFromFile("scripts/arenas.txt"); -  }*/ - -  // get all arenas from .arena files -  numdirs = trap_FS_GetFileList("scripts", ".arena", dirlist, 1024 ); -  dirptr  = dirlist; -  for (i = 0; i < numdirs; i++, dirptr += dirlen+1) { -    dirlen = strlen(dirptr); -    strcpy(filename, "scripts/"); -    strcat(filename, dirptr); -    UI_LoadArenasFromFile(filename); -  } -  trap_Print( va( "%i arenas parsed\n", ui_numArenas ) ); -  if (UI_OutOfMemory()) { -    trap_Print(S_COLOR_YELLOW"WARNING: not anough memory in pool to load all arenas\n"); -  } - -  for( n = 0; n < ui_numArenas; n++ ) -  { -      // determine type -    type = Info_ValueForKey( ui_arenaInfos[ n ], "type" ); -    // if no type specified, it will be treated as "ffa" - -    if( *type && strstr( type, "tremulous" ) ) -      uiInfo.mapList[ uiInfo.mapCount ].typeBits |= ( 1 << 0 ); -    else -      continue; //not a trem map - -    uiInfo.mapList[uiInfo.mapCount].cinematic = -1; -    uiInfo.mapList[uiInfo.mapCount].mapLoadName = String_Alloc(Info_ValueForKey(ui_arenaInfos[n], "map")); -    uiInfo.mapList[uiInfo.mapCount].mapName = String_Alloc(Info_ValueForKey(ui_arenaInfos[n], "longname")); -    uiInfo.mapList[uiInfo.mapCount].levelShot = -1; -    uiInfo.mapList[uiInfo.mapCount].imageName = String_Alloc(va("levelshots/%s", uiInfo.mapList[uiInfo.mapCount].mapLoadName)); - -    uiInfo.mapCount++; -    if( uiInfo.mapCount >= MAX_MAPS ) -      break; -  } -} - - -/* -=============== -UI_LoadBotsFromFile -=============== -*/ -static void UI_LoadBotsFromFile( char *filename ) { -  int       len; -  fileHandle_t  f; -  char      buf[MAX_BOTS_TEXT]; - -  len = trap_FS_FOpenFile( filename, &f, FS_READ ); -  if ( !f ) { -    trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) ); -    return; -  } -  if ( len >= MAX_BOTS_TEXT ) { -    trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_BOTS_TEXT ) ); -    trap_FS_FCloseFile( f ); -    return; -  } - -  trap_FS_Read( buf, len, f ); -  buf[len] = 0; -  trap_FS_FCloseFile( f ); - -  COM_Compress(buf); - -  ui_numBots += UI_ParseInfos( buf, MAX_BOTS - ui_numBots, &ui_botInfos[ui_numBots] ); -} - -/* -=============== -UI_LoadBots -=============== -*/ -void UI_LoadBots( void ) { -  vmCvar_t  botsFile; -  int     numdirs; -  char    filename[128]; -  char    dirlist[1024]; -  char*   dirptr; -  int     i; -  int     dirlen; - -  ui_numBots = 0; - -  trap_Cvar_Register( &botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM ); -  if( *botsFile.string ) { -    UI_LoadBotsFromFile(botsFile.string); -  } -  else { -    UI_LoadBotsFromFile("scripts/bots.txt"); -  } - -  // get all bots from .bot files -  numdirs = trap_FS_GetFileList("scripts", ".bot", dirlist, 1024 ); -  dirptr  = dirlist; -  for (i = 0; i < numdirs; i++, dirptr += dirlen+1) { -    dirlen = strlen(dirptr); -    strcpy(filename, "scripts/"); -    strcat(filename, dirptr); -    UI_LoadBotsFromFile(filename); -  } -  trap_Print( va( "%i bots parsed\n", ui_numBots ) ); -} - - -/* -=============== -UI_GetBotInfoByNumber -=============== -*/ -char *UI_GetBotInfoByNumber( int num ) { -  if( num < 0 || num >= ui_numBots ) { -    trap_Print( va( S_COLOR_RED "Invalid bot number: %i\n", num ) ); -    return NULL; -  } -  return ui_botInfos[num]; -} - - -/* -=============== -UI_GetBotInfoByName -=============== -*/ -char *UI_GetBotInfoByName( const char *name ) { -  int   n; -  char  *value; - -  for ( n = 0; n < ui_numBots ; n++ ) { -    value = Info_ValueForKey( ui_botInfos[n], "name" ); -    if ( !Q_stricmp( value, name ) ) { -      return ui_botInfos[n]; -    } -  } - -  return NULL; -} - -int UI_GetNumBots() { -  return ui_numBots; -} - - -char *UI_GetBotNameByNumber( int num ) { -  char *info = UI_GetBotInfoByNumber(num); -  if (info) { -    return Info_ValueForKey( info, "name" ); -  } -  return "Sarge"; -} diff --git a/mod/src/ui/ui_local.h b/mod/src/ui/ui_local.h deleted file mode 100644 index cdcfc57f..00000000 --- a/mod/src/ui/ui_local.h +++ /dev/null @@ -1,1208 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#ifndef __UI_LOCAL_H__ -#define __UI_LOCAL_H__ - -#include "../game/q_shared.h" -#include "../cgame/tr_types.h" -#include "ui_public.h" -#include "keycodes.h" -#include "../game/bg_public.h" -#include "ui_shared.h" - -// global display context - -extern vmCvar_t  ui_ffa_fraglimit; -extern vmCvar_t  ui_ffa_timelimit; - -extern vmCvar_t  ui_tourney_fraglimit; -extern vmCvar_t  ui_tourney_timelimit; - -extern vmCvar_t  ui_team_fraglimit; -extern vmCvar_t  ui_team_timelimit; -extern vmCvar_t  ui_team_friendly; - -extern vmCvar_t  ui_ctf_capturelimit; -extern vmCvar_t  ui_ctf_timelimit; -extern vmCvar_t  ui_ctf_friendly; - -extern vmCvar_t  ui_arenasFile; -extern vmCvar_t  ui_botsFile; -extern vmCvar_t  ui_spScores1; -extern vmCvar_t  ui_spScores2; -extern vmCvar_t  ui_spScores3; -extern vmCvar_t  ui_spScores4; -extern vmCvar_t  ui_spScores5; -extern vmCvar_t  ui_spAwards; -extern vmCvar_t  ui_spVideos; -extern vmCvar_t  ui_spSkill; - -extern vmCvar_t  ui_spSelection; - -extern vmCvar_t  ui_browserMaster; -extern vmCvar_t  ui_browserGameType; -extern vmCvar_t  ui_browserSortKey; -extern vmCvar_t  ui_browserShowFull; -extern vmCvar_t  ui_browserShowEmpty; - -extern vmCvar_t  ui_brassTime; -extern vmCvar_t  ui_drawCrosshair; -extern vmCvar_t  ui_drawCrosshairNames; -extern vmCvar_t  ui_marks; - -extern vmCvar_t  ui_server1; -extern vmCvar_t  ui_server2; -extern vmCvar_t  ui_server3; -extern vmCvar_t  ui_server4; -extern vmCvar_t  ui_server5; -extern vmCvar_t  ui_server6; -extern vmCvar_t  ui_server7; -extern vmCvar_t  ui_server8; -extern vmCvar_t  ui_server9; -extern vmCvar_t  ui_server10; -extern vmCvar_t  ui_server11; -extern vmCvar_t  ui_server12; -extern vmCvar_t  ui_server13; -extern vmCvar_t  ui_server14; -extern vmCvar_t  ui_server15; -extern vmCvar_t  ui_server16; - -extern vmCvar_t  ui_cdkey; -extern vmCvar_t  ui_cdkeychecked; - -extern vmCvar_t  ui_captureLimit; -extern vmCvar_t  ui_fragLimit; -extern vmCvar_t  ui_gameType; -extern vmCvar_t  ui_netGameType; -extern vmCvar_t  ui_actualNetGameType; -extern vmCvar_t  ui_joinGameType; -extern vmCvar_t  ui_netSource; -extern vmCvar_t  ui_serverFilterType; -extern vmCvar_t  ui_dedicated; -extern vmCvar_t  ui_opponentName; -extern vmCvar_t  ui_menuFiles; -extern vmCvar_t  ui_currentTier; -extern vmCvar_t  ui_currentMap; -extern vmCvar_t  ui_currentNetMap; -extern vmCvar_t  ui_mapIndex; -extern vmCvar_t  ui_currentOpponent; -extern vmCvar_t  ui_selectedPlayer; -extern vmCvar_t  ui_selectedPlayerName; -extern vmCvar_t  ui_lastServerRefresh_0; -extern vmCvar_t  ui_lastServerRefresh_1; -extern vmCvar_t  ui_lastServerRefresh_2; -extern vmCvar_t  ui_lastServerRefresh_3; -extern vmCvar_t  ui_singlePlayerActive; -extern vmCvar_t  ui_scoreAccuracy; -extern vmCvar_t  ui_scoreImpressives; -extern vmCvar_t  ui_scoreExcellents; -extern vmCvar_t  ui_scoreDefends; -extern vmCvar_t  ui_scoreAssists; -extern vmCvar_t  ui_scoreGauntlets; -extern vmCvar_t  ui_scoreScore; -extern vmCvar_t  ui_scorePerfect; -extern vmCvar_t  ui_scoreTeam; -extern vmCvar_t  ui_scoreBase; -extern vmCvar_t  ui_scoreTimeBonus; -extern vmCvar_t  ui_scoreSkillBonus; -extern vmCvar_t  ui_scoreShutoutBonus; -extern vmCvar_t  ui_scoreTime; -extern vmCvar_t  ui_smallFont; -extern vmCvar_t  ui_bigFont; -extern vmCvar_t ui_serverStatusTimeOut; - -//TA: bank values -extern vmCvar_t  ui_bank; - - -// -// ui_qmenu.c -// - -#define RCOLUMN_OFFSET      ( BIGCHAR_WIDTH ) -#define LCOLUMN_OFFSET      (-BIGCHAR_WIDTH ) - -#define SLIDER_RANGE      10 -#define  MAX_EDIT_LINE      256 - -#define MAX_MENUDEPTH      8 -#define MAX_MENUITEMS      96 - -#define MTYPE_NULL        0 -#define MTYPE_SLIDER      1 -#define MTYPE_ACTION      2 -#define MTYPE_SPINCONTROL    3 -#define MTYPE_FIELD        4 -#define MTYPE_RADIOBUTTON    5 -#define MTYPE_BITMAP      6 -#define MTYPE_TEXT        7 -#define MTYPE_SCROLLLIST    8 -#define MTYPE_PTEXT        9 -#define MTYPE_BTEXT        10 - -#define QMF_BLINK        0x00000001 -#define QMF_SMALLFONT      0x00000002 -#define QMF_LEFT_JUSTIFY    0x00000004 -#define QMF_CENTER_JUSTIFY    0x00000008 -#define QMF_RIGHT_JUSTIFY    0x00000010 -#define QMF_NUMBERSONLY      0x00000020  // edit field is only numbers -#define QMF_HIGHLIGHT      0x00000040 -#define QMF_HIGHLIGHT_IF_FOCUS  0x00000080  // steady focus -#define QMF_PULSEIFFOCUS    0x00000100  // pulse if focus -#define QMF_HASMOUSEFOCUS    0x00000200 -#define QMF_NOONOFFTEXT      0x00000400 -#define QMF_MOUSEONLY      0x00000800  // only mouse input allowed -#define QMF_HIDDEN        0x00001000  // skips drawing -#define QMF_GRAYED        0x00002000  // grays and disables -#define QMF_INACTIVE      0x00004000  // disables any input -#define QMF_NODEFAULTINIT    0x00008000  // skip default initialization -#define QMF_OWNERDRAW      0x00010000 -#define QMF_PULSE        0x00020000 -#define QMF_LOWERCASE      0x00040000  // edit field is all lower case -#define QMF_UPPERCASE      0x00080000  // edit field is all upper case -#define QMF_SILENT        0x00100000 - -// callback notifications -#define QM_GOTFOCUS        1 -#define QM_LOSTFOCUS      2 -#define QM_ACTIVATED      3 - -typedef struct _tag_menuframework -{ -  int  cursor; -  int cursor_prev; - -  int  nitems; -  void *items[MAX_MENUITEMS]; - -  void (*draw) (void); -  sfxHandle_t (*key) (int key); - -  qboolean  wrapAround; -  qboolean  fullscreen; -  qboolean  showlogo; -} menuframework_s; - -typedef struct -{ -  int type; -  const char *name; -  int  id; -  int x, y; -  int left; -  int  top; -  int  right; -  int  bottom; -  menuframework_s *parent; -  int menuPosition; -  unsigned flags; - -  void (*callback)( void *self, int event ); -  void (*statusbar)( void *self ); -  void (*ownerdraw)( void *self ); -} menucommon_s; - -typedef struct { -  int    cursor; -  int    scroll; -  int    widthInChars; -  char  buffer[MAX_EDIT_LINE]; -  int    maxchars; -} mfield_t; - -typedef struct -{ -  menucommon_s  generic; -  mfield_t    field; -} menufield_s; - -typedef struct -{ -  menucommon_s generic; - -  float minvalue; -  float maxvalue; -  float curvalue; - -  float range; -} menuslider_s; - -typedef struct -{ -  menucommon_s generic; - -  int  oldvalue; -  int curvalue; -  int  numitems; -  int  top; - -  const char **itemnames; - -  int width; -  int height; -  int  columns; -  int  seperation; -} menulist_s; - -typedef struct -{ -  menucommon_s generic; -} menuaction_s; - -typedef struct -{ -  menucommon_s generic; -  int curvalue; -} menuradiobutton_s; - -typedef struct -{ -  menucommon_s  generic; -  char*      focuspic; -  char*      errorpic; -  qhandle_t    shader; -  qhandle_t    focusshader; -  int        width; -  int        height; -  float*      focuscolor; -} menubitmap_s; - -typedef struct -{ -  menucommon_s  generic; -  char*      string; -  int        style; -  float*      color; -} menutext_s; - -extern void      Menu_Cache( void ); -extern void      Menu_Focus( menucommon_s *m ); -extern void      Menu_AddItem( menuframework_s *menu, void *item ); -extern void      Menu_AdjustCursor( menuframework_s *menu, int dir ); -extern void      Menu_Draw( menuframework_s *menu ); -extern void      *Menu_ItemAtCursor( menuframework_s *m ); -extern sfxHandle_t  Menu_ActivateItem( menuframework_s *s, menucommon_s* item ); -extern void      Menu_SetCursor( menuframework_s *s, int cursor ); -extern void      Menu_SetCursorToItem( menuframework_s *m, void* ptr ); -extern sfxHandle_t  Menu_DefaultKey( menuframework_s *s, int key ); -extern void      Bitmap_Init( menubitmap_s *b ); -extern void      Bitmap_Draw( menubitmap_s *b ); -extern void      ScrollList_Draw( menulist_s *l ); -extern sfxHandle_t  ScrollList_Key( menulist_s *l, int key ); -extern sfxHandle_t  menu_in_sound; -extern sfxHandle_t  menu_move_sound; -extern sfxHandle_t  menu_out_sound; -extern sfxHandle_t  menu_buzz_sound; -extern sfxHandle_t  menu_null_sound; -extern sfxHandle_t  weaponChangeSound; -extern vec4_t    menu_text_color; -extern vec4_t    menu_grayed_color; -extern vec4_t    menu_dark_color; -extern vec4_t    menu_highlight_color; -extern vec4_t    menu_red_color; -extern vec4_t    menu_black_color; -extern vec4_t    menu_dim_color; -extern vec4_t    color_black; -extern vec4_t    color_white; -extern vec4_t    color_yellow; -extern vec4_t    color_blue; -extern vec4_t    color_orange; -extern vec4_t    color_red; -extern vec4_t    color_dim; -extern vec4_t    name_color; -extern vec4_t    list_color; -extern vec4_t    listbar_color; -extern vec4_t    text_color_disabled; -extern vec4_t    text_color_normal; -extern vec4_t    text_color_highlight; - -extern char  *ui_medalNames[]; -extern char  *ui_medalPicNames[]; -extern char  *ui_medalSounds[]; - -// -// ui_mfield.c -// -extern void      MField_Clear( mfield_t *edit ); -extern void      MField_KeyDownEvent( mfield_t *edit, int key ); -extern void      MField_CharEvent( mfield_t *edit, int ch ); -extern void      MField_Draw( mfield_t *edit, int x, int y, int style, vec4_t color ); -extern void      MenuField_Init( menufield_s* m ); -extern void      MenuField_Draw( menufield_s *f ); -extern sfxHandle_t  MenuField_Key( menufield_s* m, int* key ); - -// -// ui_main.c -// -void UI_Report( void ); -void UI_Load( void ); -void UI_LoadMenus(const char *menuFile, qboolean reset); -void _UI_SetActiveMenu( uiMenuCommand_t menu ); -int UI_AdjustTimeByGame(int time); -void UI_ShowPostGame(qboolean newHigh); -void UI_ClearScores( void ); -void UI_LoadArenas(void); - -// -// ui_menu.c -// -extern void MainMenu_Cache( void ); -extern void UI_MainMenu(void); -extern void UI_RegisterCvars( void ); -extern void UI_UpdateCvars( void ); - -// -// ui_credits.c -// -extern void UI_CreditMenu( void ); - -// -// ui_ingame.c -// -extern void InGame_Cache( void ); -extern void UI_InGameMenu(void); - -// -// ui_confirm.c -// -extern void ConfirmMenu_Cache( void ); -extern void UI_ConfirmMenu( const char *question, void (*draw)( void ), void (*action)( qboolean result ) ); - -// -// ui_setup.c -// -extern void UI_SetupMenu_Cache( void ); -extern void UI_SetupMenu(void); - -// -// ui_team.c -// -extern void UI_TeamMainMenu( void ); -extern void TeamMain_Cache( void ); - -// -// ui_connect.c -// -extern void UI_DrawConnectScreen( qboolean overlay ); - -// -// ui_controls2.c -// -extern void UI_ControlsMenu( void ); -extern void Controls_Cache( void ); - -// -// ui_demo2.c -// -extern void UI_DemosMenu( void ); -extern void Demos_Cache( void ); - -// -// ui_cinematics.c -// -extern void UI_CinematicsMenu( void ); -extern void UI_CinematicsMenu_f( void ); -extern void UI_CinematicsMenu_Cache( void ); - -// -// ui_mods.c -// -extern void UI_ModsMenu( void ); -extern void UI_ModsMenu_Cache( void ); - -// -// ui_cdkey.c -// -extern void UI_CDKeyMenu( void ); -extern void UI_CDKeyMenu_Cache( void ); -extern void UI_CDKeyMenu_f( void ); - -// -// ui_playermodel.c -// -extern void UI_PlayerModelMenu( void ); -extern void PlayerModel_Cache( void ); - -// -// ui_playersettings.c -// -extern void UI_PlayerSettingsMenu( void ); -extern void PlayerSettings_Cache( void ); - -// -// ui_preferences.c -// -extern void UI_PreferencesMenu( void ); -extern void Preferences_Cache( void ); - -// -// ui_specifyleague.c -// -extern void UI_SpecifyLeagueMenu( void ); -extern void SpecifyLeague_Cache( void ); - -// -// ui_specifyserver.c -// -extern void UI_SpecifyServerMenu( void ); -extern void SpecifyServer_Cache( void ); - -// -// ui_servers2.c -// -#define MAX_FAVORITESERVERS 16 - -extern void UI_ArenaServersMenu( void ); -extern void ArenaServers_Cache( void ); - -// -// ui_startserver.c -// -extern void UI_StartServerMenu( qboolean multiplayer ); -extern void StartServer_Cache( void ); -extern void ServerOptions_Cache( void ); -extern void UI_BotSelectMenu( char *bot ); -extern void UI_BotSelectMenu_Cache( void ); - -// -// ui_serverinfo.c -// -extern void UI_ServerInfoMenu( void ); -extern void ServerInfo_Cache( void ); - -// -// ui_video.c -// -extern void UI_GraphicsOptionsMenu( void ); -extern void GraphicsOptions_Cache( void ); -extern void DriverInfo_Cache( void ); - -// -// ui_players.c -// - -//FIXME ripped from cg_local.h -typedef struct { -  int      oldFrame; -  int      oldFrameTime;    // time when ->oldFrame was exactly on - -  int      frame; -  int      frameTime;      // time when ->frame will be exactly on - -  float    backlerp; - -  float    yawAngle; -  qboolean  yawing; -  float    pitchAngle; -  qboolean  pitching; - -  int      animationNumber;  // may include ANIM_TOGGLEBIT -  animation_t  *animation; -  int      animationTime;    // time when the first frame of the animation will be exact -} lerpFrame_t; - -typedef struct { -  // model info -  qhandle_t    legsModel; -  qhandle_t    legsSkin; -  lerpFrame_t    legs; - -  qhandle_t    torsoModel; -  qhandle_t    torsoSkin; -  lerpFrame_t    torso; - -  qhandle_t    headModel; -  qhandle_t    headSkin; - -  animation_t    animations[MAX_PLAYER_TOTALANIMATIONS]; - -  qhandle_t    weaponModel; -  qhandle_t    barrelModel; -  qhandle_t    flashModel; -  vec3_t      flashDlightColor; -  int        muzzleFlashTime; - -  // currently in use drawing parms -  vec3_t      viewAngles; -  vec3_t      moveAngles; -  weapon_t    currentWeapon; -  int        legsAnim; -  int        torsoAnim; - -  // animation vars -  weapon_t    weapon; -  weapon_t    lastWeapon; -  weapon_t    pendingWeapon; -  int        weaponTimer; -  int        pendingLegsAnim; -  int        torsoAnimationTimer; - -  int        pendingTorsoAnim; -  int        legsAnimationTimer; - -  qboolean    chat; -  qboolean    newModel; - -  qboolean    barrelSpinning; -  float      barrelAngle; -  int        barrelTime; - -  int        realWeapon; -} playerInfo_t; - -void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time ); -void UI_PlayerInfo_SetModel( playerInfo_t *pi, const char *model, const char *headmodel, char *teamName ); -void UI_PlayerInfo_SetInfo( playerInfo_t *pi, int legsAnim, int torsoAnim, vec3_t viewAngles, vec3_t moveAngles, weapon_t weaponNum, qboolean chat ); -qboolean UI_RegisterClientModelname( playerInfo_t *pi, const char *modelSkinName , const char *headName, const char *teamName); - -// -// ui_atoms.c -// -// this is only used in the old ui, the new ui has it's own version -typedef struct { -  int          frametime; -  int          realtime; -  int          cursorx; -  int          cursory; -  glconfig_t   glconfig; -  qboolean    debug; -  qhandle_t    whiteShader; -  qhandle_t    menuBackShader; -  qhandle_t    menuBackShader2; -  qhandle_t    menuBackNoLogoShader; -  qhandle_t    charset; -  qhandle_t    charsetProp; -  qhandle_t    charsetPropGlow; -  qhandle_t    charsetPropB; -  qhandle_t    cursor; -  qhandle_t    rb_on; -  qhandle_t    rb_off; -  float        scale; -  float        bias; -  qboolean    demoversion; -  qboolean    firstdraw; -} uiStatic_t; - - -// new ui stuff -#define UI_NUMFX 7 -#define MAX_HEADS 64 -#define MAX_ALIASES 64 -#define MAX_HEADNAME  32 -#define MAX_TEAMS 64 -#define MAX_GAMETYPES 16 -#define MAX_MAPS 128 -#define MAX_SPMAPS 16 -#define PLAYERS_PER_TEAM 5 -#define MAX_PINGREQUESTS    32 -#define MAX_ADDRESSLENGTH    64 -#define MAX_HOSTNAMELENGTH    22 -#define MAX_MAPNAMELENGTH    16 -#define MAX_STATUSLENGTH    64 -#define MAX_LISTBOXWIDTH    59 -#define UI_FONT_THRESHOLD    0.1 -#define MAX_DISPLAY_SERVERS    2048 -#define MAX_SERVERSTATUS_LINES  128 -#define MAX_SERVERSTATUS_TEXT  1024 -#define MAX_FOUNDPLAYER_SERVERS  16 -#define TEAM_MEMBERS 5 -#define GAMES_ALL      0 -#define GAMES_FFA      1 -#define GAMES_TEAMPLAY    2 -#define GAMES_TOURNEY    3 -#define GAMES_CTF      4 -#define MAPS_PER_TIER 3 -#define MAX_TIERS 16 -#define MAX_MODS 64 -#define MAX_DEMOS 256 -#define MAX_MOVIES 256 -#define MAX_PLAYERMODELS 256 - - -typedef struct { -  const char *name; -  const char *imageName; -  qhandle_t headImage; -  const char *base; -  qboolean active; -  int reference; -} characterInfo; - -typedef struct { -  const char *name; -  const char *ai; -  const char *action; -} aliasInfo; - -typedef struct { -  const char *teamName; -  const char *imageName; -  const char *teamMembers[TEAM_MEMBERS]; -  qhandle_t teamIcon; -  qhandle_t teamIcon_Metal; -  qhandle_t teamIcon_Name; -  int cinematic; -} teamInfo; - -typedef struct { -  const char *gameType; -  int gtEnum; -} gameTypeInfo; - -typedef struct { -  const char *mapName; -  const char *mapLoadName; -  const char *imageName; -  const char *opponentName; -  int teamMembers; -  int typeBits; -  int cinematic; -  int timeToBeat[MAX_GAMETYPES]; -  qhandle_t levelShot; -  qboolean active; -} mapInfo; - -typedef struct { -  const char *tierName; -  const char *maps[MAPS_PER_TIER]; -  int gameTypes[MAPS_PER_TIER]; -  qhandle_t mapHandles[MAPS_PER_TIER]; -} tierInfo; - -typedef struct serverFilter_s { -  const char *description; -  const char *basedir; -} serverFilter_t; - -typedef struct { -  char  adrstr[MAX_ADDRESSLENGTH]; -  int    start; -} pinglist_t; - - -typedef struct serverStatus_s { -  pinglist_t pingList[MAX_PINGREQUESTS]; -  int    numqueriedservers; -  int    currentping; -  int    nextpingtime; -  int    maxservers; -  int    refreshtime; -  int    numServers; -  int    sortKey; -  int    sortDir; -  int    lastCount; -  qboolean refreshActive; -  int    currentServer; -  int    displayServers[MAX_DISPLAY_SERVERS]; -  int    numDisplayServers; -  int    numPlayersOnServers; -  int    nextDisplayRefresh; -  int    nextSortTime; -  qhandle_t currentServerPreview; -  int    currentServerCinematic; -  int    motdLen; -  int    motdWidth; -  int    motdPaintX; -  int    motdPaintX2; -  int    motdOffset; -  int    motdTime; -  char  motd[MAX_STRING_CHARS]; -} serverStatus_t; - - -typedef struct { -  char    adrstr[MAX_ADDRESSLENGTH]; -  char    name[MAX_ADDRESSLENGTH]; -  int      startTime; -  int      serverNum; -  qboolean  valid; -} pendingServer_t; - -typedef struct { -  int num; -  pendingServer_t server[MAX_SERVERSTATUSREQUESTS]; -} pendingServerStatus_t; - -typedef struct { -  char address[MAX_ADDRESSLENGTH]; -  char *lines[MAX_SERVERSTATUS_LINES][4]; -  char text[MAX_SERVERSTATUS_TEXT]; -  char pings[MAX_CLIENTS * 3]; -  int numLines; -} serverStatusInfo_t; - -typedef struct { -  const char *modName; -  const char *modDescr; -} modInfo_t; - -//TA: tremulous menus -#define MAX_INFOPANE_TEXT     4096 -#define MAX_INFOPANE_GRAPHICS 16 -#define MAX_INFOPANES         128 - -typedef enum -{ -  INFOPANE_TOP, -  INFOPANE_BOTTOM, -  INFOPANE_LEFT, -  INFOPANE_RIGHT -} tremIPSide_t; - -typedef struct -{ -  qhandle_t     graphic; - -  tremIPSide_t  side; -  int           offset; - -  int           width, height; -} tremIPGraphic_t; - -typedef struct -{ -  const char      *name; -  char            text[ MAX_INFOPANE_TEXT ]; -  int             align; - -  tremIPGraphic_t graphics[ MAX_INFOPANE_GRAPHICS ]; -  int             numGraphics; -} tremInfoPane_t; - -typedef struct -{ -  const char      *text; -  const char      *cmd; -  tremInfoPane_t  *infopane; -} tremMenuItem_t; -//TA: tremulous menus - -typedef struct { -  displayContextDef_t uiDC; -  int newHighScoreTime; -  int newBestTime; -  int showPostGameTime; -  qboolean newHighScore; -  qboolean demoAvailable; -  qboolean soundHighScore; - -  int characterCount; -  int botIndex; -  characterInfo characterList[MAX_HEADS]; - -  int aliasCount; -  aliasInfo aliasList[MAX_ALIASES]; - -  int teamCount; -  teamInfo teamList[MAX_TEAMS]; - -  int numGameTypes; -  gameTypeInfo gameTypes[MAX_GAMETYPES]; - -  int numJoinGameTypes; -  gameTypeInfo joinGameTypes[MAX_GAMETYPES]; - -  int redBlue; -  int playerCount; -  int myTeamCount; -  int teamIndex; -  int playerRefresh; -  int playerIndex; -  int playerNumber; -  qboolean teamLeader; -  char playerNames[MAX_CLIENTS][MAX_NAME_LENGTH]; -  char teamNames[MAX_CLIENTS][MAX_NAME_LENGTH]; -  int teamClientNums[MAX_CLIENTS]; - -  int mapCount; -  mapInfo mapList[MAX_MAPS]; - - -  int tierCount; -  tierInfo tierList[MAX_TIERS]; - -  int skillIndex; - -  modInfo_t modList[MAX_MODS]; -  int modCount; -  int modIndex; - -  const char *demoList[MAX_DEMOS]; -  int demoCount; -  int demoIndex; - -  const char *movieList[MAX_MOVIES]; -  int movieCount; -  int movieIndex; -  int previewMovie; - -  tremInfoPane_t  tremInfoPanes[ MAX_INFOPANES ]; -  int             tremInfoPaneCount; - -//TA: tremulous menus -  tremMenuItem_t  tremTeamList[ 4 ]; -  int             tremTeamCount; -  int             tremTeamIndex; - -  tremMenuItem_t  tremAlienClassList[ 3 ]; -  int             tremAlienClassCount; -  int             tremAlienClassIndex; - -  tremMenuItem_t  tremHumanItemList[ 3 ]; -  int             tremHumanItemCount; -  int             tremHumanItemIndex; - -  tremMenuItem_t  tremHumanArmouryBuyList[ 32 ]; -  int             tremHumanArmouryBuyCount; -  int             tremHumanArmouryBuyIndex; - -  tremMenuItem_t  tremHumanArmourySellList[ 32 ]; -  int             tremHumanArmourySellCount; -  int             tremHumanArmourySellIndex; - -  tremMenuItem_t  tremAlienUpgradeList[ 16 ]; -  int             tremAlienUpgradeCount; -  int             tremAlienUpgradeIndex; - -  tremMenuItem_t  tremAlienBuildList[ 32 ]; -  int             tremAlienBuildCount; -  int             tremAlienBuildIndex; - -  tremMenuItem_t  tremHumanBuildList[ 32 ]; -  int             tremHumanBuildCount; -  int             tremHumanBuildIndex; -//TA: tremulous menus - -  serverStatus_t serverStatus; - -  // for the showing the status of a server -  char serverStatusAddress[MAX_ADDRESSLENGTH]; -  serverStatusInfo_t serverStatusInfo; -  int nextServerStatusRefresh; - -  // to retrieve the status of server to find a player -  pendingServerStatus_t pendingServerStatus; -  char findPlayerName[MAX_STRING_CHARS]; -  char foundPlayerServerAddresses[MAX_FOUNDPLAYER_SERVERS][MAX_ADDRESSLENGTH]; -  char foundPlayerServerNames[MAX_FOUNDPLAYER_SERVERS][MAX_ADDRESSLENGTH]; -  int currentFoundPlayerServer; -  int numFoundPlayerServers; -  int nextFindPlayerRefresh; - -  int currentCrosshair; -  int startPostGameTime; -  sfxHandle_t newHighScoreSound; - -  int        q3HeadCount; -  char      q3HeadNames[MAX_PLAYERMODELS][64]; -  qhandle_t  q3HeadIcons[MAX_PLAYERMODELS]; -  int        q3SelectedHead; - -  int effectsColor; - -  qboolean inGameLoad; -}  uiInfo_t; - -extern uiInfo_t uiInfo; - - -extern void      UI_Init( void ); -extern void      UI_Shutdown( void ); -extern void      UI_KeyEvent( int key ); -extern void      UI_MouseEvent( int dx, int dy ); -extern void      UI_Refresh( int realtime ); -extern qboolean    UI_ConsoleCommand( int realTime ); -extern float    UI_ClampCvar( float min, float max, float value ); -extern void      UI_DrawNamedPic( float x, float y, float width, float height, const char *picname ); -extern void      UI_DrawHandlePic( float x, float y, float w, float h, qhandle_t hShader ); -extern void      UI_FillRect( float x, float y, float width, float height, const float *color ); -extern void      UI_DrawRect( float x, float y, float width, float height, const float *color ); -extern void     UI_DrawTopBottom(float x, float y, float w, float h); -extern void     UI_DrawSides(float x, float y, float w, float h); -extern void      UI_UpdateScreen( void ); -extern void      UI_SetColor( const float *rgba ); -extern void      UI_LerpColor(vec4_t a, vec4_t b, vec4_t c, float t); -extern void      UI_DrawBannerString( int x, int y, const char* str, int style, vec4_t color ); -extern float    UI_ProportionalSizeScale( int style ); -extern void      UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t color ); -extern int      UI_ProportionalStringWidth( const char* str ); -extern void      UI_DrawString( int x, int y, const char* str, int style, vec4_t color ); -extern void      UI_DrawChar( int x, int y, int ch, int style, vec4_t color ); -extern qboolean   UI_CursorInRect (int x, int y, int width, int height); -extern void      UI_AdjustFrom640( float *x, float *y, float *w, float *h ); -extern void      UI_DrawTextBox (int x, int y, int width, int lines); -extern qboolean    UI_IsFullscreen( void ); -extern void      UI_SetActiveMenu( uiMenuCommand_t menu ); -extern void      UI_PushMenu ( menuframework_s *menu ); -extern void      UI_PopMenu (void); -extern void      UI_ForceMenuOff (void); -extern char      *UI_Argv( int arg ); -extern char      *UI_Cvar_VariableString( const char *var_name ); -extern void      UI_Refresh( int time ); -extern void      UI_KeyEvent( int key ); -extern void      UI_StartDemoLoop( void ); -extern qboolean    m_entersound; -void UI_LoadBestScores(const char *map, int game); -extern uiStatic_t  uis; - -// -// ui_spLevel.c -// -void UI_SPLevelMenu_Cache( void ); -void UI_SPLevelMenu( void ); -void UI_SPLevelMenu_f( void ); -void UI_SPLevelMenu_ReInit( void ); - -// -// ui_spArena.c -// -void UI_SPArena_Start( const char *arenaInfo ); - -// -// ui_spPostgame.c -// -void UI_SPPostgameMenu_Cache( void ); -void UI_SPPostgameMenu_f( void ); - -// -// ui_spSkill.c -// -void UI_SPSkillMenu( const char *arenaInfo ); -void UI_SPSkillMenu_Cache( void ); - -// -// ui_syscalls.c -// -void      trap_Print( const char *string ); -void      trap_Error( const char *string ); -int        trap_Milliseconds( void ); -void      trap_Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags ); -void      trap_Cvar_Update( vmCvar_t *vmCvar ); -void      trap_Cvar_Set( const char *var_name, const char *value ); -float      trap_Cvar_VariableValue( const char *var_name ); -void      trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ); -void      trap_Cvar_SetValue( const char *var_name, float value ); -void      trap_Cvar_Reset( const char *name ); -void      trap_Cvar_Create( const char *var_name, const char *var_value, int flags ); -void      trap_Cvar_InfoStringBuffer( int bit, char *buffer, int bufsize ); -int        trap_Argc( void ); -void      trap_Argv( int n, char *buffer, int bufferLength ); -void      trap_Cmd_ExecuteText( int exec_when, const char *text );  // don't use EXEC_NOW! -int        trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode ); -void      trap_FS_Read( void *buffer, int len, fileHandle_t f ); -void      trap_FS_Write( const void *buffer, int len, fileHandle_t f ); -void      trap_FS_FCloseFile( fileHandle_t f ); -int        trap_FS_GetFileList(  const char *path, const char *extension, char *listbuf, int bufsize ); -int       trap_FS_Seek( fileHandle_t f, long offset, int origin ); // fsOrigin_t -qhandle_t    trap_R_RegisterModel( const char *name ); -qhandle_t    trap_R_RegisterSkin( const char *name ); -qhandle_t    trap_R_RegisterShaderNoMip( const char *name ); -void      trap_R_ClearScene( void ); -void      trap_R_AddRefEntityToScene( const refEntity_t *re ); -void      trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts ); -void      trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b ); -void      trap_R_RenderScene( const refdef_t *fd ); -void      trap_R_SetColor( const float *rgba ); -void      trap_R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader ); -void      trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs ); -void      trap_UpdateScreen( void ); -int        trap_CM_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, float frac, const char *tagName ); -void      trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum ); -sfxHandle_t    trap_S_RegisterSound( const char *sample, qboolean compressed ); -void      trap_Key_KeynumToStringBuf( int keynum, char *buf, int buflen ); -void      trap_Key_GetBindingBuf( int keynum, char *buf, int buflen ); -void      trap_Key_SetBinding( int keynum, const char *binding ); -qboolean    trap_Key_IsDown( int keynum ); -qboolean    trap_Key_GetOverstrikeMode( void ); -void      trap_Key_SetOverstrikeMode( qboolean state ); -void      trap_Key_ClearStates( void ); -int        trap_Key_GetCatcher( void ); -void      trap_Key_SetCatcher( int catcher ); -void      trap_GetClipboardData( char *buf, int bufsize ); -void      trap_GetClientState( uiClientState_t *state ); -void      trap_GetGlconfig( glconfig_t *glconfig ); -int        trap_GetConfigString( int index, char* buff, int buffsize ); -int        trap_LAN_GetServerCount( int source ); -void      trap_LAN_GetServerAddressString( int source, int n, char *buf, int buflen ); -void      trap_LAN_GetServerInfo( int source, int n, char *buf, int buflen ); -int        trap_LAN_GetServerPing( int source, int n ); -int        trap_LAN_GetPingQueueCount( void ); -void      trap_LAN_ClearPing( int n ); -void      trap_LAN_GetPing( int n, char *buf, int buflen, int *pingtime ); -void      trap_LAN_GetPingInfo( int n, char *buf, int buflen ); -void      trap_LAN_LoadCachedServers( void ); -void      trap_LAN_SaveCachedServers( void ); -void      trap_LAN_MarkServerVisible(int source, int n, qboolean visible); -int        trap_LAN_ServerIsVisible( int source, int n); -qboolean    trap_LAN_UpdateVisiblePings( int source ); -int        trap_LAN_AddServer(int source, const char *name, const char *addr); -void      trap_LAN_RemoveServer(int source, const char *addr); -void      trap_LAN_ResetPings(int n); -int        trap_LAN_ServerStatus( const char *serverAddress, char *serverStatus, int maxLen ); -int        trap_LAN_CompareServers( int source, int sortKey, int sortDir, int s1, int s2 ); -int        trap_MemoryRemaining( void ); -void      trap_GetCDKey( char *buf, int buflen ); -void      trap_SetCDKey( char *buf ); -void      trap_R_RegisterFont(const char *pFontname, int pointSize, fontInfo_t *font); -void      trap_S_StopBackgroundTrack( void ); -void      trap_S_StartBackgroundTrack( const char *intro, const char *loop); -int        trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits); -e_status    trap_CIN_StopCinematic(int handle); -e_status    trap_CIN_RunCinematic (int handle); -void      trap_CIN_DrawCinematic (int handle); -void      trap_CIN_SetExtents (int handle, int x, int y, int w, int h); -int        trap_RealTime(qtime_t *qtime); -void      trap_R_RemapShader( const char *oldShader, const char *newShader, const char *timeOffset ); -qboolean    trap_VerifyCDKey( const char *key, const char *chksum); - -void      trap_SetPbClStatus( int status ); - -// -// ui_addbots.c -// -void UI_AddBots_Cache( void ); -void UI_AddBotsMenu( void ); - -// -// ui_removebots.c -// -void UI_RemoveBots_Cache( void ); -void UI_RemoveBotsMenu( void ); - -// -// ui_teamorders.c -// -extern void UI_TeamOrdersMenu( void ); -extern void UI_TeamOrdersMenu_f( void ); -extern void UI_TeamOrdersMenu_Cache( void ); - -// -// ui_loadconfig.c -// -void UI_LoadConfig_Cache( void ); -void UI_LoadConfigMenu( void ); - -// -// ui_saveconfig.c -// -void UI_SaveConfigMenu_Cache( void ); -void UI_SaveConfigMenu( void ); - -// -// ui_display.c -// -void UI_DisplayOptionsMenu_Cache( void ); -void UI_DisplayOptionsMenu( void ); - -// -// ui_sound.c -// -void UI_SoundOptionsMenu_Cache( void ); -void UI_SoundOptionsMenu( void ); - -// -// ui_network.c -// -void UI_NetworkOptionsMenu_Cache( void ); -void UI_NetworkOptionsMenu( void ); - -// -// ui_gameinfo.c -// -typedef enum { -  AWARD_ACCURACY, -  AWARD_IMPRESSIVE, -  AWARD_EXCELLENT, -  AWARD_GAUNTLET, -  AWARD_FRAGS, -  AWARD_PERFECT -} awardType_t; - -const char *UI_GetArenaInfoByNumber( int num ); -const char *UI_GetArenaInfoByMap( const char *map ); -const char *UI_GetSpecialArenaInfo( const char *tag ); -int UI_GetNumArenas( void ); -int UI_GetNumSPArenas( void ); -int UI_GetNumSPTiers( void ); - -char *UI_GetBotInfoByNumber( int num ); -char *UI_GetBotInfoByName( const char *name ); -int UI_GetNumBots( void ); -void UI_LoadBots( void ); -char *UI_GetBotNameByNumber( int num ); - -void UI_GetBestScore( int level, int *score, int *skill ); -void UI_SetBestScore( int level, int score ); -int UI_TierCompleted( int levelWon ); -qboolean UI_ShowTierVideo( int tier ); -qboolean UI_CanShowTierVideo( int tier ); -int  UI_GetCurrentGame( void ); -void UI_NewGame( void ); -void UI_LogAwardData( int award, int data ); -int UI_GetAwardLevel( int award ); - -void UI_SPUnlock_f( void ); -void UI_SPUnlockMedals_f( void ); - -void UI_InitGameinfo( void ); - -// -// ui_login.c -// -void Login_Cache( void ); -void UI_LoginMenu( void ); - -// -// ui_signup.c -// -void Signup_Cache( void ); -void UI_SignupMenu( void ); - -// -// ui_rankstatus.c -// -void RankStatus_Cache( void ); -void UI_RankStatusMenu( void ); - - -// new ui - -#define ASSET_BACKGROUND "uiBackground" - -// for tracking sp game info in Team Arena -typedef struct postGameInfo_s { -  int score; -  int redScore; -  int blueScore; -  int perfects; -  int accuracy; -  int impressives; -  int excellents; -  int defends; -  int assists; -  int gauntlets; -  int  captures; -  int time; -  int timeBonus; -  int shutoutBonus; -  int skillBonus; -  int baseScore; -} postGameInfo_t; - - - -#endif diff --git a/mod/src/ui/ui_main.c b/mod/src/ui/ui_main.c deleted file mode 100644 index 80a5bdb4..00000000 --- a/mod/src/ui/ui_main.c +++ /dev/null @@ -1,6553 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -/* -======================================================================= - -USER INTERFACE MAIN - -======================================================================= -*/ - -// use this to get a demo build without an explicit demo build, i.e. to get the demo ui files to build -//#define PRE_RELEASE_TADEMO - -#include "ui_local.h" - -uiInfo_t uiInfo; - -static const char *MonthAbbrev[] = { -  "Jan","Feb","Mar", -  "Apr","May","Jun", -  "Jul","Aug","Sep", -  "Oct","Nov","Dec" -}; - - -static const char *skillLevels[] = { -  "I Can Win", -  "Bring It On", -  "Hurt Me Plenty", -  "Hardcore", -  "Nightmare" -}; - -static const int numSkillLevels = sizeof(skillLevels) / sizeof(const char*); - - -static const char *netSources[] = { -  "Local", -  "Mplayer", -  "Internet", -  "Favorites" -}; -static const int numNetSources = sizeof(netSources) / sizeof(const char*); - -static const serverFilter_t serverFilters[] = { -  {"All", "" }, -  {"Quake 3 Arena", "" }, -  {"Team Arena", "missionpack" }, -  {"Rocket Arena", "arena" }, -  {"Alliance", "alliance20" }, -  {"Weapons Factory Arena", "wfa" }, -  {"OSP", "osp" }, -}; - -static const char *teamArenaGameTypes[] = { -  "FFA", -  "TOURNAMENT", -  "SP", -  "TEAM DM", -  "CTF", -  "1FCTF", -  "OVERLOAD", -  "HARVESTER", -  "TEAMTOURNAMENT" -}; - -static int const numTeamArenaGameTypes = sizeof(teamArenaGameTypes) / sizeof(const char*); - - -static const char *teamArenaGameNames[] = { -  "Free For All", -  "Tournament", -  "Single Player", -  "Team Deathmatch", -  "Capture the Flag", -  "One Flag CTF", -  "Overload", -  "Harvester", -  "Team Tournament", -}; - -static int const numTeamArenaGameNames = sizeof(teamArenaGameNames) / sizeof(const char*); - - -static const int numServerFilters = sizeof(serverFilters) / sizeof(serverFilter_t); - -static const char *sortKeys[] = { -  "Server Name", -  "Map Name", -  "Open Player Spots", -  "Game Type", -  "Ping Time" -}; -static const int numSortKeys = sizeof(sortKeys) / sizeof(const char*); - -static char* netnames[] = { -  "???", -  "UDP", -  "IPX", -  NULL -}; - -static int gamecodetoui[] = {4,2,3,0,5,1,6}; - - -static void UI_StartServerRefresh(qboolean full); -static void UI_StopServerRefresh( void ); -static void UI_DoServerRefresh( void ); -static void UI_FeederSelection(float feederID, int index); -static void UI_BuildServerDisplayList(qboolean force); -static void UI_BuildServerStatus(qboolean force); -static void UI_BuildFindPlayerList(qboolean force); -static int QDECL UI_ServersQsortCompare( const void *arg1, const void *arg2 ); -static int UI_MapCountByGameType(qboolean singlePlayer); -static int UI_HeadCountByTeam( void ); -static const char *UI_SelectedMap(int index, int *actual); -static const char *UI_SelectedHead(int index, int *actual); -static int UI_GetIndexFromSelection(int actual); - -int ProcessNewUI( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6 ); - -/* -================ -vmMain - -This is the only way control passes into the module. -This must be the very first function compiled into the .qvm file -================ -*/ -vmCvar_t  ui_new; -vmCvar_t  ui_debug; -vmCvar_t  ui_initialized; -vmCvar_t  ui_teamArenaFirstRun; - -void _UI_Init( qboolean ); -void _UI_Shutdown( void ); -void _UI_KeyEvent( int key, qboolean down ); -void _UI_MouseEvent( int dx, int dy ); -void _UI_Refresh( int realtime ); -qboolean _UI_IsFullscreen( void ); -long vmMain( long command, long arg0, long arg1, long arg2, long arg3, -                           long arg4, long arg5, long arg6, long arg7, -                           long arg8, long arg9, long arg10, long arg11  ) { -  switch ( command ) { -    case UI_GETAPIVERSION: -      return UI_API_VERSION; - -    case UI_INIT: -      _UI_Init(arg0); -      return 0; - -    case UI_SHUTDOWN: -      _UI_Shutdown(); -      return 0; - -    case UI_KEY_EVENT: -      _UI_KeyEvent( arg0, arg1 ); -      return 0; - -    case UI_MOUSE_EVENT: -      _UI_MouseEvent( arg0, arg1 ); -      return 0; - -    case UI_REFRESH: -      _UI_Refresh( arg0 ); -      return 0; - -    case UI_IS_FULLSCREEN: -      return _UI_IsFullscreen(); - -    case UI_SET_ACTIVE_MENU: -      _UI_SetActiveMenu( arg0 ); -      return 0; - -    case UI_CONSOLE_COMMAND: -      return UI_ConsoleCommand(arg0); - -    case UI_DRAW_CONNECT_SCREEN: -      UI_DrawConnectScreen( arg0 ); -      return 0; -    case UI_HASUNIQUECDKEY: // mod authors need to observe this -      return qfalse; // bk010117 - change this to qfalse for mods! - -  } - -  return -1; -} - - - -void AssetCache( void ) { -  uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( ASSET_GRADIENTBAR ); -  uiInfo.uiDC.Assets.scrollBar = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR ); -  uiInfo.uiDC.Assets.scrollBarArrowDown = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWDOWN ); -  uiInfo.uiDC.Assets.scrollBarArrowUp = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWUP ); -  uiInfo.uiDC.Assets.scrollBarArrowLeft = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWLEFT ); -  uiInfo.uiDC.Assets.scrollBarArrowRight = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWRIGHT ); -  uiInfo.uiDC.Assets.scrollBarThumb = trap_R_RegisterShaderNoMip( ASSET_SCROLL_THUMB ); -  uiInfo.uiDC.Assets.sliderBar = trap_R_RegisterShaderNoMip( ASSET_SLIDER_BAR ); -  uiInfo.uiDC.Assets.sliderThumb = trap_R_RegisterShaderNoMip( ASSET_SLIDER_THUMB ); -} - -void _UI_DrawSides(float x, float y, float w, float h, float size) { -  UI_AdjustFrom640( &x, &y, &w, &h ); -  size *= uiInfo.uiDC.xscale; -  trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader ); -  trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader ); -} - -void _UI_DrawTopBottom(float x, float y, float w, float h, float size) { -  UI_AdjustFrom640( &x, &y, &w, &h ); -  size *= uiInfo.uiDC.yscale; -  trap_R_DrawStretchPic( x, y, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader ); -  trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader ); -} -/* -================ -UI_DrawRect - -Coordinates are 640*480 virtual values -================= -*/ -void _UI_DrawRect( float x, float y, float width, float height, float size, const float *color ) { -  trap_R_SetColor( color ); - -  _UI_DrawTopBottom(x, y, width, height, size); -  _UI_DrawSides(x, y, width, height, size); - -  trap_R_SetColor( NULL ); -} - - - - -int Text_Width(const char *text, float scale, int limit) { -  int count,len; -  float out; -  glyphInfo_t *glyph; -  float useScale; -  const char *s = text; -  fontInfo_t *font = &uiInfo.uiDC.Assets.textFont; -  if (scale <= ui_smallFont.value) { -    font = &uiInfo.uiDC.Assets.smallFont; -  } else if (scale >= ui_bigFont.value) { -    font = &uiInfo.uiDC.Assets.bigFont; -  } -  useScale = scale * font->glyphScale; -  out = 0; -  if (text) { -    len = strlen(text); -    if (limit > 0 && len > limit) { -      len = limit; -    } -    count = 0; -    while (s && *s && count < len) { -      if ( Q_IsColorString(s) ) { -        s += 2; -        continue; -      } else { -        glyph = &font->glyphs[(int)*s]; -        out += glyph->xSkip; -        s++; -        count++; -      } -    } -  } -  return out * useScale; -} - -int Text_Height(const char *text, float scale, int limit) { -  int len, count; -  float max; -  glyphInfo_t *glyph; -  float useScale; -  const char *s = text; // bk001206 - unsigned -  fontInfo_t *font = &uiInfo.uiDC.Assets.textFont; -  if (scale <= ui_smallFont.value) { -    font = &uiInfo.uiDC.Assets.smallFont; -  } else if (scale >= ui_bigFont.value) { -    font = &uiInfo.uiDC.Assets.bigFont; -  } -  useScale = scale * font->glyphScale; -  max = 0; -  if (text) { -    len = strlen(text); -    if (limit > 0 && len > limit) { -      len = limit; -    } -    count = 0; -    while (s && *s && count < len) { -      if ( Q_IsColorString(s) ) { -        s += 2; -        continue; -      } else { -        glyph = &font->glyphs[(int)*s]; -        if (max < glyph->height) { -          max = glyph->height; -        } -        s++; -        count++; -      } -    } -  } -  return max * useScale; -} - -void Text_PaintChar(float x, float y, float width, float height, float scale, float s, float t, float s2, float t2, qhandle_t hShader) { -  float w, h; -  w = width * scale; -  h = height * scale; -  UI_AdjustFrom640( &x, &y, &w, &h ); -  trap_R_DrawStretchPic( x, y, w, h, s, t, s2, t2, hShader ); -} - -void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style) { -  int len, count; -  vec4_t newColor; -  glyphInfo_t *glyph; -  float useScale; -  fontInfo_t *font = &uiInfo.uiDC.Assets.textFont; -  if (scale <= ui_smallFont.value) { -    font = &uiInfo.uiDC.Assets.smallFont; -  } else if (scale >= ui_bigFont.value) { -    font = &uiInfo.uiDC.Assets.bigFont; -  } -  useScale = scale * font->glyphScale; -  if (text) { -    const char *s = text; // bk001206 - unsigned -    trap_R_SetColor( color ); -    memcpy(&newColor[0], &color[0], sizeof(vec4_t)); -    len = strlen(text); -    if (limit > 0 && len > limit) { -      len = limit; -    } -    count = 0; -    while (s && *s && count < len) { -      glyph = &font->glyphs[(int)*s]; -      //int yadj = Assets.textFont.glyphs[text[i]].bottom + Assets.textFont.glyphs[text[i]].top; -      //float yadj = scale * (Assets.textFont.glyphs[text[i]].imageHeight - Assets.textFont.glyphs[text[i]].height); -      if ( Q_IsColorString( s ) ) { -        memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) ); -        newColor[3] = color[3]; -        trap_R_SetColor( newColor ); -        s += 2; -        continue; -      } else { -        float yadj = useScale * glyph->top; -        if (style == ITEM_TEXTSTYLE_SHADOWED || style == ITEM_TEXTSTYLE_SHADOWEDMORE) { -          int ofs = style == ITEM_TEXTSTYLE_SHADOWED ? 1 : 2; -          colorBlack[3] = newColor[3]; -          trap_R_SetColor( colorBlack ); -          Text_PaintChar(x + ofs, y - yadj + ofs, -                            glyph->imageWidth, -                            glyph->imageHeight, -                            useScale, -                            glyph->s, -                            glyph->t, -                            glyph->s2, -                            glyph->t2, -                            glyph->glyph); -          trap_R_SetColor( newColor ); -          colorBlack[3] = 1.0; -        } -        else if( style == ITEM_TEXTSTYLE_NEON ) -        { -          vec4_t glow, outer, inner, white; - -          glow[ 0 ] = newColor[ 0 ] * 0.5; -          glow[ 1 ] = newColor[ 1 ] * 0.5; -          glow[ 2 ] = newColor[ 2 ] * 0.5; -          glow[ 3 ] = newColor[ 3 ] * 0.2; - -          outer[ 0 ] = newColor[ 0 ]; -          outer[ 1 ] = newColor[ 1 ]; -          outer[ 2 ] = newColor[ 2 ]; -          outer[ 3 ] = newColor[ 3 ]; - -          inner[ 0 ] = newColor[ 0 ] * 1.5 > 1.0f ? 1.0f : newColor[ 0 ] * 1.5; -          inner[ 1 ] = newColor[ 1 ] * 1.5 > 1.0f ? 1.0f : newColor[ 1 ] * 1.5; -          inner[ 2 ] = newColor[ 2 ] * 1.5 > 1.0f ? 1.0f : newColor[ 2 ] * 1.5; -          inner[ 3 ] = newColor[ 3 ]; - -          white[ 0 ] = white[ 1 ] = white[ 2 ] = white[ 3 ] = 1.0f; - -          trap_R_SetColor( glow ); -          Text_PaintChar( x - 1.5, y - yadj - 1.5, -                          glyph->imageWidth + 3, -                          glyph->imageHeight + 3, -                          useScale, -                          glyph->s, -                          glyph->t, -                          glyph->s2, -                          glyph->t2, -                          glyph->glyph ); - -          trap_R_SetColor( outer ); -          Text_PaintChar( x - 1, y - yadj - 1, -                          glyph->imageWidth + 2, -                          glyph->imageHeight + 2, -                          useScale, -                          glyph->s, -                          glyph->t, -                          glyph->s2, -                          glyph->t2, -                          glyph->glyph ); - -          trap_R_SetColor( inner ); -          Text_PaintChar( x - 0.5, y - yadj - 0.5, -                          glyph->imageWidth + 1, -                          glyph->imageHeight + 1, -                          useScale, -                          glyph->s, -                          glyph->t, -                          glyph->s2, -                          glyph->t2, -                          glyph->glyph ); - -          trap_R_SetColor( white ); -        } - -        Text_PaintChar(x, y - yadj, -                          glyph->imageWidth, -                          glyph->imageHeight, -                          useScale, -                          glyph->s, -                          glyph->t, -                          glyph->s2, -                          glyph->t2, -                          glyph->glyph); - -        x += (glyph->xSkip * useScale) + adjust; -        s++; -        count++; -      } -    } -    trap_R_SetColor( NULL ); -  } -} - -void Text_PaintWithCursor(float x, float y, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int limit, int style) { -  int len, count; -  vec4_t newColor; -  glyphInfo_t *glyph, *glyph2; -  float yadj; -  float useScale; -  fontInfo_t *font = &uiInfo.uiDC.Assets.textFont; -  if (scale <= ui_smallFont.value) { -    font = &uiInfo.uiDC.Assets.smallFont; -  } else if (scale >= ui_bigFont.value) { -    font = &uiInfo.uiDC.Assets.bigFont; -  } -  useScale = scale * font->glyphScale; -  if (text) { -    const char *s = text; // bk001206 - unsigned -    trap_R_SetColor( color ); -    memcpy(&newColor[0], &color[0], sizeof(vec4_t)); -    len = strlen(text); -    if (limit > 0 && len > limit) { -      len = limit; -    } -    count = 0; -    glyph2 = &font->glyphs[ (int) cursor]; // bk001206 - possible signed char -    while (s && *s && count < len) { -      glyph = &font->glyphs[(int)*s]; -      if ( Q_IsColorString( s ) ) { -        memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) ); -        newColor[3] = color[3]; -        trap_R_SetColor( newColor ); -        s += 2; -        continue; -      } else { -        yadj = useScale * glyph->top; -        if (style == ITEM_TEXTSTYLE_SHADOWED || style == ITEM_TEXTSTYLE_SHADOWEDMORE) { -          int ofs = style == ITEM_TEXTSTYLE_SHADOWED ? 1 : 2; -          colorBlack[3] = newColor[3]; -          trap_R_SetColor( colorBlack ); -          Text_PaintChar(x + ofs, y - yadj + ofs, -                            glyph->imageWidth, -                            glyph->imageHeight, -                            useScale, -                            glyph->s, -                            glyph->t, -                            glyph->s2, -                            glyph->t2, -                            glyph->glyph); -          colorBlack[3] = 1.0; -          trap_R_SetColor( newColor ); -        } -        else if( style == ITEM_TEXTSTYLE_NEON ) -        { -          vec4_t glow, outer, inner, white; - -          glow[ 0 ] = newColor[ 0 ] * 0.5; -          glow[ 1 ] = newColor[ 1 ] * 0.5; -          glow[ 2 ] = newColor[ 2 ] * 0.5; -          glow[ 3 ] = newColor[ 3 ] * 0.2; - -          outer[ 0 ] = newColor[ 0 ]; -          outer[ 1 ] = newColor[ 1 ]; -          outer[ 2 ] = newColor[ 2 ]; -          outer[ 3 ] = newColor[ 3 ]; - -          inner[ 0 ] = newColor[ 0 ] * 1.5 > 1.0f ? 1.0f : newColor[ 0 ] * 1.5; -          inner[ 1 ] = newColor[ 1 ] * 1.5 > 1.0f ? 1.0f : newColor[ 1 ] * 1.5; -          inner[ 2 ] = newColor[ 2 ] * 1.5 > 1.0f ? 1.0f : newColor[ 2 ] * 1.5; -          inner[ 3 ] = newColor[ 3 ]; - -          white[ 0 ] = white[ 1 ] = white[ 2 ] = white[ 3 ] = 1.0f; - -          trap_R_SetColor( glow ); -          Text_PaintChar( x - 1.5, y - yadj - 1.5, -                          glyph->imageWidth + 3, -                          glyph->imageHeight + 3, -                          useScale, -                          glyph->s, -                          glyph->t, -                          glyph->s2, -                          glyph->t2, -                          glyph->glyph ); - -          trap_R_SetColor( outer ); -          Text_PaintChar( x - 1, y - yadj - 1, -                          glyph->imageWidth + 2, -                          glyph->imageHeight + 2, -                          useScale, -                          glyph->s, -                          glyph->t, -                          glyph->s2, -                          glyph->t2, -                          glyph->glyph ); - -          trap_R_SetColor( inner ); -          Text_PaintChar( x - 0.5, y - yadj - 0.5, -                          glyph->imageWidth + 1, -                          glyph->imageHeight + 1, -                          useScale, -                          glyph->s, -                          glyph->t, -                          glyph->s2, -                          glyph->t2, -                          glyph->glyph ); - -          trap_R_SetColor( white ); -        } - -        Text_PaintChar(x, y - yadj, -                          glyph->imageWidth, -                          glyph->imageHeight, -                          useScale, -                          glyph->s, -                          glyph->t, -                          glyph->s2, -                          glyph->t2, -                          glyph->glyph); - -        // CG_DrawPic(x, y - yadj, scale * uiDC.Assets.textFont.glyphs[text[i]].imageWidth, scale * uiDC.Assets.textFont.glyphs[text[i]].imageHeight, uiDC.Assets.textFont.glyphs[text[i]].glyph); -        yadj = useScale * glyph2->top; -        if (count == cursorPos && !((uiInfo.uiDC.realTime/BLINK_DIVISOR) & 1)) { -          Text_PaintChar(x, y - yadj, -                            glyph2->imageWidth, -                            glyph2->imageHeight, -                            useScale, -                            glyph2->s, -                            glyph2->t, -                            glyph2->s2, -                            glyph2->t2, -                            glyph2->glyph); -        } - -        x += (glyph->xSkip * useScale); -        s++; -        count++; -      } -    } -    // need to paint cursor at end of text -    if (cursorPos == len && !((uiInfo.uiDC.realTime/BLINK_DIVISOR) & 1)) { -        yadj = useScale * glyph2->top; -        Text_PaintChar(x, y - yadj, -                          glyph2->imageWidth, -                          glyph2->imageHeight, -                          useScale, -                          glyph2->s, -                          glyph2->t, -                          glyph2->s2, -                          glyph2->t2, -                          glyph2->glyph); - -    } - - -    trap_R_SetColor( NULL ); -  } -} - - -static void Text_Paint_Limit(float *maxX, float x, float y, float scale, vec4_t color, const char* text, float adjust, int limit) { -  int len, count; -  vec4_t newColor; -  glyphInfo_t *glyph; -  if (text) { -    const char *s = text; // bk001206 - unsigned -    float max = *maxX; -    float useScale; -    fontInfo_t *font = &uiInfo.uiDC.Assets.textFont; -    if (scale <= ui_smallFont.value) { -      font = &uiInfo.uiDC.Assets.smallFont; -    } else if (scale > ui_bigFont.value) { -      font = &uiInfo.uiDC.Assets.bigFont; -    } -    useScale = scale * font->glyphScale; -    trap_R_SetColor( color ); -    len = strlen(text); -    if (limit > 0 && len > limit) { -      len = limit; -    } -    count = 0; -    while (s && *s && count < len) { -      glyph = &font->glyphs[(int)*s]; -      if ( Q_IsColorString( s ) ) { -        memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) ); -        newColor[3] = color[3]; -        trap_R_SetColor( newColor ); -        s += 2; -        continue; -      } else { -        float yadj = useScale * glyph->top; -        if (Text_Width(s, useScale, 1) + x > max) { -          *maxX = 0; -          break; -        } -        Text_PaintChar(x, y - yadj, -                       glyph->imageWidth, -                       glyph->imageHeight, -                       useScale, -                       glyph->s, -                       glyph->t, -                       glyph->s2, -                       glyph->t2, -                       glyph->glyph); -        x += (glyph->xSkip * useScale) + adjust; -        *maxX = x; -        count++; -        s++; -      } -    } -    trap_R_SetColor( NULL ); -  } - -} - - -void UI_ShowPostGame(qboolean newHigh) { -  trap_Cvar_Set ("cg_cameraOrbit", "0"); -  trap_Cvar_Set("cg_thirdPerson", "0"); -  trap_Cvar_Set( "sv_killserver", "1" ); -  uiInfo.soundHighScore = newHigh; -  _UI_SetActiveMenu(UIMENU_POSTGAME); -} -/* -================= -_UI_Refresh -================= -*/ - -void UI_DrawCenteredPic(qhandle_t image, int w, int h) { -  int x, y; -  x = (SCREEN_WIDTH - w) / 2; -  y = (SCREEN_HEIGHT - h) / 2; -  UI_DrawHandlePic(x, y, w, h, image); -} - -int frameCount = 0; -int startTime; - -#define UI_FPS_FRAMES 4 -void _UI_Refresh( int realtime ) -{ -  static int index; -  static int  previousTimes[UI_FPS_FRAMES]; - -  //if ( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) { -  //  return; -  //} - -  uiInfo.uiDC.frameTime = realtime - uiInfo.uiDC.realTime; -  uiInfo.uiDC.realTime = realtime; - -  previousTimes[index % UI_FPS_FRAMES] = uiInfo.uiDC.frameTime; -  index++; -  if ( index > UI_FPS_FRAMES ) { -    int i, total; -    // average multiple frames together to smooth changes out a bit -    total = 0; -    for ( i = 0 ; i < UI_FPS_FRAMES ; i++ ) { -      total += previousTimes[i]; -    } -    if ( !total ) { -      total = 1; -    } -    uiInfo.uiDC.FPS = 1000 * UI_FPS_FRAMES / total; -  } - - - -  UI_UpdateCvars(); - -  if (Menu_Count() > 0) { -    // paint all the menus -    Menu_PaintAll(); -    // refresh server browser list -    UI_DoServerRefresh(); -    // refresh server status -    UI_BuildServerStatus(qfalse); -    // refresh find player list -    UI_BuildFindPlayerList(qfalse); -  } - -  // draw cursor -  UI_SetColor( NULL ); - -  //TA: don't draw the cursor whilst loading -  if( Menu_Count( ) > 0 && !trap_Cvar_VariableValue( "ui_loading" ) ) -    UI_DrawHandlePic( uiInfo.uiDC.cursorx-16, uiInfo.uiDC.cursory-16, 32, 32, uiInfo.uiDC.Assets.cursor); - -#ifndef NDEBUG -  if (uiInfo.uiDC.debug) -  { -    // cursor coordinates -    //FIXME -    //UI_DrawString( 0, 0, va("(%d,%d)",uis.cursorx,uis.cursory), UI_LEFT|UI_SMALLFONT, colorRed ); -  } -#endif - -} - -/* -================= -_UI_Shutdown -================= -*/ -void _UI_Shutdown( void ) { -  trap_LAN_SaveCachedServers(); -} - -char *defaultMenu = NULL; - -char *GetMenuBuffer(const char *filename) { -  int len; -  fileHandle_t  f; -  static char buf[MAX_MENUFILE]; - -  len = trap_FS_FOpenFile( filename, &f, FS_READ ); -  if ( !f ) { -    trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) ); -    return defaultMenu; -  } -  if ( len >= MAX_MENUFILE ) { -    trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE ) ); -    trap_FS_FCloseFile( f ); -    return defaultMenu; -  } - -  trap_FS_Read( buf, len, f ); -  buf[len] = 0; -  trap_FS_FCloseFile( f ); -  //COM_Compress(buf); -  return buf; - -} - -qboolean Asset_Parse(int handle) { -  pc_token_t token; -  const char *tempStr; - -  if (!trap_PC_ReadToken(handle, &token)) -    return qfalse; -  if (Q_stricmp(token.string, "{") != 0) { -    return qfalse; -  } - -  while ( 1 ) { - -    memset(&token, 0, sizeof(pc_token_t)); - -    if (!trap_PC_ReadToken(handle, &token)) -      return qfalse; - -    if (Q_stricmp(token.string, "}") == 0) { -      return qtrue; -    } - -    // font -    if (Q_stricmp(token.string, "font") == 0) { -      int pointSize; -      if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle,&pointSize)) { -        return qfalse; -      } -      trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.textFont); -      uiInfo.uiDC.Assets.fontRegistered = qtrue; -      continue; -    } - -    if (Q_stricmp(token.string, "smallFont") == 0) { -      int pointSize; -      if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle,&pointSize)) { -        return qfalse; -      } -      trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.smallFont); -      continue; -    } - -    if (Q_stricmp(token.string, "bigFont") == 0) { -      int pointSize; -      if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle,&pointSize)) { -        return qfalse; -      } -      trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.bigFont); -      continue; -    } - - -    // gradientbar -    if (Q_stricmp(token.string, "gradientbar") == 0) { -      if (!PC_String_Parse(handle, &tempStr)) { -        return qfalse; -      } -      uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip(tempStr); -      continue; -    } - -    // enterMenuSound -    if (Q_stricmp(token.string, "menuEnterSound") == 0) { -      if (!PC_String_Parse(handle, &tempStr)) { -        return qfalse; -      } -      uiInfo.uiDC.Assets.menuEnterSound = trap_S_RegisterSound( tempStr, qfalse ); -      continue; -    } - -    // exitMenuSound -    if (Q_stricmp(token.string, "menuExitSound") == 0) { -      if (!PC_String_Parse(handle, &tempStr)) { -        return qfalse; -      } -      uiInfo.uiDC.Assets.menuExitSound = trap_S_RegisterSound( tempStr, qfalse ); -      continue; -    } - -    // itemFocusSound -    if (Q_stricmp(token.string, "itemFocusSound") == 0) { -      if (!PC_String_Parse(handle, &tempStr)) { -        return qfalse; -      } -      uiInfo.uiDC.Assets.itemFocusSound = trap_S_RegisterSound( tempStr, qfalse ); -      continue; -    } - -    // menuBuzzSound -    if (Q_stricmp(token.string, "menuBuzzSound") == 0) { -      if (!PC_String_Parse(handle, &tempStr)) { -        return qfalse; -      } -      uiInfo.uiDC.Assets.menuBuzzSound = trap_S_RegisterSound( tempStr, qfalse ); -      continue; -    } - -    if (Q_stricmp(token.string, "cursor") == 0) { -      if (!PC_String_Parse(handle, &uiInfo.uiDC.Assets.cursorStr)) { -        return qfalse; -      } -      uiInfo.uiDC.Assets.cursor = trap_R_RegisterShaderNoMip( uiInfo.uiDC.Assets.cursorStr); -      continue; -    } - -    if (Q_stricmp(token.string, "fadeClamp") == 0) { -      if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeClamp)) { -        return qfalse; -      } -      continue; -    } - -    if (Q_stricmp(token.string, "fadeCycle") == 0) { -      if (!PC_Int_Parse(handle, &uiInfo.uiDC.Assets.fadeCycle)) { -        return qfalse; -      } -      continue; -    } - -    if (Q_stricmp(token.string, "fadeAmount") == 0) { -      if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeAmount)) { -        return qfalse; -      } -      continue; -    } - -    if (Q_stricmp(token.string, "shadowX") == 0) { -      if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowX)) { -        return qfalse; -      } -      continue; -    } - -    if (Q_stricmp(token.string, "shadowY") == 0) { -      if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowY)) { -        return qfalse; -      } -      continue; -    } - -    if (Q_stricmp(token.string, "shadowColor") == 0) { -      if (!PC_Color_Parse(handle, &uiInfo.uiDC.Assets.shadowColor)) { -        return qfalse; -      } -      uiInfo.uiDC.Assets.shadowFadeClamp = uiInfo.uiDC.Assets.shadowColor[3]; -      continue; -    } - -  } -  return qfalse; -} - -void Font_Report( void ) { -  int i; -  Com_Printf("Font Info\n"); -  Com_Printf("=========\n"); -  for ( i = 32; i < 96; i++) { -    Com_Printf("Glyph handle %i: %i\n", i, uiInfo.uiDC.Assets.textFont.glyphs[i].glyph); -  } -} - -void UI_Report( void ) { -  String_Report(); -  //Font_Report(); - -} - -void UI_ParseMenu(const char *menuFile) { -  int handle; -  pc_token_t token; - -  /*Com_Printf("Parsing menu file:%s\n", menuFile);*/ - -  handle = trap_PC_LoadSource(menuFile); -  if (!handle) { -    return; -  } - -  while ( 1 ) { -    memset(&token, 0, sizeof(pc_token_t)); -    if (!trap_PC_ReadToken( handle, &token )) { -      break; -    } - -    //if ( Q_stricmp( token, "{" ) ) { -    //  Com_Printf( "Missing { in menu file\n" ); -    //  break; -    //} - -    //if ( menuCount == MAX_MENUS ) { -    //  Com_Printf( "Too many menus!\n" ); -    //  break; -    //} - -    if ( token.string[0] == '}' ) { -      break; -    } - -    if (Q_stricmp(token.string, "assetGlobalDef") == 0) { -      if (Asset_Parse(handle)) { -        continue; -      } else { -        break; -      } -    } - -    if (Q_stricmp(token.string, "menudef") == 0) { -      // start a new menu -      Menu_New(handle); -    } -  } -  trap_PC_FreeSource(handle); -} - -/* -=============== -UI_FindInfoPaneByName -=============== -*/ -tremInfoPane_t *UI_FindInfoPaneByName( const char *name ) -{ -  int i; - -  for( i = 0; i < uiInfo.tremInfoPaneCount; i++ ) -  { -    if( !Q_stricmp( uiInfo.tremInfoPanes[ i ].name, name ) ) -      return &uiInfo.tremInfoPanes[ i ]; -  } - -  //create a dummy infopane demanding the user write the infopane -  uiInfo.tremInfoPanes[ i ].name = String_Alloc( name ); -  strncpy( uiInfo.tremInfoPanes[ i ].text, "Not implemented.\n\nui/infopanes.def\n", MAX_INFOPANE_TEXT ); -  Q_strcat( uiInfo.tremInfoPanes[ i ].text, MAX_INFOPANE_TEXT, String_Alloc( name ) ); - -  uiInfo.tremInfoPaneCount++; - -  return &uiInfo.tremInfoPanes[ i ]; -} - -/* -=============== -UI_LoadInfoPane -=============== -*/ -qboolean UI_LoadInfoPane( int handle ) -{ -  pc_token_t  token; -  qboolean    valid = qfalse; - -  while( 1 ) -  { -    memset( &token, 0, sizeof( pc_token_t ) ); - -    if( !trap_PC_ReadToken( handle, &token ) ) -      break; - -    if( !Q_stricmp( token.string, "name" ) ) -    { -      memset( &token, 0, sizeof( pc_token_t ) ); - -      if( !trap_PC_ReadToken( handle, &token ) ) -        break; - -      uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].name = String_Alloc( token.string ); -      valid = qtrue; -    } -    else if( !Q_stricmp( token.string, "graphic" ) ) -    { -      int *graphic; - -      memset( &token, 0, sizeof( pc_token_t ) ); - -      if( !trap_PC_ReadToken( handle, &token ) ) -        break; - -      graphic = &uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].numGraphics; - -      if( !Q_stricmp( token.string, "top" ) ) -        uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].side = INFOPANE_TOP; -      else if( !Q_stricmp( token.string, "bottom" ) ) -        uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].side = INFOPANE_BOTTOM; -      else if( !Q_stricmp( token.string, "left" ) ) -        uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].side = INFOPANE_LEFT; -      else if( !Q_stricmp( token.string, "right" ) ) -        uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].side = INFOPANE_RIGHT; -      else -        break; - -      memset( &token, 0, sizeof( pc_token_t ) ); - -      if( !trap_PC_ReadToken( handle, &token ) ) -        break; - -      if( !Q_stricmp( token.string, "center" ) ) -        uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].offset = -1; -      else -        uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].offset = token.intvalue; - -      memset( &token, 0, sizeof( pc_token_t ) ); - -      if( !trap_PC_ReadToken( handle, &token ) ) -        break; - -      uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].graphic = -        trap_R_RegisterShaderNoMip( token.string ); - -      memset( &token, 0, sizeof( pc_token_t ) ); - -      if( !trap_PC_ReadToken( handle, &token ) ) -        break; - -      uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].width = token.intvalue; - -      memset( &token, 0, sizeof( pc_token_t ) ); - -      if( !trap_PC_ReadToken( handle, &token ) ) -        break; - -      uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].height = token.intvalue; - -      //increment graphics -      (*graphic)++; - -      if( *graphic == MAX_INFOPANE_GRAPHICS ) -        break; -    } -    else if( !Q_stricmp( token.string, "text" ) ) -    { -      memset( &token, 0, sizeof( pc_token_t ) ); - -      if( !trap_PC_ReadToken( handle, &token ) ) -        break; - -      Q_strcat( uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].text, MAX_INFOPANE_TEXT, token.string ); -    } -    else if( !Q_stricmp( token.string, "align" ) ) -    { -      memset( &token, 0, sizeof( pc_token_t ) ); - -      if( !trap_PC_ReadToken( handle, &token ) ) -        break; - -      if( !Q_stricmp( token.string, "left" ) ) -        uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].align = ITEM_ALIGN_LEFT; -      else if( !Q_stricmp( token.string, "right" ) ) -        uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].align = ITEM_ALIGN_RIGHT; -      else if( !Q_stricmp( token.string, "center" ) ) -        uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].align = ITEM_ALIGN_CENTER; -    } -    else if( token.string[ 0 ] == '}' ) -    { -      //reached the end, break -      break; -    } -    else -      break; -  } - -  if( valid ) -  { -    uiInfo.tremInfoPaneCount++; -    return qtrue; -  } -  else -  { -    return qfalse; -  } -} - -/* -=============== -UI_LoadInfoPanes -=============== -*/ -void UI_LoadInfoPanes( const char *file ) -{ -  pc_token_t token; -  int handle; -  int count; - -  uiInfo.tremInfoPaneCount = count = 0; - -  handle = trap_PC_LoadSource( file ); - -  if( !handle ) -  { -    trap_Error( va( S_COLOR_YELLOW "infopane file not found: %s\n", file ) ); -    return; -  } - -  while( 1 ) -  { -    if( !trap_PC_ReadToken( handle, &token ) ) -      break; - -    if( token.string[ 0 ] == 0 ) -      break; - -    if( token.string[ 0 ] == '{' ) -    { -      if( UI_LoadInfoPane( handle ) ) -        count++; - -      if( count == MAX_INFOPANES ) -        break; -    } -  } - -  trap_PC_FreeSource( handle ); -} - -qboolean Load_Menu(int handle) { -  pc_token_t token; - -  if (!trap_PC_ReadToken(handle, &token)) -    return qfalse; -  if (token.string[0] != '{') { -    return qfalse; -  } - -  while ( 1 ) { - -    if (!trap_PC_ReadToken(handle, &token)) -      return qfalse; - -    if ( token.string[0] == 0 ) { -      return qfalse; -    } - -    if ( token.string[0] == '}' ) { -      return qtrue; -    } - -    UI_ParseMenu(token.string); -  } -  return qfalse; -} - -void UI_LoadMenus(const char *menuFile, qboolean reset) { -  pc_token_t token; -  int handle; -  int start; - -  start = trap_Milliseconds(); - -  handle = trap_PC_LoadSource( menuFile ); -  if (!handle) { -    trap_Error( va( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile ) ); -    handle = trap_PC_LoadSource( "ui/menus.txt" ); -    if (!handle) { -      trap_Error( va( S_COLOR_RED "default menu file not found: ui/menus.txt, unable to continue!\n", menuFile ) ); -    } -  } - -  ui_new.integer = 1; - -  if (reset) { -    Menu_Reset(); -  } - -  while ( 1 ) { -    if (!trap_PC_ReadToken(handle, &token)) -      break; -    if( token.string[0] == 0 || token.string[0] == '}') { -      break; -    } - -    if ( token.string[0] == '}' ) { -      break; -    } - -    if (Q_stricmp(token.string, "loadmenu") == 0) { -      if (Load_Menu(handle)) { -        continue; -      } else { -        break; -      } -    } -  } - -  Com_Printf("UI menu load time = %d milli seconds\n", trap_Milliseconds() - start); - -  trap_PC_FreeSource( handle ); -} - -void UI_Load( void ) { -  char lastName[1024]; -  menuDef_t *menu = Menu_GetFocused(); -  char *menuSet = UI_Cvar_VariableString("ui_menuFiles"); -  if (menu && menu->window.name) { -    strcpy(lastName, menu->window.name); -  } -  if (menuSet == NULL || menuSet[0] == '\0') { -    menuSet = "ui/menus.txt"; -  } - -  String_Init(); - -/*  UI_ParseGameInfo("gameinfo.txt"); -  UI_LoadArenas();*/ - -  UI_LoadMenus(menuSet, qtrue); -  Menus_CloseAll(); -  Menus_ActivateByName(lastName); - -} - -static const char *handicapValues[] = {"None","95","90","85","80","75","70","65","60","55","50","45","40","35","30","25","20","15","10","5",NULL}; - -static void UI_DrawHandicap(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  int i, h; - -  h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") ); -  i = 20 - h / 5; - -  Text_Paint(rect->x, rect->y, scale, color, handicapValues[i], 0, 0, textStyle); -} - -static void UI_DrawClanName(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_teamName"), 0, 0, textStyle); -} - - -static void UI_SetCapFragLimits(qboolean uiVars) { -  int cap = 5; -  int frag = 10; -  if (uiVars) { -    trap_Cvar_Set("ui_captureLimit", va("%d", cap)); -    trap_Cvar_Set("ui_fragLimit", va("%d", frag)); -  } else { -    trap_Cvar_Set("capturelimit", va("%d", cap)); -    trap_Cvar_Set("fraglimit", va("%d", frag)); -  } -} -// ui_gameType assumes gametype 0 is -1 ALL and will not show -static void UI_DrawGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[ui_gameType.integer].gameType, 0, 0, textStyle); -} - -static void UI_DrawNetGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  if (ui_netGameType.integer < 0 || ui_netGameType.integer > uiInfo.numGameTypes) { -    trap_Cvar_Set("ui_netGameType", "0"); -    trap_Cvar_Set("ui_actualNetGameType", "0"); -  } -  Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[ui_netGameType.integer].gameType , 0, 0, textStyle); -} - -static void UI_DrawJoinGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  if (ui_joinGameType.integer < 0 || ui_joinGameType.integer > uiInfo.numJoinGameTypes) { -    trap_Cvar_Set("ui_joinGameType", "0"); -  } -  Text_Paint(rect->x, rect->y, scale, color, uiInfo.joinGameTypes[ui_joinGameType.integer].gameType , 0, 0, textStyle); -} - - - -static int UI_TeamIndexFromName(const char *name) { -  int i; - -  if (name && *name) { -    for (i = 0; i < uiInfo.teamCount; i++) { -      if (Q_stricmp(name, uiInfo.teamList[i].teamName) == 0) { -        return i; -      } -    } -  } - -  return 0; - -} - -static void UI_DrawClanLogo(rectDef_t *rect, float scale, vec4_t color) { -  int i; -  i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); -  if (i >= 0 && i < uiInfo.teamCount) { -    trap_R_SetColor( color ); - -    if (uiInfo.teamList[i].teamIcon == -1) { -      uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); -      uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); -      uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); -    } - -    UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon); -    trap_R_SetColor(NULL); -  } -} - -static void UI_DrawClanCinematic(rectDef_t *rect, float scale, vec4_t color) { -  int i; -  i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); -  if (i >= 0 && i < uiInfo.teamCount) { - -    if (uiInfo.teamList[i].cinematic >= -2) { -      if (uiInfo.teamList[i].cinematic == -1) { -        uiInfo.teamList[i].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.teamList[i].imageName), 0, 0, 0, 0, (CIN_loop | CIN_silent) ); -      } -      if (uiInfo.teamList[i].cinematic >= 0) { -        trap_CIN_RunCinematic(uiInfo.teamList[i].cinematic); -        trap_CIN_SetExtents(uiInfo.teamList[i].cinematic, rect->x, rect->y, rect->w, rect->h); -        trap_CIN_DrawCinematic(uiInfo.teamList[i].cinematic); -      } else { -          trap_R_SetColor( color ); -        UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal); -        trap_R_SetColor(NULL); -        uiInfo.teamList[i].cinematic = -2; -      } -    } else { -      trap_R_SetColor( color ); -      UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon); -      trap_R_SetColor(NULL); -    } -  } - -} - -static void UI_DrawPreviewCinematic(rectDef_t *rect, float scale, vec4_t color) { -  if (uiInfo.previewMovie > -2) { -    uiInfo.previewMovie = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.movieList[uiInfo.movieIndex]), 0, 0, 0, 0, (CIN_loop | CIN_silent) ); -    if (uiInfo.previewMovie >= 0) { -      trap_CIN_RunCinematic(uiInfo.previewMovie); -      trap_CIN_SetExtents(uiInfo.previewMovie, rect->x, rect->y, rect->w, rect->h); -      trap_CIN_DrawCinematic(uiInfo.previewMovie); -    } else { -      uiInfo.previewMovie = -2; -    } -  } - -} - - -#define GRAPHIC_BWIDTH  8.0f -/* -=============== -UI_DrawInfoPane -=============== -*/ -static void UI_DrawInfoPane( tremInfoPane_t *pane, rectDef_t *rect, float text_x, float text_y, -                             float scale, vec4_t color, int textStyle ) -{ -  int       i; -  float     maxLeft = 0, maxTop = 0; -  float     maxRight = 0, maxBottom = 0; -  float     x = rect->x - text_x, y = rect->y - text_y, w, h; -  float     xoffset = 0, yoffset = 0; -  menuDef_t dummyParent; -  itemDef_t textItem; - -  //iterate through graphics -  for( i = 0; i < pane->numGraphics; i++ ) -  { -    float width         = pane->graphics[ i ].width; -    float height        = pane->graphics[ i ].height; -    qhandle_t graphic = pane->graphics[ i ].graphic; - -    if( pane->graphics[ i ].side == INFOPANE_TOP || pane->graphics[ i ].side == INFOPANE_BOTTOM ) -    { -      //set horizontal offset of graphic -      if( pane->graphics[ i ].offset < 0 ) -        xoffset = ( rect->w / 2 ) - ( pane->graphics[ i ].width / 2 ); -      else -        xoffset = pane->graphics[ i ].offset + GRAPHIC_BWIDTH; -    } -    else if( pane->graphics[ i ].side == INFOPANE_LEFT || pane->graphics[ i ].side == INFOPANE_RIGHT ) -    { -      //set vertical offset of graphic -      if( pane->graphics[ i ].offset < 0 ) -        yoffset = ( rect->h / 2 ) - ( pane->graphics[ i ].height / 2 ); -      else -        yoffset = pane->graphics[ i ].offset + GRAPHIC_BWIDTH; -    } - -    if( pane->graphics[ i ].side == INFOPANE_LEFT ) -    { -      //set the horizontal offset of the text -      if( pane->graphics[ i ].width > maxLeft ) -        maxLeft = pane->graphics[ i ].width + GRAPHIC_BWIDTH; - -      xoffset = GRAPHIC_BWIDTH; -    } -    else if( pane->graphics[ i ].side == INFOPANE_RIGHT ) -    { -      if( pane->graphics[ i ].width > maxRight ) -        maxRight = pane->graphics[ i ].width + GRAPHIC_BWIDTH; - -      xoffset = rect->w - width - GRAPHIC_BWIDTH; -    } -    else if( pane->graphics[ i ].side == INFOPANE_TOP ) -    { -      //set the vertical offset of the text -      if( pane->graphics[ i ].height > maxTop ) -        maxTop = pane->graphics[ i ].height + GRAPHIC_BWIDTH; - -      yoffset = GRAPHIC_BWIDTH; -    } -    else if( pane->graphics[ i ].side == INFOPANE_BOTTOM ) -    { -      if( pane->graphics[ i ].height > maxBottom ) -        maxBottom = pane->graphics[ i ].height + GRAPHIC_BWIDTH; - -      yoffset = rect->h - height - GRAPHIC_BWIDTH; -    } - -    //draw the graphic -    UI_DrawHandlePic( x + xoffset, y + yoffset, width, height, graphic ); -  } - -  //offset the text -  x = rect->x + maxLeft; -  y = rect->y + maxTop; -  w = rect->w - ( maxLeft + maxRight + 16 + ( 2 * text_x ) ); //16 to ensure text within frame -  h = rect->h - ( maxTop + maxBottom ); - -  textItem.text = pane->text; - -  textItem.parent = &dummyParent; -  memcpy( textItem.window.foreColor, color, sizeof( vec4_t ) ); -  textItem.window.flags = 0; - -  switch( pane->align ) -  { -    case ITEM_ALIGN_LEFT: -      textItem.window.rect.x = x; -      break; - -    case ITEM_ALIGN_RIGHT: -      textItem.window.rect.x = x + w; -      break; - -    case ITEM_ALIGN_CENTER: -      textItem.window.rect.x = x + ( w / 2 ); -      break; - -    default: -      textItem.window.rect.x = x; -      break; -  } - -  textItem.window.rect.y = y; -  textItem.window.rect.w = w; -  textItem.window.rect.h = h; -  textItem.window.borderSize = 0; -  textItem.textRect.x = 0; -  textItem.textRect.y = 0; -  textItem.textRect.w = 0; -  textItem.textRect.h = 0; -  textItem.textalignment = pane->align; -  textItem.textalignx = text_x; -  textItem.textaligny = text_y; -  textItem.textscale = scale; -  textItem.textStyle = textStyle; - -  textItem.enableCvar = NULL; -  textItem.cvarTest = NULL; - -  //hack to utilise existing autowrap code -  Item_Text_AutoWrapped_Paint( &textItem ); -} - - -static void UI_DrawSkill(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  int i; -  i = trap_Cvar_VariableValue( "g_spSkill" ); -  if (i < 1 || i > numSkillLevels) { -    i = 1; -  } -  Text_Paint(rect->x, rect->y, scale, color, skillLevels[i-1],0, 0, textStyle); -} - - -static void UI_DrawTeamName(rectDef_t *rect, float scale, vec4_t color, qboolean blue, int textStyle) { -  int i; -  i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam")); -  if (i >= 0 && i < uiInfo.teamCount) { -    Text_Paint(rect->x, rect->y, scale, color, va("%s: %s", (blue) ? "Blue" : "Red", uiInfo.teamList[i].teamName),0, 0, textStyle); -  } -} - -static void UI_DrawTeamMember(rectDef_t *rect, float scale, vec4_t color, qboolean blue, int num, int textStyle) { -  // 0 - None -  // 1 - Human -  // 2..NumCharacters - Bot -  int value = trap_Cvar_VariableValue(va(blue ? "ui_blueteam%i" : "ui_redteam%i", num)); -  const char *text; -  if (value <= 0) { -    text = "Closed"; -  } else if (value == 1) { -    text = "Human"; -  } else { -    value -= 2; - -    if( value >= UI_GetNumBots( ) ) -      value = 0; - -    text = UI_GetBotNameByNumber(value); -  } -  Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle); -} - -static void UI_DrawMapPreview(rectDef_t *rect, float scale, vec4_t color, qboolean net) { -  int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer; -  if (map < 0 || map > uiInfo.mapCount) { -    if (net) { -      ui_currentNetMap.integer = 0; -      trap_Cvar_Set("ui_currentNetMap", "0"); -    } else { -      ui_currentMap.integer = 0; -      trap_Cvar_Set("ui_currentMap", "0"); -    } -    map = 0; -  } - -  if (uiInfo.mapList[map].levelShot == -1) { -    uiInfo.mapList[map].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[map].imageName); -  } - -  if (uiInfo.mapList[map].levelShot > 0) { -    UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.mapList[map].levelShot); -  } else { -    UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip("gfx/2d/load_screen")); -  } -} - - -static void UI_DrawMapTimeToBeat(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  int minutes, seconds, time; -  if (ui_currentMap.integer < 0 || ui_currentMap.integer > uiInfo.mapCount) { -    ui_currentMap.integer = 0; -    trap_Cvar_Set("ui_currentMap", "0"); -  } - -  time = uiInfo.mapList[ui_currentMap.integer].timeToBeat[uiInfo.gameTypes[ui_gameType.integer].gtEnum]; - -  minutes = time / 60; -  seconds = time % 60; - -  Text_Paint(rect->x, rect->y, scale, color, va("%02i:%02i", minutes, seconds), 0, 0, textStyle); -} - - - -static void UI_DrawMapCinematic(rectDef_t *rect, float scale, vec4_t color, qboolean net) { - -  int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer; -  if (map < 0 || map > uiInfo.mapCount) { -    if (net) { -      ui_currentNetMap.integer = 0; -      trap_Cvar_Set("ui_currentNetMap", "0"); -    } else { -      ui_currentMap.integer = 0; -      trap_Cvar_Set("ui_currentMap", "0"); -    } -    map = 0; -  } - -  if (uiInfo.mapList[map].cinematic >= -1) { -    if (uiInfo.mapList[map].cinematic == -1) { -      uiInfo.mapList[map].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.mapList[map].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent) ); -    } -    if (uiInfo.mapList[map].cinematic >= 0) { -      trap_CIN_RunCinematic(uiInfo.mapList[map].cinematic); -      trap_CIN_SetExtents(uiInfo.mapList[map].cinematic, rect->x, rect->y, rect->w, rect->h); -      trap_CIN_DrawCinematic(uiInfo.mapList[map].cinematic); -    } else { -      uiInfo.mapList[map].cinematic = -2; -    } -  } else { -    UI_DrawMapPreview(rect, scale, color, net); -  } -} - - - -static qboolean updateModel = qtrue; -static qboolean q3Model = qfalse; - -static void UI_DrawPlayerModel(rectDef_t *rect) { -  static playerInfo_t info; -  char model[MAX_QPATH]; -  char team[256]; -  char head[256]; -  vec3_t  viewangles; -  vec3_t  moveangles; - -    if (trap_Cvar_VariableValue("ui_Q3Model")) { -    strcpy(model, UI_Cvar_VariableString("model")); -    strcpy(head, UI_Cvar_VariableString("headmodel")); -    if (!q3Model) { -      q3Model = qtrue; -      updateModel = qtrue; -    } -    team[0] = '\0'; -  } else { - -    strcpy(team, UI_Cvar_VariableString("ui_teamName")); -    strcpy(model, UI_Cvar_VariableString("team_model")); -    strcpy(head, UI_Cvar_VariableString("team_headmodel")); -    if (q3Model) { -      q3Model = qfalse; -      updateModel = qtrue; -    } -  } -  if (updateModel) { -    memset( &info, 0, sizeof(playerInfo_t) ); -    viewangles[YAW]   = 180 - 10; -    viewangles[PITCH] = 0; -    viewangles[ROLL]  = 0; -    VectorClear( moveangles ); -    UI_PlayerInfo_SetModel( &info, model, head, team); -    UI_PlayerInfo_SetInfo( &info, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MACHINEGUN, qfalse ); -//    UI_RegisterClientModelname( &info, model, head, team); -    updateModel = qfalse; -  } - -  UI_DrawPlayer( rect->x, rect->y, rect->w, rect->h, &info, uiInfo.uiDC.realTime / 2); - -} - -static void UI_DrawNetSource(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  if (ui_netSource.integer < 0 || ui_netSource.integer > numNetSources) { -    ui_netSource.integer = 0; -  } -  Text_Paint(rect->x, rect->y, scale, color, va("Source: %s", netSources[ui_netSource.integer]), 0, 0, textStyle); -} - -static void UI_DrawNetMapPreview(rectDef_t *rect, float scale, vec4_t color) { - -  if (uiInfo.serverStatus.currentServerPreview > 0) { -    UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.serverStatus.currentServerPreview); -  } else { -    UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip("gfx/2d/load_screen")); -  } -} - -static void UI_DrawNetMapCinematic(rectDef_t *rect, float scale, vec4_t color) { -  if (ui_currentNetMap.integer < 0 || ui_currentNetMap.integer > uiInfo.mapCount) { -    ui_currentNetMap.integer = 0; -    trap_Cvar_Set("ui_currentNetMap", "0"); -  } - -  if (uiInfo.serverStatus.currentServerCinematic >= 0) { -    trap_CIN_RunCinematic(uiInfo.serverStatus.currentServerCinematic); -    trap_CIN_SetExtents(uiInfo.serverStatus.currentServerCinematic, rect->x, rect->y, rect->w, rect->h); -    trap_CIN_DrawCinematic(uiInfo.serverStatus.currentServerCinematic); -  } else { -    UI_DrawNetMapPreview(rect, scale, color); -  } -} - - - -static void UI_DrawNetFilter(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  if (ui_serverFilterType.integer < 0 || ui_serverFilterType.integer > numServerFilters) { -    ui_serverFilterType.integer = 0; -  } -  Text_Paint(rect->x, rect->y, scale, color, va("Filter: %s", serverFilters[ui_serverFilterType.integer].description), 0, 0, textStyle); -} - - -static void UI_DrawTier(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  int i; -  i = trap_Cvar_VariableValue( "ui_currentTier" ); -  if (i < 0 || i >= uiInfo.tierCount) { -    i = 0; -  } -  Text_Paint(rect->x, rect->y, scale, color, va("Tier: %s", uiInfo.tierList[i].tierName),0, 0, textStyle); -} - -static void UI_DrawTierMap(rectDef_t *rect, int index) { -  int i; -  i = trap_Cvar_VariableValue( "ui_currentTier" ); -  if (i < 0 || i >= uiInfo.tierCount) { -    i = 0; -  } - -  if (uiInfo.tierList[i].mapHandles[index] == -1) { -    uiInfo.tierList[i].mapHandles[index] = trap_R_RegisterShaderNoMip(va("levelshots/%s", uiInfo.tierList[i].maps[index])); -  } - -  UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.tierList[i].mapHandles[index]); -} - -static const char *UI_EnglishMapName(const char *map) { -  int i; -  for (i = 0; i < uiInfo.mapCount; i++) { -    if (Q_stricmp(map, uiInfo.mapList[i].mapLoadName) == 0) { -      return uiInfo.mapList[i].mapName; -    } -  } -  return ""; -} - -static void UI_DrawTierMapName(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  int i, j; -  i = trap_Cvar_VariableValue( "ui_currentTier" ); -  if (i < 0 || i >= uiInfo.tierCount) { -    i = 0; -  } -  j = trap_Cvar_VariableValue("ui_currentMap"); -  if (j < 0 || j > MAPS_PER_TIER) { -    j = 0; -  } - -  Text_Paint(rect->x, rect->y, scale, color, UI_EnglishMapName(uiInfo.tierList[i].maps[j]), 0, 0, textStyle); -} - -static void UI_DrawTierGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  int i, j; -  i = trap_Cvar_VariableValue( "ui_currentTier" ); -  if (i < 0 || i >= uiInfo.tierCount) { -    i = 0; -  } -  j = trap_Cvar_VariableValue("ui_currentMap"); -  if (j < 0 || j > MAPS_PER_TIER) { -    j = 0; -  } - -  Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[uiInfo.tierList[i].gameTypes[j]].gameType , 0, 0, textStyle); -} - - -static const char *UI_AIFromName(const char *name) { -  int j; -  for (j = 0; j < uiInfo.aliasCount; j++) { -    if (Q_stricmp(uiInfo.aliasList[j].name, name) == 0) { -      return uiInfo.aliasList[j].ai; -    } -  } -  return "James"; -} - -static qboolean updateOpponentModel = qtrue; -static void UI_DrawOpponent(rectDef_t *rect) { -  static playerInfo_t info2; -  char model[MAX_QPATH]; -  char headmodel[MAX_QPATH]; -  char team[256]; -  vec3_t  viewangles; -  vec3_t  moveangles; - -  if (updateOpponentModel) { - -    strcpy(model, UI_Cvar_VariableString("ui_opponentModel")); -    strcpy(headmodel, UI_Cvar_VariableString("ui_opponentModel")); -    team[0] = '\0'; - -    memset( &info2, 0, sizeof(playerInfo_t) ); -    viewangles[YAW]   = 180 - 10; -    viewangles[PITCH] = 0; -    viewangles[ROLL]  = 0; -    VectorClear( moveangles ); -    UI_PlayerInfo_SetModel( &info2, model, headmodel, ""); -    UI_PlayerInfo_SetInfo( &info2, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MACHINEGUN, qfalse ); -    UI_RegisterClientModelname( &info2, model, headmodel, team); -    updateOpponentModel = qfalse; -  } - -  UI_DrawPlayer( rect->x, rect->y, rect->w, rect->h, &info2, uiInfo.uiDC.realTime / 2); - -} - -static void UI_NextOpponent( void ) { -  int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); -  int j = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); -  i++; -  if (i >= uiInfo.teamCount) { -    i = 0; -  } -  if (i == j) { -    i++; -    if ( i >= uiInfo.teamCount) { -      i = 0; -    } -  } -  trap_Cvar_Set( "ui_opponentName", uiInfo.teamList[i].teamName ); -} - -static void UI_PriorOpponent( void ) { -  int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); -  int j = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); -  i--; -  if (i < 0) { -    i = uiInfo.teamCount - 1; -  } -  if (i == j) { -    i--; -    if ( i < 0) { -      i = uiInfo.teamCount - 1; -    } -  } -  trap_Cvar_Set( "ui_opponentName", uiInfo.teamList[i].teamName ); -} - -static void UI_DrawPlayerLogo(rectDef_t *rect, vec3_t color) { -  int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); - -  if (uiInfo.teamList[i].teamIcon == -1) { -    uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); -    uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); -    uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); -  } - -  trap_R_SetColor( color ); -  UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon ); -  trap_R_SetColor( NULL ); -} - -static void UI_DrawPlayerLogoMetal(rectDef_t *rect, vec3_t color) { -  int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); -  if (uiInfo.teamList[i].teamIcon == -1) { -    uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); -    uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); -    uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); -  } - -  trap_R_SetColor( color ); -  UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal ); -  trap_R_SetColor( NULL ); -} - -static void UI_DrawPlayerLogoName(rectDef_t *rect, vec3_t color) { -  int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); -  if (uiInfo.teamList[i].teamIcon == -1) { -    uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); -    uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); -    uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); -  } - -  trap_R_SetColor( color ); -  UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Name ); -  trap_R_SetColor( NULL ); -} - -static void UI_DrawOpponentLogo(rectDef_t *rect, vec3_t color) { -  int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); -  if (uiInfo.teamList[i].teamIcon == -1) { -    uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); -    uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); -    uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); -  } - -  trap_R_SetColor( color ); -  UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon ); -  trap_R_SetColor( NULL ); -} - -static void UI_DrawOpponentLogoMetal(rectDef_t *rect, vec3_t color) { -  int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); -  if (uiInfo.teamList[i].teamIcon == -1) { -    uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); -    uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); -    uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); -  } - -  trap_R_SetColor( color ); -  UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal ); -  trap_R_SetColor( NULL ); -} - -static void UI_DrawOpponentLogoName(rectDef_t *rect, vec3_t color) { -  int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); -  if (uiInfo.teamList[i].teamIcon == -1) { -    uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); -    uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); -    uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); -  } - -  trap_R_SetColor( color ); -  UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Name ); -  trap_R_SetColor( NULL ); -} - -static void UI_DrawAllMapsSelection(rectDef_t *rect, float scale, vec4_t color, int textStyle, qboolean net) { -  int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer; -  if (map >= 0 && map < uiInfo.mapCount) { -    Text_Paint(rect->x, rect->y, scale, color, uiInfo.mapList[map].mapName, 0, 0, textStyle); -  } -} - -static void UI_DrawOpponentName(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_opponentName"), 0, 0, textStyle); -} - - -static int UI_OwnerDrawWidth(int ownerDraw, float scale) { -  int i, h, value; -  const char *text; -  const char *s = NULL; - -  switch( ownerDraw ) -  { -    case UI_HANDICAP: -        h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") ); -        i = 20 - h / 5; -        s = handicapValues[i]; -      break; -    case UI_CLANNAME: -        s = UI_Cvar_VariableString("ui_teamName"); -      break; -    case UI_GAMETYPE: -        s = uiInfo.gameTypes[ui_gameType.integer].gameType; -      break; -    case UI_SKILL: -        i = trap_Cvar_VariableValue( "g_spSkill" ); -        if (i < 1 || i > numSkillLevels) { -          i = 1; -        } -        s = skillLevels[i-1]; -      break; -    case UI_BLUETEAMNAME: -        i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_blueTeam")); -        if (i >= 0 && i < uiInfo.teamCount) { -          s = va("%s: %s", "Blue", uiInfo.teamList[i].teamName); -        } -      break; -    case UI_REDTEAMNAME: -        i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_redTeam")); -        if (i >= 0 && i < uiInfo.teamCount) { -          s = va("%s: %s", "Red", uiInfo.teamList[i].teamName); -        } -      break; -    case UI_BLUETEAM1: -    case UI_BLUETEAM2: -    case UI_BLUETEAM3: -    case UI_BLUETEAM4: -    case UI_BLUETEAM5: -      value = trap_Cvar_VariableValue(va("ui_blueteam%i", ownerDraw-UI_BLUETEAM1 + 1)); -      if (value <= 0) { -        text = "Closed"; -      } else if (value == 1) { -        text = "Human"; -      } else { -        value -= 2; -        if (value >= uiInfo.aliasCount) { -          value = 0; -        } -        text = uiInfo.aliasList[value].name; -      } -      s = va("%i. %s", ownerDraw-UI_BLUETEAM1 + 1, text); -      break; -    case UI_REDTEAM1: -    case UI_REDTEAM2: -    case UI_REDTEAM3: -    case UI_REDTEAM4: -    case UI_REDTEAM5: -      value = trap_Cvar_VariableValue(va("ui_redteam%i", ownerDraw-UI_REDTEAM1 + 1)); -      if (value <= 0) { -        text = "Closed"; -      } else if (value == 1) { -        text = "Human"; -      } else { -        value -= 2; -        if (value >= uiInfo.aliasCount) { -          value = 0; -        } -        text = uiInfo.aliasList[value].name; -      } -      s = va("%i. %s", ownerDraw-UI_REDTEAM1 + 1, text); -      break; -    case UI_NETSOURCE: -      if (ui_netSource.integer < 0 || ui_netSource.integer > uiInfo.numJoinGameTypes) { -        ui_netSource.integer = 0; -      } -      s = va("Source: %s", netSources[ui_netSource.integer]); -      break; -    case UI_NETFILTER: -      if (ui_serverFilterType.integer < 0 || ui_serverFilterType.integer > numServerFilters) { -        ui_serverFilterType.integer = 0; -      } -      s = va("Filter: %s", serverFilters[ui_serverFilterType.integer].description ); -      break; -    case UI_TIER: -      break; -    case UI_TIER_MAPNAME: -      break; -    case UI_TIER_GAMETYPE: -      break; -    case UI_ALLMAPS_SELECTION: -      break; -    case UI_OPPONENT_NAME: -      break; -    case UI_KEYBINDSTATUS: -      if (Display_KeyBindPending()) { -        s = "Waiting for new key... Press ESCAPE to cancel"; -      } else { -        s = "Press ENTER or CLICK to change, Press BACKSPACE to clear"; -      } -      break; -    case UI_SERVERREFRESHDATE: -      s = UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer)); -      break; -    default: -      break; -  } - -  if (s) { -    return Text_Width(s, scale, 0); -  } -  return 0; -} - -static void UI_DrawBotName(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  int value = uiInfo.botIndex; -  const char *text = ""; - -  if( value >= UI_GetNumBots( ) ) -    value = 0; - -  text = UI_GetBotNameByNumber( value ); - -  Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle); -} - -static void UI_DrawBotSkill(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  if (uiInfo.skillIndex >= 0 && uiInfo.skillIndex < numSkillLevels) { -    Text_Paint(rect->x, rect->y, scale, color, skillLevels[uiInfo.skillIndex], 0, 0, textStyle); -  } -} - -static void UI_DrawRedBlue(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  Text_Paint(rect->x, rect->y, scale, color, (uiInfo.redBlue == 0) ? "Red" : "Blue", 0, 0, textStyle); -} - -/* -=============== -UI_BuildPlayerList -=============== -*/ -static void UI_BuildPlayerList( void ) { -  uiClientState_t cs; -  int   n, count, team, team2, playerTeamNumber; -  char  info[MAX_INFO_STRING]; - -  trap_GetClientState( &cs ); -  trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING ); -  uiInfo.playerNumber = cs.clientNum; -  uiInfo.teamLeader = atoi(Info_ValueForKey(info, "tl")); -  team = atoi(Info_ValueForKey(info, "t")); -  trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ); -  count = atoi( Info_ValueForKey( info, "sv_maxclients" ) ); -  uiInfo.playerCount = 0; -  uiInfo.myTeamCount = 0; -  playerTeamNumber = 0; -  for( n = 0; n < count; n++ ) { -    trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING ); - -    if (info[0]) { -      Q_strncpyz( uiInfo.playerNames[uiInfo.playerCount], Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH ); -      Q_CleanStr( uiInfo.playerNames[uiInfo.playerCount] ); -      uiInfo.playerCount++; -      team2 = atoi(Info_ValueForKey(info, "t")); -      if (team2 == team) { -        Q_strncpyz( uiInfo.teamNames[uiInfo.myTeamCount], Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH ); -        Q_CleanStr( uiInfo.teamNames[uiInfo.myTeamCount] ); -        uiInfo.teamClientNums[uiInfo.myTeamCount] = n; -        if (uiInfo.playerNumber == n) { -          playerTeamNumber = uiInfo.myTeamCount; -        } -        uiInfo.myTeamCount++; -      } -    } -  } - -  if (!uiInfo.teamLeader) { -    trap_Cvar_Set("cg_selectedPlayer", va("%d", playerTeamNumber)); -  } - -  n = trap_Cvar_VariableValue("cg_selectedPlayer"); -  if (n < 0 || n > uiInfo.myTeamCount) { -    n = 0; -  } -  if (n < uiInfo.myTeamCount) { -    trap_Cvar_Set("cg_selectedPlayerName", uiInfo.teamNames[n]); -  } -} - - -static void UI_DrawSelectedPlayer(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) { -    uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000; -    UI_BuildPlayerList(); -  } -  Text_Paint(rect->x, rect->y, scale, color, (uiInfo.teamLeader) ? UI_Cvar_VariableString("cg_selectedPlayerName") : UI_Cvar_VariableString("name") , 0, 0, textStyle); -} - -static void UI_DrawServerRefreshDate(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  if (uiInfo.serverStatus.refreshActive) { -    vec4_t lowLight, newColor; -    lowLight[0] = 0.8 * color[0]; -    lowLight[1] = 0.8 * color[1]; -    lowLight[2] = 0.8 * color[2]; -    lowLight[3] = 0.8 * color[3]; -    LerpColor(color,lowLight,newColor,0.5+0.5*sin(uiInfo.uiDC.realTime / PULSE_DIVISOR)); -    Text_Paint(rect->x, rect->y, scale, newColor, va("Getting info for %d servers (ESC to cancel)", trap_LAN_GetServerCount(ui_netSource.integer)), 0, 0, textStyle); -  } else { -    char buff[64]; -    Q_strncpyz(buff, UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer)), 64); -    Text_Paint(rect->x, rect->y, scale, color, va("Refresh Time: %s", buff), 0, 0, textStyle); -  } -} - -static void UI_DrawServerMOTD(rectDef_t *rect, float scale, vec4_t color) { -  if (uiInfo.serverStatus.motdLen) { -    float maxX; - -    if (uiInfo.serverStatus.motdWidth == -1) { -      uiInfo.serverStatus.motdWidth = 0; -      uiInfo.serverStatus.motdPaintX = rect->x + 1; -      uiInfo.serverStatus.motdPaintX2 = -1; -    } - -    if (uiInfo.serverStatus.motdOffset > uiInfo.serverStatus.motdLen) { -      uiInfo.serverStatus.motdOffset = 0; -      uiInfo.serverStatus.motdPaintX = rect->x + 1; -      uiInfo.serverStatus.motdPaintX2 = -1; -    } - -    if (uiInfo.uiDC.realTime > uiInfo.serverStatus.motdTime) { -      uiInfo.serverStatus.motdTime = uiInfo.uiDC.realTime + 10; -      if (uiInfo.serverStatus.motdPaintX <= rect->x + 2) { -        if (uiInfo.serverStatus.motdOffset < uiInfo.serverStatus.motdLen) { -          uiInfo.serverStatus.motdPaintX += Text_Width(&uiInfo.serverStatus.motd[uiInfo.serverStatus.motdOffset], scale, 1) - 1; -          uiInfo.serverStatus.motdOffset++; -        } else { -          uiInfo.serverStatus.motdOffset = 0; -          if (uiInfo.serverStatus.motdPaintX2 >= 0) { -            uiInfo.serverStatus.motdPaintX = uiInfo.serverStatus.motdPaintX2; -          } else { -            uiInfo.serverStatus.motdPaintX = rect->x + rect->w - 2; -          } -          uiInfo.serverStatus.motdPaintX2 = -1; -        } -      } else { -        //serverStatus.motdPaintX--; -        uiInfo.serverStatus.motdPaintX -= 2; -        if (uiInfo.serverStatus.motdPaintX2 >= 0) { -          //serverStatus.motdPaintX2--; -          uiInfo.serverStatus.motdPaintX2 -= 2; -        } -      } -    } - -    maxX = rect->x + rect->w - 2; -    Text_Paint_Limit(&maxX, uiInfo.serverStatus.motdPaintX, rect->y + rect->h - 3, scale, color, &uiInfo.serverStatus.motd[uiInfo.serverStatus.motdOffset], 0, 0); -    if (uiInfo.serverStatus.motdPaintX2 >= 0) { -      float maxX2 = rect->x + rect->w - 2; -      Text_Paint_Limit(&maxX2, uiInfo.serverStatus.motdPaintX2, rect->y + rect->h - 3, scale, color, uiInfo.serverStatus.motd, 0, uiInfo.serverStatus.motdOffset); -    } -    if (uiInfo.serverStatus.motdOffset && maxX > 0) { -      // if we have an offset ( we are skipping the first part of the string ) and we fit the string -      if (uiInfo.serverStatus.motdPaintX2 == -1) { -            uiInfo.serverStatus.motdPaintX2 = rect->x + rect->w - 2; -      } -    } else { -      uiInfo.serverStatus.motdPaintX2 = -1; -    } - -  } -} - -static void UI_DrawKeyBindStatus(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -//  int ofs = 0; TTimo: unused -  if (Display_KeyBindPending()) { -    Text_Paint(rect->x, rect->y, scale, color, "Waiting for new key... Press ESCAPE to cancel", 0, 0, textStyle); -  } else { -    Text_Paint(rect->x, rect->y, scale, color, "Press ENTER or CLICK to change, Press BACKSPACE to clear", 0, 0, textStyle); -  } -} - -static void UI_DrawGLInfo(rectDef_t *rect, float scale, vec4_t color, int textStyle) { -  char * eptr; -  char buff[1024]; -  const char *lines[64]; -  int y, numLines, i; - -  Text_Paint(rect->x + 2, rect->y, scale, color, va("VENDOR: %s", uiInfo.uiDC.glconfig.vendor_string), 0, 30, textStyle); -  Text_Paint(rect->x + 2, rect->y + 15, scale, color, va("VERSION: %s: %s", uiInfo.uiDC.glconfig.version_string,uiInfo.uiDC.glconfig.renderer_string), 0, 30, textStyle); -  Text_Paint(rect->x + 2, rect->y + 30, scale, color, va ("PIXELFORMAT: color(%d-bits) Z(%d-bits) stencil(%d-bits)", uiInfo.uiDC.glconfig.colorBits, uiInfo.uiDC.glconfig.depthBits, uiInfo.uiDC.glconfig.stencilBits), 0, 30, textStyle); - -  // build null terminated extension strings -  // TTimo: https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=399 -  // in TA this was not directly crashing, but displaying a nasty broken shader right in the middle -  // brought down the string size to 1024, there's not much that can be shown on the screen anyway -  Q_strncpyz(buff, uiInfo.uiDC.glconfig.extensions_string, 1024); -  eptr = buff; -  y = rect->y + 45; -  numLines = 0; -  while ( y < rect->y + rect->h && *eptr ) -  { -    while ( *eptr && *eptr == ' ' ) -      *eptr++ = '\0'; - -    // track start of valid string -    if (*eptr && *eptr != ' ') { -      lines[numLines++] = eptr; -    } - -    while ( *eptr && *eptr != ' ' ) -      eptr++; -  } - -  i = 0; -  while (i < numLines) { -    Text_Paint(rect->x + 2, y, scale, color, lines[i++], 0, 20, textStyle); -    if (i < numLines) { -      Text_Paint(rect->x + rect->w / 2, y, scale, color, lines[i++], 0, 20, textStyle); -    } -    y += 10; -    if (y > rect->y + rect->h - 11) { -      break; -    } -  } - - -} - -// FIXME: table drive -// -static void UI_OwnerDraw( float x, float y, float w, float h, -                          float text_x, float text_y, int ownerDraw, -                          int ownerDrawFlags, int align, float special, -                          float scale, vec4_t color, qhandle_t shader, int textStyle ) -{ -  rectDef_t       rect; -  tremInfoPane_t  *pane = NULL; - -  rect.x = x + text_x; -  rect.y = y + text_y; -  rect.w = w; -  rect.h = h; - -  switch( ownerDraw ) -  { -    case UI_TEAMINFOPANE: -      if( ( pane = uiInfo.tremTeamList[ uiInfo.tremTeamIndex ].infopane ) ) -        UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle ); -      break; - -    case UI_ACLASSINFOPANE: -      if( ( pane = uiInfo.tremAlienClassList[ uiInfo.tremAlienClassIndex ].infopane ) ) -        UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle ); -      break; - -    case UI_AUPGRADEINFOPANE: -      if( ( pane = uiInfo.tremAlienUpgradeList[ uiInfo.tremAlienUpgradeIndex ].infopane ) ) -        UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle ); -      break; - -    case UI_HITEMINFOPANE: -      if( ( pane = uiInfo.tremHumanItemList[ uiInfo.tremHumanItemIndex ].infopane ) ) -        UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle ); -      break; - -    case UI_HBUYINFOPANE: -      if( ( pane = uiInfo.tremHumanArmouryBuyList[ uiInfo.tremHumanArmouryBuyIndex ].infopane ) ) -        UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle ); -      break; - -    case UI_HSELLINFOPANE: -      if( ( pane = uiInfo.tremHumanArmourySellList[ uiInfo.tremHumanArmourySellIndex ].infopane ) ) -        UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle ); -      break; - -    case UI_ABUILDINFOPANE: -      if( ( pane = uiInfo.tremAlienBuildList[ uiInfo.tremAlienBuildIndex ].infopane ) ) -        UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle ); -      break; - -    case UI_HBUILDINFOPANE: -      if( ( pane = uiInfo.tremHumanBuildList[ uiInfo.tremHumanBuildIndex ].infopane ) ) -        UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle ); -      break; - -    case UI_HANDICAP: -      UI_DrawHandicap(&rect, scale, color, textStyle); -      break; -    case UI_PLAYERMODEL: -      UI_DrawPlayerModel(&rect); -      break; -    case UI_CLANNAME: -      UI_DrawClanName(&rect, scale, color, textStyle); -      break; -    case UI_CLANLOGO: -      UI_DrawClanLogo(&rect, scale, color); -      break; -    case UI_CLANCINEMATIC: -      UI_DrawClanCinematic(&rect, scale, color); -      break; -    case UI_PREVIEWCINEMATIC: -      UI_DrawPreviewCinematic(&rect, scale, color); -      break; -    case UI_GAMETYPE: -      UI_DrawGameType(&rect, scale, color, textStyle); -      break; -    case UI_NETGAMETYPE: -      UI_DrawNetGameType(&rect, scale, color, textStyle); -      break; -    case UI_JOINGAMETYPE: -    UI_DrawJoinGameType(&rect, scale, color, textStyle); -    break; -    case UI_MAPPREVIEW: -      UI_DrawMapPreview(&rect, scale, color, qtrue); -      break; -    case UI_MAP_TIMETOBEAT: -      UI_DrawMapTimeToBeat(&rect, scale, color, textStyle); -      break; -    case UI_MAPCINEMATIC: -      UI_DrawMapCinematic(&rect, scale, color, qfalse); -      break; -    case UI_STARTMAPCINEMATIC: -      UI_DrawMapCinematic(&rect, scale, color, qtrue); -      break; -    case UI_SKILL: -      UI_DrawSkill(&rect, scale, color, textStyle); -      break; -    case UI_BLUETEAMNAME: -      UI_DrawTeamName(&rect, scale, color, qtrue, textStyle); -      break; -    case UI_REDTEAMNAME: -      UI_DrawTeamName(&rect, scale, color, qfalse, textStyle); -      break; -    case UI_BLUETEAM1: -    case UI_BLUETEAM2: -    case UI_BLUETEAM3: -    case UI_BLUETEAM4: -    case UI_BLUETEAM5: -      UI_DrawTeamMember(&rect, scale, color, qtrue, ownerDraw - UI_BLUETEAM1 + 1, textStyle); -      break; -    case UI_REDTEAM1: -    case UI_REDTEAM2: -    case UI_REDTEAM3: -    case UI_REDTEAM4: -    case UI_REDTEAM5: -      UI_DrawTeamMember(&rect, scale, color, qfalse, ownerDraw - UI_REDTEAM1 + 1, textStyle); -      break; -    case UI_NETSOURCE: -      UI_DrawNetSource(&rect, scale, color, textStyle); -      break; -    case UI_NETMAPPREVIEW: -      UI_DrawNetMapPreview(&rect, scale, color); -      break; -    case UI_NETMAPCINEMATIC: -      UI_DrawNetMapCinematic(&rect, scale, color); -      break; -    case UI_NETFILTER: -      UI_DrawNetFilter(&rect, scale, color, textStyle); -      break; -    case UI_TIER: -      UI_DrawTier(&rect, scale, color, textStyle); -      break; -    case UI_OPPONENTMODEL: -      UI_DrawOpponent(&rect); -      break; -    case UI_TIERMAP1: -      UI_DrawTierMap(&rect, 0); -      break; -    case UI_TIERMAP2: -      UI_DrawTierMap(&rect, 1); -      break; -    case UI_TIERMAP3: -      UI_DrawTierMap(&rect, 2); -      break; -    case UI_PLAYERLOGO: -      UI_DrawPlayerLogo(&rect, color); -      break; -    case UI_PLAYERLOGO_METAL: -      UI_DrawPlayerLogoMetal(&rect, color); -      break; -    case UI_PLAYERLOGO_NAME: -      UI_DrawPlayerLogoName(&rect, color); -      break; -    case UI_OPPONENTLOGO: -      UI_DrawOpponentLogo(&rect, color); -      break; -    case UI_OPPONENTLOGO_METAL: -      UI_DrawOpponentLogoMetal(&rect, color); -      break; -    case UI_OPPONENTLOGO_NAME: -      UI_DrawOpponentLogoName(&rect, color); -      break; -    case UI_TIER_MAPNAME: -      UI_DrawTierMapName(&rect, scale, color, textStyle); -      break; -    case UI_TIER_GAMETYPE: -      UI_DrawTierGameType(&rect, scale, color, textStyle); -      break; -    case UI_ALLMAPS_SELECTION: -      UI_DrawAllMapsSelection(&rect, scale, color, textStyle, qtrue); -      break; -    case UI_MAPS_SELECTION: -      UI_DrawAllMapsSelection(&rect, scale, color, textStyle, qfalse); -      break; -    case UI_OPPONENT_NAME: -      UI_DrawOpponentName(&rect, scale, color, textStyle); -      break; -    case UI_BOTNAME: -      UI_DrawBotName(&rect, scale, color, textStyle); -      break; -    case UI_BOTSKILL: -      UI_DrawBotSkill(&rect, scale, color, textStyle); -      break; -    case UI_REDBLUE: -      UI_DrawRedBlue(&rect, scale, color, textStyle); -      break; -    case UI_SELECTEDPLAYER: -      UI_DrawSelectedPlayer(&rect, scale, color, textStyle); -      break; -    case UI_SERVERREFRESHDATE: -      UI_DrawServerRefreshDate(&rect, scale, color, textStyle); -      break; -    case UI_SERVERMOTD: -      UI_DrawServerMOTD(&rect, scale, color); -      break; -    case UI_GLINFO: -      UI_DrawGLInfo(&rect,scale, color, textStyle); -      break; -    case UI_KEYBINDSTATUS: -      UI_DrawKeyBindStatus(&rect,scale, color, textStyle); -      break; -    default: -      break; -  } - -} - -static qboolean UI_OwnerDrawVisible(int flags) { -  qboolean vis = qtrue; -  uiClientState_t cs; -  pTeam_t         team; -  char            info[ MAX_INFO_STRING ]; - -  trap_GetClientState( &cs ); -  trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING ); -  team = atoi( Info_ValueForKey( info, "t" ) ); - - -  while (flags) { - -    if( flags & UI_SHOW_NOTSPECTATING ) -    { -      if( team == PTE_NONE ) -        vis = qfalse; - -      flags &= ~UI_SHOW_NOTSPECTATING; -    } - -    if( flags & UI_SHOW_VOTEACTIVE ) -    { -      if( !trap_Cvar_VariableValue( "ui_voteActive" ) ) -        vis = qfalse; - -      flags &= ~UI_SHOW_VOTEACTIVE; -    } - -    if( flags & UI_SHOW_CANVOTE ) -    { -      if( trap_Cvar_VariableValue( "ui_voteActive" ) ) -        vis = qfalse; - -      flags &= ~UI_SHOW_CANVOTE; -    } - -    if( flags & UI_SHOW_TEAMVOTEACTIVE ) -    { -      if( team == PTE_ALIENS ) -      { -        if( !trap_Cvar_VariableValue( "ui_alienTeamVoteActive" ) ) -          vis = qfalse; -      } -      else if( team == PTE_HUMANS ) -      { -        if( !trap_Cvar_VariableValue( "ui_humanTeamVoteActive" ) ) -          vis = qfalse; -      } - -      flags &= ~UI_SHOW_TEAMVOTEACTIVE; -    } - -    if( flags & UI_SHOW_CANTEAMVOTE ) -    { -      if( team == PTE_ALIENS ) -      { -        if( trap_Cvar_VariableValue( "ui_alienTeamVoteActive" ) ) -          vis = qfalse; -      } -      else if( team == PTE_HUMANS ) -      { -        if( trap_Cvar_VariableValue( "ui_humanTeamVoteActive" ) ) -          vis = qfalse; -      } - -      flags &= ~UI_SHOW_CANTEAMVOTE; -    } - -    if (flags & UI_SHOW_LEADER) { -      // these need to show when this client can give orders to a player or a group -      if (!uiInfo.teamLeader) { -        vis = qfalse; -      } else { -        // if showing yourself -        if (ui_selectedPlayer.integer < uiInfo.myTeamCount && uiInfo.teamClientNums[ui_selectedPlayer.integer] == uiInfo.playerNumber) { -          vis = qfalse; -        } -      } -      flags &= ~UI_SHOW_LEADER; -    } -    if (flags & UI_SHOW_NOTLEADER) { -      // these need to show when this client is assigning their own status or they are NOT the leader -      if (uiInfo.teamLeader) { -        // if not showing yourself -        if (!(ui_selectedPlayer.integer < uiInfo.myTeamCount && uiInfo.teamClientNums[ui_selectedPlayer.integer] == uiInfo.playerNumber)) { -          vis = qfalse; -        } -        // these need to show when this client can give orders to a player or a group -      } -      flags &= ~UI_SHOW_NOTLEADER; -    } -    if (flags & UI_SHOW_FAVORITESERVERS) { -      // this assumes you only put this type of display flag on something showing in the proper context -      if (ui_netSource.integer != AS_FAVORITES) { -        vis = qfalse; -      } -      flags &= ~UI_SHOW_FAVORITESERVERS; -    } -    if (flags & UI_SHOW_NOTFAVORITESERVERS) { -      // this assumes you only put this type of display flag on something showing in the proper context -      if (ui_netSource.integer == AS_FAVORITES) { -        vis = qfalse; -      } -      flags &= ~UI_SHOW_NOTFAVORITESERVERS; -    } -    if (flags & UI_SHOW_NEWHIGHSCORE) { -      if (uiInfo.newHighScoreTime < uiInfo.uiDC.realTime) { -        vis = qfalse; -      } else { -        if (uiInfo.soundHighScore) { -          if (trap_Cvar_VariableValue("sv_killserver") == 0) { -            // wait on server to go down before playing sound -            trap_S_StartLocalSound(uiInfo.newHighScoreSound, CHAN_ANNOUNCER); -            uiInfo.soundHighScore = qfalse; -          } -        } -      } -      flags &= ~UI_SHOW_NEWHIGHSCORE; -    } -    if (flags & UI_SHOW_NEWBESTTIME) { -      if (uiInfo.newBestTime < uiInfo.uiDC.realTime) { -        vis = qfalse; -      } -      flags &= ~UI_SHOW_NEWBESTTIME; -    } -    if (flags & UI_SHOW_DEMOAVAILABLE) { -      if (!uiInfo.demoAvailable) { -        vis = qfalse; -      } -      flags &= ~UI_SHOW_DEMOAVAILABLE; -    } else { -      flags = 0; -    } -  } -  return vis; -} - -static qboolean UI_Handicap_HandleKey(int flags, float *special, int key) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { -    int h; -    h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") ); -    if (key == K_MOUSE2) { -      h -= 5; -    } else { -      h += 5; -    } -    if (h > 100) { -      h = 5; -    } else if (h < 0) { -      h = 100; -    } -    trap_Cvar_Set( "handicap", va( "%i", h) ); -    return qtrue; -  } -  return qfalse; -} - -static qboolean UI_ClanName_HandleKey(int flags, float *special, int key) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { -    int i; -    i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); -    if (uiInfo.teamList[i].cinematic >= 0) { -      trap_CIN_StopCinematic(uiInfo.teamList[i].cinematic); -      uiInfo.teamList[i].cinematic = -1; -    } -    if (key == K_MOUSE2) { -      i--; -    } else { -      i++; -    } -    if (i >= uiInfo.teamCount) { -      i = 0; -    } else if (i < 0) { -      i = uiInfo.teamCount - 1; -    } -    trap_Cvar_Set( "ui_teamName", uiInfo.teamList[i].teamName); -  UI_HeadCountByTeam(); -  UI_FeederSelection(FEEDER_HEADS, 0); -  updateModel = qtrue; -    return qtrue; -  } -  return qfalse; -} - -static qboolean UI_GameType_HandleKey(int flags, float *special, int key, qboolean resetMap) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { -    int oldCount = UI_MapCountByGameType(qtrue); - -    // hard coded mess here -    if (key == K_MOUSE2) { -      ui_gameType.integer--; -      if (ui_gameType.integer == 2) { -        ui_gameType.integer = 1; -      } else if (ui_gameType.integer < 2) { -        ui_gameType.integer = uiInfo.numGameTypes - 1; -      } -    } else { -      ui_gameType.integer++; -      if (ui_gameType.integer >= uiInfo.numGameTypes) { -        ui_gameType.integer = 1; -      } else if (ui_gameType.integer == 2) { -        ui_gameType.integer = 3; -      } -    } - -    trap_Cvar_Set("ui_Q3Model", "0"); - -    trap_Cvar_Set("ui_gameType", va("%d", ui_gameType.integer)); -    UI_SetCapFragLimits(qtrue); -    UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum); -    if (resetMap && oldCount != UI_MapCountByGameType(qtrue)) { -      trap_Cvar_Set( "ui_currentMap", "0"); -      Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, NULL); -    } -    return qtrue; -  } -  return qfalse; -} - -static qboolean UI_NetGameType_HandleKey(int flags, float *special, int key) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { - -    if (key == K_MOUSE2) { -      ui_netGameType.integer--; -    } else { -      ui_netGameType.integer++; -    } - -    if (ui_netGameType.integer < 0) { -      ui_netGameType.integer = uiInfo.numGameTypes - 1; -    } else if (ui_netGameType.integer >= uiInfo.numGameTypes) { -      ui_netGameType.integer = 0; -    } - -    trap_Cvar_Set( "ui_netGameType", va("%d", ui_netGameType.integer)); -    trap_Cvar_Set( "ui_actualnetGameType", va("%d", uiInfo.gameTypes[ui_netGameType.integer].gtEnum)); -    trap_Cvar_Set( "ui_currentNetMap", "0"); -    UI_MapCountByGameType(qfalse); -    Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, NULL); -    return qtrue; -  } -  return qfalse; -} - -static qboolean UI_JoinGameType_HandleKey(int flags, float *special, int key) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { - -    if (key == K_MOUSE2) { -      ui_joinGameType.integer--; -    } else { -      ui_joinGameType.integer++; -    } - -    if (ui_joinGameType.integer < 0) { -      ui_joinGameType.integer = uiInfo.numJoinGameTypes - 1; -    } else if (ui_joinGameType.integer >= uiInfo.numJoinGameTypes) { -      ui_joinGameType.integer = 0; -    } - -    trap_Cvar_Set( "ui_joinGameType", va("%d", ui_joinGameType.integer)); -    UI_BuildServerDisplayList(qtrue); -    return qtrue; -  } -  return qfalse; -} - - - -static qboolean UI_Skill_HandleKey(int flags, float *special, int key) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { -    int i = trap_Cvar_VariableValue( "g_spSkill" ); - -    if (key == K_MOUSE2) { -      i--; -    } else { -      i++; -    } - -    if (i < 1) { -      i = numSkillLevels; -    } else if (i > numSkillLevels) { -      i = 1; -    } - -    trap_Cvar_Set("g_spSkill", va("%i", i)); -    return qtrue; -  } -  return qfalse; -} - -static qboolean UI_TeamName_HandleKey(int flags, float *special, int key, qboolean blue) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { -    int i; -    i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam")); - -    if (key == K_MOUSE2) { -      i--; -    } else { -      i++; -    } - -    if (i >= uiInfo.teamCount) { -      i = 0; -    } else if (i < 0) { -      i = uiInfo.teamCount - 1; -    } - -    trap_Cvar_Set( (blue) ? "ui_blueTeam" : "ui_redTeam", uiInfo.teamList[i].teamName); - -    return qtrue; -  } -  return qfalse; -} - -static qboolean UI_TeamMember_HandleKey(int flags, float *special, int key, qboolean blue, int num) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { -    // 0 - None -    // 1 - Human -    // 2..NumCharacters - Bot -    char *cvar = va(blue ? "ui_blueteam%i" : "ui_redteam%i", num); -    int value = trap_Cvar_VariableValue(cvar); - -    if (key == K_MOUSE2) { -      value--; -    } else { -      value++; -    } - -    if( value >= UI_GetNumBots( ) + 2 ) -      value = 0; -    else if( value < 0 ) -      value = UI_GetNumBots( ) + 2 - 1; - -    trap_Cvar_Set(cvar, va("%i", value)); -    return qtrue; -  } -  return qfalse; -} - -static qboolean UI_NetSource_HandleKey(int flags, float *special, int key) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { - -    if (key == K_MOUSE2) { -      ui_netSource.integer--; -      if (ui_netSource.integer == AS_MPLAYER) -        ui_netSource.integer--; -    } else { -      ui_netSource.integer++; -      if (ui_netSource.integer == AS_MPLAYER) -        ui_netSource.integer++; -    } - -    if (ui_netSource.integer >= numNetSources) { -      ui_netSource.integer = 0; -    } else if (ui_netSource.integer < 0) { -      ui_netSource.integer = numNetSources - 1; -    } - -    UI_BuildServerDisplayList(qtrue); -    if (ui_netSource.integer != AS_GLOBAL) { -      UI_StartServerRefresh(qtrue); -    } -    trap_Cvar_Set( "ui_netSource", va("%d", ui_netSource.integer)); -    return qtrue; -  } -  return qfalse; -} - -static qboolean UI_NetFilter_HandleKey(int flags, float *special, int key) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { - -    if (key == K_MOUSE2) { -      ui_serverFilterType.integer--; -    } else { -      ui_serverFilterType.integer++; -    } - -    if (ui_serverFilterType.integer >= numServerFilters) { -      ui_serverFilterType.integer = 0; -    } else if (ui_serverFilterType.integer < 0) { -      ui_serverFilterType.integer = numServerFilters - 1; -    } -    UI_BuildServerDisplayList(qtrue); -    return qtrue; -  } -  return qfalse; -} - -static qboolean UI_OpponentName_HandleKey(int flags, float *special, int key) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { -    if (key == K_MOUSE2) { -      UI_PriorOpponent(); -    } else { -      UI_NextOpponent(); -    } -    return qtrue; -  } -  return qfalse; -} - -static qboolean UI_BotName_HandleKey(int flags, float *special, int key) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { -    int value = uiInfo.botIndex; - -    if (key == K_MOUSE2) { -      value--; -    } else { -      value++; -    } - - -    if( value >= UI_GetNumBots( ) + 2 ) -      value = 0; -    else if( value < 0 ) -      value = UI_GetNumBots( ) + 2 - 1; - -    uiInfo.botIndex = value; -    return qtrue; -  } -  return qfalse; -} - -static qboolean UI_BotSkill_HandleKey(int flags, float *special, int key) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { -    if (key == K_MOUSE2) { -      uiInfo.skillIndex--; -    } else { -      uiInfo.skillIndex++; -    } -    if (uiInfo.skillIndex >= numSkillLevels) { -      uiInfo.skillIndex = 0; -    } else if (uiInfo.skillIndex < 0) { -      uiInfo.skillIndex = numSkillLevels-1; -    } -    return qtrue; -  } -  return qfalse; -} - -static qboolean UI_RedBlue_HandleKey(int flags, float *special, int key) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { -    uiInfo.redBlue ^= 1; -    return qtrue; -  } -  return qfalse; -} - - - -static qboolean UI_SelectedPlayer_HandleKey(int flags, float *special, int key) { -  if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { -    int selected; - -    UI_BuildPlayerList(); -    if (!uiInfo.teamLeader) { -      return qfalse; -    } -    selected = trap_Cvar_VariableValue("cg_selectedPlayer"); - -    if (key == K_MOUSE2) { -      selected--; -    } else { -      selected++; -    } - -    if (selected > uiInfo.myTeamCount) { -      selected = 0; -    } else if (selected < 0) { -      selected = uiInfo.myTeamCount; -    } - -    if (selected == uiInfo.myTeamCount) { -      trap_Cvar_Set( "cg_selectedPlayerName", "Everyone"); -    } else { -      trap_Cvar_Set( "cg_selectedPlayerName", uiInfo.teamNames[selected]); -    } -    trap_Cvar_Set( "cg_selectedPlayer", va("%d", selected)); -  } -  return qfalse; -} - - -static qboolean UI_OwnerDrawHandleKey(int ownerDraw, int flags, float *special, int key) { -  switch (ownerDraw) { -    case UI_HANDICAP: -      return UI_Handicap_HandleKey(flags, special, key); -      break; -    case UI_CLANNAME: -      return UI_ClanName_HandleKey(flags, special, key); -      break; -    case UI_GAMETYPE: -      return UI_GameType_HandleKey(flags, special, key, qtrue); -      break; -    case UI_NETGAMETYPE: -      return UI_NetGameType_HandleKey(flags, special, key); -      break; -    case UI_JOINGAMETYPE: -      return UI_JoinGameType_HandleKey(flags, special, key); -      break; -    case UI_SKILL: -      return UI_Skill_HandleKey(flags, special, key); -      break; -    case UI_BLUETEAMNAME: -      return UI_TeamName_HandleKey(flags, special, key, qtrue); -      break; -    case UI_REDTEAMNAME: -      return UI_TeamName_HandleKey(flags, special, key, qfalse); -      break; -    case UI_BLUETEAM1: -    case UI_BLUETEAM2: -    case UI_BLUETEAM3: -    case UI_BLUETEAM4: -    case UI_BLUETEAM5: -      UI_TeamMember_HandleKey(flags, special, key, qtrue, ownerDraw - UI_BLUETEAM1 + 1); -      break; -    case UI_REDTEAM1: -    case UI_REDTEAM2: -    case UI_REDTEAM3: -    case UI_REDTEAM4: -    case UI_REDTEAM5: -      UI_TeamMember_HandleKey(flags, special, key, qfalse, ownerDraw - UI_REDTEAM1 + 1); -      break; -    case UI_NETSOURCE: -      UI_NetSource_HandleKey(flags, special, key); -      break; -    case UI_NETFILTER: -      UI_NetFilter_HandleKey(flags, special, key); -      break; -    case UI_OPPONENT_NAME: -      UI_OpponentName_HandleKey(flags, special, key); -      break; -    case UI_BOTNAME: -      return UI_BotName_HandleKey(flags, special, key); -      break; -    case UI_BOTSKILL: -      return UI_BotSkill_HandleKey(flags, special, key); -      break; -    case UI_REDBLUE: -      UI_RedBlue_HandleKey(flags, special, key); -      break; -    case UI_SELECTEDPLAYER: -      UI_SelectedPlayer_HandleKey(flags, special, key); -      break; -    default: -      break; -  } - -  return qfalse; -} - - -static float UI_GetValue(int ownerDraw) { -  return 0; -} - -/* -================= -UI_ServersQsortCompare -================= -*/ -static int QDECL UI_ServersQsortCompare( const void *arg1, const void *arg2 ) { -  return trap_LAN_CompareServers( ui_netSource.integer, uiInfo.serverStatus.sortKey, uiInfo.serverStatus.sortDir, *(int*)arg1, *(int*)arg2); -} - - -/* -================= -UI_ServersSort -================= -*/ -void UI_ServersSort(int column, qboolean force) { - -  if ( !force ) { -    if ( uiInfo.serverStatus.sortKey == column ) { -      return; -    } -  } - -  uiInfo.serverStatus.sortKey = column; -  qsort( &uiInfo.serverStatus.displayServers[0], uiInfo.serverStatus.numDisplayServers, sizeof(int), UI_ServersQsortCompare); -} - - -/* -=============== -UI_GetCurrentAlienStage -=============== -*/ -static stage_t UI_GetCurrentAlienStage( void ) -{ -  char    buffer[ MAX_TOKEN_CHARS ]; -  stage_t stage, dummy; - -  trap_Cvar_VariableStringBuffer( "ui_stages", buffer, sizeof( buffer ) ); -  sscanf( buffer, "%d %d", (int *)&stage , (int *)&dummy ); - -  return stage; -} - -/* -=============== -UI_GetCurrentHumanStage -=============== -*/ -static stage_t UI_GetCurrentHumanStage( void ) -{ -  char    buffer[ MAX_TOKEN_CHARS ]; -  stage_t stage, dummy; - -  trap_Cvar_VariableStringBuffer( "ui_stages", buffer, sizeof( buffer ) ); -  sscanf( buffer, "%d %d", (int *)&dummy, (int *)&stage ); - -  return stage; -} - -/* -=============== -UI_LoadTremTeams -=============== -*/ -static void UI_LoadTremTeams( void ) -{ -  uiInfo.tremTeamCount = 4; - -  uiInfo.tremTeamList[ 0 ].text = String_Alloc( "Aliens" ); -  uiInfo.tremTeamList[ 0 ].cmd = String_Alloc( "cmd team aliens\n" ); -  uiInfo.tremTeamList[ 0 ].infopane = UI_FindInfoPaneByName( "alienteam" ); - -  uiInfo.tremTeamList[ 1 ].text = String_Alloc( "Humans" ); -  uiInfo.tremTeamList[ 1 ].cmd = String_Alloc( "cmd team humans\n" ); -  uiInfo.tremTeamList[ 1 ].infopane = UI_FindInfoPaneByName( "humanteam" ); - -  uiInfo.tremTeamList[ 2 ].text = String_Alloc( "Spectate" ); -  uiInfo.tremTeamList[ 2 ].cmd = String_Alloc( "cmd team spectate\n" ); -  uiInfo.tremTeamList[ 2 ].infopane = UI_FindInfoPaneByName( "spectateteam" ); - -  uiInfo.tremTeamList[ 3 ].text = String_Alloc( "Auto select" ); -  uiInfo.tremTeamList[ 3 ].cmd = String_Alloc( "cmd team auto\n" ); -  uiInfo.tremTeamList[ 3 ].infopane = UI_FindInfoPaneByName( "autoteam" ); -} - -/* -============ -UI_WeaponIsAllowed -============ -*/ -qboolean UI_WeaponIsAllowed( weapon_t weapon ) -{ -  int       i; -  weapon_t  weapons[ WP_NUM_WEAPONS ]; -  char      cvar[ MAX_CVAR_VALUE_STRING ]; - -  trap_Cvar_VariableStringBuffer( "g_disabledEquipment", -      cvar, MAX_CVAR_VALUE_STRING ); - -  BG_ParseCSVEquipmentList( cvar, weapons, WP_NUM_WEAPONS, NULL, 0 ); - -  for( i = 0; i < WP_NUM_WEAPONS && -      weapons[ i ] != WP_NONE; i++ ) -  { -    if( weapons[ i ] == weapon ) -      return qfalse; -  } - -  return qtrue; -} - -/* -============ -UI_UpgradeIsAllowed -============ -*/ -qboolean UI_UpgradeIsAllowed( upgrade_t upgrade ) -{ -  int       i; -  upgrade_t upgrades[ UP_NUM_UPGRADES ]; -  char      cvar[ MAX_CVAR_VALUE_STRING ]; - -  trap_Cvar_VariableStringBuffer( "g_disabledEquipment", -      cvar, MAX_CVAR_VALUE_STRING ); - -  BG_ParseCSVEquipmentList( cvar, NULL, 0, upgrades, UP_NUM_UPGRADES ); - -  for( i = 0; i < UP_NUM_UPGRADES && -      upgrades[ i ] != UP_NONE; i++ ) -  { -    if( upgrades[ i ] == upgrade ) -      return qfalse; -  } - -  return qtrue; -} - -/* -============ -UI_ClassIsAllowed -============ -*/ -qboolean UI_ClassIsAllowed( pClass_t class ) -{ -  int       i; -  pClass_t  classes[ PCL_NUM_CLASSES ]; -  char      cvar[ MAX_CVAR_VALUE_STRING ]; - -  trap_Cvar_VariableStringBuffer( "g_disabledClasses", -      cvar, MAX_CVAR_VALUE_STRING ); - -  BG_ParseCSVClassList( cvar, classes, PCL_NUM_CLASSES ); - -  for( i = 0; i < PCL_NUM_CLASSES && -      classes[ i ] != PCL_NONE; i++ ) -  { -    if( classes[ i ] == class ) -      return qfalse; -  } - -  return qtrue; -} - -/* -============ -UI_BuildableIsAllowed -============ -*/ -qboolean UI_BuildableIsAllowed( buildable_t buildable ) -{ -  int         i; -  buildable_t buildables[ BA_NUM_BUILDABLES ]; -  char        cvar[ MAX_CVAR_VALUE_STRING ]; - -  trap_Cvar_VariableStringBuffer( "g_disabledBuildables", -      cvar, MAX_CVAR_VALUE_STRING ); - -  BG_ParseCSVBuildableList( cvar, buildables, BA_NUM_BUILDABLES ); - -  for( i = 0; i < BA_NUM_BUILDABLES && -      buildables[ i ] != BA_NONE; i++ ) -  { -    if( buildables[ i ] == buildable ) -      return qfalse; -  } - -  return qtrue; -} - -/* -=============== -UI_AddClass -=============== -*/ -static void UI_AddClass( pClass_t class ) -{ -  uiInfo.tremAlienClassList[ uiInfo.tremAlienClassCount ].text = -    String_Alloc( BG_FindHumanNameForClassNum( class ) ); -  uiInfo.tremAlienClassList[ uiInfo.tremAlienClassCount ].cmd = -    String_Alloc( va( "cmd class %s\n", BG_FindNameForClassNum( class ) ) ); -  uiInfo.tremAlienClassList[ uiInfo.tremAlienClassCount ].infopane = -    UI_FindInfoPaneByName( va( "%sclass", BG_FindNameForClassNum( class ) ) ); - -  uiInfo.tremAlienClassCount++; -} - -/* -=============== -UI_LoadTremAlienClasses -=============== -*/ -static void UI_LoadTremAlienClasses( void ) -{ -  uiInfo.tremAlienClassCount = 0; - -  if( UI_ClassIsAllowed( PCL_ALIEN_LEVEL0 ) ) -    UI_AddClass( PCL_ALIEN_LEVEL0 ); - -  if( UI_ClassIsAllowed( PCL_ALIEN_BUILDER0_UPG ) && -      BG_FindStagesForClass( PCL_ALIEN_BUILDER0_UPG, UI_GetCurrentAlienStage( ) ) ) -    UI_AddClass( PCL_ALIEN_BUILDER0_UPG ); -  else if( UI_ClassIsAllowed( PCL_ALIEN_BUILDER0 ) ) -    UI_AddClass( PCL_ALIEN_BUILDER0 ); -} - -/* -=============== -UI_AddItem -=============== -*/ -static void UI_AddItem( weapon_t weapon ) -{ -  uiInfo.tremHumanItemList[ uiInfo.tremHumanItemCount ].text = -    String_Alloc( BG_FindHumanNameForWeapon( weapon ) ); -  uiInfo.tremHumanItemList[ uiInfo.tremHumanItemCount ].cmd = -    String_Alloc( va( "cmd class %s\n", BG_FindNameForWeapon( weapon ) ) ); -  uiInfo.tremHumanItemList[ uiInfo.tremHumanItemCount ].infopane = -    UI_FindInfoPaneByName( va( "%sitem", BG_FindNameForWeapon( weapon ) ) ); - -  uiInfo.tremHumanItemCount++; -} - -/* -=============== -UI_LoadTremHumanItems -=============== -*/ -static void UI_LoadTremHumanItems( void ) -{ -  uiInfo.tremHumanItemCount = 0; - -  if( UI_WeaponIsAllowed( WP_MACHINEGUN ) ) -    UI_AddItem( WP_MACHINEGUN ); - -  if( UI_WeaponIsAllowed( WP_HBUILD2 ) && -      BG_FindStagesForWeapon( WP_HBUILD2, UI_GetCurrentHumanStage( ) ) ) -    UI_AddItem( WP_HBUILD2 ); -  else if( UI_WeaponIsAllowed( WP_HBUILD ) ) -    UI_AddItem( WP_HBUILD ); -} - -/* -=============== -UI_ParseCarriageList -=============== -*/ -static void UI_ParseCarriageList( int *weapons, int *upgrades ) -{ -  int  i; -  char carriageCvar[ MAX_TOKEN_CHARS ]; -  char *iterator; -  char buffer[ MAX_TOKEN_CHARS ]; -  char *bufPointer; - -  trap_Cvar_VariableStringBuffer( "ui_carriage", carriageCvar, sizeof( carriageCvar ) ); -  iterator = carriageCvar; - -  if( weapons ) -    *weapons = 0; - -  if( upgrades ) -    *upgrades = 0; - -  //simple parser to give rise to weapon/upgrade list -  while( iterator && iterator[ 0 ] != '$' ) -  { -    bufPointer = buffer; - -    if( iterator[ 0 ] == 'W' ) -    { -      iterator++; - -      while( iterator[ 0 ] != ' ' ) -        *bufPointer++ = *iterator++; - -      *bufPointer++ = '\n'; - -      i = atoi( buffer ); - -      if( weapons ) -        *weapons |= ( 1 << i ); -    } -    else if( iterator[ 0 ] == 'U' ) -    { -      iterator++; - -      while( iterator[ 0 ] != ' ' ) -        *bufPointer++ = *iterator++; - -      *bufPointer++ = '\n'; - -      i = atoi( buffer ); - -      if( upgrades ) -        *upgrades |= ( 1 << i ); -    } - -    iterator++; -  } -} - -/* -=============== -UI_LoadTremHumanArmouryBuys -=============== -*/ -static void UI_LoadTremHumanArmouryBuys( void ) -{ -  int i, j = 0; -  stage_t stage = UI_GetCurrentHumanStage( ); -  int weapons, upgrades; -  int slots = 0; - -  UI_ParseCarriageList( &weapons, &upgrades ); - -  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) -  { -    if( weapons & ( 1 << i ) ) -      slots |= BG_FindSlotsForWeapon( i ); -  } - -  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -  { -    if( upgrades & ( 1 << i ) ) -      slots |= BG_FindSlotsForUpgrade( i ); -  } - -  uiInfo.tremHumanArmouryBuyCount = 0; - -  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) -  { -    if( BG_FindTeamForWeapon( i ) == WUT_HUMANS && -        BG_FindPurchasableForWeapon( i ) && -        BG_FindStagesForWeapon( i, stage ) && -        UI_WeaponIsAllowed( i ) && -        !( BG_FindSlotsForWeapon( i ) & slots ) && -        !( weapons & ( 1 << i ) ) ) -    { -      uiInfo.tremHumanArmouryBuyList[ j ].text = -        String_Alloc( BG_FindHumanNameForWeapon( i ) ); -      uiInfo.tremHumanArmouryBuyList[ j ].cmd = -        String_Alloc( va( "cmd buy %s retrigger\n", BG_FindNameForWeapon( i ) ) ); -      uiInfo.tremHumanArmouryBuyList[ j ].infopane = -        UI_FindInfoPaneByName( va( "%sitem", BG_FindNameForWeapon( i ) ) ); - -      j++; - -      uiInfo.tremHumanArmouryBuyCount++; -    } -  } - -  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -  { -    if( BG_FindTeamForUpgrade( i ) == WUT_HUMANS && -        BG_FindPurchasableForUpgrade( i ) && -        BG_FindStagesForUpgrade( i, stage ) && -        UI_UpgradeIsAllowed( i ) && -        !( BG_FindSlotsForUpgrade( i ) & slots ) && -        !( upgrades & ( 1 << i ) ) ) -    { -      uiInfo.tremHumanArmouryBuyList[ j ].text = -        String_Alloc( BG_FindHumanNameForUpgrade( i ) ); -      uiInfo.tremHumanArmouryBuyList[ j ].cmd = -        String_Alloc( va( "cmd buy %s retrigger\n", BG_FindNameForUpgrade( i ) ) ); -      uiInfo.tremHumanArmouryBuyList[ j ].infopane = -        UI_FindInfoPaneByName( va( "%sitem", BG_FindNameForUpgrade( i ) ) ); - -      j++; - -      uiInfo.tremHumanArmouryBuyCount++; -    } -  } -} - -/* -=============== -UI_LoadTremHumanArmourySells -=============== -*/ -static void UI_LoadTremHumanArmourySells( void ) -{ -  int weapons, upgrades; -  int i, j = 0; - -  uiInfo.tremHumanArmourySellCount = 0; -  UI_ParseCarriageList( &weapons, &upgrades ); - -  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) -  { -    if( weapons & ( 1 << i ) ) -    { -      uiInfo.tremHumanArmourySellList[ j ].text = String_Alloc( BG_FindHumanNameForWeapon( i ) ); -      uiInfo.tremHumanArmourySellList[ j ].cmd = -        String_Alloc( va( "cmd sell %s retrigger\n", BG_FindNameForWeapon( i ) ) ); -      uiInfo.tremHumanArmourySellList[ j ].infopane = -        UI_FindInfoPaneByName( va( "%sitem", BG_FindNameForWeapon( i ) ) ); - -      j++; - -      uiInfo.tremHumanArmourySellCount++; -    } -  } - -  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) -  { -    if( upgrades & ( 1 << i ) ) -    { -      uiInfo.tremHumanArmourySellList[ j ].text = String_Alloc( BG_FindHumanNameForUpgrade( i ) ); -      uiInfo.tremHumanArmourySellList[ j ].cmd = -        String_Alloc( va( "cmd sell %s retrigger\n", BG_FindNameForUpgrade( i ) ) ); -      uiInfo.tremHumanArmourySellList[ j ].infopane = -        UI_FindInfoPaneByName( va( "%sitem", BG_FindNameForUpgrade( i ) ) ); - -      j++; - -      uiInfo.tremHumanArmourySellCount++; -    } -  } -} - -/* -=============== -UI_LoadTremAlienUpgrades -=============== -*/ -static void UI_LoadTremAlienUpgrades( void ) -{ -  int     i, j = 0; -  int     class, credits; -  char    ui_currentClass[ MAX_STRING_CHARS ]; -  stage_t stage = UI_GetCurrentAlienStage( ); - -  trap_Cvar_VariableStringBuffer( "ui_currentClass", ui_currentClass, MAX_STRING_CHARS ); -  sscanf( ui_currentClass, "%d %d", &class, &credits ); - -  uiInfo.tremAlienUpgradeCount = 0; - -  for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ ) -  { -    if( BG_ClassCanEvolveFromTo( class, i, credits, 0 ) >= 0 && -        BG_FindStagesForClass( i, stage ) && -        UI_ClassIsAllowed( i ) ) -    { -      uiInfo.tremAlienUpgradeList[ j ].text = String_Alloc( BG_FindHumanNameForClassNum( i ) ); -      uiInfo.tremAlienUpgradeList[ j ].cmd = -        String_Alloc( va( "cmd class %s\n", BG_FindNameForClassNum( i ) ) ); -      uiInfo.tremAlienUpgradeList[ j ].infopane = -        UI_FindInfoPaneByName( va( "%sclass", BG_FindNameForClassNum( i ) ) ); - -      j++; - -      uiInfo.tremAlienUpgradeCount++; -    } -  } -} - -/* -=============== -UI_LoadTremAlienBuilds -=============== -*/ -static void UI_LoadTremAlienBuilds( void ) -{ -  int     weapons; -  int     i, j = 0; -  stage_t stage; - -  UI_ParseCarriageList( &weapons, NULL ); -  stage = UI_GetCurrentAlienStage( ); - -  uiInfo.tremAlienBuildCount = 0; - -  for( i = BA_NONE +1; i < BA_NUM_BUILDABLES; i++ ) -  { -    if( BG_FindTeamForBuildable( i ) == BIT_ALIENS && -        BG_FindBuildWeaponForBuildable( i ) & weapons && -        BG_FindStagesForBuildable( i, stage ) && -        UI_BuildableIsAllowed( i ) ) -    { -      uiInfo.tremAlienBuildList[ j ].text = -        String_Alloc( BG_FindHumanNameForBuildable( i ) ); -      uiInfo.tremAlienBuildList[ j ].cmd = -        String_Alloc( va( "cmd build %s\n", BG_FindNameForBuildable( i ) ) ); -      uiInfo.tremAlienBuildList[ j ].infopane = -        UI_FindInfoPaneByName( va( "%sbuild", BG_FindNameForBuildable( i ) ) ); - -      j++; - -      uiInfo.tremAlienBuildCount++; -    } -  } -} - -/* -=============== -UI_LoadTremHumanBuilds -=============== -*/ -static void UI_LoadTremHumanBuilds( void ) -{ -  int     weapons; -  int     i, j = 0; -  stage_t stage; - -  UI_ParseCarriageList( &weapons, NULL ); -  stage = UI_GetCurrentHumanStage( ); - -  uiInfo.tremHumanBuildCount = 0; - -  for( i = BA_NONE +1; i < BA_NUM_BUILDABLES; i++ ) -  { -    if( BG_FindTeamForBuildable( i ) == BIT_HUMANS && -        BG_FindBuildWeaponForBuildable( i ) & weapons && -        BG_FindStagesForBuildable( i, stage ) && -        UI_BuildableIsAllowed( i ) ) -    { -      uiInfo.tremHumanBuildList[ j ].text = -        String_Alloc( BG_FindHumanNameForBuildable( i ) ); -      uiInfo.tremHumanBuildList[ j ].cmd = -        String_Alloc( va( "cmd build %s\n", BG_FindNameForBuildable( i ) ) ); -      uiInfo.tremHumanBuildList[ j ].infopane = -        UI_FindInfoPaneByName( va( "%sbuild", BG_FindNameForBuildable( i ) ) ); - -      j++; - -      uiInfo.tremHumanBuildCount++; -    } -  } -} - -/* -=============== -UI_LoadMods -=============== -*/ -static void UI_LoadMods( void ) { -  int   numdirs; -  char  dirlist[2048]; -  char  *dirptr; -  char  *descptr; -  int   i; -  int   dirlen; - -  uiInfo.modCount = 0; -  numdirs = trap_FS_GetFileList( "$modlist", "", dirlist, sizeof(dirlist) ); -  dirptr  = dirlist; -  for( i = 0; i < numdirs; i++ ) { -    dirlen = strlen( dirptr ) + 1; -    descptr = dirptr + dirlen; -    uiInfo.modList[uiInfo.modCount].modName = String_Alloc(dirptr); -    uiInfo.modList[uiInfo.modCount].modDescr = String_Alloc(descptr); -    dirptr += dirlen + strlen(descptr) + 1; -    uiInfo.modCount++; -    if (uiInfo.modCount >= MAX_MODS) { -      break; -    } -  } - -} - - -/* -=============== -UI_LoadMovies -=============== -*/ -static void UI_LoadMovies( void ) { -  char  movielist[4096]; -  char  *moviename; -  int   i, len; - -  uiInfo.movieCount = trap_FS_GetFileList( "video", "roq", movielist, 4096 ); - -  if (uiInfo.movieCount) { -    if (uiInfo.movieCount > MAX_MOVIES) { -      uiInfo.movieCount = MAX_MOVIES; -    } -    moviename = movielist; -    for ( i = 0; i < uiInfo.movieCount; i++ ) { -      len = strlen( moviename ); -      if (!Q_stricmp(moviename +  len - 4,".roq")) { -        moviename[len-4] = '\0'; -      } -      Q_strupr(moviename); -      uiInfo.movieList[i] = String_Alloc(moviename); -      moviename += len + 1; -    } -  } - -} - - - -/* -=============== -UI_LoadDemos -=============== -*/ -static void UI_LoadDemos( void ) { -  char  demolist[4096]; -  char demoExt[32]; -  char  *demoname; -  int   i, len; - -  Com_sprintf(demoExt, sizeof(demoExt), "dm_%d", (int)trap_Cvar_VariableValue("protocol")); - -  uiInfo.demoCount = trap_FS_GetFileList( "demos", demoExt, demolist, 4096 ); - -  Com_sprintf(demoExt, sizeof(demoExt), ".dm_%d", (int)trap_Cvar_VariableValue("protocol")); - -  if (uiInfo.demoCount) { -    if (uiInfo.demoCount > MAX_DEMOS) { -      uiInfo.demoCount = MAX_DEMOS; -    } -    demoname = demolist; -    for ( i = 0; i < uiInfo.demoCount; i++ ) { -      len = strlen( demoname ); -      if (!Q_stricmp(demoname +  len - strlen(demoExt), demoExt)) { -        demoname[len-strlen(demoExt)] = '\0'; -      } -      Q_strupr(demoname); -      uiInfo.demoList[i] = String_Alloc(demoname); -      demoname += len + 1; -    } -  } - -} - - -static qboolean UI_SetNextMap(int actual, int index) { -  int i; -  for (i = actual + 1; i < uiInfo.mapCount; i++) { -    if (uiInfo.mapList[i].active) { -      Menu_SetFeederSelection(NULL, FEEDER_MAPS, index + 1, "skirmish"); -      return qtrue; -    } -  } -  return qfalse; -} - - -static void UI_StartSkirmish(qboolean next) { -  int i, k, g, delay, temp; -  float skill; -  char buff[MAX_STRING_CHARS]; - -  if (next) { -    int actual; -    int index = trap_Cvar_VariableValue("ui_mapIndex"); -    UI_MapCountByGameType(qtrue); -    UI_SelectedMap(index, &actual); -    if (UI_SetNextMap(actual, index)) { -    } else { -      UI_GameType_HandleKey(0, NULL, K_MOUSE1, qfalse); -      UI_MapCountByGameType(qtrue); -      Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, "skirmish"); -    } -  } - -  g = uiInfo.gameTypes[ui_gameType.integer].gtEnum; -  trap_Cvar_SetValue( "g_gametype", g ); -  trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.mapList[ui_currentMap.integer].mapLoadName) ); -  skill = trap_Cvar_VariableValue( "g_spSkill" ); -  trap_Cvar_Set("ui_scoreMap", uiInfo.mapList[ui_currentMap.integer].mapName); - -  k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); - -  trap_Cvar_Set("ui_singlePlayerActive", "1"); - -  // set up sp overrides, will be replaced on postgame -  temp = trap_Cvar_VariableValue( "capturelimit" ); -  trap_Cvar_Set("ui_saveCaptureLimit", va("%i", temp)); -  temp = trap_Cvar_VariableValue( "fraglimit" ); -  trap_Cvar_Set("ui_saveFragLimit", va("%i", temp)); - -  UI_SetCapFragLimits(qfalse); - -  temp = trap_Cvar_VariableValue( "cg_drawTimer" ); -  trap_Cvar_Set("ui_drawTimer", va("%i", temp)); -  temp = trap_Cvar_VariableValue( "g_doWarmup" ); -  trap_Cvar_Set("ui_doWarmup", va("%i", temp)); -  temp = trap_Cvar_VariableValue( "g_friendlyFire" ); -  trap_Cvar_Set("ui_friendlyFire", va("%i", temp)); -  temp = trap_Cvar_VariableValue( "sv_maxClients" ); -  trap_Cvar_Set("ui_maxClients", va("%i", temp)); -  temp = trap_Cvar_VariableValue( "g_warmup" ); -  trap_Cvar_Set("ui_Warmup", va("%i", temp)); -  temp = trap_Cvar_VariableValue( "sv_pure" ); -  trap_Cvar_Set("ui_pure", va("%i", temp)); - -  trap_Cvar_Set("cg_cameraOrbit", "0"); -  trap_Cvar_Set("cg_thirdPerson", "0"); -  trap_Cvar_Set("cg_drawTimer", "1"); -  trap_Cvar_Set("g_doWarmup", "1"); -  trap_Cvar_Set("g_warmup", "15"); -  trap_Cvar_Set("sv_pure", "0"); -  trap_Cvar_Set("g_friendlyFire", "0"); -  trap_Cvar_Set("g_redTeam", UI_Cvar_VariableString("ui_teamName")); -  trap_Cvar_Set("g_blueTeam", UI_Cvar_VariableString("ui_opponentName")); - -  if (trap_Cvar_VariableValue("ui_recordSPDemo")) { -    Com_sprintf(buff, MAX_STRING_CHARS, "%s_%i", uiInfo.mapList[ui_currentMap.integer].mapLoadName, g); -    trap_Cvar_Set("ui_recordSPDemoName", buff); -  } - -  delay = 500; - -  { -    temp = uiInfo.mapList[ui_currentMap.integer].teamMembers * 2; -    trap_Cvar_Set("sv_maxClients", va("%d", temp)); -    for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers; i++) { -      Com_sprintf( buff, sizeof(buff), "addbot %s %f %s %i %s\n", UI_AIFromName(uiInfo.teamList[k].teamMembers[i]), skill, "", delay, uiInfo.teamList[k].teamMembers[i]); -      trap_Cmd_ExecuteText( EXEC_APPEND, buff ); -      delay += 500; -    } -    k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); -    for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers-1; i++) { -      Com_sprintf( buff, sizeof(buff), "addbot %s %f %s %i %s\n", UI_AIFromName(uiInfo.teamList[k].teamMembers[i]), skill, "", delay, uiInfo.teamList[k].teamMembers[i]); -      trap_Cmd_ExecuteText( EXEC_APPEND, buff ); -      delay += 500; -    } -  } -} - -static void UI_Update(const char *name) { -  int val = trap_Cvar_VariableValue(name); - -  if (Q_stricmp(name, "ui_SetName") == 0) { -    trap_Cvar_Set( "name", UI_Cvar_VariableString("ui_Name")); -  } else if (Q_stricmp(name, "ui_setRate") == 0) { -    float rate = trap_Cvar_VariableValue("rate"); -    if (rate >= 5000) { -      trap_Cvar_Set("cl_maxpackets", "30"); -      trap_Cvar_Set("cl_packetdup", "1"); -    } else if (rate >= 4000) { -      trap_Cvar_Set("cl_maxpackets", "15"); -      trap_Cvar_Set("cl_packetdup", "2");   // favor less prediction errors when there's packet loss -    } else { -      trap_Cvar_Set("cl_maxpackets", "15"); -      trap_Cvar_Set("cl_packetdup", "1");   // favor lower bandwidth -    } -  } else if (Q_stricmp(name, "ui_GetName") == 0) { -    trap_Cvar_Set( "ui_Name", UI_Cvar_VariableString("name")); -  } else if (Q_stricmp(name, "r_colorbits") == 0) { -    switch (val) { -      case 0: -        trap_Cvar_SetValue( "r_depthbits", 0 ); -        trap_Cvar_SetValue( "r_stencilbits", 0 ); -      break; -      case 16: -        trap_Cvar_SetValue( "r_depthbits", 16 ); -        trap_Cvar_SetValue( "r_stencilbits", 0 ); -      break; -      case 32: -        trap_Cvar_SetValue( "r_depthbits", 24 ); -      break; -    } -  } else if (Q_stricmp(name, "r_lodbias") == 0) { -    switch (val) { -      case 0: -        trap_Cvar_SetValue( "r_subdivisions", 4 ); -      break; -      case 1: -        trap_Cvar_SetValue( "r_subdivisions", 12 ); -      break; -      case 2: -        trap_Cvar_SetValue( "r_subdivisions", 20 ); -      break; -    } -  } else if (Q_stricmp(name, "ui_glCustom") == 0) { -    switch (val) { -      case 0: // high quality -        trap_Cvar_SetValue( "r_fullScreen", 1 ); -        trap_Cvar_SetValue( "r_subdivisions", 4 ); -        trap_Cvar_SetValue( "r_vertexlight", 0 ); -        trap_Cvar_SetValue( "r_lodbias", 0 ); -        trap_Cvar_SetValue( "r_colorbits", 32 ); -        trap_Cvar_SetValue( "r_depthbits", 24 ); -        trap_Cvar_SetValue( "r_picmip", 0 ); -        trap_Cvar_SetValue( "r_mode", 4 ); -        trap_Cvar_SetValue( "r_texturebits", 32 ); -        trap_Cvar_SetValue( "r_fastSky", 0 ); -        trap_Cvar_SetValue( "r_inGameVideo", 1 ); -        trap_Cvar_SetValue( "cg_shadows", 1 ); -        trap_Cvar_SetValue( "cg_brassTime", 2500 ); -        trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" ); -      break; -      case 1: // normal -        trap_Cvar_SetValue( "r_fullScreen", 1 ); -        trap_Cvar_SetValue( "r_subdivisions", 12 ); -        trap_Cvar_SetValue( "r_vertexlight", 0 ); -        trap_Cvar_SetValue( "r_lodbias", 0 ); -        trap_Cvar_SetValue( "r_colorbits", 0 ); -        trap_Cvar_SetValue( "r_depthbits", 24 ); -        trap_Cvar_SetValue( "r_picmip", 1 ); -        trap_Cvar_SetValue( "r_mode", 3 ); -        trap_Cvar_SetValue( "r_texturebits", 0 ); -        trap_Cvar_SetValue( "r_fastSky", 0 ); -        trap_Cvar_SetValue( "r_inGameVideo", 1 ); -        trap_Cvar_SetValue( "cg_brassTime", 2500 ); -        trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" ); -        trap_Cvar_SetValue( "cg_shadows", 0 ); -      break; -      case 2: // fast -        trap_Cvar_SetValue( "r_fullScreen", 1 ); -        trap_Cvar_SetValue( "r_subdivisions", 8 ); -        trap_Cvar_SetValue( "r_vertexlight", 0 ); -        trap_Cvar_SetValue( "r_lodbias", 1 ); -        trap_Cvar_SetValue( "r_colorbits", 0 ); -        trap_Cvar_SetValue( "r_depthbits", 0 ); -        trap_Cvar_SetValue( "r_picmip", 1 ); -        trap_Cvar_SetValue( "r_mode", 3 ); -        trap_Cvar_SetValue( "r_texturebits", 0 ); -        trap_Cvar_SetValue( "cg_shadows", 0 ); -        trap_Cvar_SetValue( "r_fastSky", 1 ); -        trap_Cvar_SetValue( "r_inGameVideo", 0 ); -        trap_Cvar_SetValue( "cg_brassTime", 0 ); -        trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" ); -      break; -      case 3: // fastest -        trap_Cvar_SetValue( "r_fullScreen", 1 ); -        trap_Cvar_SetValue( "r_subdivisions", 20 ); -        trap_Cvar_SetValue( "r_vertexlight", 1 ); -        trap_Cvar_SetValue( "r_lodbias", 2 ); -        trap_Cvar_SetValue( "r_colorbits", 16 ); -        trap_Cvar_SetValue( "r_depthbits", 16 ); -        trap_Cvar_SetValue( "r_mode", 3 ); -        trap_Cvar_SetValue( "r_picmip", 2 ); -        trap_Cvar_SetValue( "r_texturebits", 16 ); -        trap_Cvar_SetValue( "cg_shadows", 0 ); -        trap_Cvar_SetValue( "cg_brassTime", 0 ); -        trap_Cvar_SetValue( "r_fastSky", 1 ); -        trap_Cvar_SetValue( "r_inGameVideo", 0 ); -        trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" ); -      break; -    } -  } else if (Q_stricmp(name, "ui_mousePitch") == 0) { -    if (val == 0) { -      trap_Cvar_SetValue( "m_pitch", 0.022f ); -    } else { -      trap_Cvar_SetValue( "m_pitch", -0.022f ); -    } -  } -} - -static void UI_RunMenuScript(char **args) { -  const char *name, *name2; -  char buff[1024]; -  const char *cmd; - -  if (String_Parse(args, &name)) { -    if (Q_stricmp(name, "StartServer") == 0) { -      int i, clients, oldclients; -      float skill; -      trap_Cvar_Set("cg_thirdPerson", "0"); -      trap_Cvar_Set("cg_cameraOrbit", "0"); -      trap_Cvar_Set("ui_singlePlayerActive", "0"); -      trap_Cvar_SetValue( "dedicated", Com_Clamp( 0, 2, ui_dedicated.integer ) ); -      trap_Cvar_SetValue( "g_gametype", Com_Clamp( 0, 8, uiInfo.gameTypes[ui_netGameType.integer].gtEnum ) ); -      trap_Cvar_Set("g_redTeam", UI_Cvar_VariableString("ui_teamName")); -      trap_Cvar_Set("g_blueTeam", UI_Cvar_VariableString("ui_opponentName")); -      trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.mapList[ui_currentNetMap.integer].mapLoadName ) ); -      skill = trap_Cvar_VariableValue( "g_spSkill" ); -      // set max clients based on spots -      oldclients = trap_Cvar_VariableValue( "sv_maxClients" ); -      clients = 0; -      for (i = 0; i < PLAYERS_PER_TEAM; i++) { -        int bot = trap_Cvar_VariableValue( va("ui_blueteam%i", i+1)); -        if (bot >= 0) { -          clients++; -        } -        bot = trap_Cvar_VariableValue( va("ui_redteam%i", i+1)); -        if (bot >= 0) { -          clients++; -        } -      } -      if (clients == 0) { -        clients = 8; -      } - -      if (oldclients > clients) { -        clients = oldclients; -      } - -      trap_Cvar_Set("sv_maxClients", va("%d",clients)); - -      for (i = 0; i < PLAYERS_PER_TEAM; i++) { -        int bot = trap_Cvar_VariableValue( va("ui_blueteam%i", i+1)); -        if (bot > 1) { -          Com_sprintf( buff, sizeof(buff), "addbot %s %f \n", UI_GetBotNameByNumber(bot-2), skill); -          trap_Cmd_ExecuteText( EXEC_APPEND, buff ); -        } -        bot = trap_Cvar_VariableValue( va("ui_redteam%i", i+1)); -        if (bot > 1) { -          Com_sprintf( buff, sizeof(buff), "addbot %s %f \n", UI_GetBotNameByNumber(bot-2), skill); -          trap_Cmd_ExecuteText( EXEC_APPEND, buff ); -        } -      } -    } else if (Q_stricmp(name, "updateSPMenu") == 0) { -      UI_SetCapFragLimits(qtrue); -      UI_MapCountByGameType(qtrue); -      ui_mapIndex.integer = UI_GetIndexFromSelection(ui_currentMap.integer); -      trap_Cvar_Set("ui_mapIndex", va("%d", ui_mapIndex.integer)); -      Menu_SetFeederSelection(NULL, FEEDER_MAPS, ui_mapIndex.integer, "skirmish"); -      UI_GameType_HandleKey(0, NULL, K_MOUSE1, qfalse); -      UI_GameType_HandleKey(0, NULL, K_MOUSE2, qfalse); -    } else if (Q_stricmp(name, "resetDefaults") == 0) { -      trap_Cmd_ExecuteText( EXEC_APPEND, "exec default.cfg\n"); -      trap_Cmd_ExecuteText( EXEC_APPEND, "cvar_restart\n"); -      Controls_SetDefaults(); -      trap_Cvar_Set("com_introPlayed", "1" ); -      trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" ); -    } else if (Q_stricmp(name, "getCDKey") == 0) { -      char out[17]; -      trap_GetCDKey(buff, 17); -      trap_Cvar_Set("cdkey1", ""); -      trap_Cvar_Set("cdkey2", ""); -      trap_Cvar_Set("cdkey3", ""); -      trap_Cvar_Set("cdkey4", ""); -      if (strlen(buff) == CDKEY_LEN) { -        Q_strncpyz(out, buff, 5); -        trap_Cvar_Set("cdkey1", out); -        Q_strncpyz(out, buff + 4, 5); -        trap_Cvar_Set("cdkey2", out); -        Q_strncpyz(out, buff + 8, 5); -        trap_Cvar_Set("cdkey3", out); -        Q_strncpyz(out, buff + 12, 5); -        trap_Cvar_Set("cdkey4", out); -      } - -    } else if (Q_stricmp(name, "verifyCDKey") == 0) { -      buff[0] = '\0'; -      Q_strcat(buff, 1024, UI_Cvar_VariableString("cdkey1")); -      Q_strcat(buff, 1024, UI_Cvar_VariableString("cdkey2")); -      Q_strcat(buff, 1024, UI_Cvar_VariableString("cdkey3")); -      Q_strcat(buff, 1024, UI_Cvar_VariableString("cdkey4")); -      trap_Cvar_Set("cdkey", buff); -      if (trap_VerifyCDKey(buff, UI_Cvar_VariableString("cdkeychecksum"))) { -        trap_Cvar_Set("ui_cdkeyvalid", "CD Key Appears to be valid."); -        trap_SetCDKey(buff); -      } else { -        trap_Cvar_Set("ui_cdkeyvalid", "CD Key does not appear to be valid."); -      } -    } else if (Q_stricmp(name, "loadArenas") == 0) { -      UI_LoadArenas(); -      UI_MapCountByGameType(qfalse); -      Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, "createserver"); -    } else if (Q_stricmp(name, "saveControls") == 0) { -      Controls_SetConfig(qtrue); -    } else if (Q_stricmp(name, "loadControls") == 0) { -      Controls_GetConfig(); -    } else if (Q_stricmp(name, "clearError") == 0) { -      trap_Cvar_Set("com_errorMessage", ""); -    } else if (Q_stricmp(name, "loadGameInfo") == 0) { -/*      UI_ParseGameInfo("gameinfo.txt"); -      UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);*/ -    } else if (Q_stricmp(name, "resetScores") == 0) { -      UI_ClearScores(); -    } else if (Q_stricmp(name, "RefreshServers") == 0) { -      UI_StartServerRefresh(qtrue); -      UI_BuildServerDisplayList(qtrue); -    } else if (Q_stricmp(name, "RefreshFilter") == 0) { -      UI_StartServerRefresh(qfalse); -      UI_BuildServerDisplayList(qtrue); -    } else if (Q_stricmp(name, "RunSPDemo") == 0) { -      if (uiInfo.demoAvailable) { -        trap_Cmd_ExecuteText( EXEC_APPEND, va("demo %s_%i\n", uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum)); -      } -    } else if (Q_stricmp(name, "LoadDemos") == 0) { -      UI_LoadDemos(); -    } else if (Q_stricmp(name, "LoadMovies") == 0) { -      UI_LoadMovies(); -    } else if (Q_stricmp(name, "LoadMods") == 0) { -      UI_LoadMods(); -    } - -//TA: tremulous menus -    else if( Q_stricmp( name, "LoadTeams" ) == 0 ) -      UI_LoadTremTeams( ); -    else if( Q_stricmp( name, "JoinTeam" ) == 0 ) -    { -      if( ( cmd = uiInfo.tremTeamList[ uiInfo.tremTeamIndex ].cmd ) ) -        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); -    } -    else if( Q_stricmp( name, "LoadHumanItems" ) == 0 ) -      UI_LoadTremHumanItems( ); -    else if( Q_stricmp( name, "SpawnWithHumanItem" ) == 0 ) -    { -      if( ( cmd = uiInfo.tremHumanItemList[ uiInfo.tremHumanItemIndex ].cmd ) ) -        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); -    } -    else if( Q_stricmp( name, "LoadAlienClasses" ) == 0 ) -      UI_LoadTremAlienClasses( ); -    else if( Q_stricmp( name, "SpawnAsAlienClass" ) == 0 ) -    { -      if( ( cmd = uiInfo.tremAlienClassList[ uiInfo.tremAlienClassIndex ].cmd ) ) -        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); -    } -    else if( Q_stricmp( name, "LoadHumanArmouryBuys" ) == 0 ) -      UI_LoadTremHumanArmouryBuys( ); -    else if( Q_stricmp( name, "BuyFromArmoury" ) == 0 ) -    { -      if( ( cmd = uiInfo.tremHumanArmouryBuyList[ uiInfo.tremHumanArmouryBuyIndex ].cmd ) ) -        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); -    } -    else if( Q_stricmp( name, "LoadHumanArmourySells" ) == 0 ) -      UI_LoadTremHumanArmourySells( ); -    else if( Q_stricmp( name, "SellToArmoury" ) == 0 ) -    { -      if( ( cmd = uiInfo.tremHumanArmourySellList[ uiInfo.tremHumanArmourySellIndex ].cmd ) ) -        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); -    } -    else if( Q_stricmp( name, "LoadAlienUpgrades" ) == 0 ) -    { -      UI_LoadTremAlienUpgrades( ); - -      //disallow the menu if it would be empty -      if( uiInfo.tremAlienUpgradeCount <= 0 ) -        Menus_CloseAll( ); -    } -    else if( Q_stricmp( name, "UpgradeToNewClass" ) == 0 ) -    { -      if( ( cmd = uiInfo.tremAlienUpgradeList[ uiInfo.tremAlienUpgradeIndex ].cmd ) ) -        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); -    } -    else if( Q_stricmp( name, "LoadAlienBuilds" ) == 0 ) -      UI_LoadTremAlienBuilds( ); -    else if( Q_stricmp( name, "BuildAlienBuildable" ) == 0 ) -    { -      if( ( cmd = uiInfo.tremAlienBuildList[ uiInfo.tremAlienBuildIndex ].cmd ) ) -        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); -    } -    else if( Q_stricmp( name, "LoadHumanBuilds" ) == 0 ) -      UI_LoadTremHumanBuilds( ); -    else if( Q_stricmp( name, "BuildHumanBuildable" ) == 0 ) -    { -      if( ( cmd = uiInfo.tremHumanBuildList[ uiInfo.tremHumanBuildIndex ].cmd ) ) -        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); -    } -    else if( Q_stricmp( name, "PTRCRestore" ) == 0 ) -    { -      int           len; -      char          text[ 16 ]; -      fileHandle_t  f; -      char          command[ 32 ]; - -      // load the file -      len = trap_FS_FOpenFile( "ptrc.cfg", &f, FS_READ ); - -      if( len > 0 && ( len < sizeof( text ) - 1 ) ) -      { -        trap_FS_Read( text, len, f ); -        text[ len ] = 0; -        trap_FS_FCloseFile( f ); - -        Com_sprintf( command, 32, "ptrcrestore %s", text ); - -        trap_Cmd_ExecuteText( EXEC_APPEND, command ); -      } -    } -//TA: tremulous menus - -    else if (Q_stricmp(name, "playMovie") == 0) { -      if (uiInfo.previewMovie >= 0) { -        trap_CIN_StopCinematic(uiInfo.previewMovie); -      } -      trap_Cmd_ExecuteText( EXEC_APPEND, va("cinematic %s.roq 2\n", uiInfo.movieList[uiInfo.movieIndex])); -    } else if (Q_stricmp(name, "RunMod") == 0) { -      trap_Cvar_Set( "fs_game", uiInfo.modList[uiInfo.modIndex].modName); -      trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); -    } else if (Q_stricmp(name, "RunDemo") == 0) { -      trap_Cmd_ExecuteText( EXEC_APPEND, va("demo %s\n", uiInfo.demoList[uiInfo.demoIndex])); -    } else if (Q_stricmp(name, "Quake3") == 0) { -      trap_Cvar_Set( "fs_game", ""); -      trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); -    } else if (Q_stricmp(name, "closeJoin") == 0) { -      if (uiInfo.serverStatus.refreshActive) { -        UI_StopServerRefresh(); -        uiInfo.serverStatus.nextDisplayRefresh = 0; -        uiInfo.nextServerStatusRefresh = 0; -        uiInfo.nextFindPlayerRefresh = 0; -        UI_BuildServerDisplayList(qtrue); -      } else { -        Menus_CloseByName("joinserver"); -        Menus_OpenByName("main"); -      } -    } else if (Q_stricmp(name, "StopRefresh") == 0) { -      UI_StopServerRefresh(); -      uiInfo.serverStatus.nextDisplayRefresh = 0; -      uiInfo.nextServerStatusRefresh = 0; -      uiInfo.nextFindPlayerRefresh = 0; -    } else if (Q_stricmp(name, "UpdateFilter") == 0) { -      if (ui_netSource.integer == AS_LOCAL) { -        UI_StartServerRefresh(qtrue); -      } -      UI_BuildServerDisplayList(qtrue); -      UI_FeederSelection(FEEDER_SERVERS, 0); -    } else if (Q_stricmp(name, "ServerStatus") == 0) { -      trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], uiInfo.serverStatusAddress, sizeof(uiInfo.serverStatusAddress)); -      UI_BuildServerStatus(qtrue); -    } else if (Q_stricmp(name, "FoundPlayerServerStatus") == 0) { -      Q_strncpyz(uiInfo.serverStatusAddress, uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer], sizeof(uiInfo.serverStatusAddress)); -      UI_BuildServerStatus(qtrue); -      Menu_SetFeederSelection(NULL, FEEDER_FINDPLAYER, 0, NULL); -    } else if (Q_stricmp(name, "FindPlayer") == 0) { -      UI_BuildFindPlayerList(qtrue); -      // clear the displayed server status info -      uiInfo.serverStatusInfo.numLines = 0; -      Menu_SetFeederSelection(NULL, FEEDER_FINDPLAYER, 0, NULL); -    } else if (Q_stricmp(name, "JoinServer") == 0) { -      trap_Cvar_Set("cg_thirdPerson", "0"); -      trap_Cvar_Set("cg_cameraOrbit", "0"); -      trap_Cvar_Set("ui_singlePlayerActive", "0"); -      if (uiInfo.serverStatus.currentServer >= 0 && uiInfo.serverStatus.currentServer < uiInfo.serverStatus.numDisplayServers) { -        trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, 1024); -        trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", buff ) ); -      } -    } else if (Q_stricmp(name, "FoundPlayerJoinServer") == 0) { -      trap_Cvar_Set("ui_singlePlayerActive", "0"); -      if (uiInfo.currentFoundPlayerServer >= 0 && uiInfo.currentFoundPlayerServer < uiInfo.numFoundPlayerServers) { -        trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer] ) ); -      } -    } else if (Q_stricmp(name, "Quit") == 0) { -      trap_Cvar_Set("ui_singlePlayerActive", "0"); -      trap_Cmd_ExecuteText( EXEC_NOW, "quit"); -    } else if (Q_stricmp(name, "Controls") == 0) { -      trap_Cvar_Set( "cl_paused", "1" ); -      trap_Key_SetCatcher( KEYCATCH_UI ); -      Menus_CloseAll(); -      Menus_ActivateByName("setup_menu2"); -    } else if (Q_stricmp(name, "Leave") == 0) { -      trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" ); -      trap_Key_SetCatcher( KEYCATCH_UI ); -      Menus_CloseAll(); -      Menus_ActivateByName("main"); -    } else if (Q_stricmp(name, "ServerSort") == 0) { -      int sortColumn; -      if (Int_Parse(args, &sortColumn)) { -        // if same column we're already sorting on then flip the direction -        if (sortColumn == uiInfo.serverStatus.sortKey) { -          uiInfo.serverStatus.sortDir = !uiInfo.serverStatus.sortDir; -        } -        // make sure we sort again -        UI_ServersSort(sortColumn, qtrue); -      } -    } else if (Q_stricmp(name, "nextSkirmish") == 0) { -      UI_StartSkirmish(qtrue); -    } else if (Q_stricmp(name, "SkirmishStart") == 0) { -      UI_StartSkirmish(qfalse); -    } else if (Q_stricmp(name, "closeingame") == 0) { -      trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); -      trap_Key_ClearStates(); -      trap_Cvar_Set( "cl_paused", "0" ); -      Menus_CloseAll(); -    } else if (Q_stricmp(name, "voteMap") == 0) { -      if (ui_currentNetMap.integer >=0 && ui_currentNetMap.integer < uiInfo.mapCount) { -        trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote map %s\n",uiInfo.mapList[ui_currentNetMap.integer].mapLoadName) ); -      } -    } else if (Q_stricmp(name, "voteKick") == 0) { -      if (uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount) { -        trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote kick %s\n",uiInfo.playerNames[uiInfo.playerIndex]) ); -      } -    } -    else if( Q_stricmp( name, "voteTeamKick" ) == 0 ) -    { -      if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) -      { -        trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote teamkick %s\n", uiInfo.playerNames[ uiInfo.teamIndex ] ) ); -      } -    } -    else if (Q_stricmp(name, "voteGame") == 0) { -      if (ui_netGameType.integer >= 0 && ui_netGameType.integer < uiInfo.numGameTypes) { -        trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote g_gametype %i\n",uiInfo.gameTypes[ui_netGameType.integer].gtEnum) ); -      } -    } else if (Q_stricmp(name, "voteLeader") == 0) { -      if (uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount) { -        trap_Cmd_ExecuteText( EXEC_APPEND, va("callteamvote leader %s\n",uiInfo.teamNames[uiInfo.teamIndex]) ); -      } -    } -    else if (Q_stricmp(name, "addBot") == 0) { -        trap_Cmd_ExecuteText( EXEC_APPEND, va("addbot %s %i %s\n", UI_GetBotNameByNumber(uiInfo.botIndex), uiInfo.skillIndex+1, (uiInfo.redBlue == 0) ? "Red" : "Blue") ); -    } else if (Q_stricmp(name, "addFavorite") == 0) { -      if (ui_netSource.integer != AS_FAVORITES) { -        char name[MAX_NAME_LENGTH]; -        char addr[MAX_NAME_LENGTH]; -        int res; - -        trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS); -        name[0] = addr[0] = '\0'; -        Q_strncpyz(name,  Info_ValueForKey(buff, "hostname"), MAX_NAME_LENGTH); -        Q_strncpyz(addr,  Info_ValueForKey(buff, "addr"), MAX_NAME_LENGTH); -        if (strlen(name) > 0 && strlen(addr) > 0) { -          res = trap_LAN_AddServer(AS_FAVORITES, name, addr); -          if (res == 0) { -            // server already in the list -            Com_Printf("Favorite already in list\n"); -          } -          else if (res == -1) { -            // list full -            Com_Printf("Favorite list full\n"); -          } -          else { -            // successfully added -            Com_Printf("Added favorite server %s\n", addr); -          } -        } -      } -    } else if (Q_stricmp(name, "deleteFavorite") == 0) { -      if (ui_netSource.integer == AS_FAVORITES) { -        char addr[MAX_NAME_LENGTH]; -        trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS); -        addr[0] = '\0'; -        Q_strncpyz(addr,  Info_ValueForKey(buff, "addr"), MAX_NAME_LENGTH); -        if (strlen(addr) > 0) { -          trap_LAN_RemoveServer(AS_FAVORITES, addr); -        } -      } -    } else if (Q_stricmp(name, "createFavorite") == 0) { -      if (ui_netSource.integer == AS_FAVORITES) { -        char name[MAX_NAME_LENGTH]; -        char addr[MAX_NAME_LENGTH]; -        int res; - -        name[0] = addr[0] = '\0'; -        Q_strncpyz(name,  UI_Cvar_VariableString("ui_favoriteName"), MAX_NAME_LENGTH); -        Q_strncpyz(addr,  UI_Cvar_VariableString("ui_favoriteAddress"), MAX_NAME_LENGTH); -        if (strlen(name) > 0 && strlen(addr) > 0) { -          res = trap_LAN_AddServer(AS_FAVORITES, name, addr); -          if (res == 0) { -            // server already in the list -            Com_Printf("Favorite already in list\n"); -          } -          else if (res == -1) { -            // list full -            Com_Printf("Favorite list full\n"); -          } -          else { -            // successfully added -            Com_Printf("Added favorite server %s\n", addr); -          } -        } -      } -    } else if (Q_stricmp(name, "orders") == 0) { -      const char *orders; -      if (String_Parse(args, &orders)) { -        int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer"); -        if (selectedPlayer < uiInfo.myTeamCount) { -          strcpy(buff, orders); -          trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamClientNums[selectedPlayer]) ); -          trap_Cmd_ExecuteText( EXEC_APPEND, "\n" ); -        } else { -          int i; -          for (i = 0; i < uiInfo.myTeamCount; i++) { -            if (Q_stricmp(UI_Cvar_VariableString("name"), uiInfo.teamNames[i]) == 0) { -              continue; -            } -            strcpy(buff, orders); -            trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamNames[i]) ); -            trap_Cmd_ExecuteText( EXEC_APPEND, "\n" ); -          } -        } -        trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); -        trap_Key_ClearStates(); -        trap_Cvar_Set( "cl_paused", "0" ); -        Menus_CloseAll(); -      } -    } else if (Q_stricmp(name, "voiceOrdersTeam") == 0) { -      const char *orders; -      if (String_Parse(args, &orders)) { -        int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer"); -        if (selectedPlayer == uiInfo.myTeamCount) { -          trap_Cmd_ExecuteText( EXEC_APPEND, orders ); -          trap_Cmd_ExecuteText( EXEC_APPEND, "\n" ); -        } -        trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); -        trap_Key_ClearStates(); -        trap_Cvar_Set( "cl_paused", "0" ); -        Menus_CloseAll(); -      } -    } else if (Q_stricmp(name, "voiceOrders") == 0) { -      const char *orders; -      if (String_Parse(args, &orders)) { -        int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer"); -        if (selectedPlayer < uiInfo.myTeamCount) { -          strcpy(buff, orders); -          trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamClientNums[selectedPlayer]) ); -          trap_Cmd_ExecuteText( EXEC_APPEND, "\n" ); -        } -        trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); -        trap_Key_ClearStates(); -        trap_Cvar_Set( "cl_paused", "0" ); -        Menus_CloseAll(); -      } -    } else if (Q_stricmp(name, "glCustom") == 0) { -      trap_Cvar_Set("ui_glCustom", "4"); -    } else if (Q_stricmp(name, "update") == 0) { -      if (String_Parse(args, &name2)) -        UI_Update(name2); -    } else if (Q_stricmp(name, "setPbClStatus") == 0) { -      int stat; -      if ( Int_Parse( args, &stat ) ) -        trap_SetPbClStatus( stat ); -    } -    else { -      Com_Printf("unknown UI script %s\n", name); -    } -  } -} - -static void UI_GetTeamColor(vec4_t *color) { -} - -/* -================== -UI_MapCountByGameType -================== -*/ -static int UI_MapCountByGameType(qboolean singlePlayer) { -  int i, c, game; -  c = 0; -  game = singlePlayer ? uiInfo.gameTypes[ui_gameType.integer].gtEnum : uiInfo.gameTypes[ui_netGameType.integer].gtEnum; - -  for (i = 0; i < uiInfo.mapCount; i++) { -    uiInfo.mapList[i].active = qfalse; -    if ( uiInfo.mapList[i].typeBits & (1 << game)) { -      if (singlePlayer) { -        if (!(uiInfo.mapList[i].typeBits & (1 << 2))) { -          continue; -        } -      } -      c++; -      uiInfo.mapList[i].active = qtrue; -    } -  } -  return c; -} - -qboolean UI_hasSkinForBase(const char *base, const char *team) { -  char  test[1024]; - -  Com_sprintf( test, sizeof( test ), "models/players/%s/%s/lower_default.skin", base, team ); - -  if (trap_FS_FOpenFile(test, NULL, FS_READ)) { -    return qtrue; -  } -  Com_sprintf( test, sizeof( test ), "models/players/characters/%s/%s/lower_default.skin", base, team ); - -  if (trap_FS_FOpenFile(test, NULL, FS_READ)) { -    return qtrue; -  } -  return qfalse; -} - -/* -================== -UI_MapCountByTeam -================== -*/ -static int UI_HeadCountByTeam( void ) { -  static int init = 0; -  int i, j, k, c, tIndex; - -  c = 0; -  if (!init) { -    for (i = 0; i < uiInfo.characterCount; i++) { -      uiInfo.characterList[i].reference = 0; -      for (j = 0; j < uiInfo.teamCount; j++) { -        if (UI_hasSkinForBase(uiInfo.characterList[i].base, uiInfo.teamList[j].teamName)) { -          uiInfo.characterList[i].reference |= (1<<j); -        } -      } -    } -    init = 1; -  } - -  tIndex = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); - -  // do names -  for (i = 0; i < uiInfo.characterCount; i++) { -    uiInfo.characterList[i].active = qfalse; -    for(j = 0; j < TEAM_MEMBERS; j++) { -      if (uiInfo.teamList[tIndex].teamMembers[j] != NULL) { -        if (uiInfo.characterList[i].reference&(1<<tIndex)) {// && Q_stricmp(uiInfo.teamList[tIndex].teamMembers[j], uiInfo.characterList[i].name)==0) { -          uiInfo.characterList[i].active = qtrue; -          c++; -          break; -        } -      } -    } -  } - -  // and then aliases -  for(j = 0; j < TEAM_MEMBERS; j++) { -    for(k = 0; k < uiInfo.aliasCount; k++) { -      if (uiInfo.aliasList[k].name != NULL) { -        if (Q_stricmp(uiInfo.teamList[tIndex].teamMembers[j], uiInfo.aliasList[k].name)==0) { -          for (i = 0; i < uiInfo.characterCount; i++) { -            if (uiInfo.characterList[i].headImage != -1 && uiInfo.characterList[i].reference&(1<<tIndex) && Q_stricmp(uiInfo.aliasList[k].ai, uiInfo.characterList[i].name)==0) { -              if (uiInfo.characterList[i].active == qfalse) { -                uiInfo.characterList[i].active = qtrue; -                c++; -              } -              break; -            } -          } -        } -      } -    } -  } -  return c; -} - -/* -================== -UI_InsertServerIntoDisplayList -================== -*/ -static void UI_InsertServerIntoDisplayList(int num, int position) { -  int i; - -  if (position < 0 || position > uiInfo.serverStatus.numDisplayServers ) { -    return; -  } -  // -  uiInfo.serverStatus.numDisplayServers++; -  for (i = uiInfo.serverStatus.numDisplayServers; i > position; i--) { -    uiInfo.serverStatus.displayServers[i] = uiInfo.serverStatus.displayServers[i-1]; -  } -  uiInfo.serverStatus.displayServers[position] = num; -} - -/* -================== -UI_RemoveServerFromDisplayList -================== -*/ -static void UI_RemoveServerFromDisplayList(int num) { -  int i, j; - -  for (i = 0; i < uiInfo.serverStatus.numDisplayServers; i++) { -    if (uiInfo.serverStatus.displayServers[i] == num) { -      uiInfo.serverStatus.numDisplayServers--; -      for (j = i; j < uiInfo.serverStatus.numDisplayServers; j++) { -        uiInfo.serverStatus.displayServers[j] = uiInfo.serverStatus.displayServers[j+1]; -      } -      return; -    } -  } -} - -/* -================== -UI_BinaryServerInsertion -================== -*/ -static void UI_BinaryServerInsertion(int num) { -  int mid, offset, res, len; - -  // use binary search to insert server -  len = uiInfo.serverStatus.numDisplayServers; -  mid = len; -  offset = 0; -  res = 0; -  while(mid > 0) { -    mid = len >> 1; -    // -    res = trap_LAN_CompareServers( ui_netSource.integer, uiInfo.serverStatus.sortKey, -          uiInfo.serverStatus.sortDir, num, uiInfo.serverStatus.displayServers[offset+mid]); -    // if equal -    if (res == 0) { -      UI_InsertServerIntoDisplayList(num, offset+mid); -      return; -    } -    // if larger -    else if (res == 1) { -      offset += mid; -      len -= mid; -    } -    // if smaller -    else { -      len -= mid; -    } -  } -  if (res == 1) { -    offset++; -  } -  UI_InsertServerIntoDisplayList(num, offset); -} - -/* -================== -UI_BuildServerDisplayList -================== -*/ -static void UI_BuildServerDisplayList(qboolean force) { -  int i, count, clients, maxClients, ping, game, len, visible; -  char info[MAX_STRING_CHARS]; -//  qboolean startRefresh = qtrue; TTimo: unused -  static int numinvisible; - -  if (!(force || uiInfo.uiDC.realTime > uiInfo.serverStatus.nextDisplayRefresh)) { -    return; -  } -  // if we shouldn't reset -  if ( force == 2 ) { -    force = 0; -  } - -  // do motd updates here too -  trap_Cvar_VariableStringBuffer( "cl_motdString", uiInfo.serverStatus.motd, sizeof(uiInfo.serverStatus.motd) ); -  len = strlen(uiInfo.serverStatus.motd); -  if (len == 0) { -    strcpy(uiInfo.serverStatus.motd, "Welcome to Tremulous!"); -    len = strlen(uiInfo.serverStatus.motd); -  } -  if (len != uiInfo.serverStatus.motdLen) { -    uiInfo.serverStatus.motdLen = len; -    uiInfo.serverStatus.motdWidth = -1; -  } - -  if (force) { -    numinvisible = 0; -    // clear number of displayed servers -    uiInfo.serverStatus.numDisplayServers = 0; -    uiInfo.serverStatus.numPlayersOnServers = 0; -    // set list box index to zero -    Menu_SetFeederSelection(NULL, FEEDER_SERVERS, 0, NULL); -    // mark all servers as visible so we store ping updates for them -    trap_LAN_MarkServerVisible(ui_netSource.integer, -1, qtrue); -  } - -  // get the server count (comes from the master) -  count = trap_LAN_GetServerCount(ui_netSource.integer); -  if (count == -1 || (ui_netSource.integer == AS_LOCAL && count == 0) ) { -    // still waiting on a response from the master -    uiInfo.serverStatus.numDisplayServers = 0; -    uiInfo.serverStatus.numPlayersOnServers = 0; -    uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 500; -    return; -  } - -  visible = qfalse; -  for (i = 0; i < count; i++) { -    // if we already got info for this server -    if (!trap_LAN_ServerIsVisible(ui_netSource.integer, i)) { -      continue; -    } -    visible = qtrue; -    // get the ping for this server -    ping = trap_LAN_GetServerPing(ui_netSource.integer, i); -    if (ping > 0 || ui_netSource.integer == AS_FAVORITES) { - -      trap_LAN_GetServerInfo(ui_netSource.integer, i, info, MAX_STRING_CHARS); - -      clients = atoi(Info_ValueForKey(info, "clients")); -      uiInfo.serverStatus.numPlayersOnServers += clients; - -      if (ui_browserShowEmpty.integer == 0) { -        if (clients == 0) { -          trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse); -          continue; -        } -      } - -      if (ui_browserShowFull.integer == 0) { -        maxClients = atoi(Info_ValueForKey(info, "sv_maxclients")); -        if (clients == maxClients) { -          trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse); -          continue; -        } -      } - -      if (uiInfo.joinGameTypes[ui_joinGameType.integer].gtEnum != -1) { -        game = atoi(Info_ValueForKey(info, "gametype")); -        if (game != uiInfo.joinGameTypes[ui_joinGameType.integer].gtEnum) { -          trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse); -          continue; -        } -      } - -      //TA: only show tremulous servers -      if( Q_stricmp( Info_ValueForKey( info, "game" ), "tremulous" ) != 0 ) -      { -        trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); -        continue; -      } - -      // make sure we never add a favorite server twice -      if (ui_netSource.integer == AS_FAVORITES) { -        UI_RemoveServerFromDisplayList(i); -      } -      // insert the server into the list -      UI_BinaryServerInsertion(i); -      // done with this server -      if (ping > 0) { -        trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse); -        numinvisible++; -      } -    } -  } - -  uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime; - -  // if there were no servers visible for ping updates -  if (!visible) { -//    UI_StopServerRefresh(); -//    uiInfo.serverStatus.nextDisplayRefresh = 0; -  } -} - -typedef struct -{ -  char *name, *altName; -} serverStatusCvar_t; - -serverStatusCvar_t serverStatusCvars[] = { -  {"sv_hostname", "Name"}, -  {"Address", ""}, -  {"gamename", "Game name"}, -  {"g_gametype", "Game type"}, -  {"mapname", "Map"}, -  {"version", ""}, -  {"protocol", ""}, -  {"timelimit", ""}, -  {"fraglimit", ""}, -  {NULL, NULL} -}; - -/* -================== -UI_SortServerStatusInfo -================== -*/ -static void UI_SortServerStatusInfo( serverStatusInfo_t *info ) { -  int i, j, index; -  char *tmp1, *tmp2; - -  // FIXME: if "gamename" == "baseq3" or "missionpack" then -  // replace the gametype number by FFA, CTF etc. -  // -  index = 0; -  for (i = 0; serverStatusCvars[i].name; i++) { -    for (j = 0; j < info->numLines; j++) { -      if ( !info->lines[j][1] || info->lines[j][1][0] ) { -        continue; -      } -      if ( !Q_stricmp(serverStatusCvars[i].name, info->lines[j][0]) ) { -        // swap lines -        tmp1 = info->lines[index][0]; -        tmp2 = info->lines[index][3]; -        info->lines[index][0] = info->lines[j][0]; -        info->lines[index][3] = info->lines[j][3]; -        info->lines[j][0] = tmp1; -        info->lines[j][3] = tmp2; -        // -        if ( strlen(serverStatusCvars[i].altName) ) { -          info->lines[index][0] = serverStatusCvars[i].altName; -        } -        index++; -      } -    } -  } -} - -/* -================== -UI_GetServerStatusInfo -================== -*/ -static int UI_GetServerStatusInfo( const char *serverAddress, serverStatusInfo_t *info ) { -  char *p, *score, *ping, *name; -  int i, len; - -  if (!info) { -    trap_LAN_ServerStatus( serverAddress, NULL, 0); -    return qfalse; -  } -  memset(info, 0, sizeof(*info)); -  if ( trap_LAN_ServerStatus( serverAddress, info->text, sizeof(info->text)) ) { -    Q_strncpyz(info->address, serverAddress, sizeof(info->address)); -    p = info->text; -    info->numLines = 0; -    info->lines[info->numLines][0] = "Address"; -    info->lines[info->numLines][1] = ""; -    info->lines[info->numLines][2] = ""; -    info->lines[info->numLines][3] = info->address; -    info->numLines++; -    // get the cvars -    while (p && *p) { -      p = strchr(p, '\\'); -      if (!p) break; -      *p++ = '\0'; -      if (*p == '\\') -        break; -      info->lines[info->numLines][0] = p; -      info->lines[info->numLines][1] = ""; -      info->lines[info->numLines][2] = ""; -      p = strchr(p, '\\'); -      if (!p) break; -      *p++ = '\0'; -      info->lines[info->numLines][3] = p; - -      info->numLines++; -      if (info->numLines >= MAX_SERVERSTATUS_LINES) -        break; -    } -    // get the player list -    if (info->numLines < MAX_SERVERSTATUS_LINES-3) { -      // empty line -      info->lines[info->numLines][0] = ""; -      info->lines[info->numLines][1] = ""; -      info->lines[info->numLines][2] = ""; -      info->lines[info->numLines][3] = ""; -      info->numLines++; -      // header -      info->lines[info->numLines][0] = "num"; -      info->lines[info->numLines][1] = "score"; -      info->lines[info->numLines][2] = "ping"; -      info->lines[info->numLines][3] = "name"; -      info->numLines++; -      // parse players -      i = 0; -      len = 0; -      while (p && *p) { -        if (*p == '\\') -          *p++ = '\0'; -        if (!p) -          break; -        score = p; -        p = strchr(p, ' '); -        if (!p) -          break; -        *p++ = '\0'; -        ping = p; -        p = strchr(p, ' '); -        if (!p) -          break; -        *p++ = '\0'; -        name = p; -        Com_sprintf(&info->pings[len], sizeof(info->pings)-len, "%d", i); -        info->lines[info->numLines][0] = &info->pings[len]; -        len += strlen(&info->pings[len]) + 1; -        info->lines[info->numLines][1] = score; -        info->lines[info->numLines][2] = ping; -        info->lines[info->numLines][3] = name; -        info->numLines++; -        if (info->numLines >= MAX_SERVERSTATUS_LINES) -          break; -        p = strchr(p, '\\'); -        if (!p) -          break; -        *p++ = '\0'; -        // -        i++; -      } -    } -    UI_SortServerStatusInfo( info ); -    return qtrue; -  } -  return qfalse; -} - -/* -================== -stristr -================== -*/ -static char *stristr(char *str, char *charset) { -  int i; - -  while(*str) { -    for (i = 0; charset[i] && str[i]; i++) { -      if (toupper(charset[i]) != toupper(str[i])) break; -    } -    if (!charset[i]) return str; -    str++; -  } -  return NULL; -} - -/* -================== -UI_BuildFindPlayerList -================== -*/ -static void UI_BuildFindPlayerList(qboolean force) { -  static int numFound, numTimeOuts; -  int i, j, resend; -  serverStatusInfo_t info; -  char name[MAX_NAME_LENGTH+2]; -  char infoString[MAX_STRING_CHARS]; - -  if (!force) { -    if (!uiInfo.nextFindPlayerRefresh || uiInfo.nextFindPlayerRefresh > uiInfo.uiDC.realTime) { -      return; -    } -  } -  else { -    memset(&uiInfo.pendingServerStatus, 0, sizeof(uiInfo.pendingServerStatus)); -    uiInfo.numFoundPlayerServers = 0; -    uiInfo.currentFoundPlayerServer = 0; -    trap_Cvar_VariableStringBuffer( "ui_findPlayer", uiInfo.findPlayerName, sizeof(uiInfo.findPlayerName)); -    Q_CleanStr(uiInfo.findPlayerName); -    // should have a string of some length -    if (!strlen(uiInfo.findPlayerName)) { -      uiInfo.nextFindPlayerRefresh = 0; -      return; -    } -    // set resend time -    resend = ui_serverStatusTimeOut.integer / 2 - 10; -    if (resend < 50) { -      resend = 50; -    } -    trap_Cvar_Set("cl_serverStatusResendTime", va("%d", resend)); -    // reset all server status requests -    trap_LAN_ServerStatus( NULL, NULL, 0); -    // -    uiInfo.numFoundPlayerServers = 1; -    Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], -            sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]), -              "searching %d...", uiInfo.pendingServerStatus.num); -    numFound = 0; -    numTimeOuts++; -  } -  for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) { -    // if this pending server is valid -    if (uiInfo.pendingServerStatus.server[i].valid) { -      // try to get the server status for this server -      if (UI_GetServerStatusInfo( uiInfo.pendingServerStatus.server[i].adrstr, &info ) ) { -        // -        numFound++; -        // parse through the server status lines -        for (j = 0; j < info.numLines; j++) { -          // should have ping info -          if ( !info.lines[j][2] || !info.lines[j][2][0] ) { -            continue; -          } -          // clean string first -          Q_strncpyz(name, info.lines[j][3], sizeof(name)); -          Q_CleanStr(name); -          // if the player name is a substring -          if (stristr(name, uiInfo.findPlayerName)) { -            // add to found server list if we have space (always leave space for a line with the number found) -            if (uiInfo.numFoundPlayerServers < MAX_FOUNDPLAYER_SERVERS-1) { -              // -              Q_strncpyz(uiInfo.foundPlayerServerAddresses[uiInfo.numFoundPlayerServers-1], -                    uiInfo.pendingServerStatus.server[i].adrstr, -                      sizeof(uiInfo.foundPlayerServerAddresses[0])); -              Q_strncpyz(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], -                    uiInfo.pendingServerStatus.server[i].name, -                      sizeof(uiInfo.foundPlayerServerNames[0])); -              uiInfo.numFoundPlayerServers++; -            } -            else { -              // can't add any more so we're done -              uiInfo.pendingServerStatus.num = uiInfo.serverStatus.numDisplayServers; -            } -          } -        } -        Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], -                sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]), -                  "searching %d/%d...", uiInfo.pendingServerStatus.num, numFound); -        // retrieved the server status so reuse this spot -        uiInfo.pendingServerStatus.server[i].valid = qfalse; -      } -    } -    // if empty pending slot or timed out -    if (!uiInfo.pendingServerStatus.server[i].valid || -      uiInfo.pendingServerStatus.server[i].startTime < uiInfo.uiDC.realTime - ui_serverStatusTimeOut.integer) { -      if (uiInfo.pendingServerStatus.server[i].valid) { -        numTimeOuts++; -      } -      // reset server status request for this address -      UI_GetServerStatusInfo( uiInfo.pendingServerStatus.server[i].adrstr, NULL ); -      // reuse pending slot -      uiInfo.pendingServerStatus.server[i].valid = qfalse; -      // if we didn't try to get the status of all servers in the main browser yet -      if (uiInfo.pendingServerStatus.num < uiInfo.serverStatus.numDisplayServers) { -        uiInfo.pendingServerStatus.server[i].startTime = uiInfo.uiDC.realTime; -        trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num], -              uiInfo.pendingServerStatus.server[i].adrstr, sizeof(uiInfo.pendingServerStatus.server[i].adrstr)); -        trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num], infoString, sizeof(infoString)); -        Q_strncpyz(uiInfo.pendingServerStatus.server[i].name, Info_ValueForKey(infoString, "hostname"), sizeof(uiInfo.pendingServerStatus.server[0].name)); -        uiInfo.pendingServerStatus.server[i].valid = qtrue; -        uiInfo.pendingServerStatus.num++; -        Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], -                sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]), -                  "searching %d/%d...", uiInfo.pendingServerStatus.num, numFound); -      } -    } -  } -  for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) { -    if (uiInfo.pendingServerStatus.server[i].valid) { -      break; -    } -  } -  // if still trying to retrieve server status info -  if (i < MAX_SERVERSTATUSREQUESTS) { -    uiInfo.nextFindPlayerRefresh = uiInfo.uiDC.realTime + 25; -  } -  else { -    // add a line that shows the number of servers found -    if (!uiInfo.numFoundPlayerServers) { -      Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], sizeof(uiInfo.foundPlayerServerAddresses[0]), "no servers found"); -    } -    else { -      Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], sizeof(uiInfo.foundPlayerServerAddresses[0]), -            "%d server%s found with player %s", uiInfo.numFoundPlayerServers-1, -            uiInfo.numFoundPlayerServers == 2 ? "":"s", uiInfo.findPlayerName); -    } -    uiInfo.nextFindPlayerRefresh = 0; -    // show the server status info for the selected server -    UI_FeederSelection(FEEDER_FINDPLAYER, uiInfo.currentFoundPlayerServer); -  } -} - -/* -================== -UI_BuildServerStatus -================== -*/ -static void UI_BuildServerStatus(qboolean force) { - -  if (uiInfo.nextFindPlayerRefresh) { -    return; -  } -  if (!force) { -    if (!uiInfo.nextServerStatusRefresh || uiInfo.nextServerStatusRefresh > uiInfo.uiDC.realTime) { -      return; -    } -  } -  else { -    Menu_SetFeederSelection(NULL, FEEDER_SERVERSTATUS, 0, NULL); -    uiInfo.serverStatusInfo.numLines = 0; -    // reset all server status requests -    trap_LAN_ServerStatus( NULL, NULL, 0); -  } -  if (uiInfo.serverStatus.currentServer < 0 || uiInfo.serverStatus.currentServer > uiInfo.serverStatus.numDisplayServers || uiInfo.serverStatus.numDisplayServers == 0) { -    return; -  } -  if (UI_GetServerStatusInfo( uiInfo.serverStatusAddress, &uiInfo.serverStatusInfo ) ) { -    uiInfo.nextServerStatusRefresh = 0; -    UI_GetServerStatusInfo( uiInfo.serverStatusAddress, NULL ); -  } -  else { -    uiInfo.nextServerStatusRefresh = uiInfo.uiDC.realTime + 500; -  } -} - -/* -================== -UI_FeederCount -================== -*/ -static int UI_FeederCount(float feederID) { -  if (feederID == FEEDER_HEADS) { -    return UI_HeadCountByTeam(); -  } else if (feederID == FEEDER_Q3HEADS) { -    return uiInfo.q3HeadCount; -  } else if (feederID == FEEDER_CINEMATICS) { -    return uiInfo.movieCount; -  } else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS) { -    return UI_MapCountByGameType(feederID == FEEDER_MAPS ? qtrue : qfalse); -  } else if (feederID == FEEDER_SERVERS) { -    return uiInfo.serverStatus.numDisplayServers; -  } else if (feederID == FEEDER_SERVERSTATUS) { -    return uiInfo.serverStatusInfo.numLines; -  } else if (feederID == FEEDER_FINDPLAYER) { -    return uiInfo.numFoundPlayerServers; -  } else if (feederID == FEEDER_PLAYER_LIST) { -    if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) { -      uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000; -      UI_BuildPlayerList(); -    } -    return uiInfo.playerCount; -  } else if (feederID == FEEDER_TEAM_LIST) { -    if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) { -      uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000; -      UI_BuildPlayerList(); -    } -    return uiInfo.myTeamCount; -  } else if (feederID == FEEDER_MODS) { -    return uiInfo.modCount; -  } else if (feederID == FEEDER_DEMOS) { -    return uiInfo.demoCount; -  } - -//TA: tremulous menus -  else if( feederID == FEEDER_TREMTEAMS ) -    return uiInfo.tremTeamCount; -  else if( feederID == FEEDER_TREMHUMANITEMS ) -    return uiInfo.tremHumanItemCount; -  else if( feederID == FEEDER_TREMALIENCLASSES ) -    return uiInfo.tremAlienClassCount; -  else if( feederID == FEEDER_TREMHUMANARMOURYBUY ) -    return uiInfo.tremHumanArmouryBuyCount; -  else if( feederID == FEEDER_TREMHUMANARMOURYSELL ) -    return uiInfo.tremHumanArmourySellCount; -  else if( feederID == FEEDER_TREMALIENUPGRADE ) -    return uiInfo.tremAlienUpgradeCount; -  else if( feederID == FEEDER_TREMALIENBUILD ) -    return uiInfo.tremAlienBuildCount; -  else if( feederID == FEEDER_TREMHUMANBUILD ) -    return uiInfo.tremHumanBuildCount; -//TA: tremulous menus - -  return 0; -} - -static const char *UI_SelectedMap(int index, int *actual) { -  int i, c; -  c = 0; -  *actual = 0; -  for (i = 0; i < uiInfo.mapCount; i++) { -    if (uiInfo.mapList[i].active) { -      if (c == index) { -        *actual = i; -        return uiInfo.mapList[i].mapName; -      } else { -        c++; -      } -    } -  } -  return ""; -} - -static const char *UI_SelectedHead(int index, int *actual) { -  int i, c; -  c = 0; -  *actual = 0; -  for (i = 0; i < uiInfo.characterCount; i++) { -    if (uiInfo.characterList[i].active) { -      if (c == index) { -        *actual = i; -        return uiInfo.characterList[i].name; -      } else { -        c++; -      } -    } -  } -  return ""; -} - -static int UI_GetIndexFromSelection(int actual) { -  int i, c; -  c = 0; -  for (i = 0; i < uiInfo.mapCount; i++) { -    if (uiInfo.mapList[i].active) { -      if (i == actual) { -        return c; -      } -        c++; -    } -  } -  return 0; -} - -static void UI_UpdatePendingPings( void ) { -  trap_LAN_ResetPings(ui_netSource.integer); -  uiInfo.serverStatus.refreshActive = qtrue; -  uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000; - -} - -static const char *UI_FeederItemText(float feederID, int index, int column, qhandle_t *handle) { -  static char info[MAX_STRING_CHARS]; -  static char hostname[1024]; -  static char clientBuff[32]; -  static int lastColumn = -1; -  static int lastTime = 0; -  *handle = -1; -  if (feederID == FEEDER_HEADS) { -    int actual; -    return UI_SelectedHead(index, &actual); -  } else if (feederID == FEEDER_Q3HEADS) { -    if (index >= 0 && index < uiInfo.q3HeadCount) { -      return uiInfo.q3HeadNames[index]; -    } -  } else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS) { -    int actual; -    return UI_SelectedMap(index, &actual); -  } else if (feederID == FEEDER_SERVERS) { -    if (index >= 0 && index < uiInfo.serverStatus.numDisplayServers) { -      int ping, punkbuster; -      if (lastColumn != column || lastTime > uiInfo.uiDC.realTime + 5000) { -        trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS); -        lastColumn = column; -        lastTime = uiInfo.uiDC.realTime; -      } -      /*return "bah";*/ -      ping = atoi(Info_ValueForKey(info, "ping")); -      if (ping == -1) { -        // if we ever see a ping that is out of date, do a server refresh -        // UI_UpdatePendingPings(); -      } -      switch (column) { -        case SORT_HOST : -          if (ping <= 0) { -            return Info_ValueForKey(info, "addr"); -          } else { -            if ( ui_netSource.integer == AS_LOCAL ) { -              Com_sprintf( hostname, sizeof(hostname), "%s [%s]", -                      Info_ValueForKey(info, "hostname"), -                      netnames[atoi(Info_ValueForKey(info, "nettype"))] ); -              return hostname; -            } -            else { -              Com_sprintf( hostname, sizeof(hostname), "%s", Info_ValueForKey(info, "hostname")); - -              return hostname; -            } -          } -        case SORT_MAP : -          return Info_ValueForKey(info, "mapname"); -        case SORT_CLIENTS : -          Com_sprintf( clientBuff, sizeof(clientBuff), "%s (%s)", Info_ValueForKey(info, "clients"), Info_ValueForKey(info, "sv_maxclients")); -          return clientBuff; -        case SORT_PING : -          if (ping <= 0) { -            return "..."; -          } else { -            return Info_ValueForKey(info, "ping"); -          } -        case SORT_PUNKBUSTER: -          punkbuster = atoi(Info_ValueForKey(info, "punkbuster")); -          if ( punkbuster ) { -            return "Yes"; -          } else { -            return "No"; -          } -      } -    } -  } else if (feederID == FEEDER_SERVERSTATUS) { -    if ( index >= 0 && index < uiInfo.serverStatusInfo.numLines ) { -      if ( column >= 0 && column < 4 ) { -        return uiInfo.serverStatusInfo.lines[index][column]; -      } -    } -  } else if (feederID == FEEDER_FINDPLAYER) { -    if ( index >= 0 && index < uiInfo.numFoundPlayerServers ) { -      //return uiInfo.foundPlayerServerAddresses[index]; -      return uiInfo.foundPlayerServerNames[index]; -    } -  } else if (feederID == FEEDER_PLAYER_LIST) { -    if (index >= 0 && index < uiInfo.playerCount) { -      return uiInfo.playerNames[index]; -    } -  } else if (feederID == FEEDER_TEAM_LIST) { -    if (index >= 0 && index < uiInfo.myTeamCount) { -      return uiInfo.teamNames[index]; -    } -  } else if (feederID == FEEDER_MODS) { -    if (index >= 0 && index < uiInfo.modCount) { -      if (uiInfo.modList[index].modDescr && *uiInfo.modList[index].modDescr) { -        return uiInfo.modList[index].modDescr; -      } else { -        return uiInfo.modList[index].modName; -      } -    } -  } else if (feederID == FEEDER_CINEMATICS) { -    if (index >= 0 && index < uiInfo.movieCount) { -      return uiInfo.movieList[index]; -    } -  } else if (feederID == FEEDER_DEMOS) { -    if (index >= 0 && index < uiInfo.demoCount) { -      return uiInfo.demoList[index]; -    } -  } - -//TA: tremulous menus -  else if( feederID == FEEDER_TREMTEAMS ) -  { -    if( index >= 0 && index < uiInfo.tremTeamCount ) -      return uiInfo.tremTeamList[ index ].text; -  } -  else if( feederID == FEEDER_TREMHUMANITEMS ) -  { -    if( index >= 0 && index < uiInfo.tremHumanItemCount ) -      return uiInfo.tremHumanItemList[ index ].text; -  } -  else if( feederID == FEEDER_TREMALIENCLASSES ) -  { -    if( index >= 0 && index < uiInfo.tremAlienClassCount ) -      return uiInfo.tremAlienClassList[ index ].text; -  } -  else if( feederID == FEEDER_TREMHUMANARMOURYBUY ) -  { -    if( index >= 0 && index < uiInfo.tremHumanArmouryBuyCount ) -      return uiInfo.tremHumanArmouryBuyList[ index ].text; -  } -  else if( feederID == FEEDER_TREMHUMANARMOURYSELL ) -  { -    if( index >= 0 && index < uiInfo.tremHumanArmourySellCount ) -      return uiInfo.tremHumanArmourySellList[ index ].text; -  } -  else if( feederID == FEEDER_TREMALIENUPGRADE ) -  { -    if( index >= 0 && index < uiInfo.tremAlienUpgradeCount ) -      return uiInfo.tremAlienUpgradeList[ index ].text; -  } -  else if( feederID == FEEDER_TREMALIENBUILD ) -  { -    if( index >= 0 && index < uiInfo.tremAlienBuildCount ) -      return uiInfo.tremAlienBuildList[ index ].text; -  } -  else if( feederID == FEEDER_TREMHUMANBUILD ) -  { -    if( index >= 0 && index < uiInfo.tremHumanBuildCount ) -      return uiInfo.tremHumanBuildList[ index ].text; -  } -//TA: tremulous menus - -  return ""; -} - - -static qhandle_t UI_FeederItemImage(float feederID, int index) { -  if (feederID == FEEDER_HEADS) { -  int actual; -  UI_SelectedHead(index, &actual); -  index = actual; -  if (index >= 0 && index < uiInfo.characterCount) { -    if (uiInfo.characterList[index].headImage == -1) { -      uiInfo.characterList[index].headImage = trap_R_RegisterShaderNoMip(uiInfo.characterList[index].imageName); -    } -    return uiInfo.characterList[index].headImage; -  } -  } else if (feederID == FEEDER_Q3HEADS) { -    if (index >= 0 && index < uiInfo.q3HeadCount) { -      return uiInfo.q3HeadIcons[index]; -    } -  } else if (feederID == FEEDER_ALLMAPS || feederID == FEEDER_MAPS) { -    int actual; -    UI_SelectedMap(index, &actual); -    index = actual; -    if (index >= 0 && index < uiInfo.mapCount) { -      if (uiInfo.mapList[index].levelShot == -1) { -        uiInfo.mapList[index].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[index].imageName); -      } -      return uiInfo.mapList[index].levelShot; -    } -  } -  return 0; -} - -static void UI_FeederSelection(float feederID, int index) { -  static char info[MAX_STRING_CHARS]; -  if (feederID == FEEDER_HEADS) { -  int actual; -  UI_SelectedHead(index, &actual); -  index = actual; -    if (index >= 0 && index < uiInfo.characterCount) { -    trap_Cvar_Set( "team_model", va("%s", uiInfo.characterList[index].base)); -    trap_Cvar_Set( "team_headmodel", va("*%s", uiInfo.characterList[index].name)); -    updateModel = qtrue; -    } -  } else if (feederID == FEEDER_Q3HEADS) { -    if (index >= 0 && index < uiInfo.q3HeadCount) { -      trap_Cvar_Set( "model", uiInfo.q3HeadNames[index]); -      trap_Cvar_Set( "headmodel", uiInfo.q3HeadNames[index]); -      updateModel = qtrue; -    } -  } else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS) { -    int actual, map; -    map = (feederID == FEEDER_ALLMAPS) ? ui_currentNetMap.integer : ui_currentMap.integer; -    if (uiInfo.mapList[map].cinematic >= 0) { -      trap_CIN_StopCinematic(uiInfo.mapList[map].cinematic); -      uiInfo.mapList[map].cinematic = -1; -    } -    UI_SelectedMap(index, &actual); -    trap_Cvar_Set("ui_mapIndex", va("%d", index)); -    ui_mapIndex.integer = index; - -    if (feederID == FEEDER_MAPS) { -      ui_currentMap.integer = actual; -      trap_Cvar_Set("ui_currentMap", va("%d", actual)); -      uiInfo.mapList[ui_currentMap.integer].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.mapList[ui_currentMap.integer].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent) ); -      UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum); -      trap_Cvar_Set("ui_opponentModel", uiInfo.mapList[ui_currentMap.integer].opponentName); -      updateOpponentModel = qtrue; -    } else { -      ui_currentNetMap.integer = actual; -      trap_Cvar_Set("ui_currentNetMap", va("%d", actual)); -      uiInfo.mapList[ui_currentNetMap.integer].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.mapList[ui_currentNetMap.integer].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent) ); -    } - -  } else if (feederID == FEEDER_SERVERS) { -    const char *mapName = NULL; -    uiInfo.serverStatus.currentServer = index; -    trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS); -    uiInfo.serverStatus.currentServerPreview = trap_R_RegisterShaderNoMip(va("levelshots/%s", Info_ValueForKey(info, "mapname"))); -    if (uiInfo.serverStatus.currentServerCinematic >= 0) { -      trap_CIN_StopCinematic(uiInfo.serverStatus.currentServerCinematic); -      uiInfo.serverStatus.currentServerCinematic = -1; -    } -    mapName = Info_ValueForKey(info, "mapname"); -    if (mapName && *mapName) { -      uiInfo.serverStatus.currentServerCinematic = trap_CIN_PlayCinematic(va("%s.roq", mapName), 0, 0, 0, 0, (CIN_loop | CIN_silent) ); -    } -  } else if (feederID == FEEDER_SERVERSTATUS) { -    // -  } else if (feederID == FEEDER_FINDPLAYER) { -    uiInfo.currentFoundPlayerServer = index; -    // -    if ( index < uiInfo.numFoundPlayerServers-1) { -      // build a new server status for this server -      Q_strncpyz(uiInfo.serverStatusAddress, uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer], sizeof(uiInfo.serverStatusAddress)); -      Menu_SetFeederSelection(NULL, FEEDER_SERVERSTATUS, 0, NULL); -      UI_BuildServerStatus(qtrue); -    } -  } else if (feederID == FEEDER_PLAYER_LIST) { -    uiInfo.playerIndex = index; -  } else if (feederID == FEEDER_TEAM_LIST) { -    uiInfo.teamIndex = index; -  } else if (feederID == FEEDER_MODS) { -    uiInfo.modIndex = index; -  } else if (feederID == FEEDER_CINEMATICS) { -    uiInfo.movieIndex = index; -    if (uiInfo.previewMovie >= 0) { -      trap_CIN_StopCinematic(uiInfo.previewMovie); -    } -    uiInfo.previewMovie = -1; -  } else if (feederID == FEEDER_DEMOS) { -    uiInfo.demoIndex = index; -  } - -//TA: tremulous menus -  else if( feederID == FEEDER_TREMTEAMS ) -    uiInfo.tremTeamIndex = index; -  else if( feederID == FEEDER_TREMHUMANITEMS ) -    uiInfo.tremHumanItemIndex = index; -  else if( feederID == FEEDER_TREMALIENCLASSES ) -    uiInfo.tremAlienClassIndex = index; -  else if( feederID == FEEDER_TREMHUMANARMOURYBUY ) -    uiInfo.tremHumanArmouryBuyIndex = index; -  else if( feederID == FEEDER_TREMHUMANARMOURYSELL ) -    uiInfo.tremHumanArmourySellIndex = index; -  else if( feederID == FEEDER_TREMALIENUPGRADE ) -    uiInfo.tremAlienUpgradeIndex = index; -  else if( feederID == FEEDER_TREMALIENBUILD ) -    uiInfo.tremAlienBuildIndex = index; -  else if( feederID == FEEDER_TREMHUMANBUILD ) -    uiInfo.tremHumanBuildIndex = index; -//TA: tremulous menus -} - -static void UI_Pause(qboolean b) { -  if (b) { -    // pause the game and set the ui keycatcher -    trap_Cvar_Set( "cl_paused", "1" ); -    trap_Key_SetCatcher( KEYCATCH_UI ); -  } else { -    // unpause the game and clear the ui keycatcher -    trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); -    trap_Key_ClearStates(); -    trap_Cvar_Set( "cl_paused", "0" ); -  } -} - -static int UI_PlayCinematic(const char *name, float x, float y, float w, float h) { -  return trap_CIN_PlayCinematic(name, x, y, w, h, (CIN_loop | CIN_silent)); -} - -static void UI_StopCinematic(int handle) { -  if (handle >= 0) { -    trap_CIN_StopCinematic(handle); -  } else { -    handle = abs(handle); -    if (handle == UI_MAPCINEMATIC) { -      if (uiInfo.mapList[ui_currentMap.integer].cinematic >= 0) { -        trap_CIN_StopCinematic(uiInfo.mapList[ui_currentMap.integer].cinematic); -        uiInfo.mapList[ui_currentMap.integer].cinematic = -1; -      } -    } else if (handle == UI_NETMAPCINEMATIC) { -      if (uiInfo.serverStatus.currentServerCinematic >= 0) { -        trap_CIN_StopCinematic(uiInfo.serverStatus.currentServerCinematic); -        uiInfo.serverStatus.currentServerCinematic = -1; -      } -    } else if (handle == UI_CLANCINEMATIC) { -      int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); -      if (i >= 0 && i < uiInfo.teamCount) { -        if (uiInfo.teamList[i].cinematic >= 0) { -          trap_CIN_StopCinematic(uiInfo.teamList[i].cinematic); -          uiInfo.teamList[i].cinematic = -1; -        } -      } -    } -  } -} - -static void UI_DrawCinematic(int handle, float x, float y, float w, float h) { -  trap_CIN_SetExtents(handle, x, y, w, h); -  trap_CIN_DrawCinematic(handle); -} - -static void UI_RunCinematicFrame(int handle) { -  trap_CIN_RunCinematic(handle); -} - - - -/* -================= -PlayerModel_BuildList -================= -*/ -static void UI_BuildQ3Model_List( void ) -{ -  int   numdirs; -  int   numfiles; -  char  dirlist[2048]; -  char  filelist[2048]; -  char  skinname[64]; -  char  scratch[256]; -  char* dirptr; -  char* fileptr; -  int   i; -  int   j, k, dirty; -  int   dirlen; -  int   filelen; - -  uiInfo.q3HeadCount = 0; - -  // iterate directory of all player models -  numdirs = trap_FS_GetFileList("models/players", "/", dirlist, 2048 ); -  dirptr  = dirlist; -  for (i=0; i<numdirs && uiInfo.q3HeadCount < MAX_PLAYERMODELS; i++,dirptr+=dirlen+1) -  { -    dirlen = strlen(dirptr); - -    if (dirlen && dirptr[dirlen-1]=='/') dirptr[dirlen-1]='\0'; - -    if (!strcmp(dirptr,".") || !strcmp(dirptr,"..")) -      continue; - -    // iterate all skin files in directory -    numfiles = trap_FS_GetFileList( va("models/players/%s",dirptr), "tga", filelist, 2048 ); -    fileptr  = filelist; -    for (j=0; j<numfiles && uiInfo.q3HeadCount < MAX_PLAYERMODELS;j++,fileptr+=filelen+1) -    { -      filelen = strlen(fileptr); - -      COM_StripExtension(fileptr,skinname); - -      // look for icon_???? -      if (Q_stricmpn(skinname, "icon_", 5) == 0 && !(Q_stricmp(skinname,"icon_blue") == 0 || Q_stricmp(skinname,"icon_red") == 0)) -      { -        if (Q_stricmp(skinname, "icon_default") == 0) { -          Com_sprintf( scratch, sizeof(scratch), dirptr); -        } else { -          Com_sprintf( scratch, sizeof(scratch), "%s/%s",dirptr, skinname + 5); -        } -        dirty = 0; -        for(k=0;k<uiInfo.q3HeadCount;k++) { -          if (!Q_stricmp(scratch, uiInfo.q3HeadNames[uiInfo.q3HeadCount])) { -            dirty = 1; -            break; -          } -        } -        if (!dirty) { -          Com_sprintf( uiInfo.q3HeadNames[uiInfo.q3HeadCount], sizeof(uiInfo.q3HeadNames[uiInfo.q3HeadCount]), scratch); -          uiInfo.q3HeadIcons[uiInfo.q3HeadCount++] = trap_R_RegisterShaderNoMip(va("models/players/%s/%s",dirptr,skinname)); -        } -      } - -    } -  } - -} - - - -/* -================= -UI_Init -================= -*/ -void _UI_Init( qboolean inGameLoad ) { -  const char *menuSet; -  int start; - -  BG_InitClassOverrides( ); - -  //uiInfo.inGameLoad = inGameLoad; - -  UI_RegisterCvars(); -  UI_InitMemory(); - -  // cache redundant calulations -  trap_GetGlconfig( &uiInfo.uiDC.glconfig ); - -  // for 640x480 virtualized screen -  uiInfo.uiDC.yscale = uiInfo.uiDC.glconfig.vidHeight * (1.0/480.0); -  uiInfo.uiDC.xscale = uiInfo.uiDC.glconfig.vidWidth * (1.0/640.0); -  if ( uiInfo.uiDC.glconfig.vidWidth * 480 > uiInfo.uiDC.glconfig.vidHeight * 640 ) { -    // wide screen -    uiInfo.uiDC.bias = 0.5 * ( uiInfo.uiDC.glconfig.vidWidth - ( uiInfo.uiDC.glconfig.vidHeight * (640.0/480.0) ) ); -  } -  else { -    // no wide screen -    uiInfo.uiDC.bias = 0; -  } - - -  //UI_Load(); -  uiInfo.uiDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip; -  uiInfo.uiDC.setColor = &UI_SetColor; -  uiInfo.uiDC.drawHandlePic = &UI_DrawHandlePic; -  uiInfo.uiDC.drawStretchPic = &trap_R_DrawStretchPic; -  uiInfo.uiDC.drawText = &Text_Paint; -  uiInfo.uiDC.textWidth = &Text_Width; -  uiInfo.uiDC.textHeight = &Text_Height; -  uiInfo.uiDC.registerModel = &trap_R_RegisterModel; -  uiInfo.uiDC.modelBounds = &trap_R_ModelBounds; -  uiInfo.uiDC.fillRect = &UI_FillRect; -  uiInfo.uiDC.drawRect = &_UI_DrawRect; -  uiInfo.uiDC.drawSides = &_UI_DrawSides; -  uiInfo.uiDC.drawTopBottom = &_UI_DrawTopBottom; -  uiInfo.uiDC.clearScene = &trap_R_ClearScene; -  uiInfo.uiDC.drawSides = &_UI_DrawSides; -  uiInfo.uiDC.addRefEntityToScene = &trap_R_AddRefEntityToScene; -  uiInfo.uiDC.renderScene = &trap_R_RenderScene; -  uiInfo.uiDC.registerFont = &trap_R_RegisterFont; -  uiInfo.uiDC.ownerDrawItem = &UI_OwnerDraw; -  uiInfo.uiDC.getValue = &UI_GetValue; -  uiInfo.uiDC.ownerDrawVisible = &UI_OwnerDrawVisible; -  uiInfo.uiDC.runScript = &UI_RunMenuScript; -  uiInfo.uiDC.getTeamColor = &UI_GetTeamColor; -  uiInfo.uiDC.setCVar = trap_Cvar_Set; -  uiInfo.uiDC.getCVarString = trap_Cvar_VariableStringBuffer; -  uiInfo.uiDC.getCVarValue = trap_Cvar_VariableValue; -  uiInfo.uiDC.drawTextWithCursor = &Text_PaintWithCursor; -  uiInfo.uiDC.setOverstrikeMode = &trap_Key_SetOverstrikeMode; -  uiInfo.uiDC.getOverstrikeMode = &trap_Key_GetOverstrikeMode; -  uiInfo.uiDC.startLocalSound = &trap_S_StartLocalSound; -  uiInfo.uiDC.ownerDrawHandleKey = &UI_OwnerDrawHandleKey; -  uiInfo.uiDC.feederCount = &UI_FeederCount; -  uiInfo.uiDC.feederItemImage = &UI_FeederItemImage; -  uiInfo.uiDC.feederItemText = &UI_FeederItemText; -  uiInfo.uiDC.feederSelection = &UI_FeederSelection; -  uiInfo.uiDC.setBinding = &trap_Key_SetBinding; -  uiInfo.uiDC.getBindingBuf = &trap_Key_GetBindingBuf; -  uiInfo.uiDC.keynumToStringBuf = &trap_Key_KeynumToStringBuf; -  uiInfo.uiDC.executeText = &trap_Cmd_ExecuteText; -  uiInfo.uiDC.Error = &Com_Error; -  uiInfo.uiDC.Print = &Com_Printf; -  uiInfo.uiDC.Pause = &UI_Pause; -  uiInfo.uiDC.ownerDrawWidth = &UI_OwnerDrawWidth; -  uiInfo.uiDC.registerSound = &trap_S_RegisterSound; -  uiInfo.uiDC.startBackgroundTrack = &trap_S_StartBackgroundTrack; -  uiInfo.uiDC.stopBackgroundTrack = &trap_S_StopBackgroundTrack; -  uiInfo.uiDC.playCinematic = &UI_PlayCinematic; -  uiInfo.uiDC.stopCinematic = &UI_StopCinematic; -  uiInfo.uiDC.drawCinematic = &UI_DrawCinematic; -  uiInfo.uiDC.runCinematicFrame = &UI_RunCinematicFrame; - -  Init_Display(&uiInfo.uiDC); - -  String_Init(); - -  uiInfo.uiDC.whiteShader = trap_R_RegisterShaderNoMip( "white" ); - -  AssetCache(); - -  start = trap_Milliseconds(); - -  uiInfo.teamCount = 0; -  uiInfo.characterCount = 0; -  uiInfo.aliasCount = 0; - -/*  UI_ParseTeamInfo("teaminfo.txt"); -  UI_LoadTeams(); -  UI_ParseGameInfo("gameinfo.txt");*/ - -  menuSet = UI_Cvar_VariableString("ui_menuFiles"); -  if (menuSet == NULL || menuSet[0] == '\0') { -    menuSet = "ui/menus.txt"; -  } - -#if 0 -  if (uiInfo.inGameLoad) { -    UI_LoadMenus("ui/ingame.txt", qtrue); -  } else { // bk010222: left this: UI_LoadMenus(menuSet, qtrue); -  } -#else -  UI_LoadMenus(menuSet, qtrue); -  UI_LoadMenus("ui/ingame.txt", qfalse); -  UI_LoadMenus("ui/tremulous.txt", qfalse); - -  UI_LoadInfoPanes( "ui/infopanes.def" ); - -  if( uiInfo.uiDC.debug ) -  { -    int i, j; - -    for( i = 0; i < uiInfo.tremInfoPaneCount; i++ ) -    { -      Com_Printf( "name: %s\n", uiInfo.tremInfoPanes[ i ].name ); - -      Com_Printf( "text: %s\n", uiInfo.tremInfoPanes[ i ].text ); - -      for( j = 0; j < uiInfo.tremInfoPanes[ i ].numGraphics; j++ ) -        Com_Printf( "graphic %d: %d %d %d %d\n", j, uiInfo.tremInfoPanes[ i ].graphics[ j ].side, -                                                    uiInfo.tremInfoPanes[ i ].graphics[ j ].offset, -                                                    uiInfo.tremInfoPanes[ i ].graphics[ j ].width, -                                                    uiInfo.tremInfoPanes[ i ].graphics[ j ].height ); -    } -  } -#endif - -  Menus_CloseAll(); - -  trap_LAN_LoadCachedServers(); -  UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum); - -  UI_BuildQ3Model_List(); -  /*UI_LoadBots();*/ - -  // sets defaults for ui temp cvars -  uiInfo.effectsColor = gamecodetoui[(int)trap_Cvar_VariableValue("color1")-1]; -  uiInfo.currentCrosshair = (int)trap_Cvar_VariableValue("cg_drawCrosshair"); -  trap_Cvar_Set("ui_mousePitch", (trap_Cvar_VariableValue("m_pitch") >= 0) ? "0" : "1"); - -  uiInfo.serverStatus.currentServerCinematic = -1; -  uiInfo.previewMovie = -1; - -  if (trap_Cvar_VariableValue("ui_TeamArenaFirstRun") == 0) { -    trap_Cvar_Set("s_volume", "0.8"); -    trap_Cvar_Set("s_musicvolume", "0.5"); -    trap_Cvar_Set("ui_TeamArenaFirstRun", "1"); -  } - -  trap_Cvar_Register(NULL, "debug_protocol", "", 0 ); - -  trap_Cvar_Set("ui_actualNetGameType", va("%d", ui_netGameType.integer)); -} - - -/* -================= -UI_KeyEvent -================= -*/ -void _UI_KeyEvent( int key, qboolean down ) { - -  if (Menu_Count() > 0) { -    menuDef_t *menu = Menu_GetFocused(); -    if (menu) { -      if (key == K_ESCAPE && down && !Menus_AnyFullScreenVisible()) { -        Menus_CloseAll(); -      } else { -        Menu_HandleKey(menu, key, down ); -      } -    } else { -      trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); -      trap_Key_ClearStates(); -      trap_Cvar_Set( "cl_paused", "0" ); -    } -  } - -  //if ((s > 0) && (s != menu_null_sound)) { -  //  trap_S_StartLocalSound( s, CHAN_LOCAL_SOUND ); -  //} -} - -/* -================= -UI_MouseEvent -================= -*/ -void _UI_MouseEvent( int dx, int dy ) -{ -  // update mouse screen position -  uiInfo.uiDC.cursorx += dx; -  if (uiInfo.uiDC.cursorx < 0) -    uiInfo.uiDC.cursorx = 0; -  else if (uiInfo.uiDC.cursorx > SCREEN_WIDTH) -    uiInfo.uiDC.cursorx = SCREEN_WIDTH; - -  uiInfo.uiDC.cursory += dy; -  if (uiInfo.uiDC.cursory < 0) -    uiInfo.uiDC.cursory = 0; -  else if (uiInfo.uiDC.cursory > SCREEN_HEIGHT) -    uiInfo.uiDC.cursory = SCREEN_HEIGHT; - -  if (Menu_Count() > 0) { -    //menuDef_t *menu = Menu_GetFocused(); -    //Menu_HandleMouseMove(menu, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory); -    Display_MouseMove(NULL, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory); -  } - -} - -void UI_LoadNonIngame( void ) { -  const char *menuSet = UI_Cvar_VariableString("ui_menuFiles"); -  if (menuSet == NULL || menuSet[0] == '\0') { -    menuSet = "ui/menus.txt"; -  } -  UI_LoadMenus(menuSet, qfalse); -  uiInfo.inGameLoad = qfalse; -} - -void _UI_SetActiveMenu( uiMenuCommand_t menu ) { -  char buf[256]; - -  // this should be the ONLY way the menu system is brought up -  // enusure minumum menu data is cached -  if (Menu_Count() > 0) { -    vec3_t v; -    v[0] = v[1] = v[2] = 0; -    switch ( menu ) { -    case UIMENU_NONE: -      trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); -      trap_Key_ClearStates(); -      trap_Cvar_Set( "cl_paused", "0" ); -      Menus_CloseAll(); - -      return; -    case UIMENU_MAIN: -      //trap_Cvar_Set( "sv_killserver", "1" ); -      trap_Key_SetCatcher( KEYCATCH_UI ); -      //trap_S_StartLocalSound( trap_S_RegisterSound("sound/misc/menu_background.wav", qfalse) , CHAN_LOCAL_SOUND ); -      //trap_S_StartBackgroundTrack("sound/misc/menu_background.wav", NULL); -      if (uiInfo.inGameLoad) { -        UI_LoadNonIngame(); -      } -      Menus_CloseAll(); -      Menus_ActivateByName("main"); -      trap_Cvar_VariableStringBuffer("com_errorMessage", buf, sizeof(buf)); -      if (strlen(buf)) { -        if (!ui_singlePlayerActive.integer) { -          Menus_ActivateByName("error_popmenu"); -        } else { -          trap_Cvar_Set("com_errorMessage", ""); -        } -      } - -#define MIN_HUNKMEGS  100 - -      trap_Cvar_VariableStringBuffer( "com_hunkMegs", buf, sizeof( buf ) ); -      if( strlen( buf ) && atoi( buf ) < MIN_HUNKMEGS ) -      { -        trap_Cvar_Set( "com_hunkMegs", va( "%d", MIN_HUNKMEGS ) ); -        trap_Cvar_Set( "com_errorMessage", "Your com_hunkMegs setting was too low. " -            "It has been changed to a suitable value, but you must restart Quake 3 " -            "for it to take effect." ); -        Menus_ActivateByName( "error_popmenu" ); -      } -      return; -    case UIMENU_TEAM: -      trap_Key_SetCatcher( KEYCATCH_UI ); -      Menus_ActivateByName("team"); -      return; -    case UIMENU_NEED_CD: -      // no cd check in TA -      //trap_Key_SetCatcher( KEYCATCH_UI ); -      //Menus_ActivateByName("needcd"); -      //UI_ConfirmMenu( "Insert the CD", NULL, NeedCDAction ); -      return; -    case UIMENU_BAD_CD_KEY: -      // no cd check in TA -      //trap_Key_SetCatcher( KEYCATCH_UI ); -      //Menus_ActivateByName("badcd"); -      //UI_ConfirmMenu( "Bad CD Key", NULL, NeedCDKeyAction ); -      return; -    case UIMENU_POSTGAME: -      //trap_Cvar_Set( "sv_killserver", "1" ); -      trap_Key_SetCatcher( KEYCATCH_UI ); -      if (uiInfo.inGameLoad) { -        UI_LoadNonIngame(); -      } -      Menus_CloseAll(); -      Menus_ActivateByName("endofgame"); -      //UI_ConfirmMenu( "Bad CD Key", NULL, NeedCDKeyAction ); -      return; -    case UIMENU_INGAME: -      trap_Cvar_Set( "cl_paused", "1" ); -      trap_Key_SetCatcher( KEYCATCH_UI ); -      UI_BuildPlayerList(); -      Menus_CloseAll(); -      Menus_ActivateByName("ingame"); -      return; -    } -  } -} - -qboolean _UI_IsFullscreen( void ) { -  return Menus_AnyFullScreenVisible(); -} - - - -static connstate_t  lastConnState; -static char     lastLoadingText[MAX_INFO_VALUE]; - -static void UI_ReadableSize ( char *buf, int bufsize, int value ) -{ -  if (value > 1024*1024*1024 ) { // gigs -    Com_sprintf( buf, bufsize, "%d", value / (1024*1024*1024) ); -    Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d GB", -      (value % (1024*1024*1024))*100 / (1024*1024*1024) ); -  } else if (value > 1024*1024 ) { // megs -    Com_sprintf( buf, bufsize, "%d", value / (1024*1024) ); -    Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d MB", -      (value % (1024*1024))*100 / (1024*1024) ); -  } else if (value > 1024 ) { // kilos -    Com_sprintf( buf, bufsize, "%d KB", value / 1024 ); -  } else { // bytes -    Com_sprintf( buf, bufsize, "%d bytes", value ); -  } -} - -// Assumes time is in msec -static void UI_PrintTime ( char *buf, int bufsize, int time ) { -  time /= 1000;  // change to seconds - -  if (time > 3600) { // in the hours range -    Com_sprintf( buf, bufsize, "%d hr %d min", time / 3600, (time % 3600) / 60 ); -  } else if (time > 60) { // mins -    Com_sprintf( buf, bufsize, "%d min %d sec", time / 60, time % 60 ); -  } else  { // secs -    Com_sprintf( buf, bufsize, "%d sec", time ); -  } -} - -void Text_PaintCenter(float x, float y, float scale, vec4_t color, const char *text, float adjust) { -  int len = Text_Width(text, scale, 0); -  Text_Paint(x - len / 2, y, scale, color, text, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE); -} - -void Text_PaintCenter_AutoWrapped(float x, float y, float xmax, float ystep, float scale, vec4_t color, const char *str, float adjust) { -  int width; -  char *s1,*s2,*s3; -  char c_bcp; -  char buf[1024]; - -  if (!str || str[0]=='\0') -    return; - -  Q_strncpyz(buf, str, sizeof(buf)); -  s1 = s2 = s3 = buf; - -  while (1) { -    do { -      s3++; -    } while (*s3!=' ' && *s3!='\0'); -    c_bcp = *s3; -    *s3 = '\0'; -    width = Text_Width(s1, scale, 0); -    *s3 = c_bcp; -    if (width > xmax) { -      if (s1==s2) -      { -        // fuck, don't have a clean cut, we'll overflow -        s2 = s3; -      } -      *s2 = '\0'; -      Text_PaintCenter(x, y, scale, color, s1, adjust); -      y += ystep; -      if (c_bcp == '\0') -      { -        // that was the last word -        // we could start a new loop, but that wouldn't be much use -        // even if the word is too long, we would overflow it (see above) -        // so just print it now if needed -        s2++; -        if (*s2 != '\0') // if we are printing an overflowing line we have s2 == s3 -          Text_PaintCenter(x, y, scale, color, s2, adjust); -        break; -      } -      s2++; -      s1 = s2; -      s3 = s2; -    } -    else -    { -      s2 = s3; -      if (c_bcp == '\0') // we reached the end -      { -        Text_PaintCenter(x, y, scale, color, s1, adjust); -        break; -      } -    } -  } -} - - -static void UI_DisplayDownloadInfo( const char *downloadName, float centerPoint, float yStart, float scale ) { -  static char dlText[]  = "Downloading:"; -  static char etaText[] = "Estimated time left:"; -  static char xferText[]  = "Transfer rate:"; - -  int downloadSize, downloadCount, downloadTime; -  char dlSizeBuf[64], totalSizeBuf[64], xferRateBuf[64], dlTimeBuf[64]; -  int xferRate; -  int leftWidth; -  const char *s; - -  downloadSize = trap_Cvar_VariableValue( "cl_downloadSize" ); -  downloadCount = trap_Cvar_VariableValue( "cl_downloadCount" ); -  downloadTime = trap_Cvar_VariableValue( "cl_downloadTime" ); - -  leftWidth = 320; - -  UI_SetColor(colorWhite); -  Text_PaintCenter(centerPoint, yStart + 112, scale, colorWhite, dlText, 0); -  Text_PaintCenter(centerPoint, yStart + 192, scale, colorWhite, etaText, 0); -  Text_PaintCenter(centerPoint, yStart + 248, scale, colorWhite, xferText, 0); - -  if (downloadSize > 0) { -    s = va( "%s (%d%%)", downloadName, downloadCount * 100 / downloadSize ); -  } else { -    s = downloadName; -  } - -  Text_PaintCenter(centerPoint, yStart+136, scale, colorWhite, s, 0); - -  UI_ReadableSize( dlSizeBuf,   sizeof dlSizeBuf,   downloadCount ); -  UI_ReadableSize( totalSizeBuf,  sizeof totalSizeBuf,  downloadSize ); - -  if (downloadCount < 4096 || !downloadTime) { -    Text_PaintCenter(leftWidth, yStart+216, scale, colorWhite, "estimating", 0); -    Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0); -  } else { -    if ((uiInfo.uiDC.realTime - downloadTime) / 1000) { -      xferRate = downloadCount / ((uiInfo.uiDC.realTime - downloadTime) / 1000); -    } else { -      xferRate = 0; -    } -    UI_ReadableSize( xferRateBuf, sizeof xferRateBuf, xferRate ); - -    // Extrapolate estimated completion time -    if (downloadSize && xferRate) { -      int n = downloadSize / xferRate; // estimated time for entire d/l in secs - -      // We do it in K (/1024) because we'd overflow around 4MB -      UI_PrintTime ( dlTimeBuf, sizeof dlTimeBuf, -        (n - (((downloadCount/1024) * n) / (downloadSize/1024))) * 1000); - -      Text_PaintCenter(leftWidth, yStart+216, scale, colorWhite, dlTimeBuf, 0); -      Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0); -    } else { -      Text_PaintCenter(leftWidth, yStart+216, scale, colorWhite, "estimating", 0); -      if (downloadSize) { -        Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0); -      } else { -        Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s copied)", dlSizeBuf), 0); -      } -    } - -    if (xferRate) { -      Text_PaintCenter(leftWidth, yStart+272, scale, colorWhite, va("%s/Sec", xferRateBuf), 0); -    } -  } -} - -/* -======================== -UI_DrawConnectScreen - -This will also be overlaid on the cgame info screen during loading -to prevent it from blinking away too rapidly on local or lan games. -======================== -*/ -void UI_DrawConnectScreen( qboolean overlay ) { -  char      *s; -  uiClientState_t cstate; -  char      info[MAX_INFO_VALUE]; -  char text[256]; -  float centerPoint, yStart, scale; - -  menuDef_t *menu = Menus_FindByName("Connect"); - - -  if ( !overlay && menu ) { -    Menu_Paint(menu, qtrue); -  } - -  if (!overlay) { -    centerPoint = 320; -    yStart = 130; -    scale = 0.5f; -  } else { -    centerPoint = 320; -    yStart = 32; -    scale = 0.6f; -    return; -  } - -  // see what information we should display -  trap_GetClientState( &cstate ); - -  info[0] = '\0'; -  if( trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ) ) { -    Text_PaintCenter(centerPoint, yStart, scale, colorWhite, va( "Loading %s", Info_ValueForKey( info, "mapname" )), 0); -  } - -  if (!Q_stricmp(cstate.servername,"localhost")) { -    Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite, va("Starting up..."), ITEM_TEXTSTYLE_SHADOWEDMORE); -  } else { -    strcpy(text, va("Connecting to %s", cstate.servername)); -    Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite,text , ITEM_TEXTSTYLE_SHADOWEDMORE); -  } - - -  // display global MOTD at bottom -  Text_PaintCenter(centerPoint, 600, scale, colorWhite, Info_ValueForKey( cstate.updateInfoString, "motd" ), 0); -  // print any server info (server full, bad version, etc) -  if ( cstate.connState < CA_CONNECTED ) { -    Text_PaintCenter_AutoWrapped(centerPoint, yStart + 176, 630, 20, scale, colorWhite, cstate.messageString, 0); -  } - -  if ( lastConnState > cstate.connState ) { -    lastLoadingText[0] = '\0'; -  } -  lastConnState = cstate.connState; - -  switch ( cstate.connState ) { -  case CA_CONNECTING: -    s = va("Awaiting connection...%i", cstate.connectPacketCount); -    break; -  case CA_CHALLENGING: -    s = va("Awaiting challenge...%i", cstate.connectPacketCount); -    break; -  case CA_CONNECTED: { -    char downloadName[MAX_INFO_VALUE]; - -      trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof(downloadName) ); -      if (*downloadName) { -        UI_DisplayDownloadInfo( downloadName, centerPoint, yStart, scale ); -        return; -      } -    } -    s = "Awaiting gamestate..."; -    break; -  case CA_LOADING: -    return; -  case CA_PRIMED: -    return; -  default: -    return; -  } - - -  if (Q_stricmp(cstate.servername,"localhost")) { -    Text_PaintCenter(centerPoint, yStart + 80, scale, colorWhite, s, 0); -  } - -  // password required / connection rejected information goes here -} - - -/* -================ -cvars -================ -*/ - -typedef struct { -  vmCvar_t  *vmCvar; -  char    *cvarName; -  char    *defaultString; -  int     cvarFlags; -} cvarTable_t; - -vmCvar_t  ui_ffa_fraglimit; -vmCvar_t  ui_ffa_timelimit; - -vmCvar_t  ui_tourney_fraglimit; -vmCvar_t  ui_tourney_timelimit; - -vmCvar_t  ui_team_fraglimit; -vmCvar_t  ui_team_timelimit; -vmCvar_t  ui_team_friendly; - -vmCvar_t  ui_ctf_capturelimit; -vmCvar_t  ui_ctf_timelimit; -vmCvar_t  ui_ctf_friendly; - -vmCvar_t  ui_arenasFile; -vmCvar_t  ui_botsFile; -vmCvar_t  ui_spScores1; -vmCvar_t  ui_spScores2; -vmCvar_t  ui_spScores3; -vmCvar_t  ui_spScores4; -vmCvar_t  ui_spScores5; -vmCvar_t  ui_spAwards; -vmCvar_t  ui_spVideos; -vmCvar_t  ui_spSkill; - -vmCvar_t  ui_spSelection; - -vmCvar_t  ui_browserMaster; -vmCvar_t  ui_browserGameType; -vmCvar_t  ui_browserSortKey; -vmCvar_t  ui_browserShowFull; -vmCvar_t  ui_browserShowEmpty; - -vmCvar_t  ui_brassTime; -vmCvar_t  ui_drawCrosshair; -vmCvar_t  ui_drawCrosshairNames; -vmCvar_t  ui_marks; - -vmCvar_t  ui_server1; -vmCvar_t  ui_server2; -vmCvar_t  ui_server3; -vmCvar_t  ui_server4; -vmCvar_t  ui_server5; -vmCvar_t  ui_server6; -vmCvar_t  ui_server7; -vmCvar_t  ui_server8; -vmCvar_t  ui_server9; -vmCvar_t  ui_server10; -vmCvar_t  ui_server11; -vmCvar_t  ui_server12; -vmCvar_t  ui_server13; -vmCvar_t  ui_server14; -vmCvar_t  ui_server15; -vmCvar_t  ui_server16; - -vmCvar_t  ui_cdkeychecked; - -vmCvar_t  ui_redteam; -vmCvar_t  ui_redteam1; -vmCvar_t  ui_redteam2; -vmCvar_t  ui_redteam3; -vmCvar_t  ui_redteam4; -vmCvar_t  ui_redteam5; -vmCvar_t  ui_blueteam; -vmCvar_t  ui_blueteam1; -vmCvar_t  ui_blueteam2; -vmCvar_t  ui_blueteam3; -vmCvar_t  ui_blueteam4; -vmCvar_t  ui_blueteam5; -vmCvar_t  ui_teamName; -vmCvar_t  ui_dedicated; -vmCvar_t  ui_gameType; -vmCvar_t  ui_netGameType; -vmCvar_t  ui_actualNetGameType; -vmCvar_t  ui_joinGameType; -vmCvar_t  ui_netSource; -vmCvar_t  ui_serverFilterType; -vmCvar_t  ui_opponentName; -vmCvar_t  ui_menuFiles; -vmCvar_t  ui_currentTier; -vmCvar_t  ui_currentMap; -vmCvar_t  ui_currentNetMap; -vmCvar_t  ui_mapIndex; -vmCvar_t  ui_currentOpponent; -vmCvar_t  ui_selectedPlayer; -vmCvar_t  ui_selectedPlayerName; -vmCvar_t  ui_lastServerRefresh_0; -vmCvar_t  ui_lastServerRefresh_1; -vmCvar_t  ui_lastServerRefresh_2; -vmCvar_t  ui_lastServerRefresh_3; -vmCvar_t  ui_singlePlayerActive; -vmCvar_t  ui_scoreAccuracy; -vmCvar_t  ui_scoreImpressives; -vmCvar_t  ui_scoreExcellents; -vmCvar_t  ui_scoreCaptures; -vmCvar_t  ui_scoreDefends; -vmCvar_t  ui_scoreAssists; -vmCvar_t  ui_scoreGauntlets; -vmCvar_t  ui_scoreScore; -vmCvar_t  ui_scorePerfect; -vmCvar_t  ui_scoreTeam; -vmCvar_t  ui_scoreBase; -vmCvar_t  ui_scoreTimeBonus; -vmCvar_t  ui_scoreSkillBonus; -vmCvar_t  ui_scoreShutoutBonus; -vmCvar_t  ui_scoreTime; -vmCvar_t  ui_captureLimit; -vmCvar_t  ui_fragLimit; -vmCvar_t  ui_smallFont; -vmCvar_t  ui_bigFont; -vmCvar_t  ui_findPlayer; -vmCvar_t  ui_Q3Model; -vmCvar_t  ui_hudFiles; -vmCvar_t  ui_recordSPDemo; -vmCvar_t  ui_realCaptureLimit; -vmCvar_t  ui_realWarmUp; -vmCvar_t  ui_serverStatusTimeOut; - -//TA: bank values -vmCvar_t  ui_bank; - - -// bk001129 - made static to avoid aliasing -static cvarTable_t    cvarTable[] = { -  { &ui_ffa_fraglimit, "ui_ffa_fraglimit", "20", CVAR_ARCHIVE }, -  { &ui_ffa_timelimit, "ui_ffa_timelimit", "0", CVAR_ARCHIVE }, - -  { &ui_tourney_fraglimit, "ui_tourney_fraglimit", "0", CVAR_ARCHIVE }, -  { &ui_tourney_timelimit, "ui_tourney_timelimit", "15", CVAR_ARCHIVE }, - -  { &ui_team_fraglimit, "ui_team_fraglimit", "0", CVAR_ARCHIVE }, -  { &ui_team_timelimit, "ui_team_timelimit", "20", CVAR_ARCHIVE }, -  { &ui_team_friendly, "ui_team_friendly",  "1", CVAR_ARCHIVE }, - -  { &ui_ctf_capturelimit, "ui_ctf_capturelimit", "8", CVAR_ARCHIVE }, -  { &ui_ctf_timelimit, "ui_ctf_timelimit", "30", CVAR_ARCHIVE }, -  { &ui_ctf_friendly, "ui_ctf_friendly",  "0", CVAR_ARCHIVE }, - -  { &ui_arenasFile, "g_arenasFile", "", CVAR_INIT|CVAR_ROM }, -  { &ui_botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM }, -  { &ui_spScores1, "g_spScores1", "", CVAR_ARCHIVE | CVAR_ROM }, -  { &ui_spScores2, "g_spScores2", "", CVAR_ARCHIVE | CVAR_ROM }, -  { &ui_spScores3, "g_spScores3", "", CVAR_ARCHIVE | CVAR_ROM }, -  { &ui_spScores4, "g_spScores4", "", CVAR_ARCHIVE | CVAR_ROM }, -  { &ui_spScores5, "g_spScores5", "", CVAR_ARCHIVE | CVAR_ROM }, -  { &ui_spAwards, "g_spAwards", "", CVAR_ARCHIVE | CVAR_ROM }, -  { &ui_spVideos, "g_spVideos", "", CVAR_ARCHIVE | CVAR_ROM }, -  { &ui_spSkill, "g_spSkill", "2", CVAR_ARCHIVE }, - -  { &ui_spSelection, "ui_spSelection", "", CVAR_ROM }, - -  { &ui_browserMaster, "ui_browserMaster", "0", CVAR_ARCHIVE }, -  { &ui_browserGameType, "ui_browserGameType", "0", CVAR_ARCHIVE }, -  { &ui_browserSortKey, "ui_browserSortKey", "4", CVAR_ARCHIVE }, -  { &ui_browserShowFull, "ui_browserShowFull", "1", CVAR_ARCHIVE }, -  { &ui_browserShowEmpty, "ui_browserShowEmpty", "1", CVAR_ARCHIVE }, - -  { &ui_brassTime, "cg_brassTime", "2500", CVAR_ARCHIVE }, -  { &ui_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE }, -  { &ui_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE }, -  { &ui_marks, "cg_marks", "1", CVAR_ARCHIVE }, - -  { &ui_server1, "server1", "", CVAR_ARCHIVE }, -  { &ui_server2, "server2", "", CVAR_ARCHIVE }, -  { &ui_server3, "server3", "", CVAR_ARCHIVE }, -  { &ui_server4, "server4", "", CVAR_ARCHIVE }, -  { &ui_server5, "server5", "", CVAR_ARCHIVE }, -  { &ui_server6, "server6", "", CVAR_ARCHIVE }, -  { &ui_server7, "server7", "", CVAR_ARCHIVE }, -  { &ui_server8, "server8", "", CVAR_ARCHIVE }, -  { &ui_server9, "server9", "", CVAR_ARCHIVE }, -  { &ui_server10, "server10", "", CVAR_ARCHIVE }, -  { &ui_server11, "server11", "", CVAR_ARCHIVE }, -  { &ui_server12, "server12", "", CVAR_ARCHIVE }, -  { &ui_server13, "server13", "", CVAR_ARCHIVE }, -  { &ui_server14, "server14", "", CVAR_ARCHIVE }, -  { &ui_server15, "server15", "", CVAR_ARCHIVE }, -  { &ui_server16, "server16", "", CVAR_ARCHIVE }, -  { &ui_cdkeychecked, "ui_cdkeychecked", "0", CVAR_ROM }, -  { &ui_new, "ui_new", "0", CVAR_TEMP }, -  { &ui_debug, "ui_debug", "0", CVAR_TEMP }, -  { &ui_initialized, "ui_initialized", "0", CVAR_TEMP }, -  { &ui_teamName, "ui_teamName", "Pagans", CVAR_ARCHIVE }, -  { &ui_opponentName, "ui_opponentName", "Stroggs", CVAR_ARCHIVE }, -  { &ui_redteam, "ui_redteam", "Pagans", CVAR_ARCHIVE }, -  { &ui_blueteam, "ui_blueteam", "Stroggs", CVAR_ARCHIVE }, -  { &ui_dedicated, "ui_dedicated", "0", CVAR_ARCHIVE }, -  { &ui_gameType, "ui_gametype", "3", CVAR_ARCHIVE }, -  { &ui_joinGameType, "ui_joinGametype", "0", CVAR_ARCHIVE }, -  { &ui_netGameType, "ui_netGametype", "3", CVAR_ARCHIVE }, -  { &ui_actualNetGameType, "ui_actualNetGametype", "3", CVAR_ARCHIVE }, -  { &ui_redteam1, "ui_redteam1", "0", CVAR_ARCHIVE }, -  { &ui_redteam2, "ui_redteam2", "0", CVAR_ARCHIVE }, -  { &ui_redteam3, "ui_redteam3", "0", CVAR_ARCHIVE }, -  { &ui_redteam4, "ui_redteam4", "0", CVAR_ARCHIVE }, -  { &ui_redteam5, "ui_redteam5", "0", CVAR_ARCHIVE }, -  { &ui_blueteam1, "ui_blueteam1", "0", CVAR_ARCHIVE }, -  { &ui_blueteam2, "ui_blueteam2", "0", CVAR_ARCHIVE }, -  { &ui_blueteam3, "ui_blueteam3", "0", CVAR_ARCHIVE }, -  { &ui_blueteam4, "ui_blueteam4", "0", CVAR_ARCHIVE }, -  { &ui_blueteam5, "ui_blueteam5", "0", CVAR_ARCHIVE }, -  { &ui_netSource, "ui_netSource", "0", CVAR_ARCHIVE }, -  { &ui_menuFiles, "ui_menuFiles", "ui/menus.txt", CVAR_ARCHIVE }, -  { &ui_currentTier, "ui_currentTier", "0", CVAR_ARCHIVE }, -  { &ui_currentMap, "ui_currentMap", "0", CVAR_ARCHIVE }, -  { &ui_currentNetMap, "ui_currentNetMap", "0", CVAR_ARCHIVE }, -  { &ui_mapIndex, "ui_mapIndex", "0", CVAR_ARCHIVE }, -  { &ui_currentOpponent, "ui_currentOpponent", "0", CVAR_ARCHIVE }, -  { &ui_selectedPlayer, "cg_selectedPlayer", "0", CVAR_ARCHIVE}, -  { &ui_selectedPlayerName, "cg_selectedPlayerName", "", CVAR_ARCHIVE}, -  { &ui_lastServerRefresh_0, "ui_lastServerRefresh_0", "", CVAR_ARCHIVE}, -  { &ui_lastServerRefresh_1, "ui_lastServerRefresh_1", "", CVAR_ARCHIVE}, -  { &ui_lastServerRefresh_2, "ui_lastServerRefresh_2", "", CVAR_ARCHIVE}, -  { &ui_lastServerRefresh_3, "ui_lastServerRefresh_3", "", CVAR_ARCHIVE}, -  { &ui_singlePlayerActive, "ui_singlePlayerActive", "0", 0}, -  { &ui_scoreAccuracy, "ui_scoreAccuracy", "0", CVAR_ARCHIVE}, -  { &ui_scoreImpressives, "ui_scoreImpressives", "0", CVAR_ARCHIVE}, -  { &ui_scoreExcellents, "ui_scoreExcellents", "0", CVAR_ARCHIVE}, -  { &ui_scoreCaptures, "ui_scoreCaptures", "0", CVAR_ARCHIVE}, -  { &ui_scoreDefends, "ui_scoreDefends", "0", CVAR_ARCHIVE}, -  { &ui_scoreAssists, "ui_scoreAssists", "0", CVAR_ARCHIVE}, -  { &ui_scoreGauntlets, "ui_scoreGauntlets", "0",CVAR_ARCHIVE}, -  { &ui_scoreScore, "ui_scoreScore", "0", CVAR_ARCHIVE}, -  { &ui_scorePerfect, "ui_scorePerfect", "0", CVAR_ARCHIVE}, -  { &ui_scoreTeam, "ui_scoreTeam", "0 to 0", CVAR_ARCHIVE}, -  { &ui_scoreBase, "ui_scoreBase", "0", CVAR_ARCHIVE}, -  { &ui_scoreTime, "ui_scoreTime", "00:00", CVAR_ARCHIVE}, -  { &ui_scoreTimeBonus, "ui_scoreTimeBonus", "0", CVAR_ARCHIVE}, -  { &ui_scoreSkillBonus, "ui_scoreSkillBonus", "0", CVAR_ARCHIVE}, -  { &ui_scoreShutoutBonus, "ui_scoreShutoutBonus", "0", CVAR_ARCHIVE}, -  { &ui_fragLimit, "ui_fragLimit", "10", 0}, -  { &ui_captureLimit, "ui_captureLimit", "5", 0}, -  { &ui_smallFont, "ui_smallFont", "0.2", CVAR_ARCHIVE}, -  { &ui_bigFont, "ui_bigFont", "0.5", CVAR_ARCHIVE}, -  { &ui_findPlayer, "ui_findPlayer", "Sarge", CVAR_ARCHIVE}, -  { &ui_Q3Model, "ui_q3model", "0", CVAR_ARCHIVE}, -  { &ui_hudFiles, "cg_hudFiles", "ui/hud.txt", CVAR_ARCHIVE}, -  { &ui_recordSPDemo, "ui_recordSPDemo", "0", CVAR_ARCHIVE}, -  { &ui_teamArenaFirstRun, "ui_teamArenaFirstRun", "0", CVAR_ARCHIVE}, -  { &ui_realWarmUp, "g_warmup", "20", CVAR_ARCHIVE}, -  { &ui_realCaptureLimit, "capturelimit", "8", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART}, -  { &ui_serverStatusTimeOut, "ui_serverStatusTimeOut", "7000", CVAR_ARCHIVE}, - -  { &ui_bank, "ui_bank", "0", 0 }, - -}; - -// bk001129 - made static to avoid aliasing -static int    cvarTableSize = sizeof(cvarTable) / sizeof(cvarTable[0]); - - -/* -================= -UI_RegisterCvars -================= -*/ -void UI_RegisterCvars( void ) { -  int     i; -  cvarTable_t *cv; - -  for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) { -    trap_Cvar_Register( cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags ); -  } -} - -/* -================= -UI_UpdateCvars -================= -*/ -void UI_UpdateCvars( void ) { -  int     i; -  cvarTable_t *cv; - -  for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) { -    trap_Cvar_Update( cv->vmCvar ); -  } -} - - -/* -================= -ArenaServers_StopRefresh -================= -*/ -static void UI_StopServerRefresh( void ) -{ -  int count; - -  if (!uiInfo.serverStatus.refreshActive) { -    // not currently refreshing -    return; -  } -  uiInfo.serverStatus.refreshActive = qfalse; -  Com_Printf("%d servers listed in browser with %d players.\n", -          uiInfo.serverStatus.numDisplayServers, -          uiInfo.serverStatus.numPlayersOnServers); -  count = trap_LAN_GetServerCount(ui_netSource.integer); -  if (count - uiInfo.serverStatus.numDisplayServers > 0) { -    Com_Printf("%d servers not listed due to packet loss or pings higher than %d\n", -            count - uiInfo.serverStatus.numDisplayServers, -            (int) trap_Cvar_VariableValue("cl_maxPing")); -  } - -} - -/* -================= -UI_DoServerRefresh -================= -*/ -static void UI_DoServerRefresh( void ) -{ -  qboolean wait = qfalse; - -  if (!uiInfo.serverStatus.refreshActive) { -    return; -  } -  if (ui_netSource.integer != AS_FAVORITES) { -    if (ui_netSource.integer == AS_LOCAL) { -      if (!trap_LAN_GetServerCount(ui_netSource.integer)) { -        wait = qtrue; -      } -    } else { -      if (trap_LAN_GetServerCount(ui_netSource.integer) < 0) { -        wait = qtrue; -      } -    } -  } - -  if (uiInfo.uiDC.realTime < uiInfo.serverStatus.refreshtime) { -    if (wait) { -      return; -    } -  } - -  // if still trying to retrieve pings -  if (trap_LAN_UpdateVisiblePings(ui_netSource.integer)) { -    uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000; -  } else if (!wait) { -    // get the last servers in the list -    UI_BuildServerDisplayList(2); -    // stop the refresh -    UI_StopServerRefresh(); -  } -  // -  UI_BuildServerDisplayList(qfalse); -} - -/* -================= -UI_StartServerRefresh -================= -*/ -static void UI_StartServerRefresh(qboolean full) -{ -  int   i; -  char  *ptr; - -  qtime_t q; -  trap_RealTime(&q); -  trap_Cvar_Set( va("ui_lastServerRefresh_%i", ui_netSource.integer), va("%s-%i, %i at %i:%i", MonthAbbrev[q.tm_mon],q.tm_mday, 1900+q.tm_year,q.tm_hour,q.tm_min)); - -  if (!full) { -    UI_UpdatePendingPings(); -    return; -  } - -  uiInfo.serverStatus.refreshActive = qtrue; -  uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 1000; -  // clear number of displayed servers -  uiInfo.serverStatus.numDisplayServers = 0; -  uiInfo.serverStatus.numPlayersOnServers = 0; -  // mark all servers as visible so we store ping updates for them -  trap_LAN_MarkServerVisible(ui_netSource.integer, -1, qtrue); -  // reset all the pings -  trap_LAN_ResetPings(ui_netSource.integer); -  // -  if( ui_netSource.integer == AS_LOCAL ) { -    trap_Cmd_ExecuteText( EXEC_NOW, "localservers\n" ); -    uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000; -    return; -  } - -  uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 5000; -  if( ui_netSource.integer == AS_GLOBAL || ui_netSource.integer == AS_MPLAYER ) { -    if( ui_netSource.integer == AS_GLOBAL ) { -      i = 0; -    } -    else { -      i = 1; -    } - -    ptr = UI_Cvar_VariableString("debug_protocol"); -    if (strlen(ptr)) { -      trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %s full empty\n", i, ptr)); -    } -    else { -      trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %d full empty\n", i, (int)trap_Cvar_VariableValue( "protocol" ) ) ); -    } -  } -} - diff --git a/mod/src/ui/ui_players.c b/mod/src/ui/ui_players.c deleted file mode 100644 index 71c4f5cc..00000000 --- a/mod/src/ui/ui_players.c +++ /dev/null @@ -1,1362 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -// ui_players.c - -#include "ui_local.h" - - -#define UI_TIMER_GESTURE    2300 -#define UI_TIMER_JUMP      1000 -#define UI_TIMER_LAND      130 -#define UI_TIMER_WEAPON_SWITCH  300 -#define UI_TIMER_ATTACK      500 -#define  UI_TIMER_MUZZLE_FLASH  20 -#define  UI_TIMER_WEAPON_DELAY  250 - -#define JUMP_HEIGHT        56 - -#define SWINGSPEED        0.3f - -#define SPIN_SPEED        0.9f -#define COAST_TIME        1000 - - -static int      dp_realtime; -static float    jumpHeight; -sfxHandle_t weaponChangeSound; - - -/* -=============== -UI_PlayerInfo_SetWeapon -=============== -*/ -static void UI_PlayerInfo_SetWeapon( playerInfo_t *pi, weapon_t weaponNum ) -{ -  //TA: FIXME: this is probably useless for trem -/*  gitem_t *  item; -  char    path[MAX_QPATH]; - -  pi->currentWeapon = weaponNum; -tryagain: -  pi->realWeapon = weaponNum; -  pi->weaponModel = 0; -  pi->barrelModel = 0; -  pi->flashModel = 0; - -  if ( weaponNum == WP_NONE ) { -    return; -  } - -  if ( item->classname ) { -    pi->weaponModel = trap_R_RegisterModel( item->world_model[0] ); -  } - -  if( pi->weaponModel == 0 ) { -    if( weaponNum == WP_MACHINEGUN ) { -      weaponNum = WP_NONE; -      goto tryagain; -    } -    weaponNum = WP_MACHINEGUN; -    goto tryagain; -  } - -  if ( weaponNum == WP_MACHINEGUN ) { -    strcpy( path, item->world_model[0] ); -    COM_StripExtension( path, path ); -    strcat( path, "_barrel.md3" ); -    pi->barrelModel = trap_R_RegisterModel( path ); -  } - -  strcpy( path, item->world_model[0] ); -  COM_StripExtension( path, path ); -  strcat( path, "_flash.md3" ); -  pi->flashModel = trap_R_RegisterModel( path ); - -  switch( weaponNum ) { -  case WP_GAUNTLET: -    MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); -    break; - -  case WP_MACHINEGUN: -    MAKERGB( pi->flashDlightColor, 1, 1, 0 ); -    break; - -  case WP_SHOTGUN: -    MAKERGB( pi->flashDlightColor, 1, 1, 0 ); -    break; - -  case WP_GRENADE_LAUNCHER: -    MAKERGB( pi->flashDlightColor, 1, 0.7f, 0.5f ); -    break; - -  case WP_ROCKET_LAUNCHER: -    MAKERGB( pi->flashDlightColor, 1, 0.75f, 0 ); -    break; - -  case WP_TESLAGEN: -    MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); -    break; - -  case WP_RAILGUN: -    MAKERGB( pi->flashDlightColor, 1, 0.5f, 0 ); -    break; - -  case WP_BFG: -    MAKERGB( pi->flashDlightColor, 1, 0.7f, 1 ); -    break; - -  case WP_GRAPPLING_HOOK: -    MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); -    break; - -  default: -    MAKERGB( pi->flashDlightColor, 1, 1, 1 ); -    break; -  }*/ -} - - -/* -=============== -UI_ForceLegsAnim -=============== -*/ -static void UI_ForceLegsAnim( playerInfo_t *pi, int anim ) { -  pi->legsAnim = ( ( pi->legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim; - -  if ( anim == LEGS_JUMP ) { -    pi->legsAnimationTimer = UI_TIMER_JUMP; -  } -} - - -/* -=============== -UI_SetLegsAnim -=============== -*/ -static void UI_SetLegsAnim( playerInfo_t *pi, int anim ) { -  if ( pi->pendingLegsAnim ) { -    anim = pi->pendingLegsAnim; -    pi->pendingLegsAnim = 0; -  } -  UI_ForceLegsAnim( pi, anim ); -} - - -/* -=============== -UI_ForceTorsoAnim -=============== -*/ -static void UI_ForceTorsoAnim( playerInfo_t *pi, int anim ) { -  pi->torsoAnim = ( ( pi->torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim; - -  if ( anim == TORSO_GESTURE ) { -    pi->torsoAnimationTimer = UI_TIMER_GESTURE; -  } - -  if ( anim == TORSO_ATTACK || anim == TORSO_ATTACK2 ) { -    pi->torsoAnimationTimer = UI_TIMER_ATTACK; -  } -} - - -/* -=============== -UI_SetTorsoAnim -=============== -*/ -static void UI_SetTorsoAnim( playerInfo_t *pi, int anim ) { -  if ( pi->pendingTorsoAnim ) { -    anim = pi->pendingTorsoAnim; -    pi->pendingTorsoAnim = 0; -  } - -  UI_ForceTorsoAnim( pi, anim ); -} - - -/* -=============== -UI_TorsoSequencing -=============== -*/ -static void UI_TorsoSequencing( playerInfo_t *pi ) { -  int    currentAnim; - -  currentAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT; - -  if ( pi->weapon != pi->currentWeapon ) { -    if ( currentAnim != TORSO_DROP ) { -      pi->torsoAnimationTimer = UI_TIMER_WEAPON_SWITCH; -      UI_ForceTorsoAnim( pi, TORSO_DROP ); -    } -  } - -  if ( pi->torsoAnimationTimer > 0 ) { -    return; -  } - -  if( currentAnim == TORSO_GESTURE ) { -    UI_SetTorsoAnim( pi, TORSO_STAND ); -    return; -  } - -  if( currentAnim == TORSO_ATTACK || currentAnim == TORSO_ATTACK2 ) { -    UI_SetTorsoAnim( pi, TORSO_STAND ); -    return; -  } - -  if ( currentAnim == TORSO_DROP ) { -    UI_PlayerInfo_SetWeapon( pi, pi->weapon ); -    pi->torsoAnimationTimer = UI_TIMER_WEAPON_SWITCH; -    UI_ForceTorsoAnim( pi, TORSO_RAISE ); -    return; -  } - -  if ( currentAnim == TORSO_RAISE ) { -    UI_SetTorsoAnim( pi, TORSO_STAND ); -    return; -  } -} - - -/* -=============== -UI_LegsSequencing -=============== -*/ -static void UI_LegsSequencing( playerInfo_t *pi ) { -  int    currentAnim; - -  currentAnim = pi->legsAnim & ~ANIM_TOGGLEBIT; - -  if ( pi->legsAnimationTimer > 0 ) { -    if ( currentAnim == LEGS_JUMP ) { -      jumpHeight = JUMP_HEIGHT * sin( M_PI * ( UI_TIMER_JUMP - pi->legsAnimationTimer ) / UI_TIMER_JUMP ); -    } -    return; -  } - -  if ( currentAnim == LEGS_JUMP ) { -    UI_ForceLegsAnim( pi, LEGS_LAND ); -    pi->legsAnimationTimer = UI_TIMER_LAND; -    jumpHeight = 0; -    return; -  } - -  if ( currentAnim == LEGS_LAND ) { -    UI_SetLegsAnim( pi, LEGS_IDLE ); -    return; -  } -} - - -/* -====================== -UI_PositionEntityOnTag -====================== -*/ -static void UI_PositionEntityOnTag( refEntity_t *entity, const refEntity_t *parent, -              clipHandle_t parentModel, char *tagName ) { -  int        i; -  orientation_t  lerped; - -  // lerp the tag -  trap_CM_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 ); -  } - -  // cast away const because of compiler problems -  MatrixMultiply( lerped.axis, ((refEntity_t*)parent)->axis, entity->axis ); -  entity->backlerp = parent->backlerp; -} - - -/* -====================== -UI_PositionRotatedEntityOnTag -====================== -*/ -static void UI_PositionRotatedEntityOnTag( refEntity_t *entity, const refEntity_t *parent, -              clipHandle_t parentModel, char *tagName ) { -  int        i; -  orientation_t  lerped; -  vec3_t      tempAxis[3]; - -  // lerp the tag -  trap_CM_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 ); -  } - -  // cast away const because of compiler problems -  MatrixMultiply( entity->axis, ((refEntity_t *)parent)->axis, tempAxis ); -  MatrixMultiply( lerped.axis, tempAxis, entity->axis ); -} - - -/* -=============== -UI_SetLerpFrameAnimation -=============== -*/ -static void UI_SetLerpFrameAnimation( playerInfo_t *ci, lerpFrame_t *lf, int newAnimation ) { -  animation_t  *anim; - -  lf->animationNumber = newAnimation; -  newAnimation &= ~ANIM_TOGGLEBIT; - -  if ( newAnimation < 0 || newAnimation >= MAX_PLAYER_ANIMATIONS ) { -    trap_Error( va("Bad animation number: %i", newAnimation) ); -  } - -  anim = &ci->animations[ newAnimation ]; - -  lf->animation = anim; -  lf->animationTime = lf->frameTime + anim->initialLerp; -} - - -/* -=============== -UI_RunLerpFrame -=============== -*/ -static void UI_RunLerpFrame( playerInfo_t *ci, lerpFrame_t *lf, int newAnimation ) { -  int      f; -  animation_t  *anim; - -  // see if the animation sequence is switching -  if ( newAnimation != lf->animationNumber || !lf->animation ) { -    UI_SetLerpFrameAnimation( ci, lf, newAnimation ); -  } - -  // if we have passed the current frame, move it to -  // oldFrame and calculate a new frame -  if ( dp_realtime >= lf->frameTime ) { -    lf->oldFrame = lf->frame; -    lf->oldFrameTime = lf->frameTime; - -    // get the next frame based on the animation -    anim = lf->animation; -    if ( dp_realtime < lf->animationTime ) { -      lf->frameTime = lf->animationTime;    // initial lerp -    } else { -      lf->frameTime = lf->oldFrameTime + anim->frameLerp; -    } -    f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp; -    if ( f >= anim->numFrames ) { -      f -= anim->numFrames; -      if ( anim->loopFrames ) { -        f %= anim->loopFrames; -        f += anim->numFrames - anim->loopFrames; -      } else { -        f = anim->numFrames - 1; -        // the animation is stuck at the end, so it -        // can immediately transition to another sequence -        lf->frameTime = dp_realtime; -      } -    } -    lf->frame = anim->firstFrame + f; -    if ( dp_realtime > lf->frameTime ) { -      lf->frameTime = dp_realtime; -    } -  } - -  if ( lf->frameTime > dp_realtime + 200 ) { -    lf->frameTime = dp_realtime; -  } - -  if ( lf->oldFrameTime > dp_realtime ) { -    lf->oldFrameTime = dp_realtime; -  } -  // calculate current lerp value -  if ( lf->frameTime == lf->oldFrameTime ) { -    lf->backlerp = 0; -  } else { -    lf->backlerp = 1.0 - (float)( dp_realtime - lf->oldFrameTime ) / ( lf->frameTime - lf->oldFrameTime ); -  } -} - - -/* -=============== -UI_PlayerAnimation -=============== -*/ -static void UI_PlayerAnimation( playerInfo_t *pi, int *legsOld, int *legs, float *legsBackLerp, -            int *torsoOld, int *torso, float *torsoBackLerp ) { - -  // legs animation -  pi->legsAnimationTimer -= uiInfo.uiDC.frameTime; -  if ( pi->legsAnimationTimer < 0 ) { -    pi->legsAnimationTimer = 0; -  } - -  UI_LegsSequencing( pi ); - -  if ( pi->legs.yawing && ( pi->legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_IDLE ) { -    UI_RunLerpFrame( pi, &pi->legs, LEGS_TURN ); -  } else { -    UI_RunLerpFrame( pi, &pi->legs, pi->legsAnim ); -  } -  *legsOld = pi->legs.oldFrame; -  *legs = pi->legs.frame; -  *legsBackLerp = pi->legs.backlerp; - -  // torso animation -  pi->torsoAnimationTimer -= uiInfo.uiDC.frameTime; -  if ( pi->torsoAnimationTimer < 0 ) { -    pi->torsoAnimationTimer = 0; -  } - -  UI_TorsoSequencing( pi ); - -  UI_RunLerpFrame( pi, &pi->torso, pi->torsoAnim ); -  *torsoOld = pi->torso.oldFrame; -  *torso = pi->torso.frame; -  *torsoBackLerp = pi->torso.backlerp; -} - - -/* -================== -UI_SwingAngles -================== -*/ -static void UI_SwingAngles( float destination, float swingTolerance, float clampTolerance, -          float speed, float *angle, qboolean *swinging ) { -  float  swing; -  float  move; -  float  scale; - -  if ( !*swinging ) { -    // see if a swing should be started -    swing = AngleSubtract( *angle, destination ); -    if ( swing > swingTolerance || swing < -swingTolerance ) { -      *swinging = qtrue; -    } -  } - -  if ( !*swinging ) { -    return; -  } - -  // modify the speed depending on the delta -  // so it doesn't seem so linear -  swing = AngleSubtract( destination, *angle ); -  scale = fabs( swing ); -  if ( scale < swingTolerance * 0.5 ) { -    scale = 0.5; -  } else if ( scale < swingTolerance ) { -    scale = 1.0; -  } else { -    scale = 2.0; -  } - -  // swing towards the destination angle -  if ( swing >= 0 ) { -    move = uiInfo.uiDC.frameTime * scale * speed; -    if ( move >= swing ) { -      move = swing; -      *swinging = qfalse; -    } -    *angle = AngleMod( *angle + move ); -  } else if ( swing < 0 ) { -    move = uiInfo.uiDC.frameTime * scale * -speed; -    if ( move <= swing ) { -      move = swing; -      *swinging = qfalse; -    } -    *angle = AngleMod( *angle + move ); -  } - -  // clamp to no more than tolerance -  swing = AngleSubtract( destination, *angle ); -  if ( swing > clampTolerance ) { -    *angle = AngleMod( destination - (clampTolerance - 1) ); -  } else if ( swing < -clampTolerance ) { -    *angle = AngleMod( destination + (clampTolerance - 1) ); -  } -} - - -/* -====================== -UI_MovedirAdjustment -====================== -*/ -static float UI_MovedirAdjustment( playerInfo_t *pi ) { -  vec3_t    relativeAngles; -  vec3_t    moveVector; - -  VectorSubtract( pi->viewAngles, pi->moveAngles, relativeAngles ); -  AngleVectors( relativeAngles, moveVector, NULL, NULL ); -  if ( Q_fabs( moveVector[0] ) < 0.01 ) { -    moveVector[0] = 0.0; -  } -  if ( Q_fabs( moveVector[1] ) < 0.01 ) { -    moveVector[1] = 0.0; -  } - -  if ( moveVector[1] == 0 && moveVector[0] > 0 ) { -    return 0; -  } -  if ( moveVector[1] < 0 && moveVector[0] > 0 ) { -    return 22; -  } -  if ( moveVector[1] < 0 && moveVector[0] == 0 ) { -    return 45; -  } -  if ( moveVector[1] < 0 && moveVector[0] < 0 ) { -    return -22; -  } -  if ( moveVector[1] == 0 && moveVector[0] < 0 ) { -    return 0; -  } -  if ( moveVector[1] > 0 && moveVector[0] < 0 ) { -    return 22; -  } -  if ( moveVector[1] > 0 && moveVector[0] == 0 ) { -    return  -45; -  } - -  return -22; -} - - -/* -=============== -UI_PlayerAngles -=============== -*/ -static void UI_PlayerAngles( playerInfo_t *pi, vec3_t legs[3], vec3_t torso[3], vec3_t head[3] ) { -  vec3_t    legsAngles, torsoAngles, headAngles; -  float    dest; -  float    adjust; - -  VectorCopy( pi->viewAngles, headAngles ); -  headAngles[YAW] = AngleMod( headAngles[YAW] ); -  VectorClear( legsAngles ); -  VectorClear( torsoAngles ); - -  // --------- yaw ------------- - -  // allow yaw to drift a bit -  if ( ( pi->legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_IDLE -    || ( pi->torsoAnim & ~ANIM_TOGGLEBIT ) != TORSO_STAND  ) { -    // if not standing still, always point all in the same direction -    pi->torso.yawing = qtrue;  // always center -    pi->torso.pitching = qtrue;  // always center -    pi->legs.yawing = qtrue;  // always center -  } - -  // adjust legs for movement dir -  adjust = UI_MovedirAdjustment( pi ); -  legsAngles[YAW] = headAngles[YAW] + adjust; -  torsoAngles[YAW] = headAngles[YAW] + 0.25 * adjust; - - -  // torso -  UI_SwingAngles( torsoAngles[YAW], 25, 90, SWINGSPEED, &pi->torso.yawAngle, &pi->torso.yawing ); -  UI_SwingAngles( legsAngles[YAW], 40, 90, SWINGSPEED, &pi->legs.yawAngle, &pi->legs.yawing ); - -  torsoAngles[YAW] = pi->torso.yawAngle; -  legsAngles[YAW] = pi->legs.yawAngle; - -  // --------- pitch ------------- - -  // only show a fraction of the pitch angle in the torso -  if ( headAngles[PITCH] > 180 ) { -    dest = (-360 + headAngles[PITCH]) * 0.75; -  } else { -    dest = headAngles[PITCH] * 0.75; -  } -  UI_SwingAngles( dest, 15, 30, 0.1f, &pi->torso.pitchAngle, &pi->torso.pitching ); -  torsoAngles[PITCH] = pi->torso.pitchAngle; - -  // pull the angles back out of the hierarchial chain -  AnglesSubtract( headAngles, torsoAngles, headAngles ); -  AnglesSubtract( torsoAngles, legsAngles, torsoAngles ); -  AnglesToAxis( legsAngles, legs ); -  AnglesToAxis( torsoAngles, torso ); -  AnglesToAxis( headAngles, head ); -} - - -/* -=============== -UI_PlayerFloatSprite -=============== -*/ -static void UI_PlayerFloatSprite( playerInfo_t *pi, vec3_t origin, qhandle_t shader ) { -  refEntity_t    ent; - -  memset( &ent, 0, sizeof( ent ) ); -  VectorCopy( origin, ent.origin ); -  ent.origin[2] += 48; -  ent.reType = RT_SPRITE; -  ent.customShader = shader; -  ent.radius = 10; -  ent.renderfx = 0; -  trap_R_AddRefEntityToScene( &ent ); -} - - -/* -====================== -UI_MachinegunSpinAngle -====================== -*/ -float  UI_MachinegunSpinAngle( playerInfo_t *pi ) { -  int    delta; -  float  angle; -  float  speed; -  int    torsoAnim; - -  delta = dp_realtime - pi->barrelTime; -  if ( pi->barrelSpinning ) { -    angle = pi->barrelAngle + delta * SPIN_SPEED; -  } else { -    if ( delta > COAST_TIME ) { -      delta = COAST_TIME; -    } - -    speed = 0.5 * ( SPIN_SPEED + (float)( COAST_TIME - delta ) / COAST_TIME ); -    angle = pi->barrelAngle + delta * speed; -  } - -  torsoAnim = pi->torsoAnim  & ~ANIM_TOGGLEBIT; -  if( torsoAnim == TORSO_ATTACK2 ) { -    torsoAnim = TORSO_ATTACK; -  } -  if ( pi->barrelSpinning == !(torsoAnim == TORSO_ATTACK) ) { -    pi->barrelTime = dp_realtime; -    pi->barrelAngle = AngleMod( angle ); -    pi->barrelSpinning = !!(torsoAnim == TORSO_ATTACK); -  } - -  return angle; -} - - -/* -=============== -UI_DrawPlayer -=============== -*/ -void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time ) { -  refdef_t    refdef; -  refEntity_t    legs; -  refEntity_t    torso; -  refEntity_t    head; -  refEntity_t    gun; -  refEntity_t    barrel; -  refEntity_t    flash; -  vec3_t      origin; -  int        renderfx; -  vec3_t      mins = {-16, -16, -24}; -  vec3_t      maxs = {16, 16, 32}; -  float      len; -  float      xx; - -  if ( !pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames ) { -    return; -  } - -  // this allows the ui to cache the player model on the main menu -  if (w == 0 || h == 0) { -    return; -  } - -  dp_realtime = time; - -  if ( pi->pendingWeapon != -1 && dp_realtime > pi->weaponTimer ) { -    pi->weapon = pi->pendingWeapon; -    pi->lastWeapon = pi->pendingWeapon; -    pi->pendingWeapon = -1; -    pi->weaponTimer = 0; -    if( pi->currentWeapon != pi->weapon ) { -      trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL ); -    } -  } - -  UI_AdjustFrom640( &x, &y, &w, &h ); - -  y -= jumpHeight; - -  memset( &refdef, 0, sizeof( refdef ) ); -  memset( &legs, 0, sizeof(legs) ); -  memset( &torso, 0, sizeof(torso) ); -  memset( &head, 0, sizeof(head) ); - -  refdef.rdflags = RDF_NOWORLDMODEL; - -  AxisClear( refdef.viewaxis ); - -  refdef.x = x; -  refdef.y = y; -  refdef.width = w; -  refdef.height = h; - -  refdef.fov_x = (int)((float)refdef.width / 640.0f * 90.0f); -  xx = refdef.width / tan( refdef.fov_x / 360 * M_PI ); -  refdef.fov_y = atan2( refdef.height, xx ); -  refdef.fov_y *= ( 360 / (float)M_PI ); - -  // calculate distance so the player nearly fills the box -  len = 0.7 * ( maxs[2] - mins[2] ); -  origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 ); -  origin[1] = 0.5 * ( mins[1] + maxs[1] ); -  origin[2] = -0.5 * ( mins[2] + maxs[2] ); - -  refdef.time = dp_realtime; - -  trap_R_ClearScene(); - -  // get the rotation information -  UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis ); - -  // get the animation state (after rotation, to allow feet shuffle) -  UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp, -     &torso.oldframe, &torso.frame, &torso.backlerp ); - -  renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; - -  // -  // add the legs -  // -  legs.hModel = pi->legsModel; -  legs.customSkin = pi->legsSkin; - -  VectorCopy( origin, legs.origin ); - -  VectorCopy( origin, legs.lightingOrigin ); -  legs.renderfx = renderfx; -  VectorCopy (legs.origin, legs.oldorigin); - -  trap_R_AddRefEntityToScene( &legs ); - -  if (!legs.hModel) { -    return; -  } - -  // -  // add the torso -  // -  torso.hModel = pi->torsoModel; -  if (!torso.hModel) { -    return; -  } - -  torso.customSkin = pi->torsoSkin; - -  VectorCopy( origin, torso.lightingOrigin ); - -  UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, "tag_torso"); - -  torso.renderfx = renderfx; - -  trap_R_AddRefEntityToScene( &torso ); - -  // -  // add the head -  // -  head.hModel = pi->headModel; -  if (!head.hModel) { -    return; -  } -  head.customSkin = pi->headSkin; - -  VectorCopy( origin, head.lightingOrigin ); - -  UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head"); - -  head.renderfx = renderfx; - -  trap_R_AddRefEntityToScene( &head ); - -  // -  // add the gun -  // -  if ( pi->currentWeapon != WP_NONE ) { -    memset( &gun, 0, sizeof(gun) ); -    gun.hModel = pi->weaponModel; -    VectorCopy( origin, gun.lightingOrigin ); -    UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon"); -    gun.renderfx = renderfx; -    trap_R_AddRefEntityToScene( &gun ); -  } - -  // -  // add the spinning barrel -  // -  if ( pi->realWeapon == WP_MACHINEGUN ) { -    vec3_t  angles; - -    memset( &barrel, 0, sizeof(barrel) ); -    VectorCopy( origin, barrel.lightingOrigin ); -    barrel.renderfx = renderfx; - -    barrel.hModel = pi->barrelModel; -    angles[YAW] = 0; -    angles[PITCH] = 0; -    angles[ROLL] = UI_MachinegunSpinAngle( pi ); -/*    if( pi->realWeapon == WP_GAUNTLET || pi->realWeapon == WP_BFG ) { -      angles[PITCH] = angles[ROLL]; -      angles[ROLL] = 0; -    }*/ -    AnglesToAxis( angles, barrel.axis ); - -    UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, "tag_barrel"); - -    trap_R_AddRefEntityToScene( &barrel ); -  } - -  // -  // add muzzle flash -  // -  if ( dp_realtime <= pi->muzzleFlashTime ) { -    if ( pi->flashModel ) { -      memset( &flash, 0, sizeof(flash) ); -      flash.hModel = pi->flashModel; -      VectorCopy( origin, flash.lightingOrigin ); -      UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash"); -      flash.renderfx = renderfx; -      trap_R_AddRefEntityToScene( &flash ); -    } - -    // make a dlight for the flash -    if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) { -      trap_R_AddLightToScene( flash.origin, 200 + (rand()&31), pi->flashDlightColor[0], -        pi->flashDlightColor[1], pi->flashDlightColor[2] ); -    } -  } - -  // -  // add the chat icon -  // -  if ( pi->chat ) { -    UI_PlayerFloatSprite( pi, origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) ); -  } - -  // -  // add an accent light -  // -  origin[0] -= 100;  // + = behind, - = in front -  origin[1] += 100;  // + = left, - = right -  origin[2] += 100;  // + = above, - = below -  trap_R_AddLightToScene( origin, 500, 1.0, 1.0, 1.0 ); - -  origin[0] -= 100; -  origin[1] -= 100; -  origin[2] -= 100; -  trap_R_AddLightToScene( origin, 500, 1.0, 0.0, 0.0 ); - -  trap_R_RenderScene( &refdef ); -} - -/* -========================== -UI_FileExists -========================== -*/ -static qboolean  UI_FileExists(const char *filename) { -  int len; - -  len = trap_FS_FOpenFile( filename, NULL, FS_READ ); -  if (len>0) { -    return qtrue; -  } -  return qfalse; -} - -/* -========================== -UI_FindClientHeadFile -========================== -*/ -static qboolean  UI_FindClientHeadFile( char *filename, int length, const char *teamName, const char *headModelName, const char *headSkinName, const char *base, const char *ext ) { -  char *team, *headsFolder; -  int i; - -  team = "default"; - -  if ( headModelName[0] == '*' ) { -    headsFolder = "heads/"; -    headModelName++; -  } -  else { -    headsFolder = ""; -  } -  while(1) { -    for ( i = 0; i < 2; i++ ) { -      if ( i == 0 && teamName && *teamName ) { -        Com_sprintf( filename, length, "models/players/%s%s/%s/%s%s_%s.%s", headsFolder, headModelName, headSkinName, teamName, base, team, ext ); -      } -      else { -        Com_sprintf( filename, length, "models/players/%s%s/%s/%s_%s.%s", headsFolder, headModelName, headSkinName, base, team, ext ); -      } -      if ( UI_FileExists( filename ) ) { -        return qtrue; -      } -      if ( i == 0 && teamName && *teamName ) { -        Com_sprintf( filename, length, "models/players/%s%s/%s%s_%s.%s", headsFolder, headModelName, teamName, base, headSkinName, ext ); -      } -      else { -        Com_sprintf( filename, length, "models/players/%s%s/%s_%s.%s", headsFolder, headModelName, base, headSkinName, ext ); -      } -      if ( UI_FileExists( filename ) ) { -        return qtrue; -      } -      if ( !teamName || !*teamName ) { -        break; -      } -    } -    // if tried the heads folder first -    if ( headsFolder[0] ) { -      break; -    } -    headsFolder = "heads/"; -  } - -  return qfalse; -} - -/* -========================== -UI_RegisterClientSkin -========================== -*/ -static qboolean  UI_RegisterClientSkin( playerInfo_t *pi, const char *modelName, const char *skinName, const char *headModelName, const char *headSkinName , const char *teamName) { -  char    filename[MAX_QPATH*2]; - -  if (teamName && *teamName) { -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/%s/lower_%s.skin", modelName, teamName, skinName ); -  } else { -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower_%s.skin", modelName, skinName ); -  } -  pi->legsSkin = trap_R_RegisterSkin( filename ); -  if (!pi->legsSkin) { -    if (teamName && *teamName) { -      Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/%s/lower_%s.skin", modelName, teamName, skinName ); -    } else { -      Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/lower_%s.skin", modelName, skinName ); -    } -    pi->legsSkin = trap_R_RegisterSkin( filename ); -  } - -  if (teamName && *teamName) { -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/%s/upper_%s.skin", modelName, teamName, skinName ); -  } else { -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper_%s.skin", modelName, skinName ); -  } -  pi->torsoSkin = trap_R_RegisterSkin( filename ); -  if (!pi->torsoSkin) { -    if (teamName && *teamName) { -      Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/%s/upper_%s.skin", modelName, teamName, skinName ); -    } else { -      Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/upper_%s.skin", modelName, skinName ); -    } -    pi->torsoSkin = trap_R_RegisterSkin( filename ); -  } - -  if ( UI_FindClientHeadFile( filename, sizeof(filename), teamName, headModelName, headSkinName, "head", "skin" ) ) { -    pi->headSkin = trap_R_RegisterSkin( filename ); -  } - -  if ( !pi->legsSkin || !pi->torsoSkin || !pi->headSkin ) { -    return qfalse; -  } - -  return qtrue; -} - - -/* -====================== -UI_ParseAnimationFile -====================== -*/ -static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animations ) { -  char    *text_p, *prev; -  int      len; -  int      i; -  char    *token; -  float    fps; -  int      skip; -  char    text[20000]; -  fileHandle_t  f; - -  memset( animations, 0, sizeof( animation_t ) * MAX_PLAYER_ANIMATIONS ); - -  // load the file -  len = trap_FS_FOpenFile( filename, &f, FS_READ ); -  if ( len <= 0 ) { -    return qfalse; -  } -  if ( len >= ( sizeof( text ) - 1 ) ) { -    Com_Printf( "File %s too long\n", filename ); -    trap_FS_FCloseFile( f ); -    return qfalse; -  } -  trap_FS_Read( text, len, f ); -  text[len] = 0; -  trap_FS_FCloseFile( f ); - -  COM_Compress(text); - -  // parse the text -  text_p = text; -  skip = 0;  // quite the compiler warning - -  // read optional parameters -  while ( 1 ) { -    prev = text_p;  // so we can unget -    token = COM_Parse( &text_p ); -    if ( !token ) { -      break; -    } -    if ( !Q_stricmp( token, "footsteps" ) ) { -      token = COM_Parse( &text_p ); -      if ( !token ) { -        break; -      } -      continue; -    } else if ( !Q_stricmp( token, "headoffset" ) ) { -      for ( i = 0 ; i < 3 ; i++ ) { -        token = COM_Parse( &text_p ); -        if ( !token ) { -          break; -        } -      } -      continue; -    } else if ( !Q_stricmp( token, "sex" ) ) { -      token = COM_Parse( &text_p ); -      if ( !token ) { -        break; -      } -      continue; -    } - -    // if it is a number, start parsing animations -    if ( token[0] >= '0' && token[0] <= '9' ) { -      text_p = prev;  // unget the token -      break; -    } - -    Com_Printf( "unknown token '%s' is %s\n", token, filename ); -  } - -  // read information for each frame -  for ( i = 0 ; i < MAX_PLAYER_ANIMATIONS ; i++ ) { - -    token = COM_Parse( &text_p ); -    if ( !token ) { -      break; -    } -    animations[i].firstFrame = atoi( token ); -    // leg only frames are adjusted to not count the upper body only frames -    if ( i == LEGS_WALKCR ) { -      skip = animations[LEGS_WALKCR].firstFrame - animations[TORSO_GESTURE].firstFrame; -    } -    if ( i >= LEGS_WALKCR ) { -      animations[i].firstFrame -= skip; -    } - -    token = COM_Parse( &text_p ); -    if ( !token ) { -      break; -    } -    animations[i].numFrames = atoi( token ); - -    token = COM_Parse( &text_p ); -    if ( !token ) { -      break; -    } -    animations[i].loopFrames = atoi( token ); - -    token = COM_Parse( &text_p ); -    if ( !token ) { -      break; -    } -    fps = atof( token ); -    if ( fps == 0 ) { -      fps = 1; -    } -    animations[i].frameLerp = 1000 / fps; -    animations[i].initialLerp = 1000 / fps; -  } - -  if ( i != MAX_PLAYER_ANIMATIONS ) { -    Com_Printf( "Error parsing animation file: %s", filename ); -    return qfalse; -  } - -  return qtrue; -} - -/* -========================== -UI_RegisterClientModelname -========================== -*/ -qboolean UI_RegisterClientModelname( playerInfo_t *pi, const char *modelSkinName, const char *headModelSkinName, const char *teamName ) { -  char    modelName[MAX_QPATH]; -  char    skinName[MAX_QPATH]; -  char    headModelName[MAX_QPATH]; -  char    headSkinName[MAX_QPATH]; -  char    filename[MAX_QPATH]; -  char    *slash; - -  pi->torsoModel = 0; -  pi->headModel = 0; - -  if ( !modelSkinName[0] ) { -    return qfalse; -  } - -  Q_strncpyz( modelName, modelSkinName, sizeof( modelName ) ); - -  slash = strchr( modelName, '/' ); -  if ( !slash ) { -    // modelName did not include a skin name -    Q_strncpyz( skinName, "default", sizeof( skinName ) ); -  } else { -    Q_strncpyz( skinName, slash + 1, sizeof( skinName ) ); -    *slash = '\0'; -  } - -  Q_strncpyz( headModelName, headModelSkinName, sizeof( headModelName ) ); -  slash = strchr( headModelName, '/' ); -  if ( !slash ) { -    // modelName did not include a skin name -    Q_strncpyz( headSkinName, "default", sizeof( skinName ) ); -  } else { -    Q_strncpyz( headSkinName, slash + 1, sizeof( skinName ) ); -    *slash = '\0'; -  } - -  // load cmodels before models so filecache works - -  Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower.md3", modelName ); -  pi->legsModel = trap_R_RegisterModel( filename ); -  if ( !pi->legsModel ) { -    Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/lower.md3", modelName ); -    pi->legsModel = trap_R_RegisterModel( filename ); -    if ( !pi->legsModel ) { -      Com_Printf( "Failed to load model file %s\n", filename ); -      return qfalse; -    } -  } - -  Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper.md3", modelName ); -  pi->torsoModel = trap_R_RegisterModel( filename ); -  if ( !pi->torsoModel ) { -    Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/upper.md3", modelName ); -    pi->torsoModel = trap_R_RegisterModel( filename ); -    if ( !pi->torsoModel ) { -      Com_Printf( "Failed to load model file %s\n", filename ); -      return qfalse; -    } -  } - -  if (headModelName && headModelName[0] == '*' ) { -    Com_sprintf( filename, sizeof( filename ), "models/players/heads/%s/%s.md3", &headModelName[1], &headModelName[1] ); -  } -  else { -    Com_sprintf( filename, sizeof( filename ), "models/players/%s/head.md3", headModelName ); -  } -  pi->headModel = trap_R_RegisterModel( filename ); -  if ( !pi->headModel && headModelName[0] != '*') { -    Com_sprintf( filename, sizeof( filename ), "models/players/heads/%s/%s.md3", headModelName, headModelName ); -    pi->headModel = trap_R_RegisterModel( filename ); -  } - -  if (!pi->headModel) { -    Com_Printf( "Failed to load model file %s\n", filename ); -    return qfalse; -  } - -  // if any skins failed to load, fall back to default -  if ( !UI_RegisterClientSkin( pi, modelName, skinName, headModelName, headSkinName, teamName) ) { -    if ( !UI_RegisterClientSkin( pi, modelName, "default", headModelName, "default", teamName ) ) { -      Com_Printf( "Failed to load skin file: %s : %s\n", modelName, skinName ); -      return qfalse; -    } -  } - -  // load the animations -  Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg", modelName ); -  if ( !UI_ParseAnimationFile( filename, pi->animations ) ) { -    Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/animation.cfg", modelName ); -    if ( !UI_ParseAnimationFile( filename, pi->animations ) ) { -      Com_Printf( "Failed to load animation file %s\n", filename ); -      return qfalse; -    } -  } - -  return qtrue; -} - - -/* -=============== -UI_PlayerInfo_SetModel -=============== -*/ -void UI_PlayerInfo_SetModel( playerInfo_t *pi, const char *model, const char *headmodel, char *teamName ) { -  memset( pi, 0, sizeof(*pi) ); -  UI_RegisterClientModelname( pi, model, headmodel, teamName ); -  pi->weapon = WP_MACHINEGUN; -  pi->currentWeapon = pi->weapon; -  pi->lastWeapon = pi->weapon; -  pi->pendingWeapon = -1; -  pi->weaponTimer = 0; -  pi->chat = qfalse; -  pi->newModel = qtrue; -  UI_PlayerInfo_SetWeapon( pi, pi->weapon ); -} - - -/* -=============== -UI_PlayerInfo_SetInfo -=============== -*/ -void UI_PlayerInfo_SetInfo( playerInfo_t *pi, int legsAnim, int torsoAnim, vec3_t viewAngles, vec3_t moveAngles, weapon_t weaponNumber, qboolean chat ) { -  int      currentAnim; -  weapon_t  weaponNum; - -  pi->chat = chat; - -  // view angles -  VectorCopy( viewAngles, pi->viewAngles ); - -  // move angles -  VectorCopy( moveAngles, pi->moveAngles ); - -  if ( pi->newModel ) { -    pi->newModel = qfalse; - -    jumpHeight = 0; -    pi->pendingLegsAnim = 0; -    UI_ForceLegsAnim( pi, legsAnim ); -    pi->legs.yawAngle = viewAngles[YAW]; -    pi->legs.yawing = qfalse; - -    pi->pendingTorsoAnim = 0; -    UI_ForceTorsoAnim( pi, torsoAnim ); -    pi->torso.yawAngle = viewAngles[YAW]; -    pi->torso.yawing = qfalse; - -    if ( weaponNumber != -1 ) { -      pi->weapon = weaponNumber; -      pi->currentWeapon = weaponNumber; -      pi->lastWeapon = weaponNumber; -      pi->pendingWeapon = -1; -      pi->weaponTimer = 0; -      UI_PlayerInfo_SetWeapon( pi, pi->weapon ); -    } - -    return; -  } - -  // weapon -  if ( weaponNumber == -1 ) { -    pi->pendingWeapon = -1; -    pi->weaponTimer = 0; -  } -  else if ( weaponNumber != WP_NONE ) { -    pi->pendingWeapon = weaponNumber; -    pi->weaponTimer = dp_realtime + UI_TIMER_WEAPON_DELAY; -  } -  weaponNum = pi->lastWeapon; -  pi->weapon = weaponNum; - -  if ( torsoAnim == BOTH_DEATH1 || legsAnim == BOTH_DEATH1 ) { -    torsoAnim = legsAnim = BOTH_DEATH1; -    pi->weapon = pi->currentWeapon = WP_NONE; -    UI_PlayerInfo_SetWeapon( pi, pi->weapon ); - -    jumpHeight = 0; -    pi->pendingLegsAnim = 0; -    UI_ForceLegsAnim( pi, legsAnim ); - -    pi->pendingTorsoAnim = 0; -    UI_ForceTorsoAnim( pi, torsoAnim ); - -    return; -  } - -  // leg animation -  currentAnim = pi->legsAnim & ~ANIM_TOGGLEBIT; -  if ( legsAnim != LEGS_JUMP && ( currentAnim == LEGS_JUMP || currentAnim == LEGS_LAND ) ) { -    pi->pendingLegsAnim = legsAnim; -  } -  else if ( legsAnim != currentAnim ) { -    jumpHeight = 0; -    pi->pendingLegsAnim = 0; -    UI_ForceLegsAnim( pi, legsAnim ); -  } - -  // torso animation -  if ( torsoAnim == TORSO_STAND || torsoAnim == TORSO_STAND2 ) { -    if ( weaponNum == WP_NONE ) { -      torsoAnim = TORSO_STAND2; -    } -    else { -      torsoAnim = TORSO_STAND; -    } -  } - -  if ( torsoAnim == TORSO_ATTACK || torsoAnim == TORSO_ATTACK2 ) { -    if ( weaponNum == WP_NONE ) { -      torsoAnim = TORSO_ATTACK2; -    } -    else { -      torsoAnim = TORSO_ATTACK; -    } -    pi->muzzleFlashTime = dp_realtime + UI_TIMER_MUZZLE_FLASH; -    //FIXME play firing sound here -  } - -  currentAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT; - -  if ( weaponNum != pi->currentWeapon || currentAnim == TORSO_RAISE || currentAnim == TORSO_DROP ) { -    pi->pendingTorsoAnim = torsoAnim; -  } -  else if ( ( currentAnim == TORSO_GESTURE || currentAnim == TORSO_ATTACK ) && ( torsoAnim != currentAnim ) ) { -    pi->pendingTorsoAnim = torsoAnim; -  } -  else if ( torsoAnim != currentAnim ) { -    pi->pendingTorsoAnim = 0; -    UI_ForceTorsoAnim( pi, torsoAnim ); -  } -} diff --git a/mod/src/ui/ui_public.h b/mod/src/ui/ui_public.h deleted file mode 100644 index 9cf36d66..00000000 --- a/mod/src/ui/ui_public.h +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#ifndef __UI_PUBLIC_H__ -#define __UI_PUBLIC_H__ - -#define UI_API_VERSION  6 - -typedef struct { -  connstate_t   connState; -  int       connectPacketCount; -  int       clientNum; -  char      servername[MAX_STRING_CHARS]; -  char      updateInfoString[MAX_STRING_CHARS]; -  char      messageString[MAX_STRING_CHARS]; -} uiClientState_t; - -typedef enum { -  UI_ERROR, -  UI_PRINT, -  UI_MILLISECONDS, -  UI_CVAR_SET, -  UI_CVAR_VARIABLEVALUE, -  UI_CVAR_VARIABLESTRINGBUFFER, -  UI_CVAR_SETVALUE, -  UI_CVAR_RESET, -  UI_CVAR_CREATE, -  UI_CVAR_INFOSTRINGBUFFER, -  UI_ARGC, -  UI_ARGV, -  UI_CMD_EXECUTETEXT, -  UI_FS_FOPENFILE, -  UI_FS_READ, -  UI_FS_WRITE, -  UI_FS_FCLOSEFILE, -  UI_FS_GETFILELIST, -  UI_R_REGISTERMODEL, -  UI_R_REGISTERSKIN, -  UI_R_REGISTERSHADERNOMIP, -  UI_R_CLEARSCENE, -  UI_R_ADDREFENTITYTOSCENE, -  UI_R_ADDPOLYTOSCENE, -  UI_R_ADDLIGHTTOSCENE, -  UI_R_RENDERSCENE, -  UI_R_SETCOLOR, -  UI_R_DRAWSTRETCHPIC, -  UI_UPDATESCREEN, -  UI_CM_LERPTAG, -  UI_CM_LOADMODEL, -  UI_S_REGISTERSOUND, -  UI_S_STARTLOCALSOUND, -  UI_KEY_KEYNUMTOSTRINGBUF, -  UI_KEY_GETBINDINGBUF, -  UI_KEY_SETBINDING, -  UI_KEY_ISDOWN, -  UI_KEY_GETOVERSTRIKEMODE, -  UI_KEY_SETOVERSTRIKEMODE, -  UI_KEY_CLEARSTATES, -  UI_KEY_GETCATCHER, -  UI_KEY_SETCATCHER, -  UI_GETCLIPBOARDDATA, -  UI_GETGLCONFIG, -  UI_GETCLIENTSTATE, -  UI_GETCONFIGSTRING, -  UI_LAN_GETPINGQUEUECOUNT, -  UI_LAN_CLEARPING, -  UI_LAN_GETPING, -  UI_LAN_GETPINGINFO, -  UI_CVAR_REGISTER, -  UI_CVAR_UPDATE, -  UI_MEMORY_REMAINING, -  UI_GET_CDKEY, -  UI_SET_CDKEY, -  UI_R_REGISTERFONT, -  UI_R_MODELBOUNDS, -  UI_PC_ADD_GLOBAL_DEFINE, -  UI_PC_LOAD_SOURCE, -  UI_PC_FREE_SOURCE, -  UI_PC_READ_TOKEN, -  UI_PC_SOURCE_FILE_AND_LINE, -  UI_S_STOPBACKGROUNDTRACK, -  UI_S_STARTBACKGROUNDTRACK, -  UI_REAL_TIME, -  UI_LAN_GETSERVERCOUNT, -  UI_LAN_GETSERVERADDRESSSTRING, -  UI_LAN_GETSERVERINFO, -  UI_LAN_MARKSERVERVISIBLE, -  UI_LAN_UPDATEVISIBLEPINGS, -  UI_LAN_RESETPINGS, -  UI_LAN_LOADCACHEDSERVERS, -  UI_LAN_SAVECACHEDSERVERS, -  UI_LAN_ADDSERVER, -  UI_LAN_REMOVESERVER, -  UI_CIN_PLAYCINEMATIC, -  UI_CIN_STOPCINEMATIC, -  UI_CIN_RUNCINEMATIC, -  UI_CIN_DRAWCINEMATIC, -  UI_CIN_SETEXTENTS, -  UI_R_REMAP_SHADER, -  UI_VERIFY_CDKEY, -  UI_LAN_SERVERSTATUS, -  UI_LAN_GETSERVERPING, -  UI_LAN_SERVERISVISIBLE, -  UI_LAN_COMPARESERVERS, -  // 1.32 -  UI_FS_SEEK, -  UI_SET_PBCLSTATUS, - -  UI_MEMSET = 100, -  UI_MEMCPY, -  UI_STRNCPY, -  UI_SIN, -  UI_COS, -  UI_ATAN2, -  UI_SQRT, -  UI_FLOOR, -  UI_CEIL -} uiImport_t; - -typedef enum { -  UIMENU_NONE, -  UIMENU_MAIN, -  UIMENU_INGAME, -  UIMENU_NEED_CD, -  UIMENU_BAD_CD_KEY, -  UIMENU_TEAM, -  UIMENU_POSTGAME -} uiMenuCommand_t; - -typedef enum -{ -  SORT_HOST, -  SORT_MAP, -  SORT_CLIENTS, -  SORT_PUNKBUSTER, -  SORT_PING -} serverSortField_t; - -typedef enum { -  UI_GETAPIVERSION = 0, // system reserved - -  UI_INIT, -//  void  UI_Init( void ); - -  UI_SHUTDOWN, -//  void  UI_Shutdown( void ); - -  UI_KEY_EVENT, -//  void  UI_KeyEvent( int key ); - -  UI_MOUSE_EVENT, -//  void  UI_MouseEvent( int dx, int dy ); - -  UI_REFRESH, -//  void  UI_Refresh( int time ); - -  UI_IS_FULLSCREEN, -//  qboolean UI_IsFullscreen( void ); - -  UI_SET_ACTIVE_MENU, -//  void  UI_SetActiveMenu( uiMenuCommand_t menu ); - -  UI_CONSOLE_COMMAND, -//  qboolean UI_ConsoleCommand( int realTime ); - -  UI_DRAW_CONNECT_SCREEN, -//  void  UI_DrawConnectScreen( qboolean overlay ); -  UI_HASUNIQUECDKEY -// if !overlay, the background will be drawn, otherwise it will be -// overlayed over whatever the cgame has drawn. -// a GetClientState syscall will be made to get the current strings -} uiExport_t; - -#endif diff --git a/mod/src/ui/ui_shared.c b/mod/src/ui/ui_shared.c deleted file mode 100644 index 43c25ff8..00000000 --- a/mod/src/ui/ui_shared.c +++ /dev/null @@ -1,6071 +0,0 @@ -// -// string allocation/managment - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "ui_shared.h" - -#define SCROLL_TIME_START         500 -#define SCROLL_TIME_ADJUST        150 -#define SCROLL_TIME_ADJUSTOFFSET  40 -#define SCROLL_TIME_FLOOR         20 - -typedef struct scrollInfo_s { -  int nextScrollTime; -  int nextAdjustTime; -  int adjustValue; -  int scrollKey; -  float xStart; -  float yStart; -  itemDef_t *item; -  qboolean scrollDir; -} scrollInfo_t; - -static scrollInfo_t scrollInfo; - -//TA: hack to prevent compiler warnings -void voidFunction( void *var ) { return; } -qboolean voidFunction2( itemDef_t *var1, int var2 ) { return qfalse; } - -static void (*captureFunc) (void *p) = voidFunction; -static void *captureData = NULL; -static itemDef_t *itemCapture = NULL;   // item that has the mouse captured ( if any ) - -displayContextDef_t *DC = NULL; - -static qboolean g_waitingForKey = qfalse; -static qboolean g_editingField = qfalse; - -static itemDef_t *g_bindItem = NULL; -static itemDef_t *g_editItem = NULL; - -menuDef_t Menus[MAX_MENUS];      // defined menus -int menuCount = 0;               // how many - -menuDef_t *menuStack[MAX_OPEN_MENUS]; -int openMenuCount = 0; - -static qboolean debugMode = qfalse; - -#define DOUBLE_CLICK_DELAY 300 -static int lastListBoxClickTime = 0; - -void Item_RunScript(itemDef_t *item, const char *s); -void Item_SetupKeywordHash(void); -void Menu_SetupKeywordHash(void); -int BindingIDFromName(const char *name); -qboolean Item_Bind_HandleKey(itemDef_t *item, int key, qboolean down); -itemDef_t *Menu_SetPrevCursorItem(menuDef_t *menu); -itemDef_t *Menu_SetNextCursorItem(menuDef_t *menu); -static qboolean Menu_OverActiveItem(menuDef_t *menu, float x, float y); - -#ifdef CGAME -#define MEM_POOL_SIZE  128 * 1024 -#else -#define MEM_POOL_SIZE  1024 * 1024 -#endif - -//TA: hacked variable name to avoid conflict with new cgame Alloc -static char   UI_memoryPool[MEM_POOL_SIZE]; -static int    allocPoint, outOfMemory; - -/* -=============== -UI_Alloc -=============== -*/ -void *UI_Alloc( int size ) -{ -  char  *p; - -  if( allocPoint + size > MEM_POOL_SIZE ) -  { -    outOfMemory = qtrue; - -    if( DC->Print ) -      DC->Print( "UI_Alloc: Failure. Out of memory!\n" ); -    //DC->trap_Print(S_COLOR_YELLOW"WARNING: UI Out of Memory!\n"); -    return NULL; -  } - -  p = &UI_memoryPool[ allocPoint ]; - -  allocPoint += ( size + 15 ) & ~15; - -  return p; -} - -/* -=============== -UI_InitMemory -=============== -*/ -void UI_InitMemory( void ) -{ -  allocPoint = 0; -  outOfMemory = qfalse; -} - -qboolean UI_OutOfMemory( ) -{ -  return outOfMemory; -} - - - - - -#define HASH_TABLE_SIZE 2048 -/* -================ -return a hash value for the string -================ -*/ -static long hashForString(const char *str) { -  int   i; -  long  hash; -  char  letter; - -  hash = 0; -  i = 0; -  while (str[i] != '\0') { -    letter = tolower(str[i]); -    hash+=(long)(letter)*(i+119); -    i++; -  } -  hash &= (HASH_TABLE_SIZE-1); -  return hash; -} - -typedef struct stringDef_s { -  struct stringDef_s *next; -  const char *str; -} stringDef_t; - -static int strPoolIndex = 0; -static char strPool[STRING_POOL_SIZE]; - -static int strHandleCount = 0; -static stringDef_t *strHandle[HASH_TABLE_SIZE]; - - -const char *String_Alloc(const char *p) { -  int len; -  long hash; -  stringDef_t *str, *last; -  static const char *staticNULL = ""; - -  if (p == NULL) { -    return NULL; -  } - -  if (*p == 0) { -    return staticNULL; -  } - -  hash = hashForString(p); - -  str = strHandle[hash]; -  while (str) { -    if (strcmp(p, str->str) == 0) { -      return str->str; -    } -    str = str->next; -  } - -  len = strlen(p); -  if (len + strPoolIndex + 1 < STRING_POOL_SIZE) { -    int ph = strPoolIndex; -    strcpy(&strPool[strPoolIndex], p); -    strPoolIndex += len + 1; - -    str = strHandle[hash]; -    last = str; -    while (str && str->next) { -      last = str; -      str = str->next; -    } - -    str  = UI_Alloc(sizeof(stringDef_t)); -    str->next = NULL; -    str->str = &strPool[ph]; -    if (last) { -      last->next = str; -    } else { -      strHandle[hash] = str; -    } -    return &strPool[ph]; -  } -  return NULL; -} - -void String_Report( void ) { -  float f; -  Com_Printf("Memory/String Pool Info\n"); -  Com_Printf("----------------\n"); -  f = strPoolIndex; -  f /= STRING_POOL_SIZE; -  f *= 100; -  Com_Printf("String Pool is %.1f%% full, %i bytes out of %i used.\n", f, strPoolIndex, STRING_POOL_SIZE); -  f = allocPoint; -  f /= MEM_POOL_SIZE; -  f *= 100; -  Com_Printf("Memory Pool is %.1f%% full, %i bytes out of %i used.\n", f, allocPoint, MEM_POOL_SIZE); -} - -/* -================= -String_Init -================= -*/ -void String_Init( void ) -{ -  int i; -  for( i = 0; i < HASH_TABLE_SIZE; i++ ) -    strHandle[ i ] = 0; - -  strHandleCount = 0; -  strPoolIndex = 0; -  menuCount = 0; -  openMenuCount = 0; -  UI_InitMemory( ); -  Item_SetupKeywordHash( ); -  Menu_SetupKeywordHash( ); - -  if( DC && DC->getBindingBuf ) -    Controls_GetConfig( ); -} - -/* -================= -PC_SourceWarning -================= -*/ -void PC_SourceWarning(int handle, char *format, ...) { -  int line; -  char filename[128]; -  va_list argptr; -  static char string[4096]; - -  va_start (argptr, format); -  vsprintf (string, format, argptr); -  va_end (argptr); - -  filename[0] = '\0'; -  line = 0; -  trap_PC_SourceFileAndLine(handle, filename, &line); - -  Com_Printf(S_COLOR_YELLOW "WARNING: %s, line %d: %s\n", filename, line, string); -} - -/* -================= -PC_SourceError -================= -*/ -void PC_SourceError(int handle, char *format, ...) { -  int line; -  char filename[128]; -  va_list argptr; -  static char string[4096]; - -  va_start (argptr, format); -  vsprintf (string, format, argptr); -  va_end (argptr); - -  filename[0] = '\0'; -  line = 0; -  trap_PC_SourceFileAndLine(handle, filename, &line); - -  Com_Printf(S_COLOR_RED "ERROR: %s, line %d: %s\n", filename, line, string); -} - -/* -================= -LerpColor -================= -*/ -void LerpColor(vec4_t a, vec4_t b, vec4_t c, float t) -{ -  int i; - -  // lerp and clamp each component -  for (i=0; i<4; i++) -  { -    c[i] = a[i] + t*(b[i]-a[i]); -    if (c[i] < 0) -      c[i] = 0; -    else if (c[i] > 1.0) -      c[i] = 1.0; -  } -} - -/* -================= -Float_Parse -================= -*/ -qboolean Float_Parse(char **p, float *f) { -  char  *token; -  token = COM_ParseExt(p, qfalse); -  if (token && token[0] != 0) { -    *f = atof(token); -    return qtrue; -  } else { -    return qfalse; -  } -} - -/* -================= -PC_Float_Parse -================= -*/ -qboolean PC_Float_Parse(int handle, float *f) { -  pc_token_t token; -  int negative = qfalse; - -  if (!trap_PC_ReadToken(handle, &token)) -    return qfalse; -  if (token.string[0] == '-') { -    if (!trap_PC_ReadToken(handle, &token)) -      return qfalse; -    negative = qtrue; -  } -  if (token.type != TT_NUMBER) { -    PC_SourceError(handle, "expected float but found %s\n", token.string); -    return qfalse; -  } -  if (negative) -    *f = -token.floatvalue; -  else -    *f = token.floatvalue; -  return qtrue; -} - -/* -================= -Color_Parse -================= -*/ -qboolean Color_Parse(char **p, vec4_t *c) { -  int i; -  float f; - -  for (i = 0; i < 4; i++) { -    if (!Float_Parse(p, &f)) { -      return qfalse; -    } -    (*c)[i] = f; -  } -  return qtrue; -} - -/* -================= -PC_Color_Parse -================= -*/ -qboolean PC_Color_Parse(int handle, vec4_t *c) { -  int i; -  float f; - -  for (i = 0; i < 4; i++) { -    if (!PC_Float_Parse(handle, &f)) { -      return qfalse; -    } -    (*c)[i] = f; -  } -  return qtrue; -} - -/* -================= -Int_Parse -================= -*/ -qboolean Int_Parse(char **p, int *i) { -  char  *token; -  token = COM_ParseExt(p, qfalse); - -  if (token && token[0] != 0) { -    *i = atoi(token); -    return qtrue; -  } else { -    return qfalse; -  } -} - -/* -================= -PC_Int_Parse -================= -*/ -qboolean PC_Int_Parse(int handle, int *i) { -  pc_token_t token; -  int negative = qfalse; - -  if (!trap_PC_ReadToken(handle, &token)) -    return qfalse; -  if (token.string[0] == '-') { -    if (!trap_PC_ReadToken(handle, &token)) -      return qfalse; -    negative = qtrue; -  } -  if (token.type != TT_NUMBER) { -    PC_SourceError(handle, "expected integer but found %s\n", token.string); -    return qfalse; -  } -  *i = token.intvalue; -  if (negative) -    *i = - *i; -  return qtrue; -} - -/* -================= -Rect_Parse -================= -*/ -qboolean Rect_Parse(char **p, rectDef_t *r) { -  if (Float_Parse(p, &r->x)) { -    if (Float_Parse(p, &r->y)) { -      if (Float_Parse(p, &r->w)) { -        if (Float_Parse(p, &r->h)) { -          return qtrue; -        } -      } -    } -  } -  return qfalse; -} - -/* -================= -PC_Rect_Parse -================= -*/ -qboolean PC_Rect_Parse(int handle, rectDef_t *r) { -  if (PC_Float_Parse(handle, &r->x)) { -    if (PC_Float_Parse(handle, &r->y)) { -      if (PC_Float_Parse(handle, &r->w)) { -        if (PC_Float_Parse(handle, &r->h)) { -          return qtrue; -        } -      } -    } -  } -  return qfalse; -} - -/* -================= -String_Parse -================= -*/ -qboolean String_Parse(char **p, const char **out) { -  char *token; - -  token = COM_ParseExt(p, qfalse); -  if (token && token[0] != 0) { -    *(out) = String_Alloc(token); -    return qtrue; -  } -  return qfalse; -} - -/* -================= -PC_String_Parse -================= -*/ -qboolean PC_String_Parse(int handle, const char **out) { -  pc_token_t token; - -  if (!trap_PC_ReadToken(handle, &token)) -    return qfalse; - -  *(out) = String_Alloc(token.string); -    return qtrue; -} - -/* -================= -PC_Script_Parse -================= -*/ -qboolean PC_Script_Parse(int handle, const char **out) { -  char script[1024]; -  pc_token_t token; - -  memset(script, 0, sizeof(script)); -  // scripts start with { and have ; separated command lists.. commands are command, arg.. -  // basically we want everything between the { } as it will be interpreted at run time - -  if (!trap_PC_ReadToken(handle, &token)) -    return qfalse; -  if (Q_stricmp(token.string, "{") != 0) { -      return qfalse; -  } - -  while ( 1 ) { -    if (!trap_PC_ReadToken(handle, &token)) -      return qfalse; - -    if (Q_stricmp(token.string, "}") == 0) { -      *out = String_Alloc(script); -      return qtrue; -    } - -    if (token.string[1] != '\0') { -      Q_strcat(script, 1024, va("\"%s\"", token.string)); -    } else { -      Q_strcat(script, 1024, token.string); -    } -    Q_strcat(script, 1024, " "); -  } -  return qfalse;  // bk001105 - LCC   missing return value -} - -// display, window, menu, item code -// - -/* -================== -Init_Display - -Initializes the display with a structure to all the drawing routines -================== -*/ -void Init_Display( displayContextDef_t *dc ) -{ -  DC = dc; -} - - - -// type and style painting - -void GradientBar_Paint( rectDef_t *rect, vec4_t color ) -{ -  // gradient bar takes two paints -  DC->setColor( color ); -  DC->drawHandlePic( rect->x, rect->y, rect->w, rect->h, DC->Assets.gradientBar ); -  DC->setColor( NULL ); -} - - -/* -================== -Window_Init - -Initializes a window structure ( windowDef_t ) with defaults - -================== -*/ -void Window_Init(Window *w) { -  memset(w, 0, sizeof(windowDef_t)); -  w->borderSize = 1; -  w->foreColor[0] = w->foreColor[1] = w->foreColor[2] = w->foreColor[3] = 1.0; -  w->cinematic = -1; -} - -void Fade(int *flags, float *f, float clamp, int *nextTime, int offsetTime, qboolean bFlags, float fadeAmount) { -  if (*flags & (WINDOW_FADINGOUT | WINDOW_FADINGIN)) { -    if (DC->realTime > *nextTime) { -      *nextTime = DC->realTime + offsetTime; -      if (*flags & WINDOW_FADINGOUT) { -        *f -= fadeAmount; -        if (bFlags && *f <= 0.0) { -          *flags &= ~(WINDOW_FADINGOUT | WINDOW_VISIBLE); -        } -      } else { -        *f += fadeAmount; -        if (*f >= clamp) { -          *f = clamp; -          if (bFlags) { -            *flags &= ~WINDOW_FADINGIN; -          } -        } -      } -    } -  } -} - - - -void Window_Paint(Window *w, float fadeAmount, float fadeClamp, float fadeCycle) { -  //float bordersize = 0; -  vec4_t color; -  rectDef_t fillRect = w->rect; - - -  if (debugMode) { -    color[0] = color[1] = color[2] = color[3] = 1; -    DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, 1, color); -  } - -  if (w == NULL || (w->style == 0 && w->border == 0)) { -    return; -  } - -  if (w->border != 0) { -    fillRect.x += w->borderSize; -    fillRect.y += w->borderSize; -    fillRect.w -= w->borderSize + 1; -    fillRect.h -= w->borderSize + 1; -  } - -  if (w->style == WINDOW_STYLE_FILLED) { -    // box, but possible a shader that needs filled -    if (w->background) { -      Fade(&w->flags, &w->backColor[3], fadeClamp, &w->nextTime, fadeCycle, qtrue, fadeAmount); -      DC->setColor(w->backColor); -      DC->drawHandlePic(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->background); -      DC->setColor(NULL); -    } else { -      DC->fillRect(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->backColor); -    } -  } else if (w->style == WINDOW_STYLE_GRADIENT) { -    GradientBar_Paint(&fillRect, w->backColor); -    // gradient bar -  } else if (w->style == WINDOW_STYLE_SHADER) { -    if (w->flags & WINDOW_FORECOLORSET) { -      DC->setColor(w->foreColor); -    } -    DC->drawHandlePic(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->background); -    DC->setColor(NULL); -  } else if (w->style == WINDOW_STYLE_TEAMCOLOR) { -    if (DC->getTeamColor) { -      DC->getTeamColor(&color); -      DC->fillRect(fillRect.x, fillRect.y, fillRect.w, fillRect.h, color); -    } -  } else if (w->style == WINDOW_STYLE_CINEMATIC) { -    if (w->cinematic == -1) { -      w->cinematic = DC->playCinematic(w->cinematicName, fillRect.x, fillRect.y, fillRect.w, fillRect.h); -      if (w->cinematic == -1) { -        w->cinematic = -2; -      } -    } -    if (w->cinematic >= 0) { -      DC->runCinematicFrame(w->cinematic); -      DC->drawCinematic(w->cinematic, fillRect.x, fillRect.y, fillRect.w, fillRect.h); -    } -  } - -  if (w->border == WINDOW_BORDER_FULL) { -    // full -    // HACK HACK HACK -    if (w->style == WINDOW_STYLE_TEAMCOLOR) { -      if (color[0] > 0) { -        // red -        color[0] = 1; -        color[1] = color[2] = .5; - -      } else { -        color[2] = 1; -        color[0] = color[1] = .5; -      } -      color[3] = 1; -      DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, color); -    } else { -      DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, w->borderColor); -    } -  } else if (w->border == WINDOW_BORDER_HORZ) { -    // top/bottom -    DC->setColor(w->borderColor); -    DC->drawTopBottom(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize); -    DC->setColor( NULL ); -  } else if (w->border == WINDOW_BORDER_VERT) { -    // left right -    DC->setColor(w->borderColor); -    DC->drawSides(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize); -    DC->setColor( NULL ); -  } else if (w->border == WINDOW_BORDER_KCGRADIENT) { -    // this is just two gradient bars along each horz edge -    rectDef_t r = w->rect; -    r.h = w->borderSize; -    GradientBar_Paint(&r, w->borderColor); -    r.y = w->rect.y + w->rect.h - 1; -    GradientBar_Paint(&r, w->borderColor); -  } - -} - - -void Item_SetScreenCoords(itemDef_t *item, float x, float y) { - -  if (item == NULL) { -    return; -  } - -  if (item->window.border != 0) { -    x += item->window.borderSize; -    y += item->window.borderSize; -  } - -  item->window.rect.x = x + item->window.rectClient.x; -  item->window.rect.y = y + item->window.rectClient.y; -  item->window.rect.w = item->window.rectClient.w; -  item->window.rect.h = item->window.rectClient.h; - -  // force the text rects to recompute -  item->textRect.w = 0; -  item->textRect.h = 0; -} - -// FIXME: consolidate this with nearby stuff -void Item_UpdatePosition(itemDef_t *item) { -  float x, y; -  menuDef_t *menu; - -  if (item == NULL || item->parent == NULL) { -    return; -  } - -  menu = item->parent; - -  x = menu->window.rect.x; -  y = menu->window.rect.y; - -  if (menu->window.border != 0) { -    x += menu->window.borderSize; -    y += menu->window.borderSize; -  } - -  Item_SetScreenCoords(item, x, y); - -} - -// menus -void Menu_UpdatePosition(menuDef_t *menu) { -  int i; -  float x, y; - -  if (menu == NULL) { -    return; -  } - -  x = menu->window.rect.x; -  y = menu->window.rect.y; -  if (menu->window.border != 0) { -    x += menu->window.borderSize; -    y += menu->window.borderSize; -  } - -  for (i = 0; i < menu->itemCount; i++) { -    Item_SetScreenCoords(menu->items[i], x, y); -  } -} - -void Menu_PostParse(menuDef_t *menu) { -  if (menu == NULL) { -    return; -  } -  if (menu->fullScreen) { -    menu->window.rect.x = 0; -    menu->window.rect.y = 0; -    menu->window.rect.w = 640; -    menu->window.rect.h = 480; -  } -  Menu_UpdatePosition(menu); -} - -itemDef_t *Menu_ClearFocus(menuDef_t *menu) { -  int i; -  itemDef_t *ret = NULL; - -  if (menu == NULL) { -    return NULL; -  } - -  for (i = 0; i < menu->itemCount; i++) { -    if (menu->items[i]->window.flags & WINDOW_HASFOCUS) { -      ret = menu->items[i]; -    } -    menu->items[i]->window.flags &= ~WINDOW_HASFOCUS; -    if (menu->items[i]->leaveFocus) { -      Item_RunScript(menu->items[i], menu->items[i]->leaveFocus); -    } -  } - -  return ret; -} - -qboolean IsVisible(int flags) { -  return (flags & WINDOW_VISIBLE && !(flags & WINDOW_FADINGOUT)); -} - -qboolean Rect_ContainsPoint(rectDef_t *rect, float x, float y) { -  if (rect) { -    if (x > rect->x && x < rect->x + rect->w && y > rect->y && y < rect->y + rect->h) { -      return qtrue; -    } -  } -  return qfalse; -} - -int Menu_ItemsMatchingGroup(menuDef_t *menu, const char *name) { -  int i; -  int count = 0; -  for (i = 0; i < menu->itemCount; i++) { -    if (Q_stricmp(menu->items[i]->window.name, name) == 0 || (menu->items[i]->window.group && Q_stricmp(menu->items[i]->window.group, name) == 0)) { -      count++; -    } -  } -  return count; -} - -itemDef_t *Menu_GetMatchingItemByNumber(menuDef_t *menu, int index, const char *name) { -  int i; -  int count = 0; -  for (i = 0; i < menu->itemCount; i++) { -    if (Q_stricmp(menu->items[i]->window.name, name) == 0 || (menu->items[i]->window.group && Q_stricmp(menu->items[i]->window.group, name) == 0)) { -      if (count == index) { -        return menu->items[i]; -      } -      count++; -    } -  } -  return NULL; -} - - - -void Script_SetColor(itemDef_t *item, char **args) { -  const char *name; -  int i; -  float f; -  vec4_t *out; -  // expecting type of color to set and 4 args for the color -  if (String_Parse(args, &name)) { -      out = NULL; -      if (Q_stricmp(name, "backcolor") == 0) { -        out = &item->window.backColor; -        item->window.flags |= WINDOW_BACKCOLORSET; -      } else if (Q_stricmp(name, "forecolor") == 0) { -        out = &item->window.foreColor; -        item->window.flags |= WINDOW_FORECOLORSET; -      } else if (Q_stricmp(name, "bordercolor") == 0) { -        out = &item->window.borderColor; -      } - -      if (out) { -        for (i = 0; i < 4; i++) { -          if (!Float_Parse(args, &f)) { -            return; -          } -          (*out)[i] = f; -        } -      } -  } -} - -void Script_SetAsset(itemDef_t *item, char **args) { -  const char *name; -  // expecting name to set asset to -  if (String_Parse(args, &name)) { -    // check for a model -    if (item->type == ITEM_TYPE_MODEL) { -    } -  } -} - -void Script_SetBackground(itemDef_t *item, char **args) { -  const char *name; -  // expecting name to set asset to -  if (String_Parse(args, &name)) { -    item->window.background = DC->registerShaderNoMip(name); -  } -} - - - - -itemDef_t *Menu_FindItemByName(menuDef_t *menu, const char *p) { -  int i; -  if (menu == NULL || p == NULL) { -    return NULL; -  } - -  for (i = 0; i < menu->itemCount; i++) { -    if (Q_stricmp(p, menu->items[i]->window.name) == 0) { -      return menu->items[i]; -    } -  } - -  return NULL; -} - -void Script_SetTeamColor(itemDef_t *item, char **args) { -  if (DC->getTeamColor) { -    int i; -    vec4_t color; -    DC->getTeamColor(&color); -    for (i = 0; i < 4; i++) { -      item->window.backColor[i] = color[i]; -    } -  } -} - -void Script_SetItemColor(itemDef_t *item, char **args) { -  const char *itemname; -  const char *name; -  vec4_t color; -  int i; -  vec4_t *out; -  // expecting type of color to set and 4 args for the color -  if (String_Parse(args, &itemname) && String_Parse(args, &name)) { -    itemDef_t *item2; -    int j; -    int count = Menu_ItemsMatchingGroup(item->parent, itemname); - -    if (!Color_Parse(args, &color)) { -      return; -    } - -    for (j = 0; j < count; j++) { -      item2 = Menu_GetMatchingItemByNumber(item->parent, j, itemname); -      if (item2 != NULL) { -        out = NULL; -        if (Q_stricmp(name, "backcolor") == 0) { -          out = &item2->window.backColor; -        } else if (Q_stricmp(name, "forecolor") == 0) { -          out = &item2->window.foreColor; -          item2->window.flags |= WINDOW_FORECOLORSET; -        } else if (Q_stricmp(name, "bordercolor") == 0) { -          out = &item2->window.borderColor; -        } - -        if (out) { -          for (i = 0; i < 4; i++) { -            (*out)[i] = color[i]; -          } -        } -      } -    } -  } -} - - -void Menu_ShowItemByName(menuDef_t *menu, const char *p, qboolean bShow) { -  itemDef_t *item; -  int i; -  int count = Menu_ItemsMatchingGroup(menu, p); -  for (i = 0; i < count; i++) { -    item = Menu_GetMatchingItemByNumber(menu, i, p); -    if (item != NULL) { -      if (bShow) { -        item->window.flags |= WINDOW_VISIBLE; -      } else { -        item->window.flags &= ~WINDOW_VISIBLE; -        // stop cinematics playing in the window -        if (item->window.cinematic >= 0) { -          DC->stopCinematic(item->window.cinematic); -          item->window.cinematic = -1; -        } -      } -    } -  } -} - -void Menu_FadeItemByName(menuDef_t *menu, const char *p, qboolean fadeOut) { -  itemDef_t *item; -  int i; -  int count = Menu_ItemsMatchingGroup(menu, p); -  for (i = 0; i < count; i++) { -    item = Menu_GetMatchingItemByNumber(menu, i, p); -    if (item != NULL) { -      if (fadeOut) { -        item->window.flags |= (WINDOW_FADINGOUT | WINDOW_VISIBLE); -        item->window.flags &= ~WINDOW_FADINGIN; -      } else { -        item->window.flags |= (WINDOW_VISIBLE | WINDOW_FADINGIN); -        item->window.flags &= ~WINDOW_FADINGOUT; -      } -    } -  } -} - -menuDef_t *Menus_FindByName(const char *p) { -  int i; -  for (i = 0; i < menuCount; i++) { -    if (Q_stricmp(Menus[i].window.name, p) == 0) { -      return &Menus[i]; -    } -  } -  return NULL; -} - -void Menus_ShowByName(const char *p) { -  menuDef_t *menu = Menus_FindByName(p); -  if (menu) { -    Menus_Activate(menu); -  } -} - -void Menus_OpenByName(const char *p) { -  Menus_ActivateByName(p); -} - -static void Menu_RunCloseScript(menuDef_t *menu) { -  if (menu && menu->window.flags & WINDOW_VISIBLE && menu->onClose) { -    itemDef_t item; -    item.parent = menu; -    Item_RunScript(&item, menu->onClose); -  } -} - -void Menus_CloseByName(const char *p) { -  menuDef_t *menu = Menus_FindByName(p); -  if (menu != NULL) { -    Menu_RunCloseScript(menu); -    menu->window.flags &= ~(WINDOW_VISIBLE | WINDOW_HASFOCUS); -  } -} - -void Menus_CloseAll( void ) { -  int i; -  for (i = 0; i < menuCount; i++) { -    Menu_RunCloseScript(&Menus[i]); -    Menus[i].window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE); -  } -} - - -void Script_Show(itemDef_t *item, char **args) { -  const char *name; -  if (String_Parse(args, &name)) { -    Menu_ShowItemByName(item->parent, name, qtrue); -  } -} - -void Script_Hide(itemDef_t *item, char **args) { -  const char *name; -  if (String_Parse(args, &name)) { -    Menu_ShowItemByName(item->parent, name, qfalse); -  } -} - -void Script_FadeIn(itemDef_t *item, char **args) { -  const char *name; -  if (String_Parse(args, &name)) { -    Menu_FadeItemByName(item->parent, name, qfalse); -  } -} - -void Script_FadeOut(itemDef_t *item, char **args) { -  const char *name; -  if (String_Parse(args, &name)) { -    Menu_FadeItemByName(item->parent, name, qtrue); -  } -} - - - -void Script_Open(itemDef_t *item, char **args) { -  const char *name; -  if (String_Parse(args, &name)) { -    Menus_OpenByName(name); -  } -} - -void Script_ConditionalOpen(itemDef_t *item, char **args) { -  const char *cvar; -  const char *name1; -  const char *name2; -  float           val; - -  if ( String_Parse(args, &cvar) && String_Parse(args, &name1) && String_Parse(args, &name2) ) { -    val = DC->getCVarValue( cvar ); -    if ( val == 0.f ) { -      Menus_OpenByName(name2); -    } else { -      Menus_OpenByName(name1); -    } -  } -} - -void Script_Close(itemDef_t *item, char **args) { -  const char *name; -  if (String_Parse(args, &name)) { -    Menus_CloseByName(name); -  } -} - -void Menu_TransitionItemByName(menuDef_t *menu, const char *p, rectDef_t rectFrom, rectDef_t rectTo, int time, float amt) { -  itemDef_t *item; -  int i; -  int count = Menu_ItemsMatchingGroup(menu, p); -  for (i = 0; i < count; i++) { -    item = Menu_GetMatchingItemByNumber(menu, i, p); -    if (item != NULL) { -      item->window.flags |= (WINDOW_INTRANSITION | WINDOW_VISIBLE); -      item->window.offsetTime = time; -      memcpy(&item->window.rectClient, &rectFrom, sizeof(rectDef_t)); -      memcpy(&item->window.rectEffects, &rectTo, sizeof(rectDef_t)); -      item->window.rectEffects2.x = abs(rectTo.x - rectFrom.x) / amt; -      item->window.rectEffects2.y = abs(rectTo.y - rectFrom.y) / amt; -      item->window.rectEffects2.w = abs(rectTo.w - rectFrom.w) / amt; -      item->window.rectEffects2.h = abs(rectTo.h - rectFrom.h) / amt; -      Item_UpdatePosition(item); -    } -  } -} - - -void Script_Transition(itemDef_t *item, char **args) { -  const char *name; -  rectDef_t rectFrom, rectTo; -  int time; -  float amt; - -  if (String_Parse(args, &name)) { -    if ( Rect_Parse(args, &rectFrom) && Rect_Parse(args, &rectTo) && Int_Parse(args, &time) && Float_Parse(args, &amt)) { -      Menu_TransitionItemByName(item->parent, name, rectFrom, rectTo, time, amt); -    } -  } -} - - -void Menu_OrbitItemByName(menuDef_t *menu, const char *p, float x, float y, float cx, float cy, int time) { -  itemDef_t *item; -  int i; -  int count = Menu_ItemsMatchingGroup(menu, p); -  for (i = 0; i < count; i++) { -    item = Menu_GetMatchingItemByNumber(menu, i, p); -    if (item != NULL) { -      item->window.flags |= (WINDOW_ORBITING | WINDOW_VISIBLE); -      item->window.offsetTime = time; -      item->window.rectEffects.x = cx; -      item->window.rectEffects.y = cy; -      item->window.rectClient.x = x; -      item->window.rectClient.y = y; -      Item_UpdatePosition(item); -    } -  } -} - - -void Script_Orbit(itemDef_t *item, char **args) { -  const char *name; -  float cx, cy, x, y; -  int time; - -  if (String_Parse(args, &name)) { -    if ( Float_Parse(args, &x) && Float_Parse(args, &y) && Float_Parse(args, &cx) && Float_Parse(args, &cy) && Int_Parse(args, &time) ) { -      Menu_OrbitItemByName(item->parent, name, x, y, cx, cy, time); -    } -  } -} - - - -void Script_SetFocus(itemDef_t *item, char **args) { -  const char *name; -  itemDef_t *focusItem; - -  if (String_Parse(args, &name)) { -    focusItem = Menu_FindItemByName(item->parent, name); -    if (focusItem && !(focusItem->window.flags & WINDOW_DECORATION) && !(focusItem->window.flags & WINDOW_HASFOCUS)) { -      Menu_ClearFocus(item->parent); -      focusItem->window.flags |= WINDOW_HASFOCUS; -      if (focusItem->onFocus) { -        Item_RunScript(focusItem, focusItem->onFocus); -      } -      if (DC->Assets.itemFocusSound) { -        DC->startLocalSound( DC->Assets.itemFocusSound, CHAN_LOCAL_SOUND ); -      } -    } -  } -} - -void Script_SetPlayerModel(itemDef_t *item, char **args) { -  const char *name; -  if (String_Parse(args, &name)) { -    DC->setCVar("team_model", name); -  } -} - -void Script_SetPlayerHead(itemDef_t *item, char **args) { -  const char *name; -  if (String_Parse(args, &name)) { -    DC->setCVar("team_headmodel", name); -  } -} - -void Script_SetCvar(itemDef_t *item, char **args) { -  const char *cvar, *val; -  if (String_Parse(args, &cvar) && String_Parse(args, &val)) { -    DC->setCVar(cvar, val); -  } - -} - -void Script_Exec(itemDef_t *item, char **args) { -  const char *val; -  if (String_Parse(args, &val)) { -    DC->executeText(EXEC_APPEND, va("%s ; ", val)); -  } -} - -void Script_Play(itemDef_t *item, char **args) { -  const char *val; -  if (String_Parse(args, &val)) { -    DC->startLocalSound(DC->registerSound(val, qfalse), CHAN_LOCAL_SOUND); -  } -} - -void Script_playLooped(itemDef_t *item, char **args) { -  const char *val; -  if (String_Parse(args, &val)) { -    DC->stopBackgroundTrack(); -    DC->startBackgroundTrack(val, val); -  } -} - - -commandDef_t commandList[] = -{ -  {"fadein", &Script_FadeIn},                   // group/name -  {"fadeout", &Script_FadeOut},                 // group/name -  {"show", &Script_Show},                       // group/name -  {"hide", &Script_Hide},                       // group/name -  {"setcolor", &Script_SetColor},               // works on this -  {"open", &Script_Open},                       // menu -  {"conditionalopen", &Script_ConditionalOpen}, // menu -  {"close", &Script_Close},                     // menu -  {"setasset", &Script_SetAsset},               // works on this -  {"setbackground", &Script_SetBackground},     // works on this -  {"setitemcolor", &Script_SetItemColor},       // group/name -  {"setteamcolor", &Script_SetTeamColor},       // sets this background color to team color -  {"setfocus", &Script_SetFocus},               // sets this background color to team color -  {"setplayermodel", &Script_SetPlayerModel},   // sets this background color to team color -  {"setplayerhead", &Script_SetPlayerHead},     // sets this background color to team color -  {"transition", &Script_Transition},           // group/name -  {"setcvar", &Script_SetCvar},           // group/name -  {"exec", &Script_Exec},           // group/name -  {"play", &Script_Play},           // group/name -  {"playlooped", &Script_playLooped},           // group/name -  {"orbit", &Script_Orbit}                      // group/name -}; - -int scriptCommandCount = sizeof(commandList) / sizeof(commandDef_t); - - -void Item_RunScript(itemDef_t *item, const char *s) { -  char script[1024], *p; -  int i; -  qboolean bRan; -  memset(script, 0, sizeof(script)); -  if (item && s && s[0]) { -    Q_strcat(script, 1024, s); -    p = script; -    while (1) { -      const char *command; -      // expect command then arguments, ; ends command, NULL ends script -      if (!String_Parse(&p, &command)) { -        return; -      } - -      if (command[0] == ';' && command[1] == '\0') { -        continue; -      } - -      bRan = qfalse; -      for (i = 0; i < scriptCommandCount; i++) { -        if (Q_stricmp(command, commandList[i].name) == 0) { -          (commandList[i].handler(item, &p)); -          bRan = qtrue; -          break; -        } -      } -      // not in our auto list, pass to handler -      if (!bRan) { -        DC->runScript(&p); -      } -    } -  } -} - - -qboolean Item_EnableShowViaCvar(itemDef_t *item, int flag) { -  char script[1024], *p; -  memset(script, 0, sizeof(script)); -  if (item && item->enableCvar && *item->enableCvar && item->cvarTest && *item->cvarTest) { -    char buff[1024]; -    DC->getCVarString(item->cvarTest, buff, sizeof(buff)); - -    Q_strcat(script, 1024, item->enableCvar); -    p = script; -    while (1) { -      const char *val; -      // expect value then ; or NULL, NULL ends list -      if (!String_Parse(&p, &val)) { -        return (item->cvarFlags & flag) ? qfalse : qtrue; -      } - -      if (val[0] == ';' && val[1] == '\0') { -        continue; -      } - -      // enable it if any of the values are true -      if (item->cvarFlags & flag) { -        if (Q_stricmp(buff, val) == 0) { -          return qtrue; -        } -      } else { -        // disable it if any of the values are true -        if (Q_stricmp(buff, val) == 0) { -          return qfalse; -        } -      } - -    } -    return (item->cvarFlags & flag) ? qfalse : qtrue; -  } -  return qtrue; -} - - -// will optionaly set focus to this item -qboolean Item_SetFocus(itemDef_t *item, float x, float y) { -  int i; -  itemDef_t *oldFocus; -  sfxHandle_t *sfx = &DC->Assets.itemFocusSound; -  qboolean playSound = qfalse; -  menuDef_t *parent; // bk001206: = (menuDef_t*)item->parent; -  // sanity check, non-null, not a decoration and does not already have the focus -  if (item == NULL || item->window.flags & WINDOW_DECORATION || item->window.flags & WINDOW_HASFOCUS || !(item->window.flags & WINDOW_VISIBLE)) { -    return qfalse; -  } - -  // bk001206 - this can be NULL. -  parent = (menuDef_t*)item->parent; - -  // items can be enabled and disabled based on cvars -  if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) { -    return qfalse; -  } - -  if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(item, CVAR_SHOW)) { -    return qfalse; -  } - -  oldFocus = Menu_ClearFocus(item->parent); - -  if (item->type == ITEM_TYPE_TEXT) { -    rectDef_t r; -    r = item->textRect; -    r.y -= r.h; -    if (Rect_ContainsPoint(&r, x, y)) { -      item->window.flags |= WINDOW_HASFOCUS; -      if (item->focusSound) { -        sfx = &item->focusSound; -      } -      playSound = qtrue; -    } else { -      if (oldFocus) { -        oldFocus->window.flags |= WINDOW_HASFOCUS; -        if (oldFocus->onFocus) { -          Item_RunScript(oldFocus, oldFocus->onFocus); -        } -      } -    } -  } else { -      item->window.flags |= WINDOW_HASFOCUS; -    if (item->onFocus) { -      Item_RunScript(item, item->onFocus); -    } -    if (item->focusSound) { -      sfx = &item->focusSound; -    } -    playSound = qtrue; -  } - -  if (playSound && sfx) { -    DC->startLocalSound( *sfx, CHAN_LOCAL_SOUND ); -  } - -  for (i = 0; i < parent->itemCount; i++) { -    if (parent->items[i] == item) { -      parent->cursorItem = i; -      break; -    } -  } - -  return qtrue; -} - -int Item_ListBox_MaxScroll(itemDef_t *item) { -  listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData; -  int count = DC->feederCount(item->special); -  int max; - -  if (item->window.flags & WINDOW_HORIZONTAL) { -    max = count - (item->window.rect.w / listPtr->elementWidth) + 1; -  } -  else { -    max = count - (item->window.rect.h / listPtr->elementHeight) + 1; -  } -  if (max < 0) { -    return 0; -  } -  return max; -} - -int Item_ListBox_ThumbPosition(itemDef_t *item) { -  float max, pos, size; -  listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData; - -  max = Item_ListBox_MaxScroll(item); -  if (item->window.flags & WINDOW_HORIZONTAL) { -    size = item->window.rect.w - (SCROLLBAR_SIZE * 2) - 2; -    if (max > 0) { -      pos = (size-SCROLLBAR_SIZE) / (float) max; -    } else { -      pos = 0; -    } -    pos *= listPtr->startPos; -    return item->window.rect.x + 1 + SCROLLBAR_SIZE + pos; -  } -  else { -    size = item->window.rect.h - (SCROLLBAR_SIZE * 2) - 2; -    if (max > 0) { -      pos = (size-SCROLLBAR_SIZE) / (float) max; -    } else { -      pos = 0; -    } -    pos *= listPtr->startPos; -    return item->window.rect.y + 1 + SCROLLBAR_SIZE + pos; -  } -} - -int Item_ListBox_ThumbDrawPosition(itemDef_t *item) { -  int min, max; - -  if (itemCapture == item) { -    if (item->window.flags & WINDOW_HORIZONTAL) { -      min = item->window.rect.x + SCROLLBAR_SIZE + 1; -      max = item->window.rect.x + item->window.rect.w - 2*SCROLLBAR_SIZE - 1; -      if (DC->cursorx >= min + SCROLLBAR_SIZE/2 && DC->cursorx <= max + SCROLLBAR_SIZE/2) { -        return DC->cursorx - SCROLLBAR_SIZE/2; -      } -      else { -        return Item_ListBox_ThumbPosition(item); -      } -    } -    else { -      min = item->window.rect.y + SCROLLBAR_SIZE + 1; -      max = item->window.rect.y + item->window.rect.h - 2*SCROLLBAR_SIZE - 1; -      if (DC->cursory >= min + SCROLLBAR_SIZE/2 && DC->cursory <= max + SCROLLBAR_SIZE/2) { -        return DC->cursory - SCROLLBAR_SIZE/2; -      } -      else { -        return Item_ListBox_ThumbPosition(item); -      } -    } -  } -  else { -    return Item_ListBox_ThumbPosition(item); -  } -} - -float Item_Slider_ThumbPosition(itemDef_t *item) { -  float value, range, x; -  editFieldDef_t *editDef = item->typeData; - -  if (item->text) { -    x = item->textRect.x + item->textRect.w + 8; -  } else { -    x = item->window.rect.x; -  } - -  if (editDef == NULL && item->cvar) { -    return x; -  } - -  value = DC->getCVarValue(item->cvar); - -  if (value < editDef->minVal) { -    value = editDef->minVal; -  } else if (value > editDef->maxVal) { -    value = editDef->maxVal; -  } - -  range = editDef->maxVal - editDef->minVal; -  value -= editDef->minVal; -  value /= range; -  //value /= (editDef->maxVal - editDef->minVal); -  value *= SLIDER_WIDTH; -  x += value; -  // vm fuckage -  //x = x + (((float)value / editDef->maxVal) * SLIDER_WIDTH); -  return x; -} - -int Item_Slider_OverSlider(itemDef_t *item, float x, float y) { -  rectDef_t r; - -  r.x = Item_Slider_ThumbPosition(item) - (SLIDER_THUMB_WIDTH / 2); -  r.y = item->window.rect.y - 2; -  r.w = SLIDER_THUMB_WIDTH; -  r.h = SLIDER_THUMB_HEIGHT; - -  if (Rect_ContainsPoint(&r, x, y)) { -    return WINDOW_LB_THUMB; -  } -  return 0; -} - -int Item_ListBox_OverLB(itemDef_t *item, float x, float y) { -  rectDef_t r; -  listBoxDef_t *listPtr; -  int thumbstart; -  int count; - -  count = DC->feederCount(item->special); -  listPtr = (listBoxDef_t*)item->typeData; -  if (item->window.flags & WINDOW_HORIZONTAL) { -    // check if on left arrow -    r.x = item->window.rect.x; -    r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE; -    r.h = r.w = SCROLLBAR_SIZE; -    if (Rect_ContainsPoint(&r, x, y)) { -      return WINDOW_LB_LEFTARROW; -    } -    // check if on right arrow -    r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE; -    if (Rect_ContainsPoint(&r, x, y)) { -      return WINDOW_LB_RIGHTARROW; -    } -    // check if on thumb -    thumbstart = Item_ListBox_ThumbPosition(item); -    r.x = thumbstart; -    if (Rect_ContainsPoint(&r, x, y)) { -      return WINDOW_LB_THUMB; -    } -    r.x = item->window.rect.x + SCROLLBAR_SIZE; -    r.w = thumbstart - r.x; -    if (Rect_ContainsPoint(&r, x, y)) { -      return WINDOW_LB_PGUP; -    } -    r.x = thumbstart + SCROLLBAR_SIZE; -    r.w = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE; -    if (Rect_ContainsPoint(&r, x, y)) { -      return WINDOW_LB_PGDN; -    } -  } else { -    r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE; -    r.y = item->window.rect.y; -    r.h = r.w = SCROLLBAR_SIZE; -    if (Rect_ContainsPoint(&r, x, y)) { -      return WINDOW_LB_LEFTARROW; -    } -    r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE; -    if (Rect_ContainsPoint(&r, x, y)) { -      return WINDOW_LB_RIGHTARROW; -    } -    thumbstart = Item_ListBox_ThumbPosition(item); -    r.y = thumbstart; -    if (Rect_ContainsPoint(&r, x, y)) { -      return WINDOW_LB_THUMB; -    } -    r.y = item->window.rect.y + SCROLLBAR_SIZE; -    r.h = thumbstart - r.y; -    if (Rect_ContainsPoint(&r, x, y)) { -      return WINDOW_LB_PGUP; -    } -    r.y = thumbstart + SCROLLBAR_SIZE; -    r.h = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE; -    if (Rect_ContainsPoint(&r, x, y)) { -      return WINDOW_LB_PGDN; -    } -  } -  return 0; -} - - -void Item_ListBox_MouseEnter(itemDef_t *item, float x, float y) -{ -  rectDef_t r; -  listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData; - -  item->window.flags &= ~(WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN); -  item->window.flags |= Item_ListBox_OverLB(item, x, y); - -  if (item->window.flags & WINDOW_HORIZONTAL) { -    if (!(item->window.flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN))) { -      // check for selection hit as we have exausted buttons and thumb -      if (listPtr->elementStyle == LISTBOX_IMAGE) { -        r.x = item->window.rect.x; -        r.y = item->window.rect.y; -        r.h = item->window.rect.h - SCROLLBAR_SIZE; -        r.w = item->window.rect.w - listPtr->drawPadding; -        if (Rect_ContainsPoint(&r, x, y)) { -          listPtr->cursorPos =  (int)((x - r.x) / listPtr->elementWidth)  + listPtr->startPos; -          if (listPtr->cursorPos >= listPtr->endPos) { -            listPtr->cursorPos = listPtr->endPos; -          } -        } -      } else { -        // text hit.. -      } -    } -  } else if (!(item->window.flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN))) { -    r.x = item->window.rect.x; -    r.y = item->window.rect.y; -    r.w = item->window.rect.w - SCROLLBAR_SIZE; -    r.h = item->window.rect.h - listPtr->drawPadding; -    if (Rect_ContainsPoint(&r, x, y)) { -      listPtr->cursorPos =  (int)((y - 2 - r.y) / listPtr->elementHeight)  + listPtr->startPos; -      if (listPtr->cursorPos > listPtr->endPos) { -        listPtr->cursorPos = listPtr->endPos; -      } -    } -  } -} - -void Item_MouseEnter(itemDef_t *item, float x, float y) { -  rectDef_t r; -  if (item) { -    r = item->textRect; -    r.y -= r.h; -    // in the text rect? - -    // items can be enabled and disabled based on cvars -    if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) { -      return; -    } - -    if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(item, CVAR_SHOW)) { -      return; -    } - -    if (Rect_ContainsPoint(&r, x, y)) { -      if (!(item->window.flags & WINDOW_MOUSEOVERTEXT)) { -        Item_RunScript(item, item->mouseEnterText); -        item->window.flags |= WINDOW_MOUSEOVERTEXT; -      } -      if (!(item->window.flags & WINDOW_MOUSEOVER)) { -        Item_RunScript(item, item->mouseEnter); -        item->window.flags |= WINDOW_MOUSEOVER; -      } - -    } else { -      // not in the text rect -      if (item->window.flags & WINDOW_MOUSEOVERTEXT) { -        // if we were -        Item_RunScript(item, item->mouseExitText); -        item->window.flags &= ~WINDOW_MOUSEOVERTEXT; -      } -      if (!(item->window.flags & WINDOW_MOUSEOVER)) { -        Item_RunScript(item, item->mouseEnter); -        item->window.flags |= WINDOW_MOUSEOVER; -      } - -      if (item->type == ITEM_TYPE_LISTBOX) { -        Item_ListBox_MouseEnter(item, x, y); -      } -    } -  } -} - -void Item_MouseLeave(itemDef_t *item) { -  if (item) { -    if (item->window.flags & WINDOW_MOUSEOVERTEXT) { -      Item_RunScript(item, item->mouseExitText); -      item->window.flags &= ~WINDOW_MOUSEOVERTEXT; -    } -    Item_RunScript(item, item->mouseExit); -    item->window.flags &= ~(WINDOW_LB_RIGHTARROW | WINDOW_LB_LEFTARROW); -  } -} - -itemDef_t *Menu_HitTest(menuDef_t *menu, float x, float y) { -  int i; -  for (i = 0; i < menu->itemCount; i++) { -    if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) { -      return menu->items[i]; -    } -  } -  return NULL; -} - -void Item_SetMouseOver(itemDef_t *item, qboolean focus) { -  if (item) { -    if (focus) { -      item->window.flags |= WINDOW_MOUSEOVER; -    } else { -      item->window.flags &= ~WINDOW_MOUSEOVER; -    } -  } -} - - -qboolean Item_OwnerDraw_HandleKey(itemDef_t *item, int key) { -  if (item && DC->ownerDrawHandleKey) { -    return DC->ownerDrawHandleKey(item->window.ownerDraw, item->window.ownerDrawFlags, &item->special, key); -  } -  return qfalse; -} - -qboolean Item_ListBox_HandleKey(itemDef_t *item, int key, qboolean down, qboolean force) { -  listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData; -  int count = DC->feederCount(item->special); -  int max, viewmax; - -  if (force || (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS)) { -    max = Item_ListBox_MaxScroll(item); -    if (item->window.flags & WINDOW_HORIZONTAL) { -      viewmax = (item->window.rect.w / listPtr->elementWidth); -      if ( key == K_LEFTARROW || key == K_KP_LEFTARROW ) -      { -        if (!listPtr->notselectable) { -          listPtr->cursorPos--; -          if (listPtr->cursorPos < 0) { -            listPtr->cursorPos = 0; -          } -          if (listPtr->cursorPos < listPtr->startPos) { -            listPtr->startPos = listPtr->cursorPos; -          } -          if (listPtr->cursorPos >= listPtr->startPos + viewmax) { -            listPtr->startPos = listPtr->cursorPos - viewmax + 1; -          } -          item->cursorPos = listPtr->cursorPos; -          DC->feederSelection(item->special, item->cursorPos); -        } -        else { -          listPtr->startPos--; -          if (listPtr->startPos < 0) -            listPtr->startPos = 0; -        } -        return qtrue; -      } -      if ( key == K_RIGHTARROW || key == K_KP_RIGHTARROW ) -      { -        if (!listPtr->notselectable) { -          listPtr->cursorPos++; -          if (listPtr->cursorPos < listPtr->startPos) { -            listPtr->startPos = listPtr->cursorPos; -          } -          if (listPtr->cursorPos >= count) { -            listPtr->cursorPos = count-1; -          } -          if (listPtr->cursorPos >= listPtr->startPos + viewmax) { -            listPtr->startPos = listPtr->cursorPos - viewmax + 1; -          } -          item->cursorPos = listPtr->cursorPos; -          DC->feederSelection(item->special, item->cursorPos); -        } -        else { -          listPtr->startPos++; -          if (listPtr->startPos >= count) -            listPtr->startPos = count-1; -        } -        return qtrue; -      } -    } -    else { -      viewmax = (item->window.rect.h / listPtr->elementHeight); -      if ( key == K_UPARROW || key == K_KP_UPARROW ) -      { -        if (!listPtr->notselectable) { -          listPtr->cursorPos--; -          if (listPtr->cursorPos < 0) { -            listPtr->cursorPos = 0; -          } -          if (listPtr->cursorPos < listPtr->startPos) { -            listPtr->startPos = listPtr->cursorPos; -          } -          if (listPtr->cursorPos >= listPtr->startPos + viewmax) { -            listPtr->startPos = listPtr->cursorPos - viewmax + 1; -          } -          item->cursorPos = listPtr->cursorPos; -          DC->feederSelection(item->special, item->cursorPos); -        } -        else { -          listPtr->startPos--; -          if (listPtr->startPos < 0) -            listPtr->startPos = 0; -        } -        return qtrue; -      } -      if ( key == K_DOWNARROW || key == K_KP_DOWNARROW ) -      { -        if (!listPtr->notselectable) { -          listPtr->cursorPos++; -          if (listPtr->cursorPos < listPtr->startPos) { -            listPtr->startPos = listPtr->cursorPos; -          } -          if (listPtr->cursorPos >= count) { -            listPtr->cursorPos = count-1; -          } -          if (listPtr->cursorPos >= listPtr->startPos + viewmax) { -            listPtr->startPos = listPtr->cursorPos - viewmax + 1; -          } -          item->cursorPos = listPtr->cursorPos; -          DC->feederSelection(item->special, item->cursorPos); -        } -        else { -          listPtr->startPos++; -          if (listPtr->startPos > max) -            listPtr->startPos = max; -        } -        return qtrue; -      } -    } -    // mouse hit -    if (key == K_MOUSE1 || key == K_MOUSE2) { -      if (item->window.flags & WINDOW_LB_LEFTARROW) { -        listPtr->startPos--; -        if (listPtr->startPos < 0) { -          listPtr->startPos = 0; -        } -      } else if (item->window.flags & WINDOW_LB_RIGHTARROW) { -        // one down -        listPtr->startPos++; -        if (listPtr->startPos > max) { -          listPtr->startPos = max; -        } -      } else if (item->window.flags & WINDOW_LB_PGUP) { -        // page up -        listPtr->startPos -= viewmax; -        if (listPtr->startPos < 0) { -          listPtr->startPos = 0; -        } -      } else if (item->window.flags & WINDOW_LB_PGDN) { -        // page down -        listPtr->startPos += viewmax; -        if (listPtr->startPos > max) { -          listPtr->startPos = max; -        } -      } else if (item->window.flags & WINDOW_LB_THUMB) { -        // Display_SetCaptureItem(item); -      } else { -        // select an item -        if (DC->realTime < lastListBoxClickTime && listPtr->doubleClick) { -          Item_RunScript(item, listPtr->doubleClick); -        } -        lastListBoxClickTime = DC->realTime + DOUBLE_CLICK_DELAY; -        if (item->cursorPos != listPtr->cursorPos) { -          item->cursorPos = listPtr->cursorPos; -          DC->feederSelection(item->special, item->cursorPos); -        } -      } -      return qtrue; -    } - -    //TA: invoke the doubleClick handler when enter is pressed -    if( key == K_ENTER ) -    { -      if( listPtr->doubleClick ) -        Item_RunScript( item, listPtr->doubleClick ); - -      return qtrue; -    } - -    if ( key == K_HOME || key == K_KP_HOME) { -      // home -      listPtr->startPos = 0; -      return qtrue; -    } -    if ( key == K_END || key == K_KP_END) { -      // end -      listPtr->startPos = max; -      return qtrue; -    } -    if (key == K_PGUP || key == K_KP_PGUP ) { -      // page up -      if (!listPtr->notselectable) { -        listPtr->cursorPos -= viewmax; -        if (listPtr->cursorPos < 0) { -          listPtr->cursorPos = 0; -        } -        if (listPtr->cursorPos < listPtr->startPos) { -          listPtr->startPos = listPtr->cursorPos; -        } -        if (listPtr->cursorPos >= listPtr->startPos + viewmax) { -          listPtr->startPos = listPtr->cursorPos - viewmax + 1; -        } -        item->cursorPos = listPtr->cursorPos; -        DC->feederSelection(item->special, item->cursorPos); -      } -      else { -        listPtr->startPos -= viewmax; -        if (listPtr->startPos < 0) { -          listPtr->startPos = 0; -        } -      } -      return qtrue; -    } -    if ( key == K_PGDN || key == K_KP_PGDN ) { -      // page down -      if (!listPtr->notselectable) { -        listPtr->cursorPos += viewmax; -        if (listPtr->cursorPos < listPtr->startPos) { -          listPtr->startPos = listPtr->cursorPos; -        } -        if (listPtr->cursorPos >= count) { -          listPtr->cursorPos = count-1; -        } -        if (listPtr->cursorPos >= listPtr->startPos + viewmax) { -          listPtr->startPos = listPtr->cursorPos - viewmax + 1; -        } -        item->cursorPos = listPtr->cursorPos; -        DC->feederSelection(item->special, item->cursorPos); -      } -      else { -        listPtr->startPos += viewmax; -        if (listPtr->startPos > max) { -          listPtr->startPos = max; -        } -      } -      return qtrue; -    } -  } -  return qfalse; -} - -qboolean Item_YesNo_HandleKey(itemDef_t *item, int key) { - -  if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS && item->cvar) { -    if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3) { -      DC->setCVar(item->cvar, va("%i", !DC->getCVarValue(item->cvar))); -      return qtrue; -    } -  } - -  return qfalse; - -} - -int Item_Multi_CountSettings(itemDef_t *item) { -  multiDef_t *multiPtr = (multiDef_t*)item->typeData; -  if (multiPtr == NULL) { -    return 0; -  } -  return multiPtr->count; -} - -int Item_Multi_FindCvarByValue(itemDef_t *item) { -  char buff[1024]; -  float value = 0; -  int i; -  multiDef_t *multiPtr = (multiDef_t*)item->typeData; -  if (multiPtr) { -    if (multiPtr->strDef) { -      DC->getCVarString(item->cvar, buff, sizeof(buff)); -    } else { -      value = DC->getCVarValue(item->cvar); -    } -    for (i = 0; i < multiPtr->count; i++) { -      if (multiPtr->strDef) { -        if (Q_stricmp(buff, multiPtr->cvarStr[i]) == 0) { -          return i; -        } -      } else { -        if (multiPtr->cvarValue[i] == value) { -          return i; -        } -      } -    } -  } -  return 0; -} - -const char *Item_Multi_Setting(itemDef_t *item) { -  char buff[1024]; -  float value = 0; -  int i; -  multiDef_t *multiPtr = (multiDef_t*)item->typeData; -  if (multiPtr) { -    if (multiPtr->strDef) { -      DC->getCVarString(item->cvar, buff, sizeof(buff)); -    } else { -      value = DC->getCVarValue(item->cvar); -    } -    for (i = 0; i < multiPtr->count; i++) { -      if (multiPtr->strDef) { -        if (Q_stricmp(buff, multiPtr->cvarStr[i]) == 0) { -          return multiPtr->cvarList[i]; -        } -      } else { -        if (multiPtr->cvarValue[i] == value) { -          return multiPtr->cvarList[i]; -        } -      } -    } -  } -  return ""; -} - -qboolean Item_Multi_HandleKey(itemDef_t *item, int key) { -  multiDef_t *multiPtr = (multiDef_t*)item->typeData; -  if (multiPtr) { -    if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS && item->cvar) { -      if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3) { -        int current = Item_Multi_FindCvarByValue(item) + 1; -        int max = Item_Multi_CountSettings(item); -        if ( current < 0 || current >= max ) { -          current = 0; -        } -        if (multiPtr->strDef) { -          DC->setCVar(item->cvar, multiPtr->cvarStr[current]); -        } else { -          float value = multiPtr->cvarValue[current]; -          if (((float)((int) value)) == value) { -            DC->setCVar(item->cvar, va("%i", (int) value )); -          } -          else { -            DC->setCVar(item->cvar, va("%f", value )); -          } -        } -        return qtrue; -      } -    } -  } -  return qfalse; -} - -qboolean Item_TextField_HandleKey(itemDef_t *item, int key) { -  char buff[1024]; -  int len; -  itemDef_t *newItem = NULL; -  editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData; - -  if (item->cvar) { - -    memset(buff, 0, sizeof(buff)); -    DC->getCVarString(item->cvar, buff, sizeof(buff)); -    len = strlen(buff); -    if (editPtr->maxChars && len > editPtr->maxChars) { -      len = editPtr->maxChars; -    } -    if ( key & K_CHAR_FLAG ) { -      key &= ~K_CHAR_FLAG; - - -      if (key == 'h' - 'a' + 1 )  { // ctrl-h is backspace -        if ( item->cursorPos > 0 ) { -          memmove( &buff[item->cursorPos - 1], &buff[item->cursorPos], len + 1 - item->cursorPos); -          item->cursorPos--; -          if (item->cursorPos < editPtr->paintOffset) { -            editPtr->paintOffset--; -          } -        } -        DC->setCVar(item->cvar, buff); -          return qtrue; -      } - - -      // -      // ignore any non printable chars -      // -      if ( key < 32 || !item->cvar) { -          return qtrue; -        } - -      if (item->type == ITEM_TYPE_NUMERICFIELD) { -        if (key < '0' || key > '9') { -          return qfalse; -        } -      } - -      if (!DC->getOverstrikeMode()) { -        if (( len == MAX_EDITFIELD - 1 ) || (editPtr->maxChars && len >= editPtr->maxChars)) { -          return qtrue; -        } -        memmove( &buff[item->cursorPos + 1], &buff[item->cursorPos], len + 1 - item->cursorPos ); -      } else { -        if (editPtr->maxChars && item->cursorPos >= editPtr->maxChars) { -          return qtrue; -        } -      } - -      buff[item->cursorPos] = key; - -      DC->setCVar(item->cvar, buff); - -      if (item->cursorPos < len + 1) { -        item->cursorPos++; -        if (editPtr->maxPaintChars && item->cursorPos > editPtr->maxPaintChars) { -          editPtr->paintOffset++; -        } -      } - -    } else { - -      if ( key == K_DEL || key == K_KP_DEL ) { -        if ( item->cursorPos < len ) { -          memmove( buff + item->cursorPos, buff + item->cursorPos + 1, len - item->cursorPos); -          DC->setCVar(item->cvar, buff); -        } -        return qtrue; -      } - -      if ( key == K_RIGHTARROW || key == K_KP_RIGHTARROW ) -      { -        if (editPtr->maxPaintChars && item->cursorPos >= editPtr->maxPaintChars && item->cursorPos < len) { -          item->cursorPos++; -          editPtr->paintOffset++; -          return qtrue; -        } -        if (item->cursorPos < len) { -          item->cursorPos++; -        } -        return qtrue; -      } - -      if ( key == K_LEFTARROW || key == K_KP_LEFTARROW ) -      { -        if ( item->cursorPos > 0 ) { -          item->cursorPos--; -        } -        if (item->cursorPos < editPtr->paintOffset) { -          editPtr->paintOffset--; -        } -        return qtrue; -      } - -      if ( key == K_HOME || key == K_KP_HOME) {// || ( tolower(key) == 'a' && trap_Key_IsDown( K_CTRL ) ) ) { -        item->cursorPos = 0; -        editPtr->paintOffset = 0; -        return qtrue; -      } - -      if ( key == K_END || key == K_KP_END)  {// ( tolower(key) == 'e' && trap_Key_IsDown( K_CTRL ) ) ) { -        item->cursorPos = len; -        if(item->cursorPos > editPtr->maxPaintChars) { -          editPtr->paintOffset = len - editPtr->maxPaintChars; -        } -        return qtrue; -      } - -      if ( key == K_INS || key == K_KP_INS ) { -        DC->setOverstrikeMode(!DC->getOverstrikeMode()); -        return qtrue; -      } -    } - -    if (key == K_TAB || key == K_DOWNARROW || key == K_KP_DOWNARROW) { -      newItem = Menu_SetNextCursorItem(item->parent); -      if (newItem && (newItem->type == ITEM_TYPE_EDITFIELD || newItem->type == ITEM_TYPE_NUMERICFIELD)) { -        g_editItem = newItem; -      } -    } - -    if (key == K_UPARROW || key == K_KP_UPARROW) { -      newItem = Menu_SetPrevCursorItem(item->parent); -      if (newItem && (newItem->type == ITEM_TYPE_EDITFIELD || newItem->type == ITEM_TYPE_NUMERICFIELD)) { -        g_editItem = newItem; -      } -    } - -    if ( key == K_ENTER || key == K_KP_ENTER || key == K_ESCAPE)  { -      return qfalse; -    } - -    return qtrue; -  } -  return qfalse; - -} - -static void Scroll_ListBox_AutoFunc(void *p) { -  scrollInfo_t *si = (scrollInfo_t*)p; -  if (DC->realTime > si->nextScrollTime) { -    // need to scroll which is done by simulating a click to the item -    // this is done a bit sideways as the autoscroll "knows" that the item is a listbox -    // so it calls it directly -    Item_ListBox_HandleKey(si->item, si->scrollKey, qtrue, qfalse); -    si->nextScrollTime = DC->realTime + si->adjustValue; -  } - -  if (DC->realTime > si->nextAdjustTime) { -    si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST; -    if (si->adjustValue > SCROLL_TIME_FLOOR) { -      si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET; -    } -  } -} - -static void Scroll_ListBox_ThumbFunc(void *p) { -  scrollInfo_t *si = (scrollInfo_t*)p; -  rectDef_t r; -  int pos, max; - -  listBoxDef_t *listPtr = (listBoxDef_t*)si->item->typeData; -  if (si->item->window.flags & WINDOW_HORIZONTAL) { -    if (DC->cursorx == si->xStart) { -      return; -    } -    r.x = si->item->window.rect.x + SCROLLBAR_SIZE + 1; -    r.y = si->item->window.rect.y + si->item->window.rect.h - SCROLLBAR_SIZE - 1; -    r.h = SCROLLBAR_SIZE; -    r.w = si->item->window.rect.w - (SCROLLBAR_SIZE*2) - 2; -    max = Item_ListBox_MaxScroll(si->item); -    // -    pos = (DC->cursorx - r.x - SCROLLBAR_SIZE/2) * max / (r.w - SCROLLBAR_SIZE); -    if (pos < 0) { -      pos = 0; -    } -    else if (pos > max) { -      pos = max; -    } -    listPtr->startPos = pos; -    si->xStart = DC->cursorx; -  } -  else if (DC->cursory != si->yStart) { - -    r.x = si->item->window.rect.x + si->item->window.rect.w - SCROLLBAR_SIZE - 1; -    r.y = si->item->window.rect.y + SCROLLBAR_SIZE + 1; -    r.h = si->item->window.rect.h - (SCROLLBAR_SIZE*2) - 2; -    r.w = SCROLLBAR_SIZE; -    max = Item_ListBox_MaxScroll(si->item); -    // -    pos = (DC->cursory - r.y - SCROLLBAR_SIZE/2) * max / (r.h - SCROLLBAR_SIZE); -    if (pos < 0) { -      pos = 0; -    } -    else if (pos > max) { -      pos = max; -    } -    listPtr->startPos = pos; -    si->yStart = DC->cursory; -  } - -  if (DC->realTime > si->nextScrollTime) { -    // need to scroll which is done by simulating a click to the item -    // this is done a bit sideways as the autoscroll "knows" that the item is a listbox -    // so it calls it directly -    Item_ListBox_HandleKey(si->item, si->scrollKey, qtrue, qfalse); -    si->nextScrollTime = DC->realTime + si->adjustValue; -  } - -  if (DC->realTime > si->nextAdjustTime) { -    si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST; -    if (si->adjustValue > SCROLL_TIME_FLOOR) { -      si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET; -    } -  } -} - -static void Scroll_Slider_ThumbFunc(void *p) { -  float x, value, cursorx; -  scrollInfo_t *si = (scrollInfo_t*)p; -  editFieldDef_t *editDef = si->item->typeData; - -  if (si->item->text) { -    x = si->item->textRect.x + si->item->textRect.w + 8; -  } else { -    x = si->item->window.rect.x; -  } - -  cursorx = DC->cursorx; - -  if (cursorx < x) { -    cursorx = x; -  } else if (cursorx > x + SLIDER_WIDTH) { -    cursorx = x + SLIDER_WIDTH; -  } -  value = cursorx - x; -  value /= SLIDER_WIDTH; -  value *= (editDef->maxVal - editDef->minVal); -  value += editDef->minVal; -  DC->setCVar(si->item->cvar, va("%f", value)); -} - -void Item_StartCapture(itemDef_t *item, int key) { -  int flags; -  switch (item->type) { -    case ITEM_TYPE_EDITFIELD: -    case ITEM_TYPE_NUMERICFIELD: - -    case ITEM_TYPE_LISTBOX: -    { -      flags = Item_ListBox_OverLB(item, DC->cursorx, DC->cursory); -      if (flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW)) { -        scrollInfo.nextScrollTime = DC->realTime + SCROLL_TIME_START; -        scrollInfo.nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST; -        scrollInfo.adjustValue = SCROLL_TIME_START; -        scrollInfo.scrollKey = key; -        scrollInfo.scrollDir = (flags & WINDOW_LB_LEFTARROW) ? qtrue : qfalse; -        scrollInfo.item = item; -        captureData = &scrollInfo; -        captureFunc = &Scroll_ListBox_AutoFunc; -        itemCapture = item; -      } else if (flags & WINDOW_LB_THUMB) { -        scrollInfo.scrollKey = key; -        scrollInfo.item = item; -        scrollInfo.xStart = DC->cursorx; -        scrollInfo.yStart = DC->cursory; -        captureData = &scrollInfo; -        captureFunc = &Scroll_ListBox_ThumbFunc; -        itemCapture = item; -      } -      break; -    } -    case ITEM_TYPE_SLIDER: -    { -      flags = Item_Slider_OverSlider(item, DC->cursorx, DC->cursory); -      if (flags & WINDOW_LB_THUMB) { -        scrollInfo.scrollKey = key; -        scrollInfo.item = item; -        scrollInfo.xStart = DC->cursorx; -        scrollInfo.yStart = DC->cursory; -        captureData = &scrollInfo; -        captureFunc = &Scroll_Slider_ThumbFunc; -        itemCapture = item; -      } -      break; -    } -  } -} - -void Item_StopCapture(itemDef_t *item) { - -} - -qboolean Item_Slider_HandleKey(itemDef_t *item, int key, qboolean down) { -  float x, value, width, work; - -  //DC->Print("slider handle key\n"); -  if (item->window.flags & WINDOW_HASFOCUS && item->cvar && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) { -    if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3) { -      editFieldDef_t *editDef = item->typeData; -      if (editDef) { -        rectDef_t testRect; -        width = SLIDER_WIDTH; -        if (item->text) { -          x = item->textRect.x + item->textRect.w + 8; -        } else { -          x = item->window.rect.x; -        } - -        testRect = item->window.rect; -        testRect.x = x; -        value = (float)SLIDER_THUMB_WIDTH / 2; -        testRect.x -= value; -        //DC->Print("slider x: %f\n", testRect.x); -        testRect.w = (SLIDER_WIDTH + (float)SLIDER_THUMB_WIDTH / 2); -        //DC->Print("slider w: %f\n", testRect.w); -        if (Rect_ContainsPoint(&testRect, DC->cursorx, DC->cursory)) { -          work = DC->cursorx - x; -          value = work / width; -          value *= (editDef->maxVal - editDef->minVal); -          // vm fuckage -          // value = (((float)(DC->cursorx - x)/ SLIDER_WIDTH) * (editDef->maxVal - editDef->minVal)); -          value += editDef->minVal; -          DC->setCVar(item->cvar, va("%f", value)); -          return qtrue; -        } -      } -    } -  } -  DC->Print("slider handle key exit\n"); -  return qfalse; -} - - -qboolean Item_HandleKey(itemDef_t *item, int key, qboolean down) { - -  if (itemCapture) { -    Item_StopCapture(itemCapture); -    itemCapture = NULL; -    captureFunc = voidFunction; -    captureData = NULL; -  } else { -    // bk001206 - parentheses -    if ( down && ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3 ) ) { -      Item_StartCapture(item, key); -    } -  } - -  if (!down) { -    return qfalse; -  } - -  switch (item->type) { -    case ITEM_TYPE_BUTTON: -      return qfalse; -      break; -    case ITEM_TYPE_RADIOBUTTON: -      return qfalse; -      break; -    case ITEM_TYPE_CHECKBOX: -      return qfalse; -      break; -    case ITEM_TYPE_EDITFIELD: -    case ITEM_TYPE_NUMERICFIELD: -      //return Item_TextField_HandleKey(item, key); -      return qfalse; -      break; -    case ITEM_TYPE_COMBO: -      return qfalse; -      break; -    case ITEM_TYPE_LISTBOX: -      return Item_ListBox_HandleKey(item, key, down, qfalse); -      break; -    case ITEM_TYPE_YESNO: -      return Item_YesNo_HandleKey(item, key); -      break; -    case ITEM_TYPE_MULTI: -      return Item_Multi_HandleKey(item, key); -      break; -    case ITEM_TYPE_OWNERDRAW: -      return Item_OwnerDraw_HandleKey(item, key); -      break; -    case ITEM_TYPE_BIND: -      return Item_Bind_HandleKey(item, key, down); -      break; -    case ITEM_TYPE_SLIDER: -      return Item_Slider_HandleKey(item, key, down); -      break; -    //case ITEM_TYPE_IMAGE: -    //  Item_Image_Paint(item); -    //  break; -    default: -      return qfalse; -      break; -  } - -  //return qfalse; -} - -void Item_Action(itemDef_t *item) { -  if (item) { -    Item_RunScript(item, item->action); -  } -} - -itemDef_t *Menu_SetPrevCursorItem(menuDef_t *menu) { -  qboolean wrapped = qfalse; -  int oldCursor = menu->cursorItem; - -  if (menu->cursorItem < 0) { -    menu->cursorItem = menu->itemCount-1; -    wrapped = qtrue; -  } - -  while (menu->cursorItem > -1) { - -    menu->cursorItem--; -    if (menu->cursorItem < 0 && !wrapped) { -      wrapped = qtrue; -      menu->cursorItem = menu->itemCount -1; -    } - -    if (Item_SetFocus(menu->items[menu->cursorItem], DC->cursorx, DC->cursory)) { -      Menu_HandleMouseMove(menu, menu->items[menu->cursorItem]->window.rect.x + 1, menu->items[menu->cursorItem]->window.rect.y + 1); -      return menu->items[menu->cursorItem]; -    } -  } -  menu->cursorItem = oldCursor; -  return NULL; - -} - -itemDef_t *Menu_SetNextCursorItem(menuDef_t *menu) { - -  qboolean wrapped = qfalse; -  int oldCursor = menu->cursorItem; - - -  if (menu->cursorItem == -1) { -    menu->cursorItem = 0; -    wrapped = qtrue; -  } - -  while (menu->cursorItem < menu->itemCount) { - -    menu->cursorItem++; -    if (menu->cursorItem >= menu->itemCount && !wrapped) { -      wrapped = qtrue; -      menu->cursorItem = 0; -    } -    if (Item_SetFocus(menu->items[menu->cursorItem], DC->cursorx, DC->cursory)) { -      Menu_HandleMouseMove(menu, menu->items[menu->cursorItem]->window.rect.x + 1, menu->items[menu->cursorItem]->window.rect.y + 1); -      return menu->items[menu->cursorItem]; -    } - -  } - -  menu->cursorItem = oldCursor; -  return NULL; -} - -static void Window_CloseCinematic(windowDef_t *window) { -  if (window->style == WINDOW_STYLE_CINEMATIC && window->cinematic >= 0) { -    DC->stopCinematic(window->cinematic); -    window->cinematic = -1; -  } -} - -static void Menu_CloseCinematics(menuDef_t *menu) { -  if (menu) { -    int i; -    Window_CloseCinematic(&menu->window); -    for (i = 0; i < menu->itemCount; i++) { -      Window_CloseCinematic(&menu->items[i]->window); -      if (menu->items[i]->type == ITEM_TYPE_OWNERDRAW) { -        DC->stopCinematic(0-menu->items[i]->window.ownerDraw); -      } -    } -  } -} - -static void Display_CloseCinematics( void ) { -  int i; -  for (i = 0; i < menuCount; i++) { -    Menu_CloseCinematics(&Menus[i]); -  } -} - -void  Menus_Activate(menuDef_t *menu) { -  menu->window.flags |= (WINDOW_HASFOCUS | WINDOW_VISIBLE); -  if (menu->onOpen) { -    itemDef_t item; -    item.parent = menu; -    Item_RunScript(&item, menu->onOpen); -  } - -  if (menu->soundName && *menu->soundName) { -//    DC->stopBackgroundTrack();          // you don't want to do this since it will reset s_rawend -    DC->startBackgroundTrack(menu->soundName, menu->soundName); -  } - -  Display_CloseCinematics(); - -} - -int Display_VisibleMenuCount( void ) { -  int i, count; -  count = 0; -  for (i = 0; i < menuCount; i++) { -    if (Menus[i].window.flags & (WINDOW_FORCED | WINDOW_VISIBLE)) { -      count++; -    } -  } -  return count; -} - -void Menus_HandleOOBClick(menuDef_t *menu, int key, qboolean down) { -  if (menu) { -    int i; -    // basically the behaviour we are looking for is if there are windows in the stack.. see if -    // the cursor is within any of them.. if not close them otherwise activate them and pass the -    // key on.. force a mouse move to activate focus and script stuff -    if (down && menu->window.flags & WINDOW_OOB_CLICK) { -      Menu_RunCloseScript(menu); -      menu->window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE); -    } - -    for (i = 0; i < menuCount; i++) { -      if (Menu_OverActiveItem(&Menus[i], DC->cursorx, DC->cursory)) { -        Menu_RunCloseScript(menu); -        menu->window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE); -        Menus_Activate(&Menus[i]); -        Menu_HandleMouseMove(&Menus[i], DC->cursorx, DC->cursory); -        Menu_HandleKey(&Menus[i], key, down); -      } -    } - -    if (Display_VisibleMenuCount() == 0) { -      if (DC->Pause) { -        DC->Pause(qfalse); -      } -    } -    Display_CloseCinematics(); -  } -} - -static rectDef_t *Item_CorrectedTextRect(itemDef_t *item) { -  static rectDef_t rect; -  memset(&rect, 0, sizeof(rectDef_t)); -  if (item) { -    rect = item->textRect; -    if (rect.w) { -      rect.y -= rect.h; -    } -  } -  return ▭ -} - -void Menu_HandleKey(menuDef_t *menu, int key, qboolean down) { -  int i; -  itemDef_t *item = NULL; -  qboolean inHandler = qfalse; - -  if (inHandler) { -    return; -  } - -  inHandler = qtrue; -  if (g_waitingForKey && down) { -    Item_Bind_HandleKey(g_bindItem, key, down); -    inHandler = qfalse; -    return; -  } - -  if (g_editingField && down) { -    if (!Item_TextField_HandleKey(g_editItem, key)) { -      g_editingField = qfalse; -      g_editItem = NULL; -      inHandler = qfalse; -      return; -    } else if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) { -      g_editingField = qfalse; -      g_editItem = NULL; -      Display_MouseMove(NULL, DC->cursorx, DC->cursory); -    } else if (key == K_TAB || key == K_UPARROW || key == K_DOWNARROW) { -      return; -    } -  } - -  if (menu == NULL) { -    inHandler = qfalse; -    return; -  } - -    // see if the mouse is within the window bounds and if so is this a mouse click -  if (down && !(menu->window.flags & WINDOW_POPUP) && !Rect_ContainsPoint(&menu->window.rect, DC->cursorx, DC->cursory)) { -    static qboolean inHandleKey = qfalse; -    // bk001206 - parentheses -    if (!inHandleKey && ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3 ) ) { -      inHandleKey = qtrue; -      Menus_HandleOOBClick(menu, key, down); -      inHandleKey = qfalse; -      inHandler = qfalse; -      return; -    } -  } - -  // get the item with focus -  for (i = 0; i < menu->itemCount; i++) { -    if (menu->items[i]->window.flags & WINDOW_HASFOCUS) { -      item = menu->items[i]; -    } -  } - -  if (item != NULL) { -    if (Item_HandleKey(item, key, down)) { -      Item_Action(item); -      inHandler = qfalse; -      return; -    } -  } - -  if (!down) { -    inHandler = qfalse; -    return; -  } - -  // default handling -  switch ( key ) { - -    case K_F11: -      if (DC->getCVarValue("developer")) { -        debugMode ^= 1; -      } -      break; - -    case K_F12: -      if (DC->getCVarValue("developer")) { -        DC->executeText(EXEC_APPEND, "screenshot\n"); -      } -      break; -    case K_KP_UPARROW: -    case K_UPARROW: -      Menu_SetPrevCursorItem(menu); -      break; - -    case K_ESCAPE: -      if (!g_waitingForKey && menu->onESC) { -        itemDef_t it; -        it.parent = menu; -        Item_RunScript(&it, menu->onESC); -      } -      break; -    case K_TAB: -    case K_KP_DOWNARROW: -    case K_DOWNARROW: -      Menu_SetNextCursorItem(menu); -      break; - -    case K_MOUSE1: -    case K_MOUSE2: -      if (item) { -        if (item->type == ITEM_TYPE_TEXT) { -          if (Rect_ContainsPoint(Item_CorrectedTextRect(item), DC->cursorx, DC->cursory)) { -            Item_Action(item); -          } -        } else if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_NUMERICFIELD) { -          if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) { -            item->cursorPos = 0; -            g_editingField = qtrue; -            g_editItem = item; -            DC->setOverstrikeMode(qtrue); -          } -        } else { -          if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) { -            Item_Action(item); -          } -        } -      } -      break; - -    case K_JOY1: -    case K_JOY2: -    case K_JOY3: -    case K_JOY4: -    case K_AUX1: -    case K_AUX2: -    case K_AUX3: -    case K_AUX4: -    case K_AUX5: -    case K_AUX6: -    case K_AUX7: -    case K_AUX8: -    case K_AUX9: -    case K_AUX10: -    case K_AUX11: -    case K_AUX12: -    case K_AUX13: -    case K_AUX14: -    case K_AUX15: -    case K_AUX16: -      break; -    case K_KP_ENTER: -    case K_ENTER: -      if (item) { -        if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_NUMERICFIELD) { -          item->cursorPos = 0; -          g_editingField = qtrue; -          g_editItem = item; -          DC->setOverstrikeMode(qtrue); -        } else { -            Item_Action(item); -        } -      } -      break; -  } -  inHandler = qfalse; -} - -void ToWindowCoords(float *x, float *y, windowDef_t *window) { -  if (window->border != 0) { -    *x += window->borderSize; -    *y += window->borderSize; -  } -  *x += window->rect.x; -  *y += window->rect.y; -} - -void Rect_ToWindowCoords(rectDef_t *rect, windowDef_t *window) { -  ToWindowCoords(&rect->x, &rect->y, window); -} - -void Item_SetTextExtents(itemDef_t *item, int *width, int *height, const char *text) { -  const char *textPtr = (text) ? text : item->text; - -  if (textPtr == NULL ) { -    return; -  } - -  *width = item->textRect.w; -  *height = item->textRect.h; - -  // keeps us from computing the widths and heights more than once -  if (*width == 0 || (item->type == ITEM_TYPE_OWNERDRAW && item->textalignment == ITEM_ALIGN_CENTER)) { -    int originalWidth = DC->textWidth(item->text, item->textscale, 0); - -    if (item->type == ITEM_TYPE_OWNERDRAW && (item->textalignment == ITEM_ALIGN_CENTER || item->textalignment == ITEM_ALIGN_RIGHT)) { -      originalWidth += DC->ownerDrawWidth(item->window.ownerDraw, item->textscale); -    } else if (item->type == ITEM_TYPE_EDITFIELD && item->textalignment == ITEM_ALIGN_CENTER && item->cvar) { -      char buff[256]; -      DC->getCVarString(item->cvar, buff, 256); -      originalWidth += DC->textWidth(buff, item->textscale, 0); -    } - -    *width = DC->textWidth(textPtr, item->textscale, 0); -    *height = DC->textHeight(textPtr, item->textscale, 0); -    item->textRect.w = *width; -    item->textRect.h = *height; -    item->textRect.x = item->textalignx; -    item->textRect.y = item->textaligny; -    if (item->textalignment == ITEM_ALIGN_RIGHT) { -      item->textRect.x = item->textalignx - originalWidth; -    } else if (item->textalignment == ITEM_ALIGN_CENTER) { -      item->textRect.x = item->textalignx - originalWidth / 2; -    } - -    ToWindowCoords(&item->textRect.x, &item->textRect.y, &item->window); -  } -} - -void Item_TextColor(itemDef_t *item, vec4_t *newColor) { -  vec4_t lowLight; -  menuDef_t *parent = (menuDef_t*)item->parent; - -  Fade(&item->window.flags, &item->window.foreColor[3], parent->fadeClamp, &item->window.nextTime, parent->fadeCycle, qtrue, parent->fadeAmount); - -  if (item->window.flags & WINDOW_HASFOCUS) { -/*    lowLight[0] = 0.8 * parent->focusColor[0]; -    lowLight[1] = 0.8 * parent->focusColor[1]; -    lowLight[2] = 0.8 * parent->focusColor[2]; -    lowLight[3] = 0.8 * parent->focusColor[3]; -    LerpColor(parent->focusColor,lowLight,*newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/ -    //TA: -    memcpy(newColor, &parent->focusColor, sizeof(vec4_t)); -  } else if (item->textStyle == ITEM_TEXTSTYLE_BLINK && !((DC->realTime/BLINK_DIVISOR) & 1)) { -    lowLight[0] = 0.8 * item->window.foreColor[0]; -    lowLight[1] = 0.8 * item->window.foreColor[1]; -    lowLight[2] = 0.8 * item->window.foreColor[2]; -    lowLight[3] = 0.8 * item->window.foreColor[3]; -    LerpColor(item->window.foreColor,lowLight,*newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR)); -  } else { -    memcpy(newColor, &item->window.foreColor, sizeof(vec4_t)); -    // items can be enabled and disabled based on cvars -  } - -  if (item->enableCvar != NULL && *item->enableCvar && item->cvarTest != NULL && *item->cvarTest) { -    if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) { -      memcpy(newColor, &parent->disableColor, sizeof(vec4_t)); -    } -  } -} - -int Item_Text_AutoWrapped_Lines( itemDef_t *item ) -{ -  char        text[ 1024 ]; -  const char  *p, *textPtr, *newLinePtr; -  char        buff[ 1024 ]; -  int         len, textWidth, newLine; -  int         lines = 0; - -  textWidth = 0; -  newLinePtr = NULL; - -  if( item->text == NULL ) -  { -    if( item->cvar == NULL ) -      return 0; -    else -    { -      DC->getCVarString( item->cvar, text, sizeof( text ) ); -      textPtr = text; -    } -  } -  else -    textPtr = item->text; - -  if( *textPtr == '\0' ) -    return 0; - -  len = 0; -  buff[ 0 ] = '\0'; -  newLine = 0; -  p = textPtr; - -  while( p ) -  { -    textWidth = DC->textWidth( buff, item->textscale, 0 ); - -    if( *p == ' ' || *p == '\t' || *p == '\n' || *p == '\0' ) -    { -      newLine = len; -      newLinePtr = p + 1; -    } - -    //TA: forceably split lines that are too long (where normal splitage has failed) -    if( textWidth > item->window.rect.w && newLine == 0 && *p != '\n' ) -    { -      newLine = len; -      newLinePtr = p; -    } - -    if( ( newLine && textWidth > item->window.rect.w ) || *p == '\n' || *p == '\0' ) -    { -      if( len ) -        buff[ newLine ] = '\0'; - -      if( !( *p == '\n' && !*( p + 1 ) ) ) -        lines++; - -      if( *p == '\0' ) -        break; - -      // -      p = newLinePtr; -      len = 0; -      newLine = 0; - -      continue; -    } - -    buff[ len++ ] = *p++; -    buff[ len ] = '\0'; -  } - -  return lines; -} - -#define MAX_AUTOWRAP_CACHE  16 -#define MAX_AUTOWRAP_LINES  32 -#define MAX_AUTOWRAP_TEXT   512 - -typedef struct -{ -  //this is used purely for checking for cache hits -  char      text[ MAX_AUTOWRAP_TEXT * MAX_AUTOWRAP_LINES ]; -  rectDef_t rect; -  int       textWidth, textHeight; -  char      lines[ MAX_AUTOWRAP_LINES ][ MAX_AUTOWRAP_TEXT ]; -  int       lineOffsets[ MAX_AUTOWRAP_LINES ][ 2 ]; -  int       numLines; -} autoWrapCache_t; - -static int              cacheIndex = 0; -static autoWrapCache_t  awc[ MAX_AUTOWRAP_CACHE ]; - -static int checkCache( const char *text, rectDef_t *rect, int width, int height ) -{ -  int i; - -  for( i = 0; i < MAX_AUTOWRAP_CACHE; i++ ) -  { -    if( Q_stricmp( text, awc[ i ].text ) ) -      continue; - -    if( rect->x != awc[ i ].rect.x || -        rect->y != awc[ i ].rect.y || -        rect->w != awc[ i ].rect.w || -        rect->h != awc[ i ].rect.h ) -      continue; - -    if( awc[ i ].textWidth != width || awc[ i ].textHeight != height ) -      continue; - -    //this is a match -    return i; -  } - -  //no match - autowrap isn't cached -  return -1; -} - -void Item_Text_AutoWrapped_Paint( itemDef_t *item ) -{ -  char        text[ 1024 ]; -  const char  *p, *textPtr, *newLinePtr; -  char        buff[ 1024 ]; -  char        lastCMod[ 2 ] = { 0, 0 }; -  qboolean    forwardColor = qfalse; -  int         width, height, len, textWidth, newLine, newLineWidth; -  int         skipLines, totalLines, lineNum = 0; -  float       y, totalY, diffY; -  vec4_t      color; -  int         cache, i; - -  textWidth = 0; -  newLinePtr = NULL; - -  if( item->text == NULL ) -  { -    if( item->cvar == NULL ) -      return; -    else -    { -      DC->getCVarString( item->cvar, text, sizeof( text ) ); -      textPtr = text; -    } -  } -  else -    textPtr = item->text; - -  if( *textPtr == '\0' ) -    return; - -  Item_TextColor( item, &color ); -  Item_SetTextExtents( item, &width, &height, textPtr ); - -  //check if this block is cached -  cache = checkCache( textPtr, &item->window.rect, width, height ); -  if( cache >= 0 ) -  { -    lineNum = awc[ cache ].numLines; - -    for( i = 0; i < lineNum; i++ ) -    { -      item->textRect.x = awc[ cache ].lineOffsets[ i ][ 0 ]; -      item->textRect.y = awc[ cache ].lineOffsets[ i ][ 1 ]; - -      DC->drawText( item->textRect.x, item->textRect.y, item->textscale, color, -                    awc[ cache ].lines[ i ], 0, 0, item->textStyle ); -    } -  } -  else -  { -    y = item->textaligny; -    len = 0; -    buff[ 0 ] = '\0'; -    newLine = 0; -    newLineWidth = 0; -    p = textPtr; - -    totalLines = Item_Text_AutoWrapped_Lines( item ); - -    totalY = totalLines * ( height + 5 ); -    diffY = totalY - item->window.rect.h; - -    if( diffY > 0.0f ) -      skipLines = (int)( diffY / ( (float)height + 5.0f ) ); -    else -      skipLines = 0; - -    //set up a cache entry -    strcpy( awc[ cacheIndex ].text, textPtr ); -    awc[ cacheIndex ].rect.x = item->window.rect.x; -    awc[ cacheIndex ].rect.y = item->window.rect.y; -    awc[ cacheIndex ].rect.w = item->window.rect.w; -    awc[ cacheIndex ].rect.h = item->window.rect.h; -    awc[ cacheIndex ].textWidth = width; -    awc[ cacheIndex ].textHeight = height; - -    while( p ) -    { -      textWidth = DC->textWidth( buff, item->textscale, 0 ); - -      if( *p == '^' ) -      { -        lastCMod[ 0 ] = p[ 0 ]; -        lastCMod[ 1 ] = p[ 1 ]; -      } - -      if( *p == ' ' || *p == '\t' || *p == '\n' || *p == '\0' ) -      { -        newLine = len; -        newLinePtr = p+1; -        newLineWidth = textWidth; - -        if( *p == '\n' ) //don't forward colours past deilberate \n's -          lastCMod[ 0 ] = lastCMod[ 1 ] = 0; -        else -          forwardColor = qtrue; -      } - -      //TA: forceably split lines that are too long (where normal splitage has failed) -      if( textWidth > item->window.rect.w && newLine == 0 && *p != '\n' ) -      { -        newLine = len; -        newLinePtr = p; -        newLineWidth = textWidth; - -        forwardColor = qtrue; -      } - -      if( ( newLine && textWidth > item->window.rect.w ) || *p == '\n' || *p == '\0' ) -      { -        if( len ) -        { -          if( item->textalignment == ITEM_ALIGN_LEFT ) -            item->textRect.x = item->textalignx; -          else if( item->textalignment == ITEM_ALIGN_RIGHT ) -            item->textRect.x = item->textalignx - newLineWidth; -          else if( item->textalignment == ITEM_ALIGN_CENTER ) -            item->textRect.x = item->textalignx - newLineWidth / 2; - -          item->textRect.y = y; -          ToWindowCoords( &item->textRect.x, &item->textRect.y, &item->window ); -          // -          buff[ newLine ] = '\0'; - -          if( !skipLines ) -          { -            DC->drawText( item->textRect.x, item->textRect.y, item->textscale, color, buff, 0, 0, item->textStyle ); - -            strcpy( awc[ cacheIndex ].lines[ lineNum ], buff ); -            awc[ cacheIndex ].lineOffsets[ lineNum ][ 0 ] = item->textRect.x; -            awc[ cacheIndex ].lineOffsets[ lineNum ][ 1 ] = item->textRect.y; - -            lineNum++; -          } -        } -        if( *p == '\0' ) -          break; - -        // -        if( !skipLines ) -          y += height + 5; - -        if( skipLines ) -          skipLines--; - -        p = newLinePtr; -        len = 0; -        newLine = 0; -        newLineWidth = 0; - -        if( forwardColor && lastCMod[ 0 ] != 0 ) -        { -          buff[ len++ ] = lastCMod[ 0 ]; -          buff[ len++ ] = lastCMod[ 1 ]; -          buff[ len ] = '\0'; - -          forwardColor = qfalse; -        } - -        continue; -      } - -      buff[ len++ ] = *p++; -      buff[ len ] = '\0'; -    } - -    //mark the end of the lines list -    awc[ cacheIndex ].numLines = lineNum; - -    //increment cacheIndex -    cacheIndex = ( cacheIndex + 1 ) % MAX_AUTOWRAP_CACHE; -  } -} - -void Item_Text_Wrapped_Paint(itemDef_t *item) { -  char text[1024]; -  const char *p, *start, *textPtr; -  char buff[1024]; -  int width, height; -  float x, y; -  vec4_t color; - -  // now paint the text and/or any optional images -  // default to left - -  if (item->text == NULL) { -    if (item->cvar == NULL) { -      return; -    } -    else { -      DC->getCVarString(item->cvar, text, sizeof(text)); -      textPtr = text; -    } -  } -  else { -    textPtr = item->text; -  } -  if (*textPtr == '\0') { -    return; -  } - -  Item_TextColor(item, &color); -  Item_SetTextExtents(item, &width, &height, textPtr); - -  x = item->textRect.x; -  y = item->textRect.y; -  start = textPtr; -  p = strchr(textPtr, '\r'); -  while (p && *p) { -    strncpy(buff, start, p-start+1); -    buff[p-start] = '\0'; -    DC->drawText(x, y, item->textscale, color, buff, 0, 0, item->textStyle); -    y += height + 5; -    start += p - start + 1; -    p = strchr(p+1, '\r'); -  } -  DC->drawText(x, y, item->textscale, color, start, 0, 0, item->textStyle); -} - -void Item_Text_Paint(itemDef_t *item) { -  char text[1024]; -  const char *textPtr; -  int height, width; -  vec4_t color; - -  if (item->window.flags & WINDOW_WRAPPED) { -    Item_Text_Wrapped_Paint(item); -    return; -  } -  if (item->window.flags & WINDOW_AUTOWRAPPED) { -    Item_Text_AutoWrapped_Paint(item); -    return; -  } - -  if (item->text == NULL) { -    if (item->cvar == NULL) { -      return; -    } -    else { -      DC->getCVarString(item->cvar, text, sizeof(text)); -      textPtr = text; -    } -  } -  else { -    textPtr = item->text; -  } - -  // this needs to go here as it sets extents for cvar types as well -  Item_SetTextExtents(item, &width, &height, textPtr); - -  if (*textPtr == '\0') { -    return; -  } - - -  Item_TextColor(item, &color); - -  //FIXME: this is a fucking mess -/* -  adjust = 0; -  if (item->textStyle == ITEM_TEXTSTYLE_OUTLINED || item->textStyle == ITEM_TEXTSTYLE_OUTLINESHADOWED) { -    adjust = 0.5; -  } - -  if (item->textStyle == ITEM_TEXTSTYLE_SHADOWED || item->textStyle == ITEM_TEXTSTYLE_OUTLINESHADOWED) { -    Fade(&item->window.flags, &DC->Assets.shadowColor[3], DC->Assets.fadeClamp, &item->window.nextTime, DC->Assets.fadeCycle, qfalse); -    DC->drawText(item->textRect.x + DC->Assets.shadowX, item->textRect.y + DC->Assets.shadowY, item->textscale, DC->Assets.shadowColor, textPtr, adjust); -  } -*/ - - -//  if (item->textStyle == ITEM_TEXTSTYLE_OUTLINED || item->textStyle == ITEM_TEXTSTYLE_OUTLINESHADOWED) { -//    Fade(&item->window.flags, &item->window.outlineColor[3], DC->Assets.fadeClamp, &item->window.nextTime, DC->Assets.fadeCycle, qfalse); -//    /* -//    Text_Paint(item->textRect.x-1, item->textRect.y-1, item->textscale, item->window.foreColor, textPtr, adjust); -//    Text_Paint(item->textRect.x, item->textRect.y-1, item->textscale, item->window.foreColor, textPtr, adjust); -//    Text_Paint(item->textRect.x+1, item->textRect.y-1, item->textscale, item->window.foreColor, textPtr, adjust); -//    Text_Paint(item->textRect.x-1, item->textRect.y, item->textscale, item->window.foreColor, textPtr, adjust); -//    Text_Paint(item->textRect.x+1, item->textRect.y, item->textscale, item->window.foreColor, textPtr, adjust); -//    Text_Paint(item->textRect.x-1, item->textRect.y+1, item->textscale, item->window.foreColor, textPtr, adjust); -//    Text_Paint(item->textRect.x, item->textRect.y+1, item->textscale, item->window.foreColor, textPtr, adjust); -//    Text_Paint(item->textRect.x+1, item->textRect.y+1, item->textscale, item->window.foreColor, textPtr, adjust); -//    */ -//    DC->drawText(item->textRect.x - 1, item->textRect.y + 1, item->textscale * 1.02, item->window.outlineColor, textPtr, adjust); -//  } - -  DC->drawText(item->textRect.x, item->textRect.y, item->textscale, color, textPtr, 0, 0, item->textStyle); -} - - - -//float     trap_Cvar_VariableValue( const char *var_name ); -//void      trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ); - -void Item_TextField_Paint(itemDef_t *item) { -  char buff[1024]; -  vec4_t newColor; -  int offset; -  menuDef_t *parent = (menuDef_t*)item->parent; -  editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData; - -  Item_Text_Paint(item); - -  buff[0] = '\0'; - -  if (item->cvar) { -    DC->getCVarString(item->cvar, buff, sizeof(buff)); -  } - -  parent = (menuDef_t*)item->parent; - -  if (item->window.flags & WINDOW_HASFOCUS) { -/*    lowLight[0] = 0.8 * parent->focusColor[0]; -    lowLight[1] = 0.8 * parent->focusColor[1]; -    lowLight[2] = 0.8 * parent->focusColor[2]; -    lowLight[3] = 0.8 * parent->focusColor[3]; -    LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/ -    //TA: -    memcpy(newColor, &parent->focusColor, sizeof(vec4_t)); -  } else { -    memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t)); -  } - -  offset = (item->text && *item->text) ? 8 : 0; -  if (item->window.flags & WINDOW_HASFOCUS && g_editingField) { -    char cursor = DC->getOverstrikeMode() ? '_' : '|'; -    DC->drawTextWithCursor(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor, buff + editPtr->paintOffset, item->cursorPos - editPtr->paintOffset , cursor, editPtr->maxPaintChars, item->textStyle); -  } else { -    DC->drawText(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor, buff + editPtr->paintOffset, 0, editPtr->maxPaintChars, item->textStyle); -  } - -} - -void Item_YesNo_Paint(itemDef_t *item) { -  vec4_t newColor; -  float value; -  menuDef_t *parent = (menuDef_t*)item->parent; - -  value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0; - -  if (item->window.flags & WINDOW_HASFOCUS) { -/*    lowLight[0] = 0.8 * parent->focusColor[0]; -    lowLight[1] = 0.8 * parent->focusColor[1]; -    lowLight[2] = 0.8 * parent->focusColor[2]; -    lowLight[3] = 0.8 * parent->focusColor[3]; -    LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/ -    //TA: -    memcpy(newColor, &parent->focusColor, sizeof(vec4_t)); -  } else { -    memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t)); -  } - -  if (item->text) { -    Item_Text_Paint(item); -    DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, (value != 0) ? "Yes" : "No", 0, 0, item->textStyle); -  } else { -    DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, (value != 0) ? "Yes" : "No", 0, 0, item->textStyle); -  } -} - -void Item_Multi_Paint(itemDef_t *item) { -  vec4_t newColor; -  const char *text = ""; -  menuDef_t *parent = (menuDef_t*)item->parent; - -  if (item->window.flags & WINDOW_HASFOCUS) { -/*    lowLight[0] = 0.8 * parent->focusColor[0]; -    lowLight[1] = 0.8 * parent->focusColor[1]; -    lowLight[2] = 0.8 * parent->focusColor[2]; -    lowLight[3] = 0.8 * parent->focusColor[3]; -    LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/ -    //TA: -    memcpy(newColor, &parent->focusColor, sizeof(vec4_t)); -  } else { -    memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t)); -  } - -  text = Item_Multi_Setting(item); - -  if (item->text) { -    Item_Text_Paint(item); -    DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, text, 0, 0, item->textStyle); -  } else { -    DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, text, 0, 0, item->textStyle); -  } -} - - -typedef struct { -  char  *command; -  int   id; -  int   defaultbind1; -  int   defaultbind2; -  int   bind1; -  int   bind2; -} bind_t; - -typedef struct -{ -  char* name; -  float defaultvalue; -  float value; -} configcvar_t; - - -static bind_t g_bindings[] = -{ -  { "+scores",      K_TAB,         -1, -1, -1 }, -  { "+button2",     K_ENTER,       -1, -1, -1 }, -  { "+speed",       K_SHIFT,       -1, -1, -1 }, -  { "boost",        'x',           -1, -1, -1 }, //TA: human sprinting -  { "+forward",     K_UPARROW,     -1, -1, -1 }, -  { "+back",        K_DOWNARROW,   -1, -1, -1 }, -  { "+moveleft",    ',',           -1, -1, -1 }, -  { "+moveright",   '.',           -1, -1, -1 }, -  { "+moveup",      K_SPACE,       -1, -1, -1 }, -  { "+movedown",    'c',           -1, -1, -1 }, -  { "+left",        K_LEFTARROW,   -1, -1, -1 }, -  { "+right",       K_RIGHTARROW,  -1, -1, -1 }, -  { "+strafe",      K_ALT,         -1, -1, -1 }, -  { "+lookup",      K_PGDN,        -1, -1, -1 }, -  { "+lookdown",    K_DEL,         -1, -1, -1 }, -  { "+mlook",       '/',           -1, -1, -1 }, -  { "centerview",   K_END,         -1, -1, -1 }, -  { "+zoom",        -1,            -1, -1, -1 }, -  { "weapon 1",     '1',           -1, -1, -1 }, -  { "weapon 2",     '2',           -1, -1, -1 }, -  { "weapon 3",     '3',           -1, -1, -1 }, -  { "weapon 4",     '4',           -1, -1, -1 }, -  { "weapon 5",     '5',           -1, -1, -1 }, -  { "weapon 6",     '6',           -1, -1, -1 }, -  { "weapon 7",     '7',           -1, -1, -1 }, -  { "weapon 8",     '8',           -1, -1, -1 }, -  { "weapon 9",     '9',           -1, -1, -1 }, -  { "weapon 10",    '0',           -1, -1, -1 }, -  { "weapon 11",    -1,            -1, -1, -1 }, -  { "weapon 12",    -1,            -1, -1, -1 }, -  { "weapon 13",    -1,            -1, -1, -1 }, -  { "+attack",      K_MOUSE1,      -1, -1, -1 }, -  { "+button5",     K_MOUSE2,      -1, -1, -1 }, //TA: secondary attack -  { "reload",       'r',           -1, -1, -1 }, //TA: reload -  { "buy ammo",     'b',           -1, -1, -1 }, //TA: buy ammo -  { "itemact medkit", 'm',         -1, -1, -1 }, //TA: use medkit -  { "+button7",     'q',           -1, -1, -1 }, //TA: buildable use -  { "deconstruct",  'e',           -1, -1, -1 }, //TA: buildable destroy -  { "weapprev",     '[',           -1, -1, -1 }, -  { "weapnext",     ']',           -1, -1, -1 }, -  { "+button3",     K_MOUSE3,      -1, -1, -1 }, -  { "+button4",     K_MOUSE4,      -1, -1, -1 }, -  { "prevTeamMember", 'w',         -1, -1, -1 }, -  { "nextTeamMember", 'r',         -1, -1, -1 }, -  { "nextOrder",    't',           -1, -1, -1 }, -  { "confirmOrder", 'y',           -1, -1, -1 }, -  { "denyOrder",    'n',           -1, -1, -1 }, -  { "taskOffense",  'o',           -1, -1, -1 }, -  { "taskDefense",  'd',           -1, -1, -1 }, -  { "taskPatrol",   'p',           -1, -1, -1 }, -  { "taskCamp",     'c',           -1, -1, -1 }, -  { "taskFollow",   'f',           -1, -1, -1 }, -  { "taskRetrieve", 'v',           -1, -1, -1 }, -  { "taskEscort",   'l',           -1, -1, -1 }, -  { "taskOwnFlag",  'i',           -1, -1, -1 }, -  { "taskSuicide",  'k',           -1, -1, -1 }, -  { "tauntKillInsult", K_F1,       -1, -1, -1 }, -  { "tauntPraise",   K_F2,         -1, -1, -1 }, -  { "tauntTaunt",    K_F3,         -1, -1, -1 }, -  { "tauntDeathInsult", K_F4,      -1, -1, -1 }, -  { "tauntGauntlet", K_F5,         -1, -1, -1 }, -  { "scoresUp",      K_KP_PGUP,    -1, -1, -1 }, -  { "scoresDown",    K_KP_PGDN,    -1, -1, -1 }, -  // bk001205 - this one below was:  '-1' -  { "messagemode",  -1,            -1, -1, -1 }, -  { "messagemode2", -1,            -1, -1, -1 }, -  { "messagemode3", -1,            -1, -1, -1 }, -  { "messagemode4", -1,            -1, -1, -1 } -}; - - -static const int g_bindCount = sizeof(g_bindings) / sizeof(bind_t); - -/* -================= -Controls_GetKeyAssignment -================= -*/ -static void Controls_GetKeyAssignment (char *command, int *twokeys) -{ -  int   count; -  int   j; -  char  b[256]; - -  twokeys[0] = twokeys[1] = -1; -  count = 0; - -  for ( j = 0; j < 256; j++ ) -  { -    DC->getBindingBuf( j, b, 256 ); -    if ( *b == 0 ) { -      continue; -    } -    if ( !Q_stricmp( b, command ) ) { -      twokeys[count] = j; -      count++; -      if (count == 2) { -        break; -      } -    } -  } -} - -/* -================= -Controls_GetConfig -================= -*/ -void Controls_GetConfig( void ) -{ -  int   i; -  int   twokeys[ 2 ]; - -  // iterate each command, get its numeric binding -  for( i = 0; i < g_bindCount; i++ ) -  { -    Controls_GetKeyAssignment( g_bindings[ i ].command, twokeys ); - -    g_bindings[ i ].bind1 = twokeys[ 0 ]; -    g_bindings[ i ].bind2 = twokeys[ 1 ]; -  } - -  //s_controls.invertmouse.curvalue  = DC->getCVarValue( "m_pitch" ) < 0; -  //s_controls.smoothmouse.curvalue  = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "m_filter" ) ); -  //s_controls.alwaysrun.curvalue    = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_run" ) ); -  //s_controls.autoswitch.curvalue   = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cg_autoswitch" ) ); -  //s_controls.sensitivity.curvalue  = UI_ClampCvar( 2, 30, Controls_GetCvarValue( "sensitivity" ) ); -  //s_controls.joyenable.curvalue    = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "in_joystick" ) ); -  //s_controls.joythreshold.curvalue = UI_ClampCvar( 0.05, 0.75, Controls_GetCvarValue( "joy_threshold" ) ); -  //s_controls.freelook.curvalue     = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_freelook" ) ); -} - -/* -================= -Controls_SetConfig -================= -*/ -void Controls_SetConfig(qboolean restart) -{ -  int   i; - -  // iterate each command, get its numeric binding -  for (i=0; i < g_bindCount; i++) -  { - -    if (g_bindings[i].bind1 != -1) -    { -      DC->setBinding( g_bindings[i].bind1, g_bindings[i].command ); - -      if (g_bindings[i].bind2 != -1) -        DC->setBinding( g_bindings[i].bind2, g_bindings[i].command ); -    } -  } - -  //if ( s_controls.invertmouse.curvalue ) -  //  DC->setCVar("m_pitch", va("%f),-fabs( DC->getCVarValue( "m_pitch" ) ) ); -  //else -  //  trap_Cvar_SetValue( "m_pitch", fabs( trap_Cvar_VariableValue( "m_pitch" ) ) ); - -  //trap_Cvar_SetValue( "m_filter", s_controls.smoothmouse.curvalue ); -  //trap_Cvar_SetValue( "cl_run", s_controls.alwaysrun.curvalue ); -  //trap_Cvar_SetValue( "cg_autoswitch", s_controls.autoswitch.curvalue ); -  //trap_Cvar_SetValue( "sensitivity", s_controls.sensitivity.curvalue ); -  //trap_Cvar_SetValue( "in_joystick", s_controls.joyenable.curvalue ); -  //trap_Cvar_SetValue( "joy_threshold", s_controls.joythreshold.curvalue ); -  //trap_Cvar_SetValue( "cl_freelook", s_controls.freelook.curvalue ); -  DC->executeText(EXEC_APPEND, "in_restart\n"); -  //trap_Cmd_ExecuteText( EXEC_APPEND, "in_restart\n" ); -} - -/* -================= -Controls_SetDefaults -================= -*/ -void Controls_SetDefaults( void ) -{ -  int i; - -  // iterate each command, set its default binding -  for (i=0; i < g_bindCount; i++) -  { -    g_bindings[i].bind1 = g_bindings[i].defaultbind1; -    g_bindings[i].bind2 = g_bindings[i].defaultbind2; -  } - -  //s_controls.invertmouse.curvalue  = Controls_GetCvarDefault( "m_pitch" ) < 0; -  //s_controls.smoothmouse.curvalue  = Controls_GetCvarDefault( "m_filter" ); -  //s_controls.alwaysrun.curvalue    = Controls_GetCvarDefault( "cl_run" ); -  //s_controls.autoswitch.curvalue   = Controls_GetCvarDefault( "cg_autoswitch" ); -  //s_controls.sensitivity.curvalue  = Controls_GetCvarDefault( "sensitivity" ); -  //s_controls.joyenable.curvalue    = Controls_GetCvarDefault( "in_joystick" ); -  //s_controls.joythreshold.curvalue = Controls_GetCvarDefault( "joy_threshold" ); -  //s_controls.freelook.curvalue     = Controls_GetCvarDefault( "cl_freelook" ); -} - -int BindingIDFromName(const char *name) { -  int i; -  for (i=0; i < g_bindCount; i++) -  { -    if (Q_stricmp(name, g_bindings[i].command) == 0) { -      return i; -    } -  } -  return -1; -} - -char g_nameBind1[32]; -char g_nameBind2[32]; - -void BindingFromName(const char *cvar) { -  int i, b1, b2; - -  // iterate each command, set its default binding -  for (i=0; i < g_bindCount; i++) -  { -    if (Q_stricmp(cvar, g_bindings[i].command) == 0) { -      b1 = g_bindings[i].bind1; -      if (b1 == -1) { -        break; -      } -        DC->keynumToStringBuf( b1, g_nameBind1, 32 ); -        Q_strupr(g_nameBind1); - -        b2 = g_bindings[i].bind2; -        if (b2 != -1) -        { -          DC->keynumToStringBuf( b2, g_nameBind2, 32 ); -          Q_strupr(g_nameBind2); -          strcat( g_nameBind1, " or " ); -          strcat( g_nameBind1, g_nameBind2 ); -        } -      return; -    } -  } -  strcpy(g_nameBind1, "???"); -} - -void Item_Slider_Paint(itemDef_t *item) { -  vec4_t newColor; -  float x, y, value; -  menuDef_t *parent = (menuDef_t*)item->parent; - -  value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0; - -  if (item->window.flags & WINDOW_HASFOCUS) { -/*    lowLight[0] = 0.8 * parent->focusColor[0]; -    lowLight[1] = 0.8 * parent->focusColor[1]; -    lowLight[2] = 0.8 * parent->focusColor[2]; -    lowLight[3] = 0.8 * parent->focusColor[3]; -    LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/ -    //TA: -    memcpy(newColor, &parent->focusColor, sizeof(vec4_t)); -  } else { -    memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t)); -  } - -  y = item->window.rect.y; -  if (item->text) { -    Item_Text_Paint(item); -    x = item->textRect.x + item->textRect.w + 8; -  } else { -    x = item->window.rect.x; -  } -  DC->setColor(newColor); -  DC->drawHandlePic( x, y, SLIDER_WIDTH, SLIDER_HEIGHT, DC->Assets.sliderBar ); - -  x = Item_Slider_ThumbPosition(item); -  DC->drawHandlePic( x - (SLIDER_THUMB_WIDTH / 2), y - 2, SLIDER_THUMB_WIDTH, SLIDER_THUMB_HEIGHT, DC->Assets.sliderThumb ); - -} - -void Item_Bind_Paint(itemDef_t *item) { -  vec4_t newColor, lowLight; -  float value; -  int maxChars = 0; -  menuDef_t *parent = (menuDef_t*)item->parent; -  editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData; -  if (editPtr) { -    maxChars = editPtr->maxPaintChars; -  } - -  value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0; - -  if (item->window.flags & WINDOW_HASFOCUS) { -    if (g_bindItem == item) { -      lowLight[0] = 0.8f * 1.0f; -      lowLight[1] = 0.8f * 0.0f; -      lowLight[2] = 0.8f * 0.0f; -      lowLight[3] = 0.8f * 1.0f; -    } else { -      lowLight[0] = 0.8f * parent->focusColor[0]; -      lowLight[1] = 0.8f * parent->focusColor[1]; -      lowLight[2] = 0.8f * parent->focusColor[2]; -      lowLight[3] = 0.8f * parent->focusColor[3]; -    } -    /*LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/ -    //TA: -    memcpy(newColor, &parent->focusColor, sizeof(vec4_t)); -  } else { -    memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t)); -  } - -  if (item->text) { -    Item_Text_Paint(item); -    BindingFromName(item->cvar); -    DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, g_nameBind1, 0, maxChars, item->textStyle); -  } else { -    DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, (value != 0) ? "FIXME" : "FIXME", 0, maxChars, item->textStyle); -  } -} - -qboolean Display_KeyBindPending( void ) { -  return g_waitingForKey; -} - -qboolean Item_Bind_HandleKey(itemDef_t *item, int key, qboolean down) { -  int     id; -  int     i; - -  if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && !g_waitingForKey) -  { -    if (down && (key == K_MOUSE1 || key == K_ENTER)) { -      g_waitingForKey = qtrue; -      g_bindItem = item; -    } -    return qtrue; -  } -  else -  { -    if (!g_waitingForKey || g_bindItem == NULL) { -      return qtrue; -    } - -    if (key & K_CHAR_FLAG) { -      return qtrue; -    } - -    switch (key) -    { -      case K_ESCAPE: -        g_waitingForKey = qfalse; -        return qtrue; - -      case K_BACKSPACE: -        id = BindingIDFromName(item->cvar); -        if (id != -1) { -          g_bindings[id].bind1 = -1; -          g_bindings[id].bind2 = -1; -        } -        Controls_SetConfig(qtrue); -        g_waitingForKey = qfalse; -        g_bindItem = NULL; -        return qtrue; - -      case '`': -        return qtrue; -    } -  } - -  if (key != -1) -  { - -    for (i=0; i < g_bindCount; i++) -    { - -      if (g_bindings[i].bind2 == key) { -        g_bindings[i].bind2 = -1; -      } - -      if (g_bindings[i].bind1 == key) -      { -        g_bindings[i].bind1 = g_bindings[i].bind2; -        g_bindings[i].bind2 = -1; -      } -    } -  } - - -  id = BindingIDFromName(item->cvar); - -  if (id != -1) { -    if (key == -1) { -      if( g_bindings[id].bind1 != -1 ) { -        DC->setBinding( g_bindings[id].bind1, "" ); -        g_bindings[id].bind1 = -1; -      } -      if( g_bindings[id].bind2 != -1 ) { -        DC->setBinding( g_bindings[id].bind2, "" ); -        g_bindings[id].bind2 = -1; -      } -    } -    else if (g_bindings[id].bind1 == -1) { -      g_bindings[id].bind1 = key; -    } -    else if (g_bindings[id].bind1 != key && g_bindings[id].bind2 == -1) { -      g_bindings[id].bind2 = key; -    } -    else { -      DC->setBinding( g_bindings[id].bind1, "" ); -      DC->setBinding( g_bindings[id].bind2, "" ); -      g_bindings[id].bind1 = key; -      g_bindings[id].bind2 = -1; -    } -  } - -  Controls_SetConfig(qtrue); -  g_waitingForKey = qfalse; - -  return qtrue; -} - - - -void AdjustFrom640(float *x, float *y, float *w, float *h) { -  //*x = *x * DC->scale + DC->bias; -  *x *= DC->xscale; -  *y *= DC->yscale; -  *w *= DC->xscale; -  *h *= DC->yscale; -} - -void Item_Model_Paint(itemDef_t *item) { -  float x, y, w, h; -  refdef_t refdef; -  refEntity_t   ent; -  vec3_t      mins, maxs, origin; -  vec3_t      angles; -  modelDef_t *modelPtr = (modelDef_t*)item->typeData; - -  if (modelPtr == NULL) { -    return; -  } - -  // setup the refdef -  memset( &refdef, 0, sizeof( refdef ) ); -  refdef.rdflags = RDF_NOWORLDMODEL; -  AxisClear( refdef.viewaxis ); -  x = item->window.rect.x+1; -  y = item->window.rect.y+1; -  w = item->window.rect.w-2; -  h = item->window.rect.h-2; - -  AdjustFrom640( &x, &y, &w, &h ); - -  refdef.x = x; -  refdef.y = y; -  refdef.width = w; -  refdef.height = h; - -  DC->modelBounds( item->asset, mins, maxs ); - -  origin[2] = -0.5 * ( mins[2] + maxs[2] ); -  origin[1] = 0.5 * ( mins[1] + maxs[1] ); - -  // calculate distance so the model nearly fills the box -  if (qtrue) { -    float len = 0.5 * ( maxs[2] - mins[2] ); -    origin[0] = len / 0.268;  // len / tan( fov/2 ) -    //origin[0] = len / tan(w/2); -  } else { -    origin[0] = item->textscale; -  } -  refdef.fov_x = (modelPtr->fov_x) ? modelPtr->fov_x : w; -  refdef.fov_y = (modelPtr->fov_y) ? modelPtr->fov_y : h; - -  //refdef.fov_x = (int)((float)refdef.width / 640.0f * 90.0f); -  //xx = refdef.width / tan( refdef.fov_x / 360 * M_PI ); -  //refdef.fov_y = atan2( refdef.height, xx ); -  //refdef.fov_y *= ( 360 / M_PI ); - -  DC->clearScene(); - -  refdef.time = DC->realTime; - -  // add the model - -  memset( &ent, 0, sizeof(ent) ); - -  //adjust = 5.0 * sin( (float)uis.realtime / 500 ); -  //adjust = 360 % (int)((float)uis.realtime / 1000); -  //VectorSet( angles, 0, 0, 1 ); - -  // use item storage to track -  if (modelPtr->rotationSpeed) { -    if (DC->realTime > item->window.nextTime) { -      item->window.nextTime = DC->realTime + modelPtr->rotationSpeed; -      modelPtr->angle = (int)(modelPtr->angle + 1) % 360; -    } -  } -  VectorSet( angles, 0, modelPtr->angle, 0 ); -  AnglesToAxis( angles, ent.axis ); - -  ent.hModel = item->asset; -  VectorCopy( origin, ent.origin ); -  VectorCopy( origin, ent.lightingOrigin ); -  ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; -  VectorCopy( ent.origin, ent.oldorigin ); - -  DC->addRefEntityToScene( &ent ); -  DC->renderScene( &refdef ); - -} - - -void Item_Image_Paint(itemDef_t *item) { -  if (item == NULL) { -    return; -  } -  DC->drawHandlePic(item->window.rect.x+1, item->window.rect.y+1, item->window.rect.w-2, item->window.rect.h-2, item->asset); -} - -void Item_ListBox_Paint(itemDef_t *item) { -  float x, y, size, thumb; -  int i, count; -  qhandle_t image; -  qhandle_t optionalImage; -  listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData; - -  // the listbox is horizontal or vertical and has a fixed size scroll bar going either direction -  // elements are enumerated from the DC and either text or image handles are acquired from the DC as well -  // textscale is used to size the text, textalignx and textaligny are used to size image elements -  // there is no clipping available so only the last completely visible item is painted -  count = DC->feederCount(item->special); -  // default is vertical if horizontal flag is not here -  if (item->window.flags & WINDOW_HORIZONTAL) { -    // draw scrollbar in bottom of the window -    // bar -    x = item->window.rect.x + 1; -    y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE - 1; -    DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowLeft); -    x += SCROLLBAR_SIZE - 1; -    size = item->window.rect.w - (SCROLLBAR_SIZE * 2); -    DC->drawHandlePic(x, y, size+1, SCROLLBAR_SIZE, DC->Assets.scrollBar); -    x += size - 1; -    DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowRight); -    // thumb -    thumb = Item_ListBox_ThumbDrawPosition(item);//Item_ListBox_ThumbPosition(item); -    if (thumb > x - SCROLLBAR_SIZE - 1) { -      thumb = x - SCROLLBAR_SIZE - 1; -    } -    DC->drawHandlePic(thumb, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb); -    // -    listPtr->endPos = listPtr->startPos; -    size = item->window.rect.w - 2; -    // items -    // size contains max available space -    if (listPtr->elementStyle == LISTBOX_IMAGE) { -      // fit = 0; -      x = item->window.rect.x + 1; -      y = item->window.rect.y + 1; -      for (i = listPtr->startPos; i < count; i++) { -        // always draw at least one -        // which may overdraw the box if it is too small for the element -        image = DC->feederItemImage(item->special, i); -        if (image) { -          DC->drawHandlePic(x+1, y+1, listPtr->elementWidth - 2, listPtr->elementHeight - 2, image); -        } - -        if (i == item->cursorPos) { -          DC->drawRect(x, y, listPtr->elementWidth-1, listPtr->elementHeight-1, item->window.borderSize, item->window.borderColor); -        } - -        listPtr->endPos++; -        size -= listPtr->elementWidth; -        if (size < listPtr->elementWidth) { -          listPtr->drawPadding = size; //listPtr->elementWidth - size; -          break; -        } -        x += listPtr->elementWidth; -        // fit++; -      } -    } else { -      // -    } -  } else { -    // draw scrollbar to right side of the window -    x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE - 1; -    y = item->window.rect.y + 1; -    DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowUp); -    y += SCROLLBAR_SIZE - 1; - -    listPtr->endPos = listPtr->startPos; -    size = item->window.rect.h - (SCROLLBAR_SIZE * 2); -    DC->drawHandlePic(x, y, SCROLLBAR_SIZE, size+1, DC->Assets.scrollBar); -    y += size - 1; -    DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowDown); -    // thumb -    thumb = Item_ListBox_ThumbDrawPosition(item);//Item_ListBox_ThumbPosition(item); -    if (thumb > y - SCROLLBAR_SIZE - 1) { -      thumb = y - SCROLLBAR_SIZE - 1; -    } -    DC->drawHandlePic(x, thumb, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb); - -    // adjust size for item painting -    size = item->window.rect.h - 2; -    if (listPtr->elementStyle == LISTBOX_IMAGE) { -      // fit = 0; -      x = item->window.rect.x + 1; -      y = item->window.rect.y + 1; -      for (i = listPtr->startPos; i < count; i++) { -        // always draw at least one -        // which may overdraw the box if it is too small for the element -        image = DC->feederItemImage(item->special, i); -        if (image) { -          DC->drawHandlePic(x+1, y+1, listPtr->elementWidth - 2, listPtr->elementHeight - 2, image); -        } - -        if (i == item->cursorPos) { -          DC->drawRect(x, y, listPtr->elementWidth - 1, listPtr->elementHeight - 1, item->window.borderSize, item->window.borderColor); -        } - -        listPtr->endPos++; -        size -= listPtr->elementWidth; -        if (size < listPtr->elementHeight) { -          listPtr->drawPadding = listPtr->elementHeight - size; -          break; -        } -        y += listPtr->elementHeight; -        // fit++; -      } -    } else { -      x = item->window.rect.x + 1; -      y = item->window.rect.y + 1; -      for (i = listPtr->startPos; i < count; i++) { -        const char *text; -        // always draw at least one -        // which may overdraw the box if it is too small for the element - -        if (listPtr->numColumns > 0) { -          int j; -          for (j = 0; j < listPtr->numColumns; j++) { -            text = DC->feederItemText(item->special, i, j, &optionalImage); -            if (optionalImage >= 0) { -              DC->drawHandlePic(x + 4 + listPtr->columnInfo[j].pos, y - 1 + listPtr->elementHeight / 2, listPtr->columnInfo[j].width, listPtr->columnInfo[j].width, optionalImage); -            } else if (text) { -              //TA: -              int alignOffset = 0.0f, tw; - -              tw = DC->textWidth( text, item->textscale, 0 ); - -              switch( listPtr->columnInfo[ j ].align ) -              { -                case ITEM_ALIGN_LEFT: -                  alignOffset = 0.0f; -                  break; - -                case ITEM_ALIGN_RIGHT: -                  alignOffset = listPtr->columnInfo[ j ].width - tw; -                  break; - -                case ITEM_ALIGN_CENTER: -                  alignOffset = ( listPtr->columnInfo[ j ].width / 2.0f ) - ( tw / 2.0f ); -                  break; - -                default: -                  alignOffset = 0.0f; -              } - -              DC->drawText( x + 4 + listPtr->columnInfo[j].pos + alignOffset, y + listPtr->elementHeight, -                            item->textscale, item->window.foreColor, text, 0, -                            listPtr->columnInfo[j].maxChars, item->textStyle ); -            } -          } -        } else { -          text = DC->feederItemText(item->special, i, 0, &optionalImage); -          if (optionalImage >= 0) { -            //DC->drawHandlePic(x + 4 + listPtr->elementHeight, y, listPtr->columnInfo[j].width, listPtr->columnInfo[j].width, optionalImage); -          } else if (text) { -            DC->drawText(x + 4, y + listPtr->elementHeight, item->textscale, item->window.foreColor, text, 0, 0, item->textStyle); -          } -        } - -        if (i == item->cursorPos) { -          DC->fillRect(x + 2, y + 2, item->window.rect.w - SCROLLBAR_SIZE - 4, listPtr->elementHeight, item->window.outlineColor); -        } - -        listPtr->endPos++; -        size -= listPtr->elementHeight; -        if (size < listPtr->elementHeight) { -          listPtr->drawPadding = listPtr->elementHeight - size; -          break; -        } -        y += listPtr->elementHeight; -        // fit++; -      } -    } -  } - -  //TA: FIXME: hacky fix to off-by-one bug -  listPtr->endPos--; -} - - -void Item_OwnerDraw_Paint(itemDef_t *item) { -  menuDef_t *parent; - -  if (item == NULL) { -    return; -  } -  parent = (menuDef_t*)item->parent; - -  if (DC->ownerDrawItem) { -    vec4_t color, lowLight; -    menuDef_t *parent = (menuDef_t*)item->parent; -    Fade(&item->window.flags, &item->window.foreColor[3], parent->fadeClamp, &item->window.nextTime, parent->fadeCycle, qtrue, parent->fadeAmount); -    memcpy(&color, &item->window.foreColor, sizeof(color)); -    if (item->numColors > 0 && DC->getValue) { -      // if the value is within one of the ranges then set color to that, otherwise leave at default -      int i; -      float f = DC->getValue(item->window.ownerDraw); -      for (i = 0; i < item->numColors; i++) { -        if (f >= item->colorRanges[i].low && f <= item->colorRanges[i].high) { -          memcpy(&color, &item->colorRanges[i].color, sizeof(color)); -          break; -        } -      } -    } - -    if (item->window.flags & WINDOW_HASFOCUS) { -/*      lowLight[0] = 0.8 * parent->focusColor[0]; -      lowLight[1] = 0.8 * parent->focusColor[1]; -      lowLight[2] = 0.8 * parent->focusColor[2]; -      lowLight[3] = 0.8 * parent->focusColor[3]; -      LerpColor(parent->focusColor,lowLight,color,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/ -      //TA: -      memcpy(color, &parent->focusColor, sizeof(vec4_t)); -    } else if (item->textStyle == ITEM_TEXTSTYLE_BLINK && !((DC->realTime/BLINK_DIVISOR) & 1)) { -      lowLight[0] = 0.8 * item->window.foreColor[0]; -      lowLight[1] = 0.8 * item->window.foreColor[1]; -      lowLight[2] = 0.8 * item->window.foreColor[2]; -      lowLight[3] = 0.8 * item->window.foreColor[3]; -      LerpColor(item->window.foreColor,lowLight,color,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR)); -    } - -    if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) { -      memcpy(color, parent->disableColor, sizeof(vec4_t)); // bk001207 - FIXME: Com_Memcpy -    } - -    if (item->text) { -      Item_Text_Paint(item); -        if (item->text[0]) { -          // +8 is an offset kludge to properly align owner draw items that have text combined with them -          DC->ownerDrawItem(item->textRect.x + item->textRect.w + 8, item->window.rect.y, item->window.rect.w, item->window.rect.h, 0, item->textaligny, item->window.ownerDraw, item->window.ownerDrawFlags, item->alignment, item->special, item->textscale, color, item->window.background, item->textStyle ); -        } else { -          DC->ownerDrawItem(item->textRect.x + item->textRect.w, item->window.rect.y, item->window.rect.w, item->window.rect.h, 0, item->textaligny, item->window.ownerDraw, item->window.ownerDrawFlags, item->alignment, item->special, item->textscale, color, item->window.background, item->textStyle ); -        } -      } else { -      DC->ownerDrawItem(item->window.rect.x, item->window.rect.y, item->window.rect.w, item->window.rect.h, item->textalignx, item->textaligny, item->window.ownerDraw, item->window.ownerDrawFlags, item->alignment, item->special, item->textscale, color, item->window.background, item->textStyle ); -    } -  } -} - - -void Item_Paint(itemDef_t *item) { -  vec4_t red; -  menuDef_t *parent = (menuDef_t*)item->parent; -  red[0] = red[3] = 1; -  red[1] = red[2] = 0; - -  if (item == NULL) { -    return; -  } - -  if (item->window.flags & WINDOW_ORBITING) { -    if (DC->realTime > item->window.nextTime) { -      float rx, ry, a, c, s, w, h; - -      item->window.nextTime = DC->realTime + item->window.offsetTime; -      // translate -      w = item->window.rectClient.w / 2; -      h = item->window.rectClient.h / 2; -      rx = item->window.rectClient.x + w - item->window.rectEffects.x; -      ry = item->window.rectClient.y + h - item->window.rectEffects.y; -      a = 3 * M_PI / 180; -      c = cos(a); -      s = sin(a); -      item->window.rectClient.x = (rx * c - ry * s) + item->window.rectEffects.x - w; -      item->window.rectClient.y = (rx * s + ry * c) + item->window.rectEffects.y - h; -      Item_UpdatePosition(item); - -    } -  } - - -  if (item->window.flags & WINDOW_INTRANSITION) { -    if (DC->realTime > item->window.nextTime) { -      int done = 0; -      item->window.nextTime = DC->realTime + item->window.offsetTime; -      // transition the x,y -      if (item->window.rectClient.x == item->window.rectEffects.x) { -        done++; -      } else { -        if (item->window.rectClient.x < item->window.rectEffects.x) { -          item->window.rectClient.x += item->window.rectEffects2.x; -          if (item->window.rectClient.x > item->window.rectEffects.x) { -            item->window.rectClient.x = item->window.rectEffects.x; -            done++; -          } -        } else { -          item->window.rectClient.x -= item->window.rectEffects2.x; -          if (item->window.rectClient.x < item->window.rectEffects.x) { -            item->window.rectClient.x = item->window.rectEffects.x; -            done++; -          } -        } -      } -      if (item->window.rectClient.y == item->window.rectEffects.y) { -        done++; -      } else { -        if (item->window.rectClient.y < item->window.rectEffects.y) { -          item->window.rectClient.y += item->window.rectEffects2.y; -          if (item->window.rectClient.y > item->window.rectEffects.y) { -            item->window.rectClient.y = item->window.rectEffects.y; -            done++; -          } -        } else { -          item->window.rectClient.y -= item->window.rectEffects2.y; -          if (item->window.rectClient.y < item->window.rectEffects.y) { -            item->window.rectClient.y = item->window.rectEffects.y; -            done++; -          } -        } -      } -      if (item->window.rectClient.w == item->window.rectEffects.w) { -        done++; -      } else { -        if (item->window.rectClient.w < item->window.rectEffects.w) { -          item->window.rectClient.w += item->window.rectEffects2.w; -          if (item->window.rectClient.w > item->window.rectEffects.w) { -            item->window.rectClient.w = item->window.rectEffects.w; -            done++; -          } -        } else { -          item->window.rectClient.w -= item->window.rectEffects2.w; -          if (item->window.rectClient.w < item->window.rectEffects.w) { -            item->window.rectClient.w = item->window.rectEffects.w; -            done++; -          } -        } -      } -      if (item->window.rectClient.h == item->window.rectEffects.h) { -        done++; -      } else { -        if (item->window.rectClient.h < item->window.rectEffects.h) { -          item->window.rectClient.h += item->window.rectEffects2.h; -          if (item->window.rectClient.h > item->window.rectEffects.h) { -            item->window.rectClient.h = item->window.rectEffects.h; -            done++; -          } -        } else { -          item->window.rectClient.h -= item->window.rectEffects2.h; -          if (item->window.rectClient.h < item->window.rectEffects.h) { -            item->window.rectClient.h = item->window.rectEffects.h; -            done++; -          } -        } -      } - -      Item_UpdatePosition(item); - -      if (done == 4) { -        item->window.flags &= ~WINDOW_INTRANSITION; -      } - -    } -  } - -  if (item->window.ownerDrawFlags && DC->ownerDrawVisible) { -    if (!DC->ownerDrawVisible(item->window.ownerDrawFlags)) { -      item->window.flags &= ~WINDOW_VISIBLE; -    } else { -      item->window.flags |= WINDOW_VISIBLE; -    } -  } - -  if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE)) { -    if (!Item_EnableShowViaCvar(item, CVAR_SHOW)) { -      return; -    } -  } - -  if (item->window.flags & WINDOW_TIMEDVISIBLE) { - -  } - -  if (!(item->window.flags & WINDOW_VISIBLE)) { -    return; -  } - -  // paint the rect first.. -  Window_Paint(&item->window, parent->fadeAmount , parent->fadeClamp, parent->fadeCycle); - -  if (debugMode) { -    vec4_t color; -    rectDef_t *r = Item_CorrectedTextRect(item); -    color[1] = color[3] = 1; -    color[0] = color[2] = 0; -    DC->drawRect(r->x, r->y, r->w, r->h, 1, color); -  } - -  //DC->drawRect(item->window.rect.x, item->window.rect.y, item->window.rect.w, item->window.rect.h, 1, red); - -  switch (item->type) { -    case ITEM_TYPE_OWNERDRAW: -      Item_OwnerDraw_Paint(item); -      break; -    case ITEM_TYPE_TEXT: -    case ITEM_TYPE_BUTTON: -      Item_Text_Paint(item); -      break; -    case ITEM_TYPE_RADIOBUTTON: -      break; -    case ITEM_TYPE_CHECKBOX: -      break; -    case ITEM_TYPE_EDITFIELD: -    case ITEM_TYPE_NUMERICFIELD: -      Item_TextField_Paint(item); -      break; -    case ITEM_TYPE_COMBO: -      break; -    case ITEM_TYPE_LISTBOX: -      Item_ListBox_Paint(item); -      break; -    //case ITEM_TYPE_IMAGE: -    //  Item_Image_Paint(item); -    //  break; -    case ITEM_TYPE_MODEL: -      Item_Model_Paint(item); -      break; -    case ITEM_TYPE_YESNO: -      Item_YesNo_Paint(item); -      break; -    case ITEM_TYPE_MULTI: -      Item_Multi_Paint(item); -      break; -    case ITEM_TYPE_BIND: -      Item_Bind_Paint(item); -      break; -    case ITEM_TYPE_SLIDER: -      Item_Slider_Paint(item); -      break; -    default: -      break; -  } - -} - -void Menu_Init(menuDef_t *menu) { -  memset(menu, 0, sizeof(menuDef_t)); -  menu->cursorItem = -1; -  menu->fadeAmount = DC->Assets.fadeAmount; -  menu->fadeClamp = DC->Assets.fadeClamp; -  menu->fadeCycle = DC->Assets.fadeCycle; -  Window_Init(&menu->window); -} - -itemDef_t *Menu_GetFocusedItem(menuDef_t *menu) { -  int i; -  if (menu) { -    for (i = 0; i < menu->itemCount; i++) { -      if (menu->items[i]->window.flags & WINDOW_HASFOCUS) { -        return menu->items[i]; -      } -    } -  } -  return NULL; -} - -menuDef_t *Menu_GetFocused( void ) { -  int i; -  for (i = 0; i < menuCount; i++) { -    if (Menus[i].window.flags & WINDOW_HASFOCUS && Menus[i].window.flags & WINDOW_VISIBLE) { -      return &Menus[i]; -    } -  } -  return NULL; -} - -void Menu_ScrollFeeder(menuDef_t *menu, int feeder, qboolean down) { -  if (menu) { -    int i; -    for (i = 0; i < menu->itemCount; i++) { -      if (menu->items[i]->special == feeder) { -        Item_ListBox_HandleKey(menu->items[i], (down) ? K_DOWNARROW : K_UPARROW, qtrue, qtrue); -        return; -      } -    } -  } -} - - - -void Menu_SetFeederSelection(menuDef_t *menu, int feeder, int index, const char *name) { -  if (menu == NULL) { -    if (name == NULL) { -      menu = Menu_GetFocused(); -    } else { -      menu = Menus_FindByName(name); -    } -  } - -  if (menu) { -    int i; -    for (i = 0; i < menu->itemCount; i++) { -      if (menu->items[i]->special == feeder) { -        if (index == 0) { -          listBoxDef_t *listPtr = (listBoxDef_t*)menu->items[i]->typeData; -          listPtr->cursorPos = 0; -          listPtr->startPos = 0; -        } -        menu->items[i]->cursorPos = index; -        DC->feederSelection(menu->items[i]->special, menu->items[i]->cursorPos); -        return; -      } -    } -  } -} - -qboolean Menus_AnyFullScreenVisible( void ) { -  int i; -  for (i = 0; i < menuCount; i++) { -    if (Menus[i].window.flags & WINDOW_VISIBLE && Menus[i].fullScreen) { -      return qtrue; -    } -  } -  return qfalse; -} - -menuDef_t *Menus_ActivateByName(const char *p) { -  int i, j; -  menuDef_t *m = NULL; -  menuDef_t *focus = Menu_GetFocused(); - -  for (i = 0; i < menuCount; i++) { -    if (Q_stricmp(Menus[i].window.name, p) == 0) { -      m = &Menus[i]; -      Menus_Activate(m); -      Menu_HandleMouseMove( m, DC->cursorx, DC->cursory ); //TA: force the item under the cursor to focus - -      for( j = 0; j < m->itemCount; j++ ) //TA: reset selection in listboxes when opened -      { -        if( m->items[ j ]->type == ITEM_TYPE_LISTBOX ) -        { -          listBoxDef_t *listPtr = (listBoxDef_t*)m->items[ j ]->typeData; -          m->items[ j ]->cursorPos = 0; -          listPtr->startPos = 0; -          DC->feederSelection( m->items[ j ]->special, 0 ); -        } -      } - -      if (openMenuCount < MAX_OPEN_MENUS && focus != NULL) { -        menuStack[openMenuCount++] = focus; -      } -    } else { -      Menus[i].window.flags &= ~WINDOW_HASFOCUS; -    } -  } -  Display_CloseCinematics(); -  return m; -} - - -void Item_Init(itemDef_t *item) { -  memset(item, 0, sizeof(itemDef_t)); -  item->textscale = 0.55f; -  Window_Init(&item->window); -} - -void Menu_HandleMouseMove(menuDef_t *menu, float x, float y) { -  int i, pass; -  qboolean focusSet = qfalse; - -  itemDef_t *overItem; -  if (menu == NULL) { -    return; -  } - -  if (!(menu->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED))) { -    return; -  } - -  if (itemCapture) { -    //Item_MouseMove(itemCapture, x, y); -    return; -  } - -  if (g_waitingForKey || g_editingField) { -    return; -  } - -  // FIXME: this is the whole issue of focus vs. mouse over.. -  // need a better overall solution as i don't like going through everything twice -  for (pass = 0; pass < 2; pass++) { -    for (i = 0; i < menu->itemCount; i++) { -      // turn off focus each item -      // menu->items[i].window.flags &= ~WINDOW_HASFOCUS; - -      if (!(menu->items[i]->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED))) { -        continue; -      } - -      // items can be enabled and disabled based on cvars -      if (menu->items[i]->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(menu->items[i], CVAR_ENABLE)) { -        continue; -      } - -      if (menu->items[i]->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(menu->items[i], CVAR_SHOW)) { -        continue; -      } - - - -      if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) { -        if (pass == 1) { -          overItem = menu->items[i]; -          if (overItem->type == ITEM_TYPE_TEXT && overItem->text) { -            if (!Rect_ContainsPoint(Item_CorrectedTextRect(overItem), x, y)) { -              continue; -            } -          } -          // if we are over an item -          if (IsVisible(overItem->window.flags)) { -            // different one -            Item_MouseEnter(overItem, x, y); -            // Item_SetMouseOver(overItem, qtrue); - -            // if item is not a decoration see if it can take focus -            if (!focusSet) { -              focusSet = Item_SetFocus(overItem, x, y); -            } -          } -        } -      } else if (menu->items[i]->window.flags & WINDOW_MOUSEOVER) { -          Item_MouseLeave(menu->items[i]); -          Item_SetMouseOver(menu->items[i], qfalse); -      } -    } -  } - -} - -void Menu_Paint(menuDef_t *menu, qboolean forcePaint) { -  int i; - -  if (menu == NULL) { -    return; -  } - -  if (!(menu->window.flags & WINDOW_VISIBLE) &&  !forcePaint) { -    return; -  } - -  if (menu->window.ownerDrawFlags && DC->ownerDrawVisible && !DC->ownerDrawVisible(menu->window.ownerDrawFlags)) { -    return; -  } - -  if (forcePaint) { -    menu->window.flags |= WINDOW_FORCED; -  } - -  // draw the background if necessary -  if (menu->fullScreen) { -    // implies a background shader -    // FIXME: make sure we have a default shader if fullscreen is set with no background -    DC->drawHandlePic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, menu->window.background ); -  } else if (menu->window.background) { -    // this allows a background shader without being full screen -    //UI_DrawHandlePic(menu->window.rect.x, menu->window.rect.y, menu->window.rect.w, menu->window.rect.h, menu->backgroundShader); -  } - -  // paint the background and or border -  Window_Paint(&menu->window, menu->fadeAmount, menu->fadeClamp, menu->fadeCycle ); - -  for (i = 0; i < menu->itemCount; i++) { -    Item_Paint(menu->items[i]); -  } - -  if (debugMode) { -    vec4_t color; -    color[0] = color[2] = color[3] = 1; -    color[1] = 0; -    DC->drawRect(menu->window.rect.x, menu->window.rect.y, menu->window.rect.w, menu->window.rect.h, 1, color); -  } -} - -/* -=============== -Item_ValidateTypeData -=============== -*/ -void Item_ValidateTypeData(itemDef_t *item) { -  if (item->typeData) { -    return; -  } - -  if (item->type == ITEM_TYPE_LISTBOX) { -    item->typeData = UI_Alloc(sizeof(listBoxDef_t)); -    memset(item->typeData, 0, sizeof(listBoxDef_t)); -  } else if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_NUMERICFIELD || item->type == ITEM_TYPE_YESNO || item->type == ITEM_TYPE_BIND || item->type == ITEM_TYPE_SLIDER || item->type == ITEM_TYPE_TEXT) { -    item->typeData = UI_Alloc(sizeof(editFieldDef_t)); -    memset(item->typeData, 0, sizeof(editFieldDef_t)); -    if (item->type == ITEM_TYPE_EDITFIELD) { -      if (!((editFieldDef_t *) item->typeData)->maxPaintChars) { -        ((editFieldDef_t *) item->typeData)->maxPaintChars = MAX_EDITFIELD; -      } -    } -  } else if (item->type == ITEM_TYPE_MULTI) { -    item->typeData = UI_Alloc(sizeof(multiDef_t)); -  } else if (item->type == ITEM_TYPE_MODEL) { -    item->typeData = UI_Alloc(sizeof(modelDef_t)); -  } -} - -/* -=============== -Keyword Hash -=============== -*/ - -#define KEYWORDHASH_SIZE  512 - -typedef struct keywordHash_s -{ -  char *keyword; -  qboolean (*func)(itemDef_t *item, int handle); -  struct keywordHash_s *next; -} keywordHash_t; - -int KeywordHash_Key(char *keyword) { -  int register hash, i; - -  hash = 0; -  for (i = 0; keyword[i] != '\0'; i++) { -    if (keyword[i] >= 'A' && keyword[i] <= 'Z') -      hash += (keyword[i] + ('a' - 'A')) * (119 + i); -    else -      hash += keyword[i] * (119 + i); -  } -  hash = (hash ^ (hash >> 10) ^ (hash >> 20)) & (KEYWORDHASH_SIZE-1); -  return hash; -} - -void KeywordHash_Add(keywordHash_t *table[], keywordHash_t *key) { -  int hash; - -  hash = KeywordHash_Key(key->keyword); -/* -  if (table[hash]) { -    int collision = qtrue; -  } -*/ -  key->next = table[hash]; -  table[hash] = key; -} - -keywordHash_t *KeywordHash_Find(keywordHash_t *table[], char *keyword) -{ -  keywordHash_t *key; -  int hash; - -  hash = KeywordHash_Key(keyword); -  for (key = table[hash]; key; key = key->next) { -    if (!Q_stricmp(key->keyword, keyword)) -      return key; -  } -  return NULL; -} - -/* -=============== -Item Keyword Parse functions -=============== -*/ - -// name <string> -qboolean ItemParse_name( itemDef_t *item, int handle ) { -  if (!PC_String_Parse(handle, &item->window.name)) { -    return qfalse; -  } -  return qtrue; -} - -// name <string> -qboolean ItemParse_focusSound( itemDef_t *item, int handle ) { -  const char *temp; -  if (!PC_String_Parse(handle, &temp)) { -    return qfalse; -  } -  item->focusSound = DC->registerSound(temp, qfalse); -  return qtrue; -} - - -// text <string> -qboolean ItemParse_text( itemDef_t *item, int handle ) { -  if (!PC_String_Parse(handle, &item->text)) { -    return qfalse; -  } -  return qtrue; -} - -// group <string> -qboolean ItemParse_group( itemDef_t *item, int handle ) { -  if (!PC_String_Parse(handle, &item->window.group)) { -    return qfalse; -  } -  return qtrue; -} - -// asset_model <string> -qboolean ItemParse_asset_model( itemDef_t *item, int handle ) { -  const char *temp; -  modelDef_t *modelPtr; -  Item_ValidateTypeData(item); -  modelPtr = (modelDef_t*)item->typeData; - -  if (!PC_String_Parse(handle, &temp)) { -    return qfalse; -  } -  item->asset = DC->registerModel(temp); -  modelPtr->angle = rand() % 360; -  return qtrue; -} - -// asset_shader <string> -qboolean ItemParse_asset_shader( itemDef_t *item, int handle ) { -  const char *temp; - -  if (!PC_String_Parse(handle, &temp)) { -    return qfalse; -  } -  item->asset = DC->registerShaderNoMip(temp); -  return qtrue; -} - -// model_origin <number> <number> <number> -qboolean ItemParse_model_origin( itemDef_t *item, int handle ) { -  modelDef_t *modelPtr; -  Item_ValidateTypeData(item); -  modelPtr = (modelDef_t*)item->typeData; - -  if (PC_Float_Parse(handle, &modelPtr->origin[0])) { -    if (PC_Float_Parse(handle, &modelPtr->origin[1])) { -      if (PC_Float_Parse(handle, &modelPtr->origin[2])) { -        return qtrue; -      } -    } -  } -  return qfalse; -} - -// model_fovx <number> -qboolean ItemParse_model_fovx( itemDef_t *item, int handle ) { -  modelDef_t *modelPtr; -  Item_ValidateTypeData(item); -  modelPtr = (modelDef_t*)item->typeData; - -  if (!PC_Float_Parse(handle, &modelPtr->fov_x)) { -    return qfalse; -  } -  return qtrue; -} - -// model_fovy <number> -qboolean ItemParse_model_fovy( itemDef_t *item, int handle ) { -  modelDef_t *modelPtr; -  Item_ValidateTypeData(item); -  modelPtr = (modelDef_t*)item->typeData; - -  if (!PC_Float_Parse(handle, &modelPtr->fov_y)) { -    return qfalse; -  } -  return qtrue; -} - -// model_rotation <integer> -qboolean ItemParse_model_rotation( itemDef_t *item, int handle ) { -  modelDef_t *modelPtr; -  Item_ValidateTypeData(item); -  modelPtr = (modelDef_t*)item->typeData; - -  if (!PC_Int_Parse(handle, &modelPtr->rotationSpeed)) { -    return qfalse; -  } -  return qtrue; -} - -// model_angle <integer> -qboolean ItemParse_model_angle( itemDef_t *item, int handle ) { -  modelDef_t *modelPtr; -  Item_ValidateTypeData(item); -  modelPtr = (modelDef_t*)item->typeData; - -  if (!PC_Int_Parse(handle, &modelPtr->angle)) { -    return qfalse; -  } -  return qtrue; -} - -// rect <rectangle> -qboolean ItemParse_rect( itemDef_t *item, int handle ) { -  if (!PC_Rect_Parse(handle, &item->window.rectClient)) { -    return qfalse; -  } -  return qtrue; -} - -// style <integer> -qboolean ItemParse_style( itemDef_t *item, int handle ) { -  if (!PC_Int_Parse(handle, &item->window.style)) { -    return qfalse; -  } -  return qtrue; -} - -// decoration -qboolean ItemParse_decoration( itemDef_t *item, int handle ) { -  item->window.flags |= WINDOW_DECORATION; -  return qtrue; -} - -// notselectable -qboolean ItemParse_notselectable( itemDef_t *item, int handle ) { -  listBoxDef_t *listPtr; -  Item_ValidateTypeData(item); -  listPtr = (listBoxDef_t*)item->typeData; -  if (item->type == ITEM_TYPE_LISTBOX && listPtr) { -    listPtr->notselectable = qtrue; -  } -  return qtrue; -} - -// manually wrapped -qboolean ItemParse_wrapped( itemDef_t *item, int handle ) { -  item->window.flags |= WINDOW_WRAPPED; -  return qtrue; -} - -// auto wrapped -qboolean ItemParse_autowrapped( itemDef_t *item, int handle ) { -  item->window.flags |= WINDOW_AUTOWRAPPED; -  return qtrue; -} - - -// horizontalscroll -qboolean ItemParse_horizontalscroll( itemDef_t *item, int handle ) { -  item->window.flags |= WINDOW_HORIZONTAL; -  return qtrue; -} - -// type <integer> -qboolean ItemParse_type( itemDef_t *item, int handle ) { -  if (!PC_Int_Parse(handle, &item->type)) { -    return qfalse; -  } -  Item_ValidateTypeData(item); -  return qtrue; -} - -// elementwidth, used for listbox image elements -// uses textalignx for storage -qboolean ItemParse_elementwidth( itemDef_t *item, int handle ) { -  listBoxDef_t *listPtr; - -  Item_ValidateTypeData(item); -  listPtr = (listBoxDef_t*)item->typeData; -  if (!PC_Float_Parse(handle, &listPtr->elementWidth)) { -    return qfalse; -  } -  return qtrue; -} - -// elementheight, used for listbox image elements -// uses textaligny for storage -qboolean ItemParse_elementheight( itemDef_t *item, int handle ) { -  listBoxDef_t *listPtr; - -  Item_ValidateTypeData(item); -  listPtr = (listBoxDef_t*)item->typeData; -  if (!PC_Float_Parse(handle, &listPtr->elementHeight)) { -    return qfalse; -  } -  return qtrue; -} - -// feeder <float> -qboolean ItemParse_feeder( itemDef_t *item, int handle ) { -  if (!PC_Float_Parse(handle, &item->special)) { -    return qfalse; -  } -  return qtrue; -} - -// elementtype, used to specify what type of elements a listbox contains -// uses textstyle for storage -qboolean ItemParse_elementtype( itemDef_t *item, int handle ) { -  listBoxDef_t *listPtr; - -  Item_ValidateTypeData(item); -  if (!item->typeData) -    return qfalse; -  listPtr = (listBoxDef_t*)item->typeData; -  if (!PC_Int_Parse(handle, &listPtr->elementStyle)) { -    return qfalse; -  } -  return qtrue; -} - -// columns sets a number of columns and an x pos and width per.. -qboolean ItemParse_columns( itemDef_t *item, int handle ) { -  int num, i; -  listBoxDef_t *listPtr; - -  Item_ValidateTypeData(item); -  if (!item->typeData) -    return qfalse; -  listPtr = (listBoxDef_t*)item->typeData; -  if (PC_Int_Parse(handle, &num)) { -    if (num > MAX_LB_COLUMNS) { -      num = MAX_LB_COLUMNS; -    } -    listPtr->numColumns = num; -    for (i = 0; i < num; i++) { -      int pos, width, maxChars, align; - -      if( PC_Int_Parse( handle, &pos ) && -          PC_Int_Parse( handle, &width ) && -          PC_Int_Parse( handle, &maxChars ) && -          PC_Int_Parse( handle, &align ) ) -      { -        listPtr->columnInfo[i].pos = pos; -        listPtr->columnInfo[i].width = width; -        listPtr->columnInfo[i].maxChars = maxChars; -        listPtr->columnInfo[i].align = align; -      } else { -        return qfalse; -      } -    } -  } else { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_border( itemDef_t *item, int handle ) { -  if (!PC_Int_Parse(handle, &item->window.border)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_bordersize( itemDef_t *item, int handle ) { -  if (!PC_Float_Parse(handle, &item->window.borderSize)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_visible( itemDef_t *item, int handle ) { -  int i; - -  if (!PC_Int_Parse(handle, &i)) { -    return qfalse; -  } -  if (i) { -    item->window.flags |= WINDOW_VISIBLE; -  } -  return qtrue; -} - -qboolean ItemParse_ownerdraw( itemDef_t *item, int handle ) { -  if (!PC_Int_Parse(handle, &item->window.ownerDraw)) { -    return qfalse; -  } -  item->type = ITEM_TYPE_OWNERDRAW; -  return qtrue; -} - -qboolean ItemParse_align( itemDef_t *item, int handle ) { -  if (!PC_Int_Parse(handle, &item->alignment)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_textalign( itemDef_t *item, int handle ) { -  if (!PC_Int_Parse(handle, &item->textalignment)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_textalignx( itemDef_t *item, int handle ) { -  if (!PC_Float_Parse(handle, &item->textalignx)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_textaligny( itemDef_t *item, int handle ) { -  if (!PC_Float_Parse(handle, &item->textaligny)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_textscale( itemDef_t *item, int handle ) { -  if (!PC_Float_Parse(handle, &item->textscale)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_textstyle( itemDef_t *item, int handle ) { -  if (!PC_Int_Parse(handle, &item->textStyle)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_backcolor( itemDef_t *item, int handle ) { -  int i; -  float f; - -  for (i = 0; i < 4; i++) { -    if (!PC_Float_Parse(handle, &f)) { -      return qfalse; -    } -    item->window.backColor[i]  = f; -  } -  return qtrue; -} - -qboolean ItemParse_forecolor( itemDef_t *item, int handle ) { -  int i; -  float f; - -  for (i = 0; i < 4; i++) { -    if (!PC_Float_Parse(handle, &f)) { -      return qfalse; -    } -    item->window.foreColor[i]  = f; -    item->window.flags |= WINDOW_FORECOLORSET; -  } -  return qtrue; -} - -qboolean ItemParse_bordercolor( itemDef_t *item, int handle ) { -  int i; -  float f; - -  for (i = 0; i < 4; i++) { -    if (!PC_Float_Parse(handle, &f)) { -      return qfalse; -    } -    item->window.borderColor[i]  = f; -  } -  return qtrue; -} - -qboolean ItemParse_outlinecolor( itemDef_t *item, int handle ) { -  if (!PC_Color_Parse(handle, &item->window.outlineColor)){ -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_background( itemDef_t *item, int handle ) { -  const char *temp; - -  if (!PC_String_Parse(handle, &temp)) { -    return qfalse; -  } -  item->window.background = DC->registerShaderNoMip(temp); -  return qtrue; -} - -qboolean ItemParse_cinematic( itemDef_t *item, int handle ) { -  if (!PC_String_Parse(handle, &item->window.cinematicName)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_doubleClick( itemDef_t *item, int handle ) { -  listBoxDef_t *listPtr; - -  Item_ValidateTypeData(item); -  if (!item->typeData) { -    return qfalse; -  } - -  listPtr = (listBoxDef_t*)item->typeData; - -  if (!PC_Script_Parse(handle, &listPtr->doubleClick)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_onFocus( itemDef_t *item, int handle ) { -  if (!PC_Script_Parse(handle, &item->onFocus)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_leaveFocus( itemDef_t *item, int handle ) { -  if (!PC_Script_Parse(handle, &item->leaveFocus)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_mouseEnter( itemDef_t *item, int handle ) { -  if (!PC_Script_Parse(handle, &item->mouseEnter)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_mouseExit( itemDef_t *item, int handle ) { -  if (!PC_Script_Parse(handle, &item->mouseExit)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_mouseEnterText( itemDef_t *item, int handle ) { -  if (!PC_Script_Parse(handle, &item->mouseEnterText)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_mouseExitText( itemDef_t *item, int handle ) { -  if (!PC_Script_Parse(handle, &item->mouseExitText)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_action( itemDef_t *item, int handle ) { -  if (!PC_Script_Parse(handle, &item->action)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_special( itemDef_t *item, int handle ) { -  if (!PC_Float_Parse(handle, &item->special)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_cvarTest( itemDef_t *item, int handle ) { -  if (!PC_String_Parse(handle, &item->cvarTest)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean ItemParse_cvar( itemDef_t *item, int handle ) { -  editFieldDef_t *editPtr; - -  Item_ValidateTypeData(item); -  if (!PC_String_Parse(handle, &item->cvar)) { -    return qfalse; -  } -  if (item->typeData) { -    editPtr = (editFieldDef_t*)item->typeData; -    editPtr->minVal = -1; -    editPtr->maxVal = -1; -    editPtr->defVal = -1; -  } -  return qtrue; -} - -qboolean ItemParse_maxChars( itemDef_t *item, int handle ) { -  editFieldDef_t *editPtr; -  int maxChars; - -  Item_ValidateTypeData(item); -  if (!item->typeData) -    return qfalse; - -  if (!PC_Int_Parse(handle, &maxChars)) { -    return qfalse; -  } -  editPtr = (editFieldDef_t*)item->typeData; -  editPtr->maxChars = maxChars; -  return qtrue; -} - -qboolean ItemParse_maxPaintChars( itemDef_t *item, int handle ) { -  editFieldDef_t *editPtr; -  int maxChars; - -  Item_ValidateTypeData(item); -  if (!item->typeData) -    return qfalse; - -  if (!PC_Int_Parse(handle, &maxChars)) { -    return qfalse; -  } -  editPtr = (editFieldDef_t*)item->typeData; -  editPtr->maxPaintChars = maxChars; -  return qtrue; -} - - - -qboolean ItemParse_cvarFloat( itemDef_t *item, int handle ) { -  editFieldDef_t *editPtr; - -  Item_ValidateTypeData(item); -  if (!item->typeData) -    return qfalse; -  editPtr = (editFieldDef_t*)item->typeData; -  if (PC_String_Parse(handle, &item->cvar) && -    PC_Float_Parse(handle, &editPtr->defVal) && -    PC_Float_Parse(handle, &editPtr->minVal) && -    PC_Float_Parse(handle, &editPtr->maxVal)) { -    return qtrue; -  } -  return qfalse; -} - -qboolean ItemParse_cvarStrList( itemDef_t *item, int handle ) { -  pc_token_t token; -  multiDef_t *multiPtr; -  int pass; - -  Item_ValidateTypeData(item); -  if (!item->typeData) -    return qfalse; -  multiPtr = (multiDef_t*)item->typeData; -  multiPtr->count = 0; -  multiPtr->strDef = qtrue; - -  if (!trap_PC_ReadToken(handle, &token)) -    return qfalse; -  if (*token.string != '{') { -    return qfalse; -  } - -  pass = 0; -  while ( 1 ) { -    if (!trap_PC_ReadToken(handle, &token)) { -      PC_SourceError(handle, "end of file inside menu item\n"); -      return qfalse; -    } - -    if (*token.string == '}') { -      return qtrue; -    } - -    if (*token.string == ',' || *token.string == ';') { -      continue; -    } - -    if (pass == 0) { -      multiPtr->cvarList[multiPtr->count] = String_Alloc(token.string); -      pass = 1; -    } else { -      multiPtr->cvarStr[multiPtr->count] = String_Alloc(token.string); -      pass = 0; -      multiPtr->count++; -      if (multiPtr->count >= MAX_MULTI_CVARS) { -        return qfalse; -      } -    } - -  } -  return qfalse;  // bk001205 - LCC missing return value -} - -qboolean ItemParse_cvarFloatList( itemDef_t *item, int handle ) { -  pc_token_t token; -  multiDef_t *multiPtr; - -  Item_ValidateTypeData(item); -  if (!item->typeData) -    return qfalse; -  multiPtr = (multiDef_t*)item->typeData; -  multiPtr->count = 0; -  multiPtr->strDef = qfalse; - -  if (!trap_PC_ReadToken(handle, &token)) -    return qfalse; -  if (*token.string != '{') { -    return qfalse; -  } - -  while ( 1 ) { -    if (!trap_PC_ReadToken(handle, &token)) { -      PC_SourceError(handle, "end of file inside menu item\n"); -      return qfalse; -    } - -    if (*token.string == '}') { -      return qtrue; -    } - -    if (*token.string == ',' || *token.string == ';') { -      continue; -    } - -    multiPtr->cvarList[multiPtr->count] = String_Alloc(token.string); -    if (!PC_Float_Parse(handle, &multiPtr->cvarValue[multiPtr->count])) { -      return qfalse; -    } - -    multiPtr->count++; -    if (multiPtr->count >= MAX_MULTI_CVARS) { -      return qfalse; -    } - -  } -  return qfalse;  // bk001205 - LCC missing return value -} - - - -qboolean ItemParse_addColorRange( itemDef_t *item, int handle ) { -  colorRangeDef_t color; - -  if (PC_Float_Parse(handle, &color.low) && -    PC_Float_Parse(handle, &color.high) && -    PC_Color_Parse(handle, &color.color) ) { -    if (item->numColors < MAX_COLOR_RANGES) { -      memcpy(&item->colorRanges[item->numColors], &color, sizeof(color)); -      item->numColors++; -    } -    return qtrue; -  } -  return qfalse; -} - -qboolean ItemParse_ownerdrawFlag( itemDef_t *item, int handle ) { -  int i; -  if (!PC_Int_Parse(handle, &i)) { -    return qfalse; -  } -  item->window.ownerDrawFlags |= i; -  return qtrue; -} - -qboolean ItemParse_enableCvar( itemDef_t *item, int handle ) { -  if (PC_Script_Parse(handle, &item->enableCvar)) { -    item->cvarFlags = CVAR_ENABLE; -    return qtrue; -  } -  return qfalse; -} - -qboolean ItemParse_disableCvar( itemDef_t *item, int handle ) { -  if (PC_Script_Parse(handle, &item->enableCvar)) { -    item->cvarFlags = CVAR_DISABLE; -    return qtrue; -  } -  return qfalse; -} - -qboolean ItemParse_showCvar( itemDef_t *item, int handle ) { -  if (PC_Script_Parse(handle, &item->enableCvar)) { -    item->cvarFlags = CVAR_SHOW; -    return qtrue; -  } -  return qfalse; -} - -qboolean ItemParse_hideCvar( itemDef_t *item, int handle ) { -  if (PC_Script_Parse(handle, &item->enableCvar)) { -    item->cvarFlags = CVAR_HIDE; -    return qtrue; -  } -  return qfalse; -} - - -keywordHash_t itemParseKeywords[] = { -  {"name", ItemParse_name, NULL}, -  {"text", ItemParse_text, NULL}, -  {"group", ItemParse_group, NULL}, -  {"asset_model", ItemParse_asset_model, NULL}, -  {"asset_shader", ItemParse_asset_shader, NULL}, -  {"model_origin", ItemParse_model_origin, NULL}, -  {"model_fovx", ItemParse_model_fovx, NULL}, -  {"model_fovy", ItemParse_model_fovy, NULL}, -  {"model_rotation", ItemParse_model_rotation, NULL}, -  {"model_angle", ItemParse_model_angle, NULL}, -  {"rect", ItemParse_rect, NULL}, -  {"style", ItemParse_style, NULL}, -  {"decoration", ItemParse_decoration, NULL}, -  {"notselectable", ItemParse_notselectable, NULL}, -  {"wrapped", ItemParse_wrapped, NULL}, -  {"autowrapped", ItemParse_autowrapped, NULL}, -  {"horizontalscroll", ItemParse_horizontalscroll, NULL}, -  {"type", ItemParse_type, NULL}, -  {"elementwidth", ItemParse_elementwidth, NULL}, -  {"elementheight", ItemParse_elementheight, NULL}, -  {"feeder", ItemParse_feeder, NULL}, -  {"elementtype", ItemParse_elementtype, NULL}, -  {"columns", ItemParse_columns, NULL}, -  {"border", ItemParse_border, NULL}, -  {"bordersize", ItemParse_bordersize, NULL}, -  {"visible", ItemParse_visible, NULL}, -  {"ownerdraw", ItemParse_ownerdraw, NULL}, -  {"align", ItemParse_align, NULL}, -  {"textalign", ItemParse_textalign, NULL}, -  {"textalignx", ItemParse_textalignx, NULL}, -  {"textaligny", ItemParse_textaligny, NULL}, -  {"textscale", ItemParse_textscale, NULL}, -  {"textstyle", ItemParse_textstyle, NULL}, -  {"backcolor", ItemParse_backcolor, NULL}, -  {"forecolor", ItemParse_forecolor, NULL}, -  {"bordercolor", ItemParse_bordercolor, NULL}, -  {"outlinecolor", ItemParse_outlinecolor, NULL}, -  {"background", ItemParse_background, NULL}, -  {"onFocus", ItemParse_onFocus, NULL}, -  {"leaveFocus", ItemParse_leaveFocus, NULL}, -  {"mouseEnter", ItemParse_mouseEnter, NULL}, -  {"mouseExit", ItemParse_mouseExit, NULL}, -  {"mouseEnterText", ItemParse_mouseEnterText, NULL}, -  {"mouseExitText", ItemParse_mouseExitText, NULL}, -  {"action", ItemParse_action, NULL}, -  {"special", ItemParse_special, NULL}, -  {"cvar", ItemParse_cvar, NULL}, -  {"maxChars", ItemParse_maxChars, NULL}, -  {"maxPaintChars", ItemParse_maxPaintChars, NULL}, -  {"focusSound", ItemParse_focusSound, NULL}, -  {"cvarFloat", ItemParse_cvarFloat, NULL}, -  {"cvarStrList", ItemParse_cvarStrList, NULL}, -  {"cvarFloatList", ItemParse_cvarFloatList, NULL}, -  {"addColorRange", ItemParse_addColorRange, NULL}, -  {"ownerdrawFlag", ItemParse_ownerdrawFlag, NULL}, -  {"enableCvar", ItemParse_enableCvar, NULL}, -  {"cvarTest", ItemParse_cvarTest, NULL}, -  {"disableCvar", ItemParse_disableCvar, NULL}, -  {"showCvar", ItemParse_showCvar, NULL}, -  {"hideCvar", ItemParse_hideCvar, NULL}, -  {"cinematic", ItemParse_cinematic, NULL}, -  {"doubleclick", ItemParse_doubleClick, NULL}, -  {NULL, voidFunction2, NULL} -}; - -keywordHash_t *itemParseKeywordHash[KEYWORDHASH_SIZE]; - -/* -=============== -Item_SetupKeywordHash -=============== -*/ -void Item_SetupKeywordHash( void ) -{ -  int i; - -  memset( itemParseKeywordHash, 0, sizeof( itemParseKeywordHash ) ); - -  for( i = 0; itemParseKeywords[ i ].keyword; i++ ) -    KeywordHash_Add( itemParseKeywordHash, &itemParseKeywords[ i ] ); -} - -/* -=============== -Item_Parse -=============== -*/ -qboolean Item_Parse(int handle, itemDef_t *item) { -  pc_token_t token; -  keywordHash_t *key; - - -  if (!trap_PC_ReadToken(handle, &token)) -    return qfalse; -  if (*token.string != '{') { -    return qfalse; -  } -  while ( 1 ) { -    if (!trap_PC_ReadToken(handle, &token)) { -      PC_SourceError(handle, "end of file inside menu item\n"); -      return qfalse; -    } - -    if (*token.string == '}') { -      return qtrue; -    } - -    key = KeywordHash_Find(itemParseKeywordHash, token.string); -    if (!key) { -      PC_SourceError(handle, "unknown menu item keyword %s", token.string); -      continue; -    } -    if ( !key->func(item, handle) ) { -      PC_SourceError(handle, "couldn't parse menu item keyword %s", token.string); -      return qfalse; -    } -  } -  return qfalse;  // bk001205 - LCC missing return value -} - - -// Item_InitControls -// init's special control types -void Item_InitControls(itemDef_t *item) { -  if (item == NULL) { -    return; -  } -  if (item->type == ITEM_TYPE_LISTBOX) { -    listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData; -    item->cursorPos = 0; -    if (listPtr) { -      listPtr->cursorPos = 0; -      listPtr->startPos = 0; -      listPtr->endPos = 0; -      listPtr->cursorPos = 0; -    } -  } -} - -/* -=============== -Menu Keyword Parse functions -=============== -*/ - -qboolean MenuParse_font( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  if (!PC_String_Parse(handle, &menu->font)) { -    return qfalse; -  } -  if (!DC->Assets.fontRegistered) { -    DC->registerFont(menu->font, 48, &DC->Assets.textFont); -    DC->Assets.fontRegistered = qtrue; -  } -  return qtrue; -} - -qboolean MenuParse_name( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  if (!PC_String_Parse(handle, &menu->window.name)) { -    return qfalse; -  } -  if (Q_stricmp(menu->window.name, "main") == 0) { -    // default main as having focus -    //menu->window.flags |= WINDOW_HASFOCUS; -  } -  return qtrue; -} - -qboolean MenuParse_fullscreen( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  if (!PC_Int_Parse(handle, (int*) &menu->fullScreen)) { // bk001206 - cast qboolean -    return qfalse; -  } -  return qtrue; -} - -qboolean MenuParse_rect( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  if (!PC_Rect_Parse(handle, &menu->window.rect)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean MenuParse_style( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  if (!PC_Int_Parse(handle, &menu->window.style)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean MenuParse_visible( itemDef_t *item, int handle ) { -  int i; -  menuDef_t *menu = (menuDef_t*)item; - -  if (!PC_Int_Parse(handle, &i)) { -    return qfalse; -  } -  if (i) { -    menu->window.flags |= WINDOW_VISIBLE; -  } -  return qtrue; -} - -qboolean MenuParse_onOpen( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  if (!PC_Script_Parse(handle, &menu->onOpen)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean MenuParse_onClose( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  if (!PC_Script_Parse(handle, &menu->onClose)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean MenuParse_onESC( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  if (!PC_Script_Parse(handle, &menu->onESC)) { -    return qfalse; -  } -  return qtrue; -} - - - -qboolean MenuParse_border( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  if (!PC_Int_Parse(handle, &menu->window.border)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean MenuParse_borderSize( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  if (!PC_Float_Parse(handle, &menu->window.borderSize)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean MenuParse_backcolor( itemDef_t *item, int handle ) { -  int i; -  float f; -  menuDef_t *menu = (menuDef_t*)item; - -  for (i = 0; i < 4; i++) { -    if (!PC_Float_Parse(handle, &f)) { -      return qfalse; -    } -    menu->window.backColor[i]  = f; -  } -  return qtrue; -} - -qboolean MenuParse_forecolor( itemDef_t *item, int handle ) { -  int i; -  float f; -  menuDef_t *menu = (menuDef_t*)item; - -  for (i = 0; i < 4; i++) { -    if (!PC_Float_Parse(handle, &f)) { -      return qfalse; -    } -    menu->window.foreColor[i]  = f; -    menu->window.flags |= WINDOW_FORECOLORSET; -  } -  return qtrue; -} - -qboolean MenuParse_bordercolor( itemDef_t *item, int handle ) { -  int i; -  float f; -  menuDef_t *menu = (menuDef_t*)item; - -  for (i = 0; i < 4; i++) { -    if (!PC_Float_Parse(handle, &f)) { -      return qfalse; -    } -    menu->window.borderColor[i]  = f; -  } -  return qtrue; -} - -qboolean MenuParse_focuscolor( itemDef_t *item, int handle ) { -  int i; -  float f; -  menuDef_t *menu = (menuDef_t*)item; - -  for (i = 0; i < 4; i++) { -    if (!PC_Float_Parse(handle, &f)) { -      return qfalse; -    } -    menu->focusColor[i]  = f; -  } -  return qtrue; -} - -qboolean MenuParse_disablecolor( itemDef_t *item, int handle ) { -  int i; -  float f; -  menuDef_t *menu = (menuDef_t*)item; -  for (i = 0; i < 4; i++) { -    if (!PC_Float_Parse(handle, &f)) { -      return qfalse; -    } -    menu->disableColor[i]  = f; -  } -  return qtrue; -} - - -qboolean MenuParse_outlinecolor( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  if (!PC_Color_Parse(handle, &menu->window.outlineColor)){ -    return qfalse; -  } -  return qtrue; -} - -qboolean MenuParse_background( itemDef_t *item, int handle ) { -  const char *buff; -  menuDef_t *menu = (menuDef_t*)item; - -  if (!PC_String_Parse(handle, &buff)) { -    return qfalse; -  } -  menu->window.background = DC->registerShaderNoMip(buff); -  return qtrue; -} - -qboolean MenuParse_cinematic( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; - -  if (!PC_String_Parse(handle, &menu->window.cinematicName)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean MenuParse_ownerdrawFlag( itemDef_t *item, int handle ) { -  int i; -  menuDef_t *menu = (menuDef_t*)item; - -  if (!PC_Int_Parse(handle, &i)) { -    return qfalse; -  } -  menu->window.ownerDrawFlags |= i; -  return qtrue; -} - -qboolean MenuParse_ownerdraw( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; - -  if (!PC_Int_Parse(handle, &menu->window.ownerDraw)) { -    return qfalse; -  } -  return qtrue; -} - - -// decoration -qboolean MenuParse_popup( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  menu->window.flags |= WINDOW_POPUP; -  return qtrue; -} - - -qboolean MenuParse_outOfBounds( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; - -  menu->window.flags |= WINDOW_OOB_CLICK; -  return qtrue; -} - -qboolean MenuParse_soundLoop( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; - -  if (!PC_String_Parse(handle, &menu->soundName)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean MenuParse_fadeClamp( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; - -  if (!PC_Float_Parse(handle, &menu->fadeClamp)) { -    return qfalse; -  } -  return qtrue; -} - -qboolean MenuParse_fadeAmount( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; - -  if (!PC_Float_Parse(handle, &menu->fadeAmount)) { -    return qfalse; -  } -  return qtrue; -} - - -qboolean MenuParse_fadeCycle( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; - -  if (!PC_Int_Parse(handle, &menu->fadeCycle)) { -    return qfalse; -  } -  return qtrue; -} - - -qboolean MenuParse_itemDef( itemDef_t *item, int handle ) { -  menuDef_t *menu = (menuDef_t*)item; -  if (menu->itemCount < MAX_MENUITEMS) { -    menu->items[menu->itemCount] = UI_Alloc(sizeof(itemDef_t)); -    Item_Init(menu->items[menu->itemCount]); -    if (!Item_Parse(handle, menu->items[menu->itemCount])) { -      return qfalse; -    } -    Item_InitControls(menu->items[menu->itemCount]); -    menu->items[menu->itemCount++]->parent = menu; -  } -  return qtrue; -} - -keywordHash_t menuParseKeywords[] = { -  {"font", MenuParse_font, NULL}, -  {"name", MenuParse_name, NULL}, -  {"fullscreen", MenuParse_fullscreen, NULL}, -  {"rect", MenuParse_rect, NULL}, -  {"style", MenuParse_style, NULL}, -  {"visible", MenuParse_visible, NULL}, -  {"onOpen", MenuParse_onOpen, NULL}, -  {"onClose", MenuParse_onClose, NULL}, -  {"onESC", MenuParse_onESC, NULL}, -  {"border", MenuParse_border, NULL}, -  {"borderSize", MenuParse_borderSize, NULL}, -  {"backcolor", MenuParse_backcolor, NULL}, -  {"forecolor", MenuParse_forecolor, NULL}, -  {"bordercolor", MenuParse_bordercolor, NULL}, -  {"focuscolor", MenuParse_focuscolor, NULL}, -  {"disablecolor", MenuParse_disablecolor, NULL}, -  {"outlinecolor", MenuParse_outlinecolor, NULL}, -  {"background", MenuParse_background, NULL}, -  {"ownerdraw", MenuParse_ownerdraw, NULL}, -  {"ownerdrawFlag", MenuParse_ownerdrawFlag, NULL}, -  {"outOfBoundsClick", MenuParse_outOfBounds, NULL}, -  {"soundLoop", MenuParse_soundLoop, NULL}, -  {"itemDef", MenuParse_itemDef, NULL}, -  {"cinematic", MenuParse_cinematic, NULL}, -  {"popup", MenuParse_popup, NULL}, -  {"fadeClamp", MenuParse_fadeClamp, NULL}, -  {"fadeCycle", MenuParse_fadeCycle, NULL}, -  {"fadeAmount", MenuParse_fadeAmount, NULL}, -  {NULL, voidFunction2, NULL} -}; - -keywordHash_t *menuParseKeywordHash[KEYWORDHASH_SIZE]; - -/* -=============== -Menu_SetupKeywordHash -=============== -*/ -void Menu_SetupKeywordHash( void ) -{ -  int i; - -  memset( menuParseKeywordHash, 0, sizeof( menuParseKeywordHash ) ); - -  for(i = 0; menuParseKeywords[ i ].keyword; i++ ) -    KeywordHash_Add( menuParseKeywordHash, &menuParseKeywords[ i ] ); -} - -/* -=============== -Menu_Parse -=============== -*/ -qboolean Menu_Parse(int handle, menuDef_t *menu) { -  pc_token_t token; -  keywordHash_t *key; - -  if (!trap_PC_ReadToken(handle, &token)) -    return qfalse; -  if (*token.string != '{') { -    return qfalse; -  } - -  while ( 1 ) { - -    memset(&token, 0, sizeof(pc_token_t)); -    if (!trap_PC_ReadToken(handle, &token)) { -      PC_SourceError(handle, "end of file inside menu\n"); -      return qfalse; -    } - -    if (*token.string == '}') { -      return qtrue; -    } - -    key = KeywordHash_Find(menuParseKeywordHash, token.string); -    if (!key) { -      PC_SourceError(handle, "unknown menu keyword %s", token.string); -      continue; -    } -    if ( !key->func((itemDef_t*)menu, handle) ) { -      PC_SourceError(handle, "couldn't parse menu keyword %s", token.string); -      return qfalse; -    } -  } -  return qfalse;  // bk001205 - LCC missing return value -} - -/* -=============== -Menu_New -=============== -*/ -void Menu_New(int handle) { -  menuDef_t *menu = &Menus[menuCount]; - -  if (menuCount < MAX_MENUS) { -    Menu_Init(menu); -    if (Menu_Parse(handle, menu)) { -      Menu_PostParse(menu); -      menuCount++; -    } -  } -} - -int Menu_Count( void ) { -  return menuCount; -} - -void Menu_PaintAll( void ) { -  int i; -  if (captureFunc) { -    captureFunc(captureData); -  } - -  for (i = 0; i < Menu_Count(); i++) { -    Menu_Paint(&Menus[i], qfalse); -  } - -  if (debugMode) { -    vec4_t v = {1, 1, 1, 1}; -    DC->drawText(5, 25, .5, v, va("fps: %f", DC->FPS), 0, 0, 0); -  } -} - -void Menu_Reset( void ) -{ -  menuCount = 0; -} - -displayContextDef_t *Display_GetContext( void ) { -  return DC; -} - -void *Display_CaptureItem(int x, int y) { -  int i; - -  for (i = 0; i < menuCount; i++) { -    // turn off focus each item -    // menu->items[i].window.flags &= ~WINDOW_HASFOCUS; -    if (Rect_ContainsPoint(&Menus[i].window.rect, x, y)) { -      return &Menus[i]; -    } -  } -  return NULL; -} - - -// FIXME: -qboolean Display_MouseMove(void *p, int x, int y) { -  int i; -  menuDef_t *menu = p; - -  if (menu == NULL) { -    menu = Menu_GetFocused(); -    if (menu) { -      if (menu->window.flags & WINDOW_POPUP) { -        Menu_HandleMouseMove(menu, x, y); -        return qtrue; -      } -    } -    for (i = 0; i < menuCount; i++) { -      Menu_HandleMouseMove(&Menus[i], x, y); -    } -  } else { -    menu->window.rect.x += x; -    menu->window.rect.y += y; -    Menu_UpdatePosition(menu); -  } -  return qtrue; - -} - -int Display_CursorType(int x, int y) { -  int i; -  for (i = 0; i < menuCount; i++) { -    rectDef_t r2; -    r2.x = Menus[i].window.rect.x - 3; -    r2.y = Menus[i].window.rect.y - 3; -    r2.w = r2.h = 7; -    if (Rect_ContainsPoint(&r2, x, y)) { -      return CURSOR_SIZER; -    } -  } -  return CURSOR_ARROW; -} - - -void Display_HandleKey(int key, qboolean down, int x, int y) { -  menuDef_t *menu = Display_CaptureItem(x, y); -  if (menu == NULL) { -    menu = Menu_GetFocused(); -  } -  if (menu) { -    Menu_HandleKey(menu, key, down ); -  } -} - -static void Window_CacheContents(windowDef_t *window) { -  if (window) { -    if (window->cinematicName) { -      int cin = DC->playCinematic(window->cinematicName, 0, 0, 0, 0); -      DC->stopCinematic(cin); -    } -  } -} - - -static void Item_CacheContents(itemDef_t *item) { -  if (item) { -    Window_CacheContents(&item->window); -  } - -} - -static void Menu_CacheContents(menuDef_t *menu) { -  if (menu) { -    int i; -    Window_CacheContents(&menu->window); -    for (i = 0; i < menu->itemCount; i++) { -      Item_CacheContents(menu->items[i]); -    } - -    if (menu->soundName && *menu->soundName) { -      DC->registerSound(menu->soundName, qfalse); -    } -  } - -} - -void Display_CacheAll( void ) { -  int i; -  for (i = 0; i < menuCount; i++) { -    Menu_CacheContents(&Menus[i]); -  } -} - - -static qboolean Menu_OverActiveItem(menuDef_t *menu, float x, float y) { -  if (menu && menu->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED)) { -    if (Rect_ContainsPoint(&menu->window.rect, x, y)) { -      int i; -      for (i = 0; i < menu->itemCount; i++) { -        // turn off focus each item -        // menu->items[i].window.flags &= ~WINDOW_HASFOCUS; - -        if (!(menu->items[i]->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED))) { -          continue; -        } - -        if (menu->items[i]->window.flags & WINDOW_DECORATION) { -          continue; -        } - -        if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) { -          itemDef_t *overItem = menu->items[i]; -          if (overItem->type == ITEM_TYPE_TEXT && overItem->text) { -            if (Rect_ContainsPoint(Item_CorrectedTextRect(overItem), x, y)) { -              return qtrue; -            } else { -              continue; -            } -          } else { -            return qtrue; -          } -        } -      } - -    } -  } -  return qfalse; -} - diff --git a/mod/src/ui/ui_shared.h b/mod/src/ui/ui_shared.h deleted file mode 100644 index b41b97e5..00000000 --- a/mod/src/ui/ui_shared.h +++ /dev/null @@ -1,444 +0,0 @@ -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#ifndef __UI_SHARED_H -#define __UI_SHARED_H - - -#include "../game/q_shared.h" -#include "../cgame/tr_types.h" -#include "keycodes.h" - -#include "../../ui/menudef.h" - -#define MAX_MENUNAME 32 -#define MAX_ITEMTEXT 64 -#define MAX_ITEMACTION 64 -#define MAX_MENUDEFFILE 4096 -#define MAX_MENUFILE 32768 -#define MAX_MENUS 256 -#define MAX_MENUITEMS 96 -#define MAX_COLOR_RANGES 10 -#define MAX_OPEN_MENUS 16 - -#define WINDOW_MOUSEOVER      0x00000001  // mouse is over it, non exclusive -#define WINDOW_HASFOCUS        0x00000002  // has cursor focus, exclusive -#define WINDOW_VISIBLE        0x00000004  // is visible -#define WINDOW_GREY            0x00000008  // is visible but grey ( non-active ) -#define WINDOW_DECORATION      0x00000010  // for decoration only, no mouse, keyboard, etc.. -#define WINDOW_FADINGOUT      0x00000020  // fading out, non-active -#define WINDOW_FADINGIN        0x00000040  // fading in -#define WINDOW_MOUSEOVERTEXT  0x00000080  // mouse is over it, non exclusive -#define WINDOW_INTRANSITION    0x00000100  // window is in transition -#define WINDOW_FORECOLORSET    0x00000200  // forecolor was explicitly set ( used to color alpha images or not ) -#define WINDOW_HORIZONTAL      0x00000400  // for list boxes and sliders, vertical is default this is set of horizontal -#define WINDOW_LB_LEFTARROW    0x00000800  // mouse is over left/up arrow -#define WINDOW_LB_RIGHTARROW  0x00001000  // mouse is over right/down arrow -#define WINDOW_LB_THUMB        0x00002000  // mouse is over thumb -#define WINDOW_LB_PGUP        0x00004000  // mouse is over page up -#define WINDOW_LB_PGDN        0x00008000  // mouse is over page down -#define WINDOW_ORBITING        0x00010000  // item is in orbit -#define WINDOW_OOB_CLICK      0x00020000  // close on out of bounds click -#define WINDOW_WRAPPED        0x00040000  // manually wrap text -#define WINDOW_AUTOWRAPPED      0x00080000  // auto wrap text -#define WINDOW_FORCED          0x00100000  // forced open -#define WINDOW_POPUP          0x00200000  // popup -#define WINDOW_BACKCOLORSET    0x00400000  // backcolor was explicitly set -#define WINDOW_TIMEDVISIBLE    0x00800000  // visibility timing ( NOT implemented ) - - -// CGAME cursor type bits -#define CURSOR_NONE          0x00000001 -#define CURSOR_ARROW        0x00000002 -#define CURSOR_SIZER        0x00000004 - -#ifdef CGAME -#define STRING_POOL_SIZE 128*1024 -#else -#define STRING_POOL_SIZE 384*1024 -#endif -#define MAX_STRING_HANDLES 4096 - -#define MAX_SCRIPT_ARGS 12 -#define MAX_EDITFIELD 256 - -#define ART_FX_BASE      "menu/art/fx_base" -#define ART_FX_BLUE      "menu/art/fx_blue" -#define ART_FX_CYAN      "menu/art/fx_cyan" -#define ART_FX_GREEN    "menu/art/fx_grn" -#define ART_FX_RED      "menu/art/fx_red" -#define ART_FX_TEAL      "menu/art/fx_teal" -#define ART_FX_WHITE    "menu/art/fx_white" -#define ART_FX_YELLOW    "menu/art/fx_yel" - -#define ASSET_GRADIENTBAR "ui/assets/gradientbar2.tga" -#define ASSET_SCROLLBAR             "ui/assets/scrollbar.tga" -#define ASSET_SCROLLBAR_ARROWDOWN   "ui/assets/scrollbar_arrow_dwn_a.tga" -#define ASSET_SCROLLBAR_ARROWUP     "ui/assets/scrollbar_arrow_up_a.tga" -#define ASSET_SCROLLBAR_ARROWLEFT   "ui/assets/scrollbar_arrow_left.tga" -#define ASSET_SCROLLBAR_ARROWRIGHT  "ui/assets/scrollbar_arrow_right.tga" -#define ASSET_SCROLL_THUMB          "ui/assets/scrollbar_thumb.tga" -#define ASSET_SLIDER_BAR            "ui/assets/slider2.tga" -#define ASSET_SLIDER_THUMB          "ui/assets/sliderbutt_1.tga" -#define SCROLLBAR_SIZE 16.0 -#define SLIDER_WIDTH 96.0 -#define SLIDER_HEIGHT 16.0 -#define SLIDER_THUMB_WIDTH 12.0 -#define SLIDER_THUMB_HEIGHT 20.0 -#define  NUM_CROSSHAIRS      10 - -typedef struct { -  const char *command; -  const char *args[MAX_SCRIPT_ARGS]; -} scriptDef_t; - - -typedef struct { -  float x;    // horiz position -  float y;    // vert position -  float w;    // width -  float h;    // height; -} rectDef_t; - -typedef rectDef_t Rectangle; - -// FIXME: do something to separate text vs window stuff -typedef struct { -  Rectangle rect;                 // client coord rectangle -  Rectangle rectClient;           // screen coord rectangle -  const char *name;               // -  const char *group;              // if it belongs to a group -  const char *cinematicName;      // cinematic name -  int cinematic;                  // cinematic handle -  int style;                      // -  int border;                     // -  int ownerDraw;                  // ownerDraw style -  int ownerDrawFlags;              // show flags for ownerdraw items -  float borderSize;               // -  int flags;                      // visible, focus, mouseover, cursor -  Rectangle rectEffects;          // for various effects -  Rectangle rectEffects2;         // for various effects -  int offsetTime;                 // time based value for various effects -  int nextTime;                   // time next effect should cycle -  vec4_t foreColor;               // text color -  vec4_t backColor;               // border color -  vec4_t borderColor;             // border color -  vec4_t outlineColor;            // border color -  qhandle_t background;           // background asset -} windowDef_t; - -typedef windowDef_t Window; - -typedef struct { -  vec4_t  color; -  float    low; -  float    high; -} colorRangeDef_t; - -// FIXME: combine flags into bitfields to save space -// FIXME: consolidate all of the common stuff in one structure for menus and items -// THINKABOUTME: is there any compelling reason not to have items contain items -// and do away with a menu per say.. major issue is not being able to dynamically allocate -// and destroy stuff.. Another point to consider is adding an alloc free call for vm's and have -// the engine just allocate the pool for it based on a cvar -// many of the vars are re-used for different item types, as such they are not always named appropriately -// the benefits of c++ in DOOM will greatly help crap like this -// FIXME: need to put a type ptr that points to specific type info per type -// -#define MAX_LB_COLUMNS 16 - -typedef struct columnInfo_s { -  int pos; -  int width; -  int maxChars; -  int align; -} columnInfo_t; - -typedef struct listBoxDef_s { -  int startPos; -  int endPos; -  int drawPadding; -  int cursorPos; -  float elementWidth; -  float elementHeight; -  int elementStyle; -  int numColumns; -  columnInfo_t columnInfo[MAX_LB_COLUMNS]; -  const char *doubleClick; -  qboolean notselectable; -} listBoxDef_t; - -typedef struct editFieldDef_s { -  float minVal;                  //  edit field limits -  float maxVal;                  // -  float defVal;                  // -  float range;                   // -  int maxChars;                  // for edit fields -  int maxPaintChars;             // for edit fields -  int paintOffset;               // -} editFieldDef_t; - -#define MAX_MULTI_CVARS 32 - -typedef struct multiDef_s { -  const char *cvarList[MAX_MULTI_CVARS]; -  const char *cvarStr[MAX_MULTI_CVARS]; -  float cvarValue[MAX_MULTI_CVARS]; -  int count; -  qboolean strDef; -} multiDef_t; - -typedef struct modelDef_s { -  int angle; -  vec3_t origin; -  float fov_x; -  float fov_y; -  int rotationSpeed; -} modelDef_t; - -#define CVAR_ENABLE    0x00000001 -#define CVAR_DISABLE  0x00000002 -#define CVAR_SHOW      0x00000004 -#define CVAR_HIDE      0x00000008 - -typedef struct itemDef_s { -  Window window;                 // common positional, border, style, layout info -  Rectangle textRect;            // rectangle the text ( if any ) consumes -  int type;                      // text, button, radiobutton, checkbox, textfield, listbox, combo -  int alignment;                 // left center right -  int textalignment;             // ( optional ) alignment for text within rect based on text width -  float textalignx;              // ( optional ) text alignment x coord -  float textaligny;              // ( optional ) text alignment x coord -  float textscale;               // scale percentage from 72pts -  int textStyle;                 // ( optional ) style, normal and shadowed are it for now -  const char *text;              // display text -  void *parent;                  // menu owner -  qhandle_t asset;               // handle to asset -  const char *mouseEnterText;    // mouse enter script -  const char *mouseExitText;     // mouse exit script -  const char *mouseEnter;        // mouse enter script -  const char *mouseExit;         // mouse exit script -  const char *action;            // select script -  const char *onFocus;           // select script -  const char *leaveFocus;        // select script -  const char *cvar;              // associated cvar -  const char *cvarTest;          // associated cvar for enable actions -  const char *enableCvar;         // enable, disable, show, or hide based on value, this can contain a list -  int cvarFlags;                 //  what type of action to take on cvarenables -  sfxHandle_t focusSound; -  int numColors;                 // number of color ranges -  colorRangeDef_t colorRanges[MAX_COLOR_RANGES]; -  float special;                 // used for feeder id's etc.. diff per type -  int cursorPos;                 // cursor position in characters -  void *typeData;                 // type specific data ptr's -} itemDef_t; - -typedef struct { -  Window window; -  const char  *font;                // font -  qboolean fullScreen;              // covers entire screen -  int itemCount;                    // number of items; -  int fontIndex;                    // -  int cursorItem;                    // which item as the cursor -  int fadeCycle;                    // -  float fadeClamp;                  // -  float fadeAmount;                  // -  const char *onOpen;                // run when the menu is first opened -  const char *onClose;              // run when the menu is closed -  const char *onESC;                // run when the menu is closed -  const char *soundName;            // background loop sound for menu - -  vec4_t focusColor;                // focus color for items -  vec4_t disableColor;              // focus color for items -  itemDef_t *items[MAX_MENUITEMS];  // items this menu contains -} menuDef_t; - -typedef struct { -  const char *fontStr; -  const char *cursorStr; -  const char *gradientStr; -  fontInfo_t textFont; -  fontInfo_t smallFont; -  fontInfo_t bigFont; -  qhandle_t cursor; -  qhandle_t gradientBar; -  qhandle_t scrollBarArrowUp; -  qhandle_t scrollBarArrowDown; -  qhandle_t scrollBarArrowLeft; -  qhandle_t scrollBarArrowRight; -  qhandle_t scrollBar; -  qhandle_t scrollBarThumb; -  qhandle_t buttonMiddle; -  qhandle_t buttonInside; -  qhandle_t solidBox; -  qhandle_t sliderBar; -  qhandle_t sliderThumb; -  sfxHandle_t menuEnterSound; -  sfxHandle_t menuExitSound; -  sfxHandle_t menuBuzzSound; -  sfxHandle_t itemFocusSound; -  float fadeClamp; -  int fadeCycle; -  float fadeAmount; -  float shadowX; -  float shadowY; -  vec4_t shadowColor; -  float shadowFadeClamp; -  qboolean fontRegistered; - -} cachedAssets_t; - -typedef struct { -  const char *name; -  void (*handler) (itemDef_t *item, char** args); -} commandDef_t; - -typedef struct { -  qhandle_t (*registerShaderNoMip) (const char *p); -  void (*setColor) (const vec4_t v); -  void (*drawHandlePic) (float x, float y, float w, float h, qhandle_t asset); -  void (*drawStretchPic) (float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader ); -  void (*drawText) (float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style ); -  int (*textWidth) (const char *text, float scale, int limit); -  int (*textHeight) (const char *text, float scale, int limit); -  qhandle_t (*registerModel) (const char *p); -  void (*modelBounds) (qhandle_t model, vec3_t min, vec3_t max); -  void (*fillRect) ( float x, float y, float w, float h, const vec4_t color); -  void (*drawRect) ( float x, float y, float w, float h, float size, const vec4_t color); -  void (*drawSides) (float x, float y, float w, float h, float size); -  void (*drawTopBottom) (float x, float y, float w, float h, float size); -  void (*clearScene) (void); -  void (*addRefEntityToScene) (const refEntity_t *re ); -  void (*renderScene) ( const refdef_t *fd ); -  void (*registerFont) (const char *pFontname, int pointSize, fontInfo_t *font); -  void (*ownerDrawItem) (float x, float y, float w, float h, float text_x, float text_y, int ownerDraw, int ownerDrawFlags, int align, float special, float scale, vec4_t color, qhandle_t shader, int textStyle); -  float (*getValue) (int ownerDraw); -  qboolean (*ownerDrawVisible) (int flags); -  void (*runScript)(char **p); -  void (*getTeamColor)(vec4_t *color); -  void (*getCVarString)(const char *cvar, char *buffer, int bufsize); -  float (*getCVarValue)(const char *cvar); -  void (*setCVar)(const char *cvar, const char *value); -  void (*drawTextWithCursor)(float x, float y, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int limit, int style); -  void (*setOverstrikeMode)(qboolean b); -  qboolean (*getOverstrikeMode)(); -  void (*startLocalSound)( sfxHandle_t sfx, int channelNum ); -  qboolean (*ownerDrawHandleKey)(int ownerDraw, int flags, float *special, int key); -  int (*feederCount)(float feederID); -  const char *(*feederItemText)(float feederID, int index, int column, qhandle_t *handle); -  qhandle_t (*feederItemImage)(float feederID, int index); -  void (*feederSelection)(float feederID, int index); -  void (*keynumToStringBuf)( int keynum, char *buf, int buflen ); -  void (*getBindingBuf)( int keynum, char *buf, int buflen ); -  void (*setBinding)( int keynum, const char *binding ); -  void (*executeText)(int exec_when, const char *text ); -  void (*Error)(int level, const char *error, ...); -  void (*Print)(const char *msg, ...); -  void (*Pause)(qboolean b); -  int (*ownerDrawWidth)(int ownerDraw, float scale); -  sfxHandle_t (*registerSound)(const char *name, qboolean compressed); -  void (*startBackgroundTrack)( const char *intro, const char *loop); -  void (*stopBackgroundTrack)( void ); -  int (*playCinematic)(const char *name, float x, float y, float w, float h); -  void (*stopCinematic)(int handle); -  void (*drawCinematic)(int handle, float x, float y, float w, float h); -  void (*runCinematicFrame)(int handle); - -  float      yscale; -  float      xscale; -  float      bias; -  int        realTime; -  int        frameTime; -  int        cursorx; -  int        cursory; -  qboolean  debug; - -  cachedAssets_t Assets; - -  glconfig_t glconfig; -  qhandle_t  whiteShader; -  qhandle_t gradientImage; -  qhandle_t cursor; -  float FPS; - -} displayContextDef_t; - -const char *String_Alloc(const char *p); -void String_Init( void ); -void String_Report( void ); -void Init_Display(displayContextDef_t *dc); -void Display_ExpandMacros(char * buff); -void Menu_Init(menuDef_t *menu); -void Item_Init(itemDef_t *item); -void Menu_PostParse(menuDef_t *menu); -menuDef_t *Menu_GetFocused( void ); -void Menu_HandleKey(menuDef_t *menu, int key, qboolean down); -void Menu_HandleMouseMove(menuDef_t *menu, float x, float y); -void Menu_ScrollFeeder(menuDef_t *menu, int feeder, qboolean down); -qboolean Float_Parse(char **p, float *f); -qboolean Color_Parse(char **p, vec4_t *c); -qboolean Int_Parse(char **p, int *i); -qboolean Rect_Parse(char **p, rectDef_t *r); -qboolean String_Parse(char **p, const char **out); -qboolean Script_Parse(char **p, const char **out); -qboolean PC_Float_Parse(int handle, float *f); -qboolean PC_Color_Parse(int handle, vec4_t *c); -qboolean PC_Int_Parse(int handle, int *i); -qboolean PC_Rect_Parse(int handle, rectDef_t *r); -qboolean PC_String_Parse(int handle, const char **out); -qboolean PC_Script_Parse(int handle, const char **out); -int Menu_Count( void ); -void Menu_New(int handle); -void Menu_PaintAll( void ); -menuDef_t *Menus_ActivateByName(const char *p); -void Menu_Reset( void ); -qboolean Menus_AnyFullScreenVisible(); -void  Menus_Activate(menuDef_t *menu); - -displayContextDef_t *Display_GetContext( void ); -void *Display_CaptureItem(int x, int y); -qboolean Display_MouseMove(void *p, int x, int y); -int Display_CursorType(int x, int y); -qboolean Display_KeyBindPending( void ); -void Menus_OpenByName(const char *p); -menuDef_t *Menus_FindByName(const char *p); -void Menus_ShowByName(const char *p); -void Menus_CloseByName(const char *p); -void Display_HandleKey(int key, qboolean down, int x, int y); -void LerpColor(vec4_t a, vec4_t b, vec4_t c, float t); -void Menus_CloseAll( void ); -void Menu_Paint(menuDef_t *menu, qboolean forcePaint); -void Menu_SetFeederSelection(menuDef_t *menu, int feeder, int index, const char *name); -void Display_CacheAll( void ); - -void *UI_Alloc( int size ); -void UI_InitMemory( void ); -qboolean UI_OutOfMemory( void ); - -void Controls_GetConfig( void ); -void Controls_SetConfig(qboolean restart); -void Controls_SetDefaults( void ); - -//for cg_draw.c -void Item_Text_AutoWrapped_Paint( itemDef_t *item ); - -int      trap_PC_AddGlobalDefine( char *define ); -int      trap_PC_LoadSource( const char *filename ); -int      trap_PC_FreeSource( int handle ); -int      trap_PC_ReadToken( int handle, pc_token_t *pc_token ); -int      trap_PC_SourceFileAndLine( int handle, char *filename, int *line ); - -void    BindingFromName( const char *cvar ); -extern char g_nameBind1[ 32 ]; -extern char g_nameBind2[ 32 ]; -#endif diff --git a/mod/src/ui/ui_syscalls.asm b/mod/src/ui/ui_syscalls.asm deleted file mode 100644 index 54255f29..00000000 --- a/mod/src/ui/ui_syscalls.asm +++ /dev/null @@ -1,103 +0,0 @@ -code - -equ trap_Error                        -1 -equ trap_Print                        -2 -equ trap_Milliseconds                 -3 -equ trap_Cvar_Set                     -4 -equ trap_Cvar_VariableValue           -5 -equ trap_Cvar_VariableStringBuffer    -6 -equ trap_Cvar_SetValue                -7 -equ trap_Cvar_Reset                   -8 -equ trap_Cvar_Create                  -9 -equ trap_Cvar_InfoStringBuffer        -10 -equ trap_Argc                         -11 -equ trap_Argv                         -12 -equ trap_Cmd_ExecuteText              -13 -equ trap_FS_FOpenFile                 -14 -equ trap_FS_Read                      -15 -equ trap_FS_Write                     -16 -equ trap_FS_FCloseFile                -17 -equ trap_FS_GetFileList               -18 -equ trap_R_RegisterModel              -19 -equ trap_R_RegisterSkin               -20 -equ trap_R_RegisterShaderNoMip        -21 -equ trap_R_ClearScene                 -22 -equ trap_R_AddRefEntityToScene        -23 -equ trap_R_AddPolyToScene             -24 -equ trap_R_AddLightToScene            -25 -equ trap_R_RenderScene                -26 -equ trap_R_SetColor                   -27 -equ trap_R_DrawStretchPic             -28 -equ trap_UpdateScreen                 -29 -equ trap_CM_LerpTag                   -30 -equ trap_CM_LoadModel                 -31 -equ trap_S_RegisterSound              -32 -equ trap_S_StartLocalSound            -33 -equ trap_Key_KeynumToStringBuf        -34 -equ trap_Key_GetBindingBuf            -35 -equ trap_Key_SetBinding               -36 -equ trap_Key_IsDown                   -37 -equ trap_Key_GetOverstrikeMode        -38 -equ trap_Key_SetOverstrikeMode        -39 -equ trap_Key_ClearStates              -40 -equ trap_Key_GetCatcher               -41 -equ trap_Key_SetCatcher               -42         -equ trap_GetClipboardData             -43 -equ trap_GetGlconfig                  -44 -equ trap_GetClientState               -45 -equ trap_GetConfigString              -46 -equ trap_LAN_GetPingQueueCount        -47 -equ trap_LAN_ClearPing                -48 -equ trap_LAN_GetPing                  -49 -equ trap_LAN_GetPingInfo              -50 -equ trap_Cvar_Register                -51 -equ trap_Cvar_Update                  -52 -equ trap_MemoryRemaining              -53 -equ trap_GetCDKey                     -54 -equ trap_SetCDKey                     -55 -equ trap_R_RegisterFont               -56 -equ trap_R_ModelBounds                -57 -equ trap_PC_AddGlobalDefine           -58 -equ trap_PC_LoadSource                -59 -equ trap_PC_FreeSource                -60 -equ trap_PC_ReadToken                 -61 -equ trap_PC_SourceFileAndLine         -62 -equ trap_S_StopBackgroundTrack        -63 -equ trap_S_StartBackgroundTrack       -64 -equ trap_RealTime                     -65 -equ trap_LAN_GetServerCount           -66 -equ trap_LAN_GetServerAddressString   -67 -equ trap_LAN_GetServerInfo            -68 -equ trap_LAN_MarkServerVisible        -69 -equ trap_LAN_UpdateVisiblePings       -70 -equ trap_LAN_ResetPings               -71 -equ trap_LAN_LoadCachedServers        -72 -equ trap_LAN_SaveCachedServers        -73 -equ trap_LAN_AddServer                -74 -equ trap_LAN_RemoveServer             -75 -equ trap_CIN_PlayCinematic            -76 -equ trap_CIN_StopCinematic            -77 -equ trap_CIN_RunCinematic             -78 -equ trap_CIN_DrawCinematic            -79 -equ trap_CIN_SetExtents               -80 -equ trap_R_RemapShader                -81 -equ trap_VerifyCDKey                  -82 -equ trap_LAN_ServerStatus             -83 -equ trap_LAN_GetServerPing            -84 -equ trap_LAN_ServerIsVisible          -85 -equ trap_LAN_CompareServers           -86 -equ trap_FS_Seek                      -87 -equ trap_SetPbClStatus                -88 - - - -equ memset                            -101 -equ memcpy                            -102 -equ strncpy                           -103 -equ sin                               -104 -equ cos                               -105 -equ atan2                             -106 -equ sqrt                              -107 -equ floor                             -108 -equ ceil                              -109 - diff --git a/mod/src/ui/ui_syscalls.c b/mod/src/ui/ui_syscalls.c deleted file mode 100644 index cef3b74f..00000000 --- a/mod/src/ui/ui_syscalls.c +++ /dev/null @@ -1,392 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - *  Portions Copyright (C) 2000-2001 Tim Angus - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the OSML - Open Source Modification License v1.0 as - *  described in the file COPYING which is distributed with this source - *  code. - * - *  This program 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. - */ - -#include "ui_local.h" - -// this file is only included when building a dll -// syscalls.asm is included instead when building a qvm - -static long (QDECL *syscall)( long arg, ... ) = (long (QDECL *)( long, ...))-1; - -void dllEntry( long (QDECL *syscallptr)( long arg,... ) ) { -  syscall = syscallptr; -} - -int PASSFLOAT( float x ) { -  float  floatTemp; -  floatTemp = x; -  return *(int *)&floatTemp; -} - -void trap_Print( const char *string ) { -  syscall( UI_PRINT, string ); -} - -void trap_Error( const char *string ) { -  syscall( UI_ERROR, string ); -} - -int trap_Milliseconds( void ) { -  return syscall( UI_MILLISECONDS ); -} - -void trap_Cvar_Register( vmCvar_t *cvar, const char *var_name, const char *value, int flags ) { -  syscall( UI_CVAR_REGISTER, cvar, var_name, value, flags ); -} - -void trap_Cvar_Update( vmCvar_t *cvar ) { -  syscall( UI_CVAR_UPDATE, cvar ); -} - -void trap_Cvar_Set( const char *var_name, const char *value ) { -  syscall( UI_CVAR_SET, var_name, value ); -} - -float trap_Cvar_VariableValue( const char *var_name ) { -  int temp; -  temp = syscall( UI_CVAR_VARIABLEVALUE, var_name ); -  return (*(float*)&temp); -} - -void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ) { -  syscall( UI_CVAR_VARIABLESTRINGBUFFER, var_name, buffer, bufsize ); -} - -void trap_Cvar_SetValue( const char *var_name, float value ) { -  syscall( UI_CVAR_SETVALUE, var_name, PASSFLOAT( value ) ); -} - -void trap_Cvar_Reset( const char *name ) { -  syscall( UI_CVAR_RESET, name ); -} - -void trap_Cvar_Create( const char *var_name, const char *var_value, int flags ) { -  syscall( UI_CVAR_CREATE, var_name, var_value, flags ); -} - -void trap_Cvar_InfoStringBuffer( int bit, char *buffer, int bufsize ) { -  syscall( UI_CVAR_INFOSTRINGBUFFER, bit, buffer, bufsize ); -} - -int trap_Argc( void ) { -  return syscall( UI_ARGC ); -} - -void trap_Argv( int n, char *buffer, int bufferLength ) { -  syscall( UI_ARGV, n, buffer, bufferLength ); -} - -void trap_Cmd_ExecuteText( int exec_when, const char *text ) { -  syscall( UI_CMD_EXECUTETEXT, exec_when, text ); -} - -int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode ) { -  return syscall( UI_FS_FOPENFILE, qpath, f, mode ); -} - -void trap_FS_Read( void *buffer, int len, fileHandle_t f ) { -  syscall( UI_FS_READ, buffer, len, f ); -} - -void trap_FS_Write( const void *buffer, int len, fileHandle_t f ) { -  syscall( UI_FS_WRITE, buffer, len, f ); -} - -void trap_FS_FCloseFile( fileHandle_t f ) { -  syscall( UI_FS_FCLOSEFILE, f ); -} - -int trap_FS_GetFileList(  const char *path, const char *extension, char *listbuf, int bufsize ) { -  return syscall( UI_FS_GETFILELIST, path, extension, listbuf, bufsize ); -} - -int trap_FS_Seek( fileHandle_t f, long offset, int origin ) { -    return syscall( UI_FS_SEEK, f, offset, origin ); -} - -qhandle_t trap_R_RegisterModel( const char *name ) { -  return syscall( UI_R_REGISTERMODEL, name ); -} - -qhandle_t trap_R_RegisterSkin( const char *name ) { -  return syscall( UI_R_REGISTERSKIN, name ); -} - -void trap_R_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font) { -  syscall( UI_R_REGISTERFONT, fontName, pointSize, font ); -} - -qhandle_t trap_R_RegisterShaderNoMip( const char *name ) { -  return syscall( UI_R_REGISTERSHADERNOMIP, name ); -} - -void trap_R_ClearScene( void ) { -  syscall( UI_R_CLEARSCENE ); -} - -void trap_R_AddRefEntityToScene( const refEntity_t *re ) { -  syscall( UI_R_ADDREFENTITYTOSCENE, re ); -} - -void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts ) { -  syscall( UI_R_ADDPOLYTOSCENE, hShader, numVerts, verts ); -} - -void trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b ) { -  syscall( UI_R_ADDLIGHTTOSCENE, org, PASSFLOAT(intensity), PASSFLOAT(r), PASSFLOAT(g), PASSFLOAT(b) ); -} - -void trap_R_RenderScene( const refdef_t *fd ) { -  syscall( UI_R_RENDERSCENE, fd ); -} - -void trap_R_SetColor( const float *rgba ) { -  syscall( UI_R_SETCOLOR, rgba ); -} - -void trap_R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader ) { -  syscall( UI_R_DRAWSTRETCHPIC, PASSFLOAT(x), PASSFLOAT(y), PASSFLOAT(w), PASSFLOAT(h), PASSFLOAT(s1), PASSFLOAT(t1), PASSFLOAT(s2), PASSFLOAT(t2), hShader ); -} - -void  trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs ) { -  syscall( UI_R_MODELBOUNDS, model, mins, maxs ); -} - -void trap_UpdateScreen( void ) { -  syscall( UI_UPDATESCREEN ); -} - -int trap_CM_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, float frac, const char *tagName ) { -  return syscall( UI_CM_LERPTAG, tag, mod, startFrame, endFrame, PASSFLOAT(frac), tagName ); -} - -void trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum ) { -  syscall( UI_S_STARTLOCALSOUND, sfx, channelNum ); -} - -sfxHandle_t  trap_S_RegisterSound( const char *sample, qboolean compressed ) { -  return syscall( UI_S_REGISTERSOUND, sample, compressed ); -} - -void trap_Key_KeynumToStringBuf( int keynum, char *buf, int buflen ) { -  syscall( UI_KEY_KEYNUMTOSTRINGBUF, keynum, buf, buflen ); -} - -void trap_Key_GetBindingBuf( int keynum, char *buf, int buflen ) { -  syscall( UI_KEY_GETBINDINGBUF, keynum, buf, buflen ); -} - -void trap_Key_SetBinding( int keynum, const char *binding ) { -  syscall( UI_KEY_SETBINDING, keynum, binding ); -} - -qboolean trap_Key_IsDown( int keynum ) { -  return syscall( UI_KEY_ISDOWN, keynum ); -} - -qboolean trap_Key_GetOverstrikeMode( void ) { -  return syscall( UI_KEY_GETOVERSTRIKEMODE ); -} - -void trap_Key_SetOverstrikeMode( qboolean state ) { -  syscall( UI_KEY_SETOVERSTRIKEMODE, state ); -} - -void trap_Key_ClearStates( void ) { -  syscall( UI_KEY_CLEARSTATES ); -} - -int trap_Key_GetCatcher( void ) { -  return syscall( UI_KEY_GETCATCHER ); -} - -void trap_Key_SetCatcher( int catcher ) { -  syscall( UI_KEY_SETCATCHER, catcher ); -} - -void trap_GetClipboardData( char *buf, int bufsize ) { -  syscall( UI_GETCLIPBOARDDATA, buf, bufsize ); -} - -void trap_GetClientState( uiClientState_t *state ) { -  syscall( UI_GETCLIENTSTATE, state ); -} - -void trap_GetGlconfig( glconfig_t *glconfig ) { -  syscall( UI_GETGLCONFIG, glconfig ); -} - -int trap_GetConfigString( int index, char* buff, int buffsize ) { -  return syscall( UI_GETCONFIGSTRING, index, buff, buffsize ); -} - -int  trap_LAN_GetServerCount( int source ) { -  return syscall( UI_LAN_GETSERVERCOUNT, source ); -} - -void trap_LAN_GetServerAddressString( int source, int n, char *buf, int buflen ) { -  syscall( UI_LAN_GETSERVERADDRESSSTRING, source, n, buf, buflen ); -} - -void trap_LAN_GetServerInfo( int source, int n, char *buf, int buflen ) { -  syscall( UI_LAN_GETSERVERINFO, source, n, buf, buflen ); -} - -int trap_LAN_GetServerPing( int source, int n ) { -  return syscall( UI_LAN_GETSERVERPING, source, n ); -} - -int trap_LAN_GetPingQueueCount( void ) { -  return syscall( UI_LAN_GETPINGQUEUECOUNT ); -} - -int trap_LAN_ServerStatus( const char *serverAddress, char *serverStatus, int maxLen ) { -  return syscall( UI_LAN_SERVERSTATUS, serverAddress, serverStatus, maxLen ); -} - -void trap_LAN_SaveCachedServers( void ) { -  syscall( UI_LAN_SAVECACHEDSERVERS ); -} - -void trap_LAN_LoadCachedServers( void ) { -  syscall( UI_LAN_LOADCACHEDSERVERS ); -} - -void trap_LAN_ResetPings(int n) { -  syscall( UI_LAN_RESETPINGS, n ); -} - -void trap_LAN_ClearPing( int n ) { -  syscall( UI_LAN_CLEARPING, n ); -} - -void trap_LAN_GetPing( int n, char *buf, int buflen, int *pingtime ) { -  syscall( UI_LAN_GETPING, n, buf, buflen, pingtime ); -} - -void trap_LAN_GetPingInfo( int n, char *buf, int buflen ) { -  syscall( UI_LAN_GETPINGINFO, n, buf, buflen ); -} - -void trap_LAN_MarkServerVisible( int source, int n, qboolean visible ) { -  syscall( UI_LAN_MARKSERVERVISIBLE, source, n, visible ); -} - -int trap_LAN_ServerIsVisible( int source, int n) { -  return syscall( UI_LAN_SERVERISVISIBLE, source, n ); -} - -qboolean trap_LAN_UpdateVisiblePings( int source ) { -  return syscall( UI_LAN_UPDATEVISIBLEPINGS, source ); -} - -int trap_LAN_AddServer(int source, const char *name, const char *addr) { -  return syscall( UI_LAN_ADDSERVER, source, name, addr ); -} - -void trap_LAN_RemoveServer(int source, const char *addr) { -  syscall( UI_LAN_REMOVESERVER, source, addr ); -} - -int trap_LAN_CompareServers( int source, int sortKey, int sortDir, int s1, int s2 ) { -  return syscall( UI_LAN_COMPARESERVERS, source, sortKey, sortDir, s1, s2 ); -} - -int trap_MemoryRemaining( void ) { -  return syscall( UI_MEMORY_REMAINING ); -} - -void trap_GetCDKey( char *buf, int buflen ) { -  syscall( UI_GET_CDKEY, buf, buflen ); -} - -void trap_SetCDKey( char *buf ) { -  syscall( UI_SET_CDKEY, buf ); -} - -int trap_PC_AddGlobalDefine( char *define ) { -  return syscall( UI_PC_ADD_GLOBAL_DEFINE, define ); -} - -int trap_PC_LoadSource( const char *filename ) { -  return syscall( UI_PC_LOAD_SOURCE, filename ); -} - -int trap_PC_FreeSource( int handle ) { -  return syscall( UI_PC_FREE_SOURCE, handle ); -} - -int trap_PC_ReadToken( int handle, pc_token_t *pc_token ) { -  return syscall( UI_PC_READ_TOKEN, handle, pc_token ); -} - -int trap_PC_SourceFileAndLine( int handle, char *filename, int *line ) { -  return syscall( UI_PC_SOURCE_FILE_AND_LINE, handle, filename, line ); -} - -void trap_S_StopBackgroundTrack( void ) { -  syscall( UI_S_STOPBACKGROUNDTRACK ); -} - -void trap_S_StartBackgroundTrack( const char *intro, const char *loop) { -  syscall( UI_S_STARTBACKGROUNDTRACK, intro, loop ); -} - -int trap_RealTime(qtime_t *qtime) { -  return syscall( UI_REAL_TIME, qtime ); -} - -// this returns a handle.  arg0 is the name in the format "idlogo.roq", set arg1 to NULL, alteredstates to qfalse (do not alter gamestate) -int trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits) { -  return syscall(UI_CIN_PLAYCINEMATIC, arg0, xpos, ypos, width, height, bits); -} - -// stops playing the cinematic and ends it.  should always return FMV_EOF -// cinematics must be stopped in reverse order of when they are started -e_status trap_CIN_StopCinematic(int handle) { -  return syscall(UI_CIN_STOPCINEMATIC, handle); -} - - -// will run a frame of the cinematic but will not draw it.  Will return FMV_EOF if the end of the cinematic has been reached. -e_status trap_CIN_RunCinematic (int handle) { -  return syscall(UI_CIN_RUNCINEMATIC, handle); -} - - -// draws the current frame -void trap_CIN_DrawCinematic (int handle) { -  syscall(UI_CIN_DRAWCINEMATIC, handle); -} - - -// allows you to resize the animation dynamically -void trap_CIN_SetExtents (int handle, int x, int y, int w, int h) { -  syscall(UI_CIN_SETEXTENTS, handle, x, y, w, h); -} - - -void  trap_R_RemapShader( const char *oldShader, const char *newShader, const char *timeOffset ) { -  syscall( UI_R_REMAP_SHADER, oldShader, newShader, timeOffset ); -} - -qboolean trap_VerifyCDKey( const char *key, const char *chksum) { -  return syscall( UI_VERIFY_CDKEY, key, chksum); -} - -void trap_SetPbClStatus( int status ) { -    syscall( UI_SET_PBCLSTATUS, status ); -}  | 
